From b3a8abb8ecc6419a5bfb6c4b64e1568e207ae2ec Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Fri, 26 Jun 2026 19:04:30 -0700 Subject: [PATCH 1/4] =?UTF-8?q?perf(blocks):=20WIP=20Phase=201=20=E2=80=94?= =?UTF-8?q?=20per-block=20.display.ts=20+=20light=20manifest=20+=20migrate?= =?UTF-8?q?=20display=20sites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foundation for the registry decouple (plan: snug-brewing-mist.md). Splits each block's display fields into blocks/blocks/.display.ts (BlockDisplay satisfies BlockDisplay), the full config spreads it; adds blocks/manifest.ts (accessors) + blocks/manifest-data.ts (BLOCK_DISPLAY 300 + TOOL_TO_BLOCK; BLOCK_CATALOG deferred to 1b). Migrates 15 pure-display callsites off @/blocks/registry → @/blocks/manifest. registry.ts/registry-maps.ts untouched (full configs intact; manifest is a parallel light source). Generated by scripts/codemod-block-display.ts + scripts/generate-block-manifest-data.ts. type-check 0 errors; manifest(300) == registry(300), zero drift. WIP — before PR: rebase onto origin/staging (1 behind, downdetector) + re-run codemod; then Phase 1b (BLOCK_CATALOG + catalog consumers) and Phase 2 (lazy configs + preload, the dev-RAM win). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../integrations-showcase.tsx | 6 +- .../add-connector-modal.tsx | 4 +- .../connectors-section/connectors-section.tsx | 4 +- .../logs/components/log-details/utils.ts | 8 +- .../app/workspace/[workspaceId]/logs/logs.tsx | 4 +- .../app/workspace/[workspaceId]/logs/utils.ts | 4 +- .../workflow-sidebar/workflow-sidebar.tsx | 4 +- .../tables/[tableId]/hooks/use-table.ts | 4 +- .../output-select/output-select.tsx | 6 +- .../connection-blocks/connection-blocks.tsx | 4 +- .../[workflowId]/components/terminal/utils.ts | 6 +- apps/sim/blocks/blocks/a2a.display.ts | 18 + apps/sim/blocks/blocks/a2a.ts | 16 +- apps/sim/blocks/blocks/agent.display.ts | 16 + apps/sim/blocks/blocks/agent.ts | 15 +- apps/sim/blocks/blocks/agentmail.display.ts | 16 + apps/sim/blocks/blocks/agentmail.ts | 14 +- apps/sim/blocks/blocks/agentphone.display.ts | 16 + apps/sim/blocks/blocks/agentphone.ts | 14 +- apps/sim/blocks/blocks/agiloft.display.ts | 16 + apps/sim/blocks/blocks/agiloft.ts | 14 +- apps/sim/blocks/blocks/ahrefs.display.ts | 16 + apps/sim/blocks/blocks/ahrefs.ts | 14 +- apps/sim/blocks/blocks/airtable.display.ts | 16 + apps/sim/blocks/blocks/airtable.ts | 14 +- apps/sim/blocks/blocks/airweave.display.ts | 17 + apps/sim/blocks/blocks/airweave.ts | 15 +- apps/sim/blocks/blocks/algolia.display.ts | 17 + apps/sim/blocks/blocks/algolia.ts | 15 +- apps/sim/blocks/blocks/amplitude.display.ts | 17 + apps/sim/blocks/blocks/amplitude.ts | 15 +- apps/sim/blocks/blocks/api.display.ts | 16 + apps/sim/blocks/blocks/api.ts | 14 +- apps/sim/blocks/blocks/api_trigger.display.ts | 15 + apps/sim/blocks/blocks/api_trigger.ts | 13 +- apps/sim/blocks/blocks/apify.display.ts | 16 + apps/sim/blocks/blocks/apify.ts | 14 +- apps/sim/blocks/blocks/apollo.display.ts | 16 + apps/sim/blocks/blocks/apollo.ts | 14 +- apps/sim/blocks/blocks/appconfig.display.ts | 16 + apps/sim/blocks/blocks/appconfig.ts | 14 +- apps/sim/blocks/blocks/arxiv.display.ts | 16 + apps/sim/blocks/blocks/arxiv.ts | 13 +- apps/sim/blocks/blocks/asana.display.ts | 15 + apps/sim/blocks/blocks/asana.ts | 13 +- apps/sim/blocks/blocks/ashby.display.ts | 17 + apps/sim/blocks/blocks/ashby.ts | 15 +- apps/sim/blocks/blocks/athena.display.ts | 17 + apps/sim/blocks/blocks/athena.ts | 14 +- apps/sim/blocks/blocks/attio.display.ts | 16 + apps/sim/blocks/blocks/attio.ts | 14 +- .../sim/blocks/blocks/azure_devops.display.ts | 17 + apps/sim/blocks/blocks/azure_devops.ts | 15 +- apps/sim/blocks/blocks/box.display.ts | 16 + apps/sim/blocks/blocks/box.ts | 14 +- apps/sim/blocks/blocks/brandfetch.display.ts | 16 + apps/sim/blocks/blocks/brandfetch.ts | 14 +- apps/sim/blocks/blocks/brex.display.ts | 16 + apps/sim/blocks/blocks/brex.ts | 14 +- apps/sim/blocks/blocks/brightdata.display.ts | 16 + apps/sim/blocks/blocks/brightdata.ts | 14 +- apps/sim/blocks/blocks/browser_use.display.ts | 16 + apps/sim/blocks/blocks/browser_use.ts | 14 +- apps/sim/blocks/blocks/calcom.display.ts | 17 + apps/sim/blocks/blocks/calcom.ts | 15 +- apps/sim/blocks/blocks/calendly.display.ts | 17 + apps/sim/blocks/blocks/calendly.ts | 15 +- .../sim/blocks/blocks/chat_trigger.display.ts | 18 + apps/sim/blocks/blocks/chat_trigger.ts | 11 +- apps/sim/blocks/blocks/circleback.display.ts | 17 + apps/sim/blocks/blocks/circleback.ts | 15 +- apps/sim/blocks/blocks/clay.display.ts | 15 + apps/sim/blocks/blocks/clay.ts | 13 +- apps/sim/blocks/blocks/clerk.display.ts | 16 + apps/sim/blocks/blocks/clerk.ts | 14 +- apps/sim/blocks/blocks/clickhouse.display.ts | 16 + apps/sim/blocks/blocks/clickhouse.ts | 13 +- apps/sim/blocks/blocks/cloudflare.display.ts | 16 + apps/sim/blocks/blocks/cloudflare.ts | 14 +- .../blocks/blocks/cloudformation.display.ts | 17 + apps/sim/blocks/blocks/cloudformation.ts | 14 +- apps/sim/blocks/blocks/cloudwatch.display.ts | 17 + apps/sim/blocks/blocks/cloudwatch.ts | 14 +- .../sim/blocks/blocks/codepipeline.display.ts | 17 + apps/sim/blocks/blocks/codepipeline.ts | 15 +- apps/sim/blocks/blocks/condition.display.ts | 14 + apps/sim/blocks/blocks/condition.ts | 12 +- apps/sim/blocks/blocks/confluence.display.ts | 24 + apps/sim/blocks/blocks/confluence.ts | 22 +- apps/sim/blocks/blocks/context_dev.display.ts | 16 + apps/sim/blocks/blocks/context_dev.ts | 14 +- apps/sim/blocks/blocks/convex.display.ts | 16 + apps/sim/blocks/blocks/convex.ts | 14 +- apps/sim/blocks/blocks/credential.display.ts | 14 + apps/sim/blocks/blocks/credential.ts | 12 +- apps/sim/blocks/blocks/crowdstrike.display.ts | 17 + apps/sim/blocks/blocks/crowdstrike.ts | 15 +- apps/sim/blocks/blocks/cursor.display.ts | 27 + apps/sim/blocks/blocks/cursor.ts | 22 +- apps/sim/blocks/blocks/dagster.display.ts | 16 + apps/sim/blocks/blocks/dagster.ts | 14 +- apps/sim/blocks/blocks/databricks.display.ts | 16 + apps/sim/blocks/blocks/databricks.ts | 14 +- apps/sim/blocks/blocks/datadog.display.ts | 17 + apps/sim/blocks/blocks/datadog.ts | 15 +- apps/sim/blocks/blocks/datagma.display.ts | 16 + apps/sim/blocks/blocks/datagma.ts | 15 +- apps/sim/blocks/blocks/daytona.display.ts | 16 + apps/sim/blocks/blocks/daytona.ts | 14 +- apps/sim/blocks/blocks/deployments.display.ts | 15 + apps/sim/blocks/blocks/deployments.ts | 13 +- apps/sim/blocks/blocks/devin.display.ts | 16 + apps/sim/blocks/blocks/devin.ts | 14 +- apps/sim/blocks/blocks/discord.display.ts | 17 + apps/sim/blocks/blocks/discord.ts | 15 +- apps/sim/blocks/blocks/docusign.display.ts | 16 + apps/sim/blocks/blocks/docusign.ts | 14 +- apps/sim/blocks/blocks/dropbox.display.ts | 17 + apps/sim/blocks/blocks/dropbox.ts | 15 +- apps/sim/blocks/blocks/dropcontact.display.ts | 16 + apps/sim/blocks/blocks/dropcontact.ts | 15 +- apps/sim/blocks/blocks/dspy.display.ts | 16 + apps/sim/blocks/blocks/dspy.ts | 14 +- apps/sim/blocks/blocks/dub.display.ts | 16 + apps/sim/blocks/blocks/dub.ts | 14 +- apps/sim/blocks/blocks/duckduckgo.display.ts | 16 + apps/sim/blocks/blocks/duckduckgo.ts | 13 +- apps/sim/blocks/blocks/dynamodb.display.ts | 17 + apps/sim/blocks/blocks/dynamodb.ts | 15 +- .../blocks/blocks/elasticsearch.display.ts | 16 + apps/sim/blocks/blocks/elasticsearch.ts | 14 +- apps/sim/blocks/blocks/elevenlabs.display.ts | 15 + apps/sim/blocks/blocks/elevenlabs.ts | 13 +- apps/sim/blocks/blocks/emailbison.display.ts | 17 + apps/sim/blocks/blocks/emailbison.ts | 15 +- apps/sim/blocks/blocks/enrich.display.ts | 16 + apps/sim/blocks/blocks/enrich.ts | 14 +- apps/sim/blocks/blocks/enrichment.display.ts | 16 + apps/sim/blocks/blocks/enrichment.ts | 14 +- apps/sim/blocks/blocks/enrow.display.ts | 16 + apps/sim/blocks/blocks/enrow.ts | 15 +- apps/sim/blocks/blocks/evaluator.display.ts | 14 + apps/sim/blocks/blocks/evaluator.ts | 12 +- apps/sim/blocks/blocks/evernote.display.ts | 16 + apps/sim/blocks/blocks/evernote.ts | 14 +- apps/sim/blocks/blocks/exa.display.ts | 17 + apps/sim/blocks/blocks/exa.ts | 15 +- apps/sim/blocks/blocks/extend.display.ts | 26 + apps/sim/blocks/blocks/extend.ts | 27 +- apps/sim/blocks/blocks/fathom.display.ts | 17 + apps/sim/blocks/blocks/fathom.ts | 15 +- apps/sim/blocks/blocks/file.display.ts | 59 + apps/sim/blocks/blocks/file.ts | 52 +- apps/sim/blocks/blocks/findymail.display.ts | 16 + apps/sim/blocks/blocks/findymail.ts | 14 +- apps/sim/blocks/blocks/firecrawl.display.ts | 16 + apps/sim/blocks/blocks/firecrawl.ts | 14 +- apps/sim/blocks/blocks/fireflies.display.ts | 27 + apps/sim/blocks/blocks/fireflies.ts | 22 +- apps/sim/blocks/blocks/function.display.ts | 14 + apps/sim/blocks/blocks/function.ts | 12 +- apps/sim/blocks/blocks/gamma.display.ts | 16 + apps/sim/blocks/blocks/gamma.ts | 14 +- .../blocks/blocks/generic_webhook.display.ts | 17 + apps/sim/blocks/blocks/generic_webhook.ts | 15 +- apps/sim/blocks/blocks/github.display.ts | 26 + apps/sim/blocks/blocks/github.ts | 21 +- apps/sim/blocks/blocks/gitlab.display.ts | 17 + apps/sim/blocks/blocks/gitlab.ts | 15 +- apps/sim/blocks/blocks/gmail.display.ts | 26 + apps/sim/blocks/blocks/gmail.ts | 21 +- apps/sim/blocks/blocks/gong.display.ts | 18 + apps/sim/blocks/blocks/gong.ts | 16 +- apps/sim/blocks/blocks/google.display.ts | 15 + apps/sim/blocks/blocks/google.ts | 13 +- apps/sim/blocks/blocks/google_ads.display.ts | 16 + apps/sim/blocks/blocks/google_ads.ts | 14 +- .../blocks/blocks/google_bigquery.display.ts | 16 + apps/sim/blocks/blocks/google_bigquery.ts | 14 +- .../sim/blocks/blocks/google_books.display.ts | 16 + apps/sim/blocks/blocks/google_books.ts | 14 +- .../blocks/blocks/google_calendar.display.ts | 25 + apps/sim/blocks/blocks/google_calendar.ts | 23 +- .../blocks/blocks/google_contacts.display.ts | 16 + apps/sim/blocks/blocks/google_contacts.ts | 14 +- apps/sim/blocks/blocks/google_docs.display.ts | 16 + apps/sim/blocks/blocks/google_docs.ts | 14 +- .../sim/blocks/blocks/google_drive.display.ts | 16 + apps/sim/blocks/blocks/google_drive.ts | 14 +- .../sim/blocks/blocks/google_forms.display.ts | 16 + apps/sim/blocks/blocks/google_forms.ts | 13 +- .../blocks/blocks/google_groups.display.ts | 16 + apps/sim/blocks/blocks/google_groups.ts | 14 +- apps/sim/blocks/blocks/google_maps.display.ts | 16 + apps/sim/blocks/blocks/google_maps.ts | 14 +- apps/sim/blocks/blocks/google_meet.display.ts | 16 + apps/sim/blocks/blocks/google_meet.ts | 14 +- .../blocks/blocks/google_pagespeed.display.ts | 16 + apps/sim/blocks/blocks/google_pagespeed.ts | 14 +- .../blocks/blocks/google_sheets.display.ts | 31 + apps/sim/blocks/blocks/google_sheets.ts | 30 +- .../blocks/blocks/google_slides.display.ts | 26 + apps/sim/blocks/blocks/google_slides.ts | 24 +- .../sim/blocks/blocks/google_tasks.display.ts | 16 + apps/sim/blocks/blocks/google_tasks.ts | 14 +- .../blocks/blocks/google_translate.display.ts | 16 + apps/sim/blocks/blocks/google_translate.ts | 14 +- .../sim/blocks/blocks/google_vault.display.ts | 16 + apps/sim/blocks/blocks/google_vault.ts | 15 +- apps/sim/blocks/blocks/grafana.display.ts | 16 + apps/sim/blocks/blocks/grafana.ts | 14 +- apps/sim/blocks/blocks/grain.display.ts | 17 + apps/sim/blocks/blocks/grain.ts | 15 +- apps/sim/blocks/blocks/granola.display.ts | 16 + apps/sim/blocks/blocks/granola.ts | 14 +- apps/sim/blocks/blocks/greenhouse.display.ts | 17 + apps/sim/blocks/blocks/greenhouse.ts | 15 +- apps/sim/blocks/blocks/greptile.display.ts | 16 + apps/sim/blocks/blocks/greptile.ts | 14 +- apps/sim/blocks/blocks/guardrails.display.ts | 14 + apps/sim/blocks/blocks/guardrails.ts | 12 +- apps/sim/blocks/blocks/hex.display.ts | 16 + apps/sim/blocks/blocks/hex.ts | 14 +- apps/sim/blocks/blocks/hubspot.display.ts | 18 + apps/sim/blocks/blocks/hubspot.ts | 16 +- apps/sim/blocks/blocks/huggingface.display.ts | 16 + apps/sim/blocks/blocks/huggingface.ts | 14 +- .../blocks/human_in_the_loop.display.ts | 14 + apps/sim/blocks/blocks/human_in_the_loop.ts | 12 +- apps/sim/blocks/blocks/hunter.display.ts | 16 + apps/sim/blocks/blocks/hunter.ts | 14 +- apps/sim/blocks/blocks/iam.display.ts | 16 + apps/sim/blocks/blocks/iam.ts | 14 +- apps/sim/blocks/blocks/icypeas.display.ts | 16 + apps/sim/blocks/blocks/icypeas.ts | 15 +- .../blocks/blocks/identity_center.display.ts | 16 + apps/sim/blocks/blocks/identity_center.ts | 14 +- .../blocks/blocks/image_generator.display.ts | 30 + apps/sim/blocks/blocks/image_generator.ts | 30 +- apps/sim/blocks/blocks/imap.display.ts | 18 + apps/sim/blocks/blocks/imap.ts | 15 +- apps/sim/blocks/blocks/incidentio.display.ts | 16 + apps/sim/blocks/blocks/incidentio.ts | 14 +- apps/sim/blocks/blocks/infisical.display.ts | 16 + apps/sim/blocks/blocks/infisical.ts | 14 +- .../blocks/blocks/input_trigger.display.ts | 19 + apps/sim/blocks/blocks/input_trigger.ts | 12 +- apps/sim/blocks/blocks/instantly.display.ts | 16 + apps/sim/blocks/blocks/instantly.ts | 14 +- apps/sim/blocks/blocks/intercom.display.ts | 25 + apps/sim/blocks/blocks/intercom.ts | 20 +- apps/sim/blocks/blocks/jina.display.ts | 16 + apps/sim/blocks/blocks/jina.ts | 14 +- apps/sim/blocks/blocks/jira.display.ts | 17 + apps/sim/blocks/blocks/jira.ts | 15 +- .../blocks/jira_service_management.display.ts | 16 + .../blocks/blocks/jira_service_management.ts | 14 +- apps/sim/blocks/blocks/kalshi.display.ts | 29 + apps/sim/blocks/blocks/kalshi.ts | 24 +- apps/sim/blocks/blocks/ketch.display.ts | 16 + apps/sim/blocks/blocks/ketch.ts | 13 +- apps/sim/blocks/blocks/knowledge.display.ts | 14 + apps/sim/blocks/blocks/knowledge.ts | 12 +- apps/sim/blocks/blocks/langsmith.display.ts | 16 + apps/sim/blocks/blocks/langsmith.ts | 14 +- apps/sim/blocks/blocks/latex.display.ts | 16 + apps/sim/blocks/blocks/latex.ts | 13 +- .../sim/blocks/blocks/launchdarkly.display.ts | 17 + apps/sim/blocks/blocks/launchdarkly.ts | 15 +- apps/sim/blocks/blocks/leadmagic.display.ts | 16 + apps/sim/blocks/blocks/leadmagic.ts | 15 +- apps/sim/blocks/blocks/lemlist.display.ts | 16 + apps/sim/blocks/blocks/lemlist.ts | 14 +- apps/sim/blocks/blocks/linear.display.ts | 25 + apps/sim/blocks/blocks/linear.ts | 20 +- apps/sim/blocks/blocks/linkedin.display.ts | 17 + apps/sim/blocks/blocks/linkedin.ts | 15 +- apps/sim/blocks/blocks/linkup.display.ts | 15 + apps/sim/blocks/blocks/linkup.ts | 13 +- apps/sim/blocks/blocks/linq.display.ts | 16 + apps/sim/blocks/blocks/linq.ts | 14 +- apps/sim/blocks/blocks/logs.display.ts | 27 + apps/sim/blocks/blocks/logs.ts | 23 +- apps/sim/blocks/blocks/loops.display.ts | 16 + apps/sim/blocks/blocks/loops.ts | 14 +- apps/sim/blocks/blocks/luma.display.ts | 16 + apps/sim/blocks/blocks/luma.ts | 14 +- apps/sim/blocks/blocks/mailchimp.display.ts | 16 + apps/sim/blocks/blocks/mailchimp.ts | 14 +- apps/sim/blocks/blocks/mailgun.display.ts | 16 + apps/sim/blocks/blocks/mailgun.ts | 14 +- .../blocks/blocks/manual_trigger.display.ts | 19 + apps/sim/blocks/blocks/manual_trigger.ts | 12 +- apps/sim/blocks/blocks/mcp.display.ts | 16 + apps/sim/blocks/blocks/mcp.ts | 14 +- apps/sim/blocks/blocks/mem0.display.ts | 15 + apps/sim/blocks/blocks/mem0.ts | 13 +- apps/sim/blocks/blocks/memory.display.ts | 14 + apps/sim/blocks/blocks/memory.ts | 12 +- .../sim/blocks/blocks/microsoft_ad.display.ts | 16 + apps/sim/blocks/blocks/microsoft_ad.ts | 14 +- .../blocks/microsoft_dataverse.display.ts | 16 + apps/sim/blocks/blocks/microsoft_dataverse.ts | 14 +- .../blocks/blocks/microsoft_excel.display.ts | 31 + apps/sim/blocks/blocks/microsoft_excel.ts | 30 +- .../blocks/microsoft_planner.display.ts | 16 + apps/sim/blocks/blocks/microsoft_planner.ts | 14 +- .../blocks/blocks/microsoft_teams.display.ts | 17 + apps/sim/blocks/blocks/microsoft_teams.ts | 15 +- .../blocks/blocks/millionverifier.display.ts | 16 + apps/sim/blocks/blocks/millionverifier.ts | 15 +- .../blocks/blocks/mistral_parse.display.ts | 32 + apps/sim/blocks/blocks/mistral_parse.ts | 32 +- apps/sim/blocks/blocks/monday.display.ts | 16 + apps/sim/blocks/blocks/monday.ts | 14 +- apps/sim/blocks/blocks/mongodb.display.ts | 16 + apps/sim/blocks/blocks/mongodb.ts | 13 +- apps/sim/blocks/blocks/mothership.display.ts | 13 + apps/sim/blocks/blocks/mothership.ts | 11 +- apps/sim/blocks/blocks/mysql.display.ts | 16 + apps/sim/blocks/blocks/mysql.ts | 14 +- apps/sim/blocks/blocks/neo4j.display.ts | 16 + apps/sim/blocks/blocks/neo4j.ts | 13 +- apps/sim/blocks/blocks/neverbounce.display.ts | 16 + apps/sim/blocks/blocks/neverbounce.ts | 15 +- apps/sim/blocks/blocks/new_relic.display.ts | 16 + apps/sim/blocks/blocks/new_relic.ts | 14 +- apps/sim/blocks/blocks/note.display.ts | 13 + apps/sim/blocks/blocks/note.ts | 11 +- apps/sim/blocks/blocks/notion.display.ts | 31 + apps/sim/blocks/blocks/notion.ts | 27 +- apps/sim/blocks/blocks/obsidian.display.ts | 16 + apps/sim/blocks/blocks/obsidian.ts | 14 +- apps/sim/blocks/blocks/okta.display.ts | 17 + apps/sim/blocks/blocks/okta.ts | 15 +- apps/sim/blocks/blocks/onedrive.display.ts | 16 + apps/sim/blocks/blocks/onedrive.ts | 14 +- apps/sim/blocks/blocks/onepassword.display.ts | 16 + apps/sim/blocks/blocks/onepassword.ts | 14 +- apps/sim/blocks/blocks/openai.display.ts | 15 + apps/sim/blocks/blocks/openai.ts | 13 +- apps/sim/blocks/blocks/outlook.display.ts | 17 + apps/sim/blocks/blocks/outlook.ts | 15 +- apps/sim/blocks/blocks/pagerduty.display.ts | 18 + apps/sim/blocks/blocks/pagerduty.ts | 16 +- apps/sim/blocks/blocks/parallel.display.ts | 16 + apps/sim/blocks/blocks/parallel.ts | 14 +- .../blocks/blocks/peopledatalabs.display.ts | 17 + apps/sim/blocks/blocks/peopledatalabs.ts | 15 +- apps/sim/blocks/blocks/perplexity.display.ts | 17 + apps/sim/blocks/blocks/perplexity.ts | 17 +- apps/sim/blocks/blocks/persona.display.ts | 16 + apps/sim/blocks/blocks/persona.ts | 14 +- apps/sim/blocks/blocks/pi.display.ts | 15 + apps/sim/blocks/blocks/pi.ts | 14 +- apps/sim/blocks/blocks/pinecone.display.ts | 16 + apps/sim/blocks/blocks/pinecone.ts | 14 +- apps/sim/blocks/blocks/pipedrive.display.ts | 17 + apps/sim/blocks/blocks/pipedrive.ts | 15 +- apps/sim/blocks/blocks/polymarket.display.ts | 17 + apps/sim/blocks/blocks/polymarket.ts | 14 +- apps/sim/blocks/blocks/postgresql.display.ts | 16 + apps/sim/blocks/blocks/postgresql.ts | 14 +- apps/sim/blocks/blocks/posthog.display.ts | 16 + apps/sim/blocks/blocks/posthog.ts | 14 +- apps/sim/blocks/blocks/profound.display.ts | 16 + apps/sim/blocks/blocks/profound.ts | 14 +- apps/sim/blocks/blocks/prospeo.display.ts | 16 + apps/sim/blocks/blocks/prospeo.ts | 14 +- apps/sim/blocks/blocks/pulse.display.ts | 26 + apps/sim/blocks/blocks/pulse.ts | 27 +- apps/sim/blocks/blocks/qdrant.display.ts | 15 + apps/sim/blocks/blocks/qdrant.ts | 13 +- apps/sim/blocks/blocks/quartr.display.ts | 16 + apps/sim/blocks/blocks/quartr.ts | 14 +- apps/sim/blocks/blocks/quiver.display.ts | 16 + apps/sim/blocks/blocks/quiver.ts | 14 +- apps/sim/blocks/blocks/railway.display.ts | 16 + apps/sim/blocks/blocks/railway.ts | 14 +- apps/sim/blocks/blocks/rb2b.display.ts | 16 + apps/sim/blocks/blocks/rb2b.ts | 14 +- apps/sim/blocks/blocks/rds.display.ts | 17 + apps/sim/blocks/blocks/rds.ts | 14 +- apps/sim/blocks/blocks/reddit.display.ts | 17 + apps/sim/blocks/blocks/reddit.ts | 15 +- apps/sim/blocks/blocks/redis.display.ts | 17 + apps/sim/blocks/blocks/redis.ts | 15 +- apps/sim/blocks/blocks/reducto.display.ts | 24 + apps/sim/blocks/blocks/reducto.ts | 25 +- apps/sim/blocks/blocks/resend.display.ts | 16 + apps/sim/blocks/blocks/resend.ts | 14 +- apps/sim/blocks/blocks/response.display.ts | 14 + apps/sim/blocks/blocks/response.ts | 12 +- apps/sim/blocks/blocks/revenuecat.display.ts | 17 + apps/sim/blocks/blocks/revenuecat.ts | 15 +- apps/sim/blocks/blocks/rippling.display.ts | 16 + apps/sim/blocks/blocks/rippling.ts | 14 +- apps/sim/blocks/blocks/rootly.display.ts | 17 + apps/sim/blocks/blocks/rootly.ts | 15 +- apps/sim/blocks/blocks/router.display.ts | 27 + apps/sim/blocks/blocks/router.ts | 25 +- apps/sim/blocks/blocks/rss.display.ts | 17 + apps/sim/blocks/blocks/rss.ts | 15 +- apps/sim/blocks/blocks/s3.display.ts | 16 + apps/sim/blocks/blocks/s3.ts | 14 +- apps/sim/blocks/blocks/salesforce.display.ts | 16 + apps/sim/blocks/blocks/salesforce.ts | 14 +- apps/sim/blocks/blocks/sap_concur.display.ts | 16 + apps/sim/blocks/blocks/sap_concur.ts | 14 +- apps/sim/blocks/blocks/sap_s4hana.display.ts | 16 + apps/sim/blocks/blocks/sap_s4hana.ts | 14 +- apps/sim/blocks/blocks/schedule.display.ts | 19 + apps/sim/blocks/blocks/schedule.ts | 12 +- apps/sim/blocks/blocks/search.display.ts | 15 + apps/sim/blocks/blocks/search.ts | 13 +- .../blocks/blocks/secrets_manager.display.ts | 16 + apps/sim/blocks/blocks/secrets_manager.ts | 13 +- apps/sim/blocks/blocks/sendblue.display.ts | 16 + apps/sim/blocks/blocks/sendblue.ts | 14 +- apps/sim/blocks/blocks/sendgrid.display.ts | 16 + apps/sim/blocks/blocks/sendgrid.ts | 14 +- apps/sim/blocks/blocks/sentry.display.ts | 16 + apps/sim/blocks/blocks/sentry.ts | 14 +- apps/sim/blocks/blocks/serper.display.ts | 15 + apps/sim/blocks/blocks/serper.ts | 13 +- apps/sim/blocks/blocks/servicenow.display.ts | 16 + apps/sim/blocks/blocks/servicenow.ts | 14 +- apps/sim/blocks/blocks/ses.display.ts | 16 + apps/sim/blocks/blocks/ses.ts | 14 +- apps/sim/blocks/blocks/sftp.display.ts | 16 + apps/sim/blocks/blocks/sftp.ts | 15 +- apps/sim/blocks/blocks/sharepoint.display.ts | 24 + apps/sim/blocks/blocks/sharepoint.ts | 22 +- apps/sim/blocks/blocks/shopify.display.ts | 16 + apps/sim/blocks/blocks/shopify.ts | 14 +- .../blocks/sim_workspace_event.display.ts | 14 + apps/sim/blocks/blocks/sim_workspace_event.ts | 12 +- apps/sim/blocks/blocks/similarweb.display.ts | 16 + apps/sim/blocks/blocks/similarweb.ts | 14 +- apps/sim/blocks/blocks/sixtyfour.display.ts | 16 + apps/sim/blocks/blocks/sixtyfour.ts | 14 +- apps/sim/blocks/blocks/slack.display.ts | 18 + apps/sim/blocks/blocks/slack.ts | 16 +- apps/sim/blocks/blocks/smtp.display.ts | 16 + apps/sim/blocks/blocks/smtp.ts | 15 +- apps/sim/blocks/blocks/sportmonks.display.ts | 16 + apps/sim/blocks/blocks/sportmonks.ts | 14 +- apps/sim/blocks/blocks/spotify.display.ts | 17 + apps/sim/blocks/blocks/spotify.ts | 15 +- apps/sim/blocks/blocks/sqs.display.ts | 16 + apps/sim/blocks/blocks/sqs.ts | 13 +- apps/sim/blocks/blocks/square.display.ts | 16 + apps/sim/blocks/blocks/square.ts | 14 +- apps/sim/blocks/blocks/ssh.display.ts | 16 + apps/sim/blocks/blocks/ssh.ts | 15 +- apps/sim/blocks/blocks/stagehand.display.ts | 16 + apps/sim/blocks/blocks/stagehand.ts | 14 +- .../blocks/blocks/start_trigger.display.ts | 16 + apps/sim/blocks/blocks/start_trigger.ts | 14 +- apps/sim/blocks/blocks/starter.display.ts | 13 + apps/sim/blocks/blocks/starter.ts | 11 +- apps/sim/blocks/blocks/stripe.display.ts | 17 + apps/sim/blocks/blocks/stripe.ts | 15 +- apps/sim/blocks/blocks/sts.display.ts | 16 + apps/sim/blocks/blocks/sts.ts | 14 +- apps/sim/blocks/blocks/stt.display.ts | 24 + apps/sim/blocks/blocks/stt.ts | 20 +- apps/sim/blocks/blocks/supabase.display.ts | 16 + apps/sim/blocks/blocks/supabase.ts | 14 +- apps/sim/blocks/blocks/table.display.ts | 14 + apps/sim/blocks/blocks/table.ts | 12 +- apps/sim/blocks/blocks/tailscale.display.ts | 16 + apps/sim/blocks/blocks/tailscale.ts | 14 +- apps/sim/blocks/blocks/tavily.display.ts | 16 + apps/sim/blocks/blocks/tavily.ts | 14 +- apps/sim/blocks/blocks/telegram.display.ts | 17 + apps/sim/blocks/blocks/telegram.ts | 15 +- apps/sim/blocks/blocks/temporal.display.ts | 16 + apps/sim/blocks/blocks/temporal.ts | 14 +- apps/sim/blocks/blocks/textract.display.ts | 24 + apps/sim/blocks/blocks/textract.ts | 25 +- apps/sim/blocks/blocks/thinking.display.ts | 15 + apps/sim/blocks/blocks/thinking.ts | 14 +- apps/sim/blocks/blocks/thrive.display.ts | 16 + apps/sim/blocks/blocks/thrive.ts | 14 +- apps/sim/blocks/blocks/tinybird.display.ts | 16 + apps/sim/blocks/blocks/tinybird.ts | 14 +- apps/sim/blocks/blocks/translate.display.ts | 15 + apps/sim/blocks/blocks/translate.ts | 14 +- apps/sim/blocks/blocks/trello.display.ts | 16 + apps/sim/blocks/blocks/trello.ts | 14 +- apps/sim/blocks/blocks/trigger_dev.display.ts | 16 + apps/sim/blocks/blocks/trigger_dev.ts | 14 +- apps/sim/blocks/blocks/tts.display.ts | 16 + apps/sim/blocks/blocks/tts.ts | 15 +- apps/sim/blocks/blocks/twilio.display.ts | 16 + apps/sim/blocks/blocks/twilio.ts | 16 +- .../sim/blocks/blocks/twilio_voice.display.ts | 18 + apps/sim/blocks/blocks/twilio_voice.ts | 18 +- apps/sim/blocks/blocks/typeform.display.ts | 16 + apps/sim/blocks/blocks/typeform.ts | 16 +- apps/sim/blocks/blocks/upstash.display.ts | 16 + apps/sim/blocks/blocks/upstash.ts | 14 +- apps/sim/blocks/blocks/vanta.display.ts | 16 + apps/sim/blocks/blocks/vanta.ts | 14 +- apps/sim/blocks/blocks/variables.display.ts | 14 + apps/sim/blocks/blocks/variables.ts | 12 +- apps/sim/blocks/blocks/vercel.display.ts | 16 + apps/sim/blocks/blocks/vercel.ts | 14 +- .../blocks/blocks/video_generator.display.ts | 39 + apps/sim/blocks/blocks/video_generator.ts | 36 +- apps/sim/blocks/blocks/vision.display.ts | 24 + apps/sim/blocks/blocks/vision.ts | 20 +- apps/sim/blocks/blocks/wait.display.ts | 18 + apps/sim/blocks/blocks/wait.ts | 11 +- apps/sim/blocks/blocks/wealthbox.display.ts | 16 + apps/sim/blocks/blocks/wealthbox.ts | 14 +- apps/sim/blocks/blocks/webflow.display.ts | 17 + apps/sim/blocks/blocks/webflow.ts | 15 +- .../blocks/blocks/webhook_request.display.ts | 14 + apps/sim/blocks/blocks/webhook_request.ts | 12 +- apps/sim/blocks/blocks/whatsapp.display.ts | 17 + apps/sim/blocks/blocks/whatsapp.ts | 15 +- apps/sim/blocks/blocks/wikipedia.display.ts | 16 + apps/sim/blocks/blocks/wikipedia.ts | 13 +- apps/sim/blocks/blocks/wiza.display.ts | 17 + apps/sim/blocks/blocks/wiza.ts | 15 +- apps/sim/blocks/blocks/wordpress.display.ts | 17 + apps/sim/blocks/blocks/wordpress.ts | 15 +- apps/sim/blocks/blocks/workday.display.ts | 16 + apps/sim/blocks/blocks/workday.ts | 13 +- apps/sim/blocks/blocks/workflow.display.ts | 13 + apps/sim/blocks/blocks/workflow.ts | 11 +- .../blocks/blocks/workflow_input.display.ts | 13 + apps/sim/blocks/blocks/workflow_input.ts | 11 +- apps/sim/blocks/blocks/x.display.ts | 16 + apps/sim/blocks/blocks/x.ts | 14 +- apps/sim/blocks/blocks/youtube.display.ts | 16 + apps/sim/blocks/blocks/youtube.ts | 14 +- apps/sim/blocks/blocks/zendesk.display.ts | 17 + apps/sim/blocks/blocks/zendesk.ts | 15 +- apps/sim/blocks/blocks/zep.display.ts | 16 + apps/sim/blocks/blocks/zep.ts | 14 +- apps/sim/blocks/blocks/zerobounce.display.ts | 16 + apps/sim/blocks/blocks/zerobounce.ts | 15 +- apps/sim/blocks/blocks/zoom.display.ts | 17 + apps/sim/blocks/blocks/zoom.ts | 15 +- apps/sim/blocks/blocks/zoominfo.display.ts | 16 + apps/sim/blocks/blocks/zoominfo.ts | 14 +- apps/sim/blocks/icon-color.ts | 4 +- apps/sim/blocks/integration-matcher.ts | 4 +- apps/sim/blocks/manifest-data.ts | 4338 +++++++++++++++++ apps/sim/blocks/manifest.ts | 149 + apps/sim/lib/logs/get-trigger-options.ts | 4 +- .../sim/lib/permission-groups/block-access.ts | 4 +- apps/sim/package.json | 1 + apps/sim/scripts/codemod-block-display.ts | 213 + .../scripts/generate-block-manifest-data.ts | 83 + 558 files changed, 10277 insertions(+), 3298 deletions(-) create mode 100644 apps/sim/blocks/blocks/a2a.display.ts create mode 100644 apps/sim/blocks/blocks/agent.display.ts create mode 100644 apps/sim/blocks/blocks/agentmail.display.ts create mode 100644 apps/sim/blocks/blocks/agentphone.display.ts create mode 100644 apps/sim/blocks/blocks/agiloft.display.ts create mode 100644 apps/sim/blocks/blocks/ahrefs.display.ts create mode 100644 apps/sim/blocks/blocks/airtable.display.ts create mode 100644 apps/sim/blocks/blocks/airweave.display.ts create mode 100644 apps/sim/blocks/blocks/algolia.display.ts create mode 100644 apps/sim/blocks/blocks/amplitude.display.ts create mode 100644 apps/sim/blocks/blocks/api.display.ts create mode 100644 apps/sim/blocks/blocks/api_trigger.display.ts create mode 100644 apps/sim/blocks/blocks/apify.display.ts create mode 100644 apps/sim/blocks/blocks/apollo.display.ts create mode 100644 apps/sim/blocks/blocks/appconfig.display.ts create mode 100644 apps/sim/blocks/blocks/arxiv.display.ts create mode 100644 apps/sim/blocks/blocks/asana.display.ts create mode 100644 apps/sim/blocks/blocks/ashby.display.ts create mode 100644 apps/sim/blocks/blocks/athena.display.ts create mode 100644 apps/sim/blocks/blocks/attio.display.ts create mode 100644 apps/sim/blocks/blocks/azure_devops.display.ts create mode 100644 apps/sim/blocks/blocks/box.display.ts create mode 100644 apps/sim/blocks/blocks/brandfetch.display.ts create mode 100644 apps/sim/blocks/blocks/brex.display.ts create mode 100644 apps/sim/blocks/blocks/brightdata.display.ts create mode 100644 apps/sim/blocks/blocks/browser_use.display.ts create mode 100644 apps/sim/blocks/blocks/calcom.display.ts create mode 100644 apps/sim/blocks/blocks/calendly.display.ts create mode 100644 apps/sim/blocks/blocks/chat_trigger.display.ts create mode 100644 apps/sim/blocks/blocks/circleback.display.ts create mode 100644 apps/sim/blocks/blocks/clay.display.ts create mode 100644 apps/sim/blocks/blocks/clerk.display.ts create mode 100644 apps/sim/blocks/blocks/clickhouse.display.ts create mode 100644 apps/sim/blocks/blocks/cloudflare.display.ts create mode 100644 apps/sim/blocks/blocks/cloudformation.display.ts create mode 100644 apps/sim/blocks/blocks/cloudwatch.display.ts create mode 100644 apps/sim/blocks/blocks/codepipeline.display.ts create mode 100644 apps/sim/blocks/blocks/condition.display.ts create mode 100644 apps/sim/blocks/blocks/confluence.display.ts create mode 100644 apps/sim/blocks/blocks/context_dev.display.ts create mode 100644 apps/sim/blocks/blocks/convex.display.ts create mode 100644 apps/sim/blocks/blocks/credential.display.ts create mode 100644 apps/sim/blocks/blocks/crowdstrike.display.ts create mode 100644 apps/sim/blocks/blocks/cursor.display.ts create mode 100644 apps/sim/blocks/blocks/dagster.display.ts create mode 100644 apps/sim/blocks/blocks/databricks.display.ts create mode 100644 apps/sim/blocks/blocks/datadog.display.ts create mode 100644 apps/sim/blocks/blocks/datagma.display.ts create mode 100644 apps/sim/blocks/blocks/daytona.display.ts create mode 100644 apps/sim/blocks/blocks/deployments.display.ts create mode 100644 apps/sim/blocks/blocks/devin.display.ts create mode 100644 apps/sim/blocks/blocks/discord.display.ts create mode 100644 apps/sim/blocks/blocks/docusign.display.ts create mode 100644 apps/sim/blocks/blocks/dropbox.display.ts create mode 100644 apps/sim/blocks/blocks/dropcontact.display.ts create mode 100644 apps/sim/blocks/blocks/dspy.display.ts create mode 100644 apps/sim/blocks/blocks/dub.display.ts create mode 100644 apps/sim/blocks/blocks/duckduckgo.display.ts create mode 100644 apps/sim/blocks/blocks/dynamodb.display.ts create mode 100644 apps/sim/blocks/blocks/elasticsearch.display.ts create mode 100644 apps/sim/blocks/blocks/elevenlabs.display.ts create mode 100644 apps/sim/blocks/blocks/emailbison.display.ts create mode 100644 apps/sim/blocks/blocks/enrich.display.ts create mode 100644 apps/sim/blocks/blocks/enrichment.display.ts create mode 100644 apps/sim/blocks/blocks/enrow.display.ts create mode 100644 apps/sim/blocks/blocks/evaluator.display.ts create mode 100644 apps/sim/blocks/blocks/evernote.display.ts create mode 100644 apps/sim/blocks/blocks/exa.display.ts create mode 100644 apps/sim/blocks/blocks/extend.display.ts create mode 100644 apps/sim/blocks/blocks/fathom.display.ts create mode 100644 apps/sim/blocks/blocks/file.display.ts create mode 100644 apps/sim/blocks/blocks/findymail.display.ts create mode 100644 apps/sim/blocks/blocks/firecrawl.display.ts create mode 100644 apps/sim/blocks/blocks/fireflies.display.ts create mode 100644 apps/sim/blocks/blocks/function.display.ts create mode 100644 apps/sim/blocks/blocks/gamma.display.ts create mode 100644 apps/sim/blocks/blocks/generic_webhook.display.ts create mode 100644 apps/sim/blocks/blocks/github.display.ts create mode 100644 apps/sim/blocks/blocks/gitlab.display.ts create mode 100644 apps/sim/blocks/blocks/gmail.display.ts create mode 100644 apps/sim/blocks/blocks/gong.display.ts create mode 100644 apps/sim/blocks/blocks/google.display.ts create mode 100644 apps/sim/blocks/blocks/google_ads.display.ts create mode 100644 apps/sim/blocks/blocks/google_bigquery.display.ts create mode 100644 apps/sim/blocks/blocks/google_books.display.ts create mode 100644 apps/sim/blocks/blocks/google_calendar.display.ts create mode 100644 apps/sim/blocks/blocks/google_contacts.display.ts create mode 100644 apps/sim/blocks/blocks/google_docs.display.ts create mode 100644 apps/sim/blocks/blocks/google_drive.display.ts create mode 100644 apps/sim/blocks/blocks/google_forms.display.ts create mode 100644 apps/sim/blocks/blocks/google_groups.display.ts create mode 100644 apps/sim/blocks/blocks/google_maps.display.ts create mode 100644 apps/sim/blocks/blocks/google_meet.display.ts create mode 100644 apps/sim/blocks/blocks/google_pagespeed.display.ts create mode 100644 apps/sim/blocks/blocks/google_sheets.display.ts create mode 100644 apps/sim/blocks/blocks/google_slides.display.ts create mode 100644 apps/sim/blocks/blocks/google_tasks.display.ts create mode 100644 apps/sim/blocks/blocks/google_translate.display.ts create mode 100644 apps/sim/blocks/blocks/google_vault.display.ts create mode 100644 apps/sim/blocks/blocks/grafana.display.ts create mode 100644 apps/sim/blocks/blocks/grain.display.ts create mode 100644 apps/sim/blocks/blocks/granola.display.ts create mode 100644 apps/sim/blocks/blocks/greenhouse.display.ts create mode 100644 apps/sim/blocks/blocks/greptile.display.ts create mode 100644 apps/sim/blocks/blocks/guardrails.display.ts create mode 100644 apps/sim/blocks/blocks/hex.display.ts create mode 100644 apps/sim/blocks/blocks/hubspot.display.ts create mode 100644 apps/sim/blocks/blocks/huggingface.display.ts create mode 100644 apps/sim/blocks/blocks/human_in_the_loop.display.ts create mode 100644 apps/sim/blocks/blocks/hunter.display.ts create mode 100644 apps/sim/blocks/blocks/iam.display.ts create mode 100644 apps/sim/blocks/blocks/icypeas.display.ts create mode 100644 apps/sim/blocks/blocks/identity_center.display.ts create mode 100644 apps/sim/blocks/blocks/image_generator.display.ts create mode 100644 apps/sim/blocks/blocks/imap.display.ts create mode 100644 apps/sim/blocks/blocks/incidentio.display.ts create mode 100644 apps/sim/blocks/blocks/infisical.display.ts create mode 100644 apps/sim/blocks/blocks/input_trigger.display.ts create mode 100644 apps/sim/blocks/blocks/instantly.display.ts create mode 100644 apps/sim/blocks/blocks/intercom.display.ts create mode 100644 apps/sim/blocks/blocks/jina.display.ts create mode 100644 apps/sim/blocks/blocks/jira.display.ts create mode 100644 apps/sim/blocks/blocks/jira_service_management.display.ts create mode 100644 apps/sim/blocks/blocks/kalshi.display.ts create mode 100644 apps/sim/blocks/blocks/ketch.display.ts create mode 100644 apps/sim/blocks/blocks/knowledge.display.ts create mode 100644 apps/sim/blocks/blocks/langsmith.display.ts create mode 100644 apps/sim/blocks/blocks/latex.display.ts create mode 100644 apps/sim/blocks/blocks/launchdarkly.display.ts create mode 100644 apps/sim/blocks/blocks/leadmagic.display.ts create mode 100644 apps/sim/blocks/blocks/lemlist.display.ts create mode 100644 apps/sim/blocks/blocks/linear.display.ts create mode 100644 apps/sim/blocks/blocks/linkedin.display.ts create mode 100644 apps/sim/blocks/blocks/linkup.display.ts create mode 100644 apps/sim/blocks/blocks/linq.display.ts create mode 100644 apps/sim/blocks/blocks/logs.display.ts create mode 100644 apps/sim/blocks/blocks/loops.display.ts create mode 100644 apps/sim/blocks/blocks/luma.display.ts create mode 100644 apps/sim/blocks/blocks/mailchimp.display.ts create mode 100644 apps/sim/blocks/blocks/mailgun.display.ts create mode 100644 apps/sim/blocks/blocks/manual_trigger.display.ts create mode 100644 apps/sim/blocks/blocks/mcp.display.ts create mode 100644 apps/sim/blocks/blocks/mem0.display.ts create mode 100644 apps/sim/blocks/blocks/memory.display.ts create mode 100644 apps/sim/blocks/blocks/microsoft_ad.display.ts create mode 100644 apps/sim/blocks/blocks/microsoft_dataverse.display.ts create mode 100644 apps/sim/blocks/blocks/microsoft_excel.display.ts create mode 100644 apps/sim/blocks/blocks/microsoft_planner.display.ts create mode 100644 apps/sim/blocks/blocks/microsoft_teams.display.ts create mode 100644 apps/sim/blocks/blocks/millionverifier.display.ts create mode 100644 apps/sim/blocks/blocks/mistral_parse.display.ts create mode 100644 apps/sim/blocks/blocks/monday.display.ts create mode 100644 apps/sim/blocks/blocks/mongodb.display.ts create mode 100644 apps/sim/blocks/blocks/mothership.display.ts create mode 100644 apps/sim/blocks/blocks/mysql.display.ts create mode 100644 apps/sim/blocks/blocks/neo4j.display.ts create mode 100644 apps/sim/blocks/blocks/neverbounce.display.ts create mode 100644 apps/sim/blocks/blocks/new_relic.display.ts create mode 100644 apps/sim/blocks/blocks/note.display.ts create mode 100644 apps/sim/blocks/blocks/notion.display.ts create mode 100644 apps/sim/blocks/blocks/obsidian.display.ts create mode 100644 apps/sim/blocks/blocks/okta.display.ts create mode 100644 apps/sim/blocks/blocks/onedrive.display.ts create mode 100644 apps/sim/blocks/blocks/onepassword.display.ts create mode 100644 apps/sim/blocks/blocks/openai.display.ts create mode 100644 apps/sim/blocks/blocks/outlook.display.ts create mode 100644 apps/sim/blocks/blocks/pagerduty.display.ts create mode 100644 apps/sim/blocks/blocks/parallel.display.ts create mode 100644 apps/sim/blocks/blocks/peopledatalabs.display.ts create mode 100644 apps/sim/blocks/blocks/perplexity.display.ts create mode 100644 apps/sim/blocks/blocks/persona.display.ts create mode 100644 apps/sim/blocks/blocks/pi.display.ts create mode 100644 apps/sim/blocks/blocks/pinecone.display.ts create mode 100644 apps/sim/blocks/blocks/pipedrive.display.ts create mode 100644 apps/sim/blocks/blocks/polymarket.display.ts create mode 100644 apps/sim/blocks/blocks/postgresql.display.ts create mode 100644 apps/sim/blocks/blocks/posthog.display.ts create mode 100644 apps/sim/blocks/blocks/profound.display.ts create mode 100644 apps/sim/blocks/blocks/prospeo.display.ts create mode 100644 apps/sim/blocks/blocks/pulse.display.ts create mode 100644 apps/sim/blocks/blocks/qdrant.display.ts create mode 100644 apps/sim/blocks/blocks/quartr.display.ts create mode 100644 apps/sim/blocks/blocks/quiver.display.ts create mode 100644 apps/sim/blocks/blocks/railway.display.ts create mode 100644 apps/sim/blocks/blocks/rb2b.display.ts create mode 100644 apps/sim/blocks/blocks/rds.display.ts create mode 100644 apps/sim/blocks/blocks/reddit.display.ts create mode 100644 apps/sim/blocks/blocks/redis.display.ts create mode 100644 apps/sim/blocks/blocks/reducto.display.ts create mode 100644 apps/sim/blocks/blocks/resend.display.ts create mode 100644 apps/sim/blocks/blocks/response.display.ts create mode 100644 apps/sim/blocks/blocks/revenuecat.display.ts create mode 100644 apps/sim/blocks/blocks/rippling.display.ts create mode 100644 apps/sim/blocks/blocks/rootly.display.ts create mode 100644 apps/sim/blocks/blocks/router.display.ts create mode 100644 apps/sim/blocks/blocks/rss.display.ts create mode 100644 apps/sim/blocks/blocks/s3.display.ts create mode 100644 apps/sim/blocks/blocks/salesforce.display.ts create mode 100644 apps/sim/blocks/blocks/sap_concur.display.ts create mode 100644 apps/sim/blocks/blocks/sap_s4hana.display.ts create mode 100644 apps/sim/blocks/blocks/schedule.display.ts create mode 100644 apps/sim/blocks/blocks/search.display.ts create mode 100644 apps/sim/blocks/blocks/secrets_manager.display.ts create mode 100644 apps/sim/blocks/blocks/sendblue.display.ts create mode 100644 apps/sim/blocks/blocks/sendgrid.display.ts create mode 100644 apps/sim/blocks/blocks/sentry.display.ts create mode 100644 apps/sim/blocks/blocks/serper.display.ts create mode 100644 apps/sim/blocks/blocks/servicenow.display.ts create mode 100644 apps/sim/blocks/blocks/ses.display.ts create mode 100644 apps/sim/blocks/blocks/sftp.display.ts create mode 100644 apps/sim/blocks/blocks/sharepoint.display.ts create mode 100644 apps/sim/blocks/blocks/shopify.display.ts create mode 100644 apps/sim/blocks/blocks/sim_workspace_event.display.ts create mode 100644 apps/sim/blocks/blocks/similarweb.display.ts create mode 100644 apps/sim/blocks/blocks/sixtyfour.display.ts create mode 100644 apps/sim/blocks/blocks/slack.display.ts create mode 100644 apps/sim/blocks/blocks/smtp.display.ts create mode 100644 apps/sim/blocks/blocks/sportmonks.display.ts create mode 100644 apps/sim/blocks/blocks/spotify.display.ts create mode 100644 apps/sim/blocks/blocks/sqs.display.ts create mode 100644 apps/sim/blocks/blocks/square.display.ts create mode 100644 apps/sim/blocks/blocks/ssh.display.ts create mode 100644 apps/sim/blocks/blocks/stagehand.display.ts create mode 100644 apps/sim/blocks/blocks/start_trigger.display.ts create mode 100644 apps/sim/blocks/blocks/starter.display.ts create mode 100644 apps/sim/blocks/blocks/stripe.display.ts create mode 100644 apps/sim/blocks/blocks/sts.display.ts create mode 100644 apps/sim/blocks/blocks/stt.display.ts create mode 100644 apps/sim/blocks/blocks/supabase.display.ts create mode 100644 apps/sim/blocks/blocks/table.display.ts create mode 100644 apps/sim/blocks/blocks/tailscale.display.ts create mode 100644 apps/sim/blocks/blocks/tavily.display.ts create mode 100644 apps/sim/blocks/blocks/telegram.display.ts create mode 100644 apps/sim/blocks/blocks/temporal.display.ts create mode 100644 apps/sim/blocks/blocks/textract.display.ts create mode 100644 apps/sim/blocks/blocks/thinking.display.ts create mode 100644 apps/sim/blocks/blocks/thrive.display.ts create mode 100644 apps/sim/blocks/blocks/tinybird.display.ts create mode 100644 apps/sim/blocks/blocks/translate.display.ts create mode 100644 apps/sim/blocks/blocks/trello.display.ts create mode 100644 apps/sim/blocks/blocks/trigger_dev.display.ts create mode 100644 apps/sim/blocks/blocks/tts.display.ts create mode 100644 apps/sim/blocks/blocks/twilio.display.ts create mode 100644 apps/sim/blocks/blocks/twilio_voice.display.ts create mode 100644 apps/sim/blocks/blocks/typeform.display.ts create mode 100644 apps/sim/blocks/blocks/upstash.display.ts create mode 100644 apps/sim/blocks/blocks/vanta.display.ts create mode 100644 apps/sim/blocks/blocks/variables.display.ts create mode 100644 apps/sim/blocks/blocks/vercel.display.ts create mode 100644 apps/sim/blocks/blocks/video_generator.display.ts create mode 100644 apps/sim/blocks/blocks/vision.display.ts create mode 100644 apps/sim/blocks/blocks/wait.display.ts create mode 100644 apps/sim/blocks/blocks/wealthbox.display.ts create mode 100644 apps/sim/blocks/blocks/webflow.display.ts create mode 100644 apps/sim/blocks/blocks/webhook_request.display.ts create mode 100644 apps/sim/blocks/blocks/whatsapp.display.ts create mode 100644 apps/sim/blocks/blocks/wikipedia.display.ts create mode 100644 apps/sim/blocks/blocks/wiza.display.ts create mode 100644 apps/sim/blocks/blocks/wordpress.display.ts create mode 100644 apps/sim/blocks/blocks/workday.display.ts create mode 100644 apps/sim/blocks/blocks/workflow.display.ts create mode 100644 apps/sim/blocks/blocks/workflow_input.display.ts create mode 100644 apps/sim/blocks/blocks/x.display.ts create mode 100644 apps/sim/blocks/blocks/youtube.display.ts create mode 100644 apps/sim/blocks/blocks/zendesk.display.ts create mode 100644 apps/sim/blocks/blocks/zep.display.ts create mode 100644 apps/sim/blocks/blocks/zerobounce.display.ts create mode 100644 apps/sim/blocks/blocks/zoom.display.ts create mode 100644 apps/sim/blocks/blocks/zoominfo.display.ts create mode 100644 apps/sim/blocks/manifest-data.ts create mode 100644 apps/sim/blocks/manifest.ts create mode 100644 apps/sim/scripts/codemod-block-display.ts create mode 100644 apps/sim/scripts/generate-block-manifest-data.ts diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx index 0f1d34ae6cd..60913fcbc46 100644 --- a/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx +++ b/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx @@ -1,5 +1,5 @@ import type { ComponentType } from 'react' -import { getBlock } from '@/blocks' +import { getBlockDisplay } from '@/blocks/manifest' /** * URL-encoded SVG used as a mask to carve the bottom-right notch out of the @@ -48,7 +48,7 @@ const SHOWCASE_TILES = [ * Returns `null` when the block is unknown or has no brand color configured. */ function resolveBrandTileBg(blockType: string): string | null { - return getBlock(blockType)?.bgColor || null + return getBlockDisplay(blockType)?.bgColor || null } interface IntegrationTileProps { @@ -119,7 +119,7 @@ export function IntegrationsShowcase() { >
{SHOWCASE_TILES.map((tile) => { - const block = getBlock(tile.id) + const block = getBlockDisplay(tile.id) if (!block) return null return (
| undefined { if ((CORE_TRIGGER_TYPES as readonly string[]).includes(triggerType)) return undefined - const block = getBlock(triggerType) + const block = getBlockDisplay(triggerType) if (!block?.icon) return undefined const BlockIcon = block.icon const TriggerIcon = ({ className }: { className?: string }) => ( diff --git a/apps/sim/app/workspace/[workspaceId]/logs/utils.ts b/apps/sim/app/workspace/[workspaceId]/logs/utils.ts index da6b50613a5..dc0e21a596d 100644 --- a/apps/sim/app/workspace/[workspaceId]/logs/utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/logs/utils.ts @@ -4,7 +4,7 @@ import { format } from 'date-fns' import { Badge } from '@/components/emcn' import type { WorkflowLogDetail } from '@/lib/api/contracts/logs' import { getIntegrationMetadata } from '@/lib/logs/get-trigger-options' -import { getBlock } from '@/blocks/registry' +import { getBlockDisplay } from '@/blocks/manifest' import { CORE_TRIGGER_TYPES } from '@/stores/logs/filters/types' export const LOG_COLUMNS = { @@ -109,7 +109,7 @@ interface TriggerBadgeProps { export function TriggerBadge({ trigger }: TriggerBadgeProps) { const metadata = getIntegrationMetadata(trigger) const isIntegration = !(CORE_TRIGGER_TYPES as readonly string[]).includes(trigger) - const block = isIntegration ? getBlock(trigger) : null + const block = isIntegration ? getBlockDisplay(trigger) : null const IconComponent = block?.icon const coreVariant = TRIGGER_VARIANT_MAP[trigger] diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx index 48038f3e1db..bc28d9aca49 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx @@ -57,7 +57,7 @@ import { RequiredLabel, } from '@/app/workspace/[workspaceId]/tables/[tableId]/components/sidebar-fields' import { PreviewWorkflow } from '@/app/workspace/[workspaceId]/w/components/preview' -import { getBlock } from '@/blocks' +import { getBlockDisplay } from '@/blocks/manifest' import { useAddWorkflowGroup, useUpdateColumn, @@ -470,7 +470,7 @@ export function WorkflowSidebarBody({ for (const f of flat) { let group = groupsByBlockId.get(f.blockId) if (!group) { - const blockConfig = getBlock(f.blockType) + const blockConfig = getBlockDisplay(f.blockType) const blockColor = blockConfig?.bgColor || '#2F55FF' let blockIcon: string | React.ComponentType<{ className?: string }> = f.blockName .charAt(0) diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/hooks/use-table.ts b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/hooks/use-table.ts index 818cdf43d20..3734f367600 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/hooks/use-table.ts +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/hooks/use-table.ts @@ -5,7 +5,7 @@ import { useQueryClient } from '@tanstack/react-query' import type { ColumnDefinition, TableDefinition, TableRow, WorkflowGroup } from '@/lib/table' import { TABLE_LIMITS } from '@/lib/table/constants' import type { FlattenOutputsBlockInput } from '@/lib/workflows/blocks/flatten-outputs' -import { getBlock } from '@/blocks' +import { getBlockDisplay } from '@/blocks/manifest' import { tableRowsInfiniteOptions, useInfiniteTableRows, @@ -211,7 +211,7 @@ export function useTable({ workspaceId, tableId, queryOptions }: UseTableParams) const isLiveMode = group.deploymentMode !== 'deployed' for (const out of group.outputs) { const block = blocks?.[out.blockId] - const blockConfig = block?.type ? getBlock(block.type) : undefined + const blockConfig = block?.type ? getBlockDisplay(block.type) : undefined const blockIconInfo: BlockIconInfo | undefined = blockConfig?.icon ? { icon: blockConfig.icon, color: blockConfig.bgColor || '#2F55FF' } : undefined diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/components/output-select/output-select.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/components/output-select/output-select.tsx index 41c5962628c..a8dce4b449f 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/components/output-select/output-select.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/components/output-select/output-select.tsx @@ -10,7 +10,7 @@ import { type FlattenOutputsBlockInput, flattenWorkflowOutputs, } from '@/lib/workflows/blocks/flatten-outputs' -import { getBlock } from '@/blocks' +import { getBlockDisplay } from '@/blocks/manifest' import { normalizeName } from '@/executor/constants' import { useWorkflowDiffStore } from '@/stores/workflow-diff/store' import { useSubBlockStore } from '@/stores/workflows/subblock/store' @@ -199,7 +199,7 @@ export function OutputSelect({ * @returns The hex color code for the block */ const getOutputColor = (blockType: string) => { - const blockConfig = getBlock(blockType) + const blockConfig = getBlockDisplay(blockType) return blockConfig?.bgColor || '#2F55FF' } @@ -254,7 +254,7 @@ export function OutputSelect({ return sortedGroups.map(({ blockName, outputs }) => { const firstOutput = outputs[0] - const blockConfig = getBlock(firstOutput.blockType) + const blockConfig = getBlockDisplay(firstOutput.blockType) const blockColor = getOutputColor(firstOutput.blockType) let blockIcon: string | React.ComponentType<{ className?: string }> = blockName diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/connection-blocks/connection-blocks.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/connection-blocks/connection-blocks.tsx index fd09b25097e..db459e25949 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/connection-blocks/connection-blocks.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/connection-blocks/connection-blocks.tsx @@ -13,7 +13,7 @@ import { } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/connection-blocks/components/field-item/field-item' import type { ConnectedBlock } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/hooks/use-block-connections' import { useBlockOutputFields } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-output-fields' -import { getBlock } from '@/blocks/registry' +import { getBlockDisplay } from '@/blocks/manifest' import { normalizeName } from '@/executor/constants' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' import { EMPTY_SUBBLOCK_VALUES, useSubBlockStore } from '@/stores/workflows/subblock/store' @@ -103,7 +103,7 @@ function ConnectionItem({ mergedSubBlocks, sourceBlock, }: ConnectionItemProps) { - const blockConfig = getBlock(connection.type) + const blockConfig = getBlockDisplay(connection.type) const fields = useBlockOutputFields({ blockId: connection.id, diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts index f7f5400fbfd..9857799191c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts @@ -7,7 +7,7 @@ import { SplitIcon, XCircleIcon, } from 'lucide-react' -import { getBlock } from '@/blocks' +import { getBlockDisplay } from '@/blocks/manifest' import { isWorkflowBlockType } from '@/executor/constants' import { TERMINAL_BLOCK_COLUMN_WIDTH } from '@/stores/constants' import type { ConsoleEntry } from '@/stores/terminal' @@ -36,7 +36,7 @@ const SPECIAL_BLOCK_COLORS = { export function getBlockIcon( blockType: string ): React.ComponentType<{ className?: string }> | null { - const blockConfig = getBlock(blockType) + const blockConfig = getBlockDisplay(blockType) if (blockConfig?.icon) { return blockConfig.icon @@ -73,7 +73,7 @@ export function getBlockIcon( * Gets the background color for a block type */ export function getBlockColor(blockType: string): string { - const blockConfig = getBlock(blockType) + const blockConfig = getBlockDisplay(blockType) if (blockConfig?.bgColor) { return blockConfig.bgColor } diff --git a/apps/sim/blocks/blocks/a2a.display.ts b/apps/sim/blocks/blocks/a2a.display.ts new file mode 100644 index 00000000000..52de68fe6ae --- /dev/null +++ b/apps/sim/blocks/blocks/a2a.display.ts @@ -0,0 +1,18 @@ +import { A2AIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const A2ABlockDisplay = { + type: 'a2a', + name: 'A2A', + description: 'Interact with external A2A-compatible agents', + category: 'blocks', + bgColor: '#4151B5', + icon: A2AIcon, + longDescription: + 'Use the A2A (Agent-to-Agent) protocol to interact with external AI agents. ' + + 'Send messages, query task status, cancel tasks, or discover agent capabilities. ' + + 'Compatible with any A2A-compliant agent including LangGraph, Google ADK, and other Sim workflows.', + docsLink: 'https://docs.sim.ai/workflows/blocks/a2a', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/a2a.ts b/apps/sim/blocks/blocks/a2a.ts index b15e8dacfd4..235bd51a688 100644 --- a/apps/sim/blocks/blocks/a2a.ts +++ b/apps/sim/blocks/blocks/a2a.ts @@ -1,6 +1,5 @@ -import { A2AIcon } from '@/components/icons' +import { A2ABlockDisplay } from '@/blocks/blocks/a2a.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ToolResponse } from '@/tools/types' @@ -55,18 +54,7 @@ export interface A2AResponse extends ToolResponse { } export const A2ABlock: BlockConfig = { - type: 'a2a', - name: 'A2A', - description: 'Interact with external A2A-compatible agents', - longDescription: - 'Use the A2A (Agent-to-Agent) protocol to interact with external AI agents. ' + - 'Send messages, query task status, cancel tasks, or discover agent capabilities. ' + - 'Compatible with any A2A-compliant agent including LangGraph, Google ADK, and other Sim workflows.', - docsLink: 'https://docs.sim.ai/workflows/blocks/a2a', - category: 'blocks', - integrationType: IntegrationType.DevOps, - bgColor: '#4151B5', - icon: A2AIcon, + ...A2ABlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/agent.display.ts b/apps/sim/blocks/blocks/agent.display.ts new file mode 100644 index 00000000000..63ee951382d --- /dev/null +++ b/apps/sim/blocks/blocks/agent.display.ts @@ -0,0 +1,16 @@ +import { AgentIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AgentBlockDisplay = { + type: 'agent', + name: 'Agent', + description: 'Build an agent', + category: 'blocks', + bgColor: 'var(--brand)', + icon: AgentIcon, + longDescription: + 'The Agent block is a core workflow block that is a wrapper around an LLM. It takes in system/user prompts and calls an LLM provider. It can also make tool calls by directly containing tools inside of its tool input. It can additionally return structured output.', + docsLink: 'https://docs.sim.ai/workflows/blocks/agent', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/agent.ts b/apps/sim/blocks/blocks/agent.ts index afa55b44db1..a376e3bdae1 100644 --- a/apps/sim/blocks/blocks/agent.ts +++ b/apps/sim/blocks/blocks/agent.ts @@ -1,7 +1,7 @@ import { createLogger } from '@sim/logger' -import { AgentIcon } from '@/components/icons' +import { AgentBlockDisplay } from '@/blocks/blocks/agent.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getModelOptions, getProviderCredentialSubBlocks, @@ -67,21 +67,12 @@ const getToolIdFromBlock = (blockType: string): string | undefined => { } export const AgentBlock: BlockConfig = { - type: 'agent', - name: 'Agent', - description: 'Build an agent', + ...AgentBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'The Agent block is a core workflow block that is a wrapper around an LLM. It takes in system/user prompts and calls an LLM provider. It can also make tool calls by directly containing tools inside of its tool input. It can additionally return structured output.', bestPractices: ` - Prefer using integrations as tools within the agent block over separate integration blocks unless complete determinism needed. - Response Format should be a valid JSON Schema. This determines the output of the agent only if present. Fields can be accessed at root level by the following blocks: e.g. . If response format is not present, the agent will return the standard outputs: content, model, tokens, toolCalls. `, - docsLink: 'https://docs.sim.ai/workflows/blocks/agent', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: 'var(--brand)', - icon: AgentIcon, subBlocks: [ { id: 'messages', diff --git a/apps/sim/blocks/blocks/agentmail.display.ts b/apps/sim/blocks/blocks/agentmail.display.ts new file mode 100644 index 00000000000..ff6e8483d4e --- /dev/null +++ b/apps/sim/blocks/blocks/agentmail.display.ts @@ -0,0 +1,16 @@ +import { AgentMailIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AgentMailBlockDisplay = { + type: 'agentmail', + name: 'AgentMail', + description: 'Manage email inboxes, threads, and messages with AgentMail', + category: 'tools', + bgColor: '#000000', + icon: AgentMailIcon, + longDescription: + 'Integrate AgentMail into your workflow. Create and manage email inboxes, send and receive messages, reply to threads, manage drafts, and organize threads with labels. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/agentmail', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/agentmail.ts b/apps/sim/blocks/blocks/agentmail.ts index 6b0607ddc92..8bad89671a3 100644 --- a/apps/sim/blocks/blocks/agentmail.ts +++ b/apps/sim/blocks/blocks/agentmail.ts @@ -1,18 +1,10 @@ import { AgentMailIcon } from '@/components/icons' +import { AgentMailBlockDisplay } from '@/blocks/blocks/agentmail.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const AgentMailBlock: BlockConfig = { - type: 'agentmail', - name: 'AgentMail', - description: 'Manage email inboxes, threads, and messages with AgentMail', - longDescription: - 'Integrate AgentMail into your workflow. Create and manage email inboxes, send and receive messages, reply to threads, manage drafts, and organize threads with labels. Requires API Key.', - docsLink: 'https://docs.sim.ai/integrations/agentmail', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#000000', - icon: AgentMailIcon, + ...AgentMailBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/agentphone.display.ts b/apps/sim/blocks/blocks/agentphone.display.ts new file mode 100644 index 00000000000..bfff96bf60c --- /dev/null +++ b/apps/sim/blocks/blocks/agentphone.display.ts @@ -0,0 +1,16 @@ +import { AgentPhoneIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AgentPhoneBlockDisplay = { + type: 'agentphone', + name: 'AgentPhone', + description: 'Provision numbers, send SMS and iMessage, and place voice calls with AgentPhone', + category: 'tools', + bgColor: 'linear-gradient(135deg, #1a1a1a 0%, #0a2a14 100%)', + icon: AgentPhoneIcon, + longDescription: + 'Give your workflow a phone. Provision SMS- and voice-enabled numbers, send messages and tapback reactions, place outbound voice calls, manage conversations and contacts, and track usage — all through a single AgentPhone API key.', + docsLink: 'https://docs.sim.ai/integrations/agentphone', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/agentphone.ts b/apps/sim/blocks/blocks/agentphone.ts index 51ccf3aa345..88241ef388f 100644 --- a/apps/sim/blocks/blocks/agentphone.ts +++ b/apps/sim/blocks/blocks/agentphone.ts @@ -1,7 +1,8 @@ import { toError } from '@sim/utils/errors' import { AgentPhoneIcon } from '@/components/icons' +import { AgentPhoneBlockDisplay } from '@/blocks/blocks/agentphone.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' const CONVERSATION_OPS = [ 'get_conversation', @@ -25,16 +26,7 @@ const OFFSET_LIMIT_OPS = [ const CURSOR_MESSAGE_OPS = ['get_number_messages', 'get_conversation_messages'] as const export const AgentPhoneBlock: BlockConfig = { - type: 'agentphone', - name: 'AgentPhone', - description: 'Provision numbers, send SMS and iMessage, and place voice calls with AgentPhone', - longDescription: - 'Give your workflow a phone. Provision SMS- and voice-enabled numbers, send messages and tapback reactions, place outbound voice calls, manage conversations and contacts, and track usage — all through a single AgentPhone API key.', - docsLink: 'https://docs.sim.ai/integrations/agentphone', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: 'linear-gradient(135deg, #1a1a1a 0%, #0a2a14 100%)', - icon: AgentPhoneIcon, + ...AgentPhoneBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/agiloft.display.ts b/apps/sim/blocks/blocks/agiloft.display.ts new file mode 100644 index 00000000000..a191f24221a --- /dev/null +++ b/apps/sim/blocks/blocks/agiloft.display.ts @@ -0,0 +1,16 @@ +import { AgiloftIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AgiloftBlockDisplay = { + type: 'agiloft', + name: 'Agiloft', + description: 'Manage records in Agiloft CLM', + category: 'tools', + bgColor: '#001028', + icon: AgiloftIcon, + longDescription: + 'Integrate with Agiloft contract lifecycle management to create, read, update, delete, and search records. Supports file attachments, SQL-based selection, saved searches, and record locking across any table in your knowledge base.', + docsLink: 'https://docs.sim.ai/integrations/agiloft', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/agiloft.ts b/apps/sim/blocks/blocks/agiloft.ts index e435ac6a26a..415ff60317a 100644 --- a/apps/sim/blocks/blocks/agiloft.ts +++ b/apps/sim/blocks/blocks/agiloft.ts @@ -1,19 +1,11 @@ import { AgiloftIcon } from '@/components/icons' +import { AgiloftBlockDisplay } from '@/blocks/blocks/agiloft.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' export const AgiloftBlock: BlockConfig = { - type: 'agiloft', - name: 'Agiloft', - description: 'Manage records in Agiloft CLM', - longDescription: - 'Integrate with Agiloft contract lifecycle management to create, read, update, delete, and search records. Supports file attachments, SQL-based selection, saved searches, and record locking across any table in your knowledge base.', - docsLink: 'https://docs.sim.ai/integrations/agiloft', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#001028', - icon: AgiloftIcon, + ...AgiloftBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/ahrefs.display.ts b/apps/sim/blocks/blocks/ahrefs.display.ts new file mode 100644 index 00000000000..60e6ad4688c --- /dev/null +++ b/apps/sim/blocks/blocks/ahrefs.display.ts @@ -0,0 +1,16 @@ +import { AhrefsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AhrefsBlockDisplay = { + type: 'ahrefs', + name: 'Ahrefs', + description: 'SEO analysis with Ahrefs', + category: 'tools', + bgColor: '#FFFFFF', + icon: AhrefsIcon, + longDescription: + 'Integrate Ahrefs SEO tools into your workflow. Analyze domain ratings, backlinks, organic keywords, top pages, and more. Requires an Ahrefs Enterprise plan with API access.', + docsLink: 'https://docs.ahrefs.com/docs/api/reference/introduction', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/ahrefs.ts b/apps/sim/blocks/blocks/ahrefs.ts index 80e56aa7d6b..3d915478f0e 100644 --- a/apps/sim/blocks/blocks/ahrefs.ts +++ b/apps/sim/blocks/blocks/ahrefs.ts @@ -1,20 +1,12 @@ import { AhrefsIcon } from '@/components/icons' +import { AhrefsBlockDisplay } from '@/blocks/blocks/ahrefs.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AhrefsResponse } from '@/tools/ahrefs/types' export const AhrefsBlock: BlockConfig = { - type: 'ahrefs', - name: 'Ahrefs', - description: 'SEO analysis with Ahrefs', + ...AhrefsBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Ahrefs SEO tools into your workflow. Analyze domain ratings, backlinks, organic keywords, top pages, and more. Requires an Ahrefs Enterprise plan with API access.', - docsLink: 'https://docs.ahrefs.com/docs/api/reference/introduction', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#FFFFFF', - icon: AhrefsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/airtable.display.ts b/apps/sim/blocks/blocks/airtable.display.ts new file mode 100644 index 00000000000..f2941cdab61 --- /dev/null +++ b/apps/sim/blocks/blocks/airtable.display.ts @@ -0,0 +1,16 @@ +import { AirtableIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AirtableBlockDisplay = { + type: 'airtable', + name: 'Airtable', + description: 'Read, create, and update Airtable', + category: 'tools', + bgColor: '#FFFFFF', + icon: AirtableIcon, + longDescription: + 'Integrates Airtable into the workflow. Can list bases, list tables (with schema), and create, get, list, or update records. Can also be used in trigger mode to trigger a workflow when an update is made to an Airtable table.', + docsLink: 'https://docs.sim.ai/integrations/airtable', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/airtable.ts b/apps/sim/blocks/blocks/airtable.ts index 6f33716c3ca..fa7c2d14461 100644 --- a/apps/sim/blocks/blocks/airtable.ts +++ b/apps/sim/blocks/blocks/airtable.ts @@ -1,22 +1,14 @@ import { AirtableIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { AirtableBlockDisplay } from '@/blocks/blocks/airtable.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AirtableResponse } from '@/tools/airtable/types' import { getTrigger } from '@/triggers' export const AirtableBlock: BlockConfig = { - type: 'airtable', - name: 'Airtable', - description: 'Read, create, and update Airtable', + ...AirtableBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrates Airtable into the workflow. Can list bases, list tables (with schema), and create, get, list, or update records. Can also be used in trigger mode to trigger a workflow when an update is made to an Airtable table.', - docsLink: 'https://docs.sim.ai/integrations/airtable', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: AirtableIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/airweave.display.ts b/apps/sim/blocks/blocks/airweave.display.ts new file mode 100644 index 00000000000..48936bd0794 --- /dev/null +++ b/apps/sim/blocks/blocks/airweave.display.ts @@ -0,0 +1,17 @@ +import { AirweaveIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AirweaveBlockDisplay = { + type: 'airweave', + name: 'Airweave', + description: 'Search your synced data collections', + category: 'tools', + bgColor: '#6366F1', + icon: AirweaveIcon, + iconColor: '#6366F1', + longDescription: + 'Search across your synced data sources using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.', + docsLink: 'https://docs.sim.ai/integrations/airweave', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/airweave.ts b/apps/sim/blocks/blocks/airweave.ts index ef77e888c6b..1ca8e146a79 100644 --- a/apps/sim/blocks/blocks/airweave.ts +++ b/apps/sim/blocks/blocks/airweave.ts @@ -1,21 +1,12 @@ import { AirweaveIcon } from '@/components/icons' +import { AirweaveBlockDisplay } from '@/blocks/blocks/airweave.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AirweaveSearchResponse } from '@/tools/airweave/types' export const AirweaveBlock: BlockConfig = { - type: 'airweave', - name: 'Airweave', - description: 'Search your synced data collections', + ...AirweaveBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Search across your synced data sources using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.', - docsLink: 'https://docs.sim.ai/integrations/airweave', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#6366F1', - iconColor: '#6366F1', - icon: AirweaveIcon, subBlocks: [ { id: 'collectionId', diff --git a/apps/sim/blocks/blocks/algolia.display.ts b/apps/sim/blocks/blocks/algolia.display.ts new file mode 100644 index 00000000000..94bba2c5a3c --- /dev/null +++ b/apps/sim/blocks/blocks/algolia.display.ts @@ -0,0 +1,17 @@ +import { AlgoliaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AlgoliaBlockDisplay = { + type: 'algolia', + name: 'Algolia', + description: 'Search and manage Algolia indices', + category: 'tools', + bgColor: '#003DFF', + icon: AlgoliaIcon, + iconColor: '#003DFF', + longDescription: + 'Integrate Algolia into your workflow. Search indices, manage records (add, update, delete, browse), configure index settings, and perform batch operations.', + docsLink: 'https://docs.sim.ai/integrations/algolia', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/algolia.ts b/apps/sim/blocks/blocks/algolia.ts index be4edae15f3..a81de1af88c 100644 --- a/apps/sim/blocks/blocks/algolia.ts +++ b/apps/sim/blocks/blocks/algolia.ts @@ -1,19 +1,10 @@ import { AlgoliaIcon } from '@/components/icons' +import { AlgoliaBlockDisplay } from '@/blocks/blocks/algolia.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const AlgoliaBlock: BlockConfig = { - type: 'algolia', - name: 'Algolia', - description: 'Search and manage Algolia indices', - longDescription: - 'Integrate Algolia into your workflow. Search indices, manage records (add, update, delete, browse), configure index settings, and perform batch operations.', - docsLink: 'https://docs.sim.ai/integrations/algolia', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#003DFF', - iconColor: '#003DFF', - icon: AlgoliaIcon, + ...AlgoliaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/amplitude.display.ts b/apps/sim/blocks/blocks/amplitude.display.ts new file mode 100644 index 00000000000..cf057fa6155 --- /dev/null +++ b/apps/sim/blocks/blocks/amplitude.display.ts @@ -0,0 +1,17 @@ +import { AmplitudeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AmplitudeBlockDisplay = { + type: 'amplitude', + name: 'Amplitude', + description: 'Track events and query analytics from Amplitude', + category: 'tools', + bgColor: '#1B1F3B', + icon: AmplitudeIcon, + iconColor: '#1F77E0', + longDescription: + 'Integrate Amplitude into your workflow to track events, identify users and groups, search for users, query analytics, and retrieve revenue data.', + docsLink: 'https://docs.sim.ai/integrations/amplitude', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/amplitude.ts b/apps/sim/blocks/blocks/amplitude.ts index a05f9ed5a0c..8f696486cf5 100644 --- a/apps/sim/blocks/blocks/amplitude.ts +++ b/apps/sim/blocks/blocks/amplitude.ts @@ -1,18 +1,9 @@ import { AmplitudeIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { AmplitudeBlockDisplay } from '@/blocks/blocks/amplitude.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' export const AmplitudeBlock: BlockConfig = { - type: 'amplitude', - name: 'Amplitude', - description: 'Track events and query analytics from Amplitude', - longDescription: - 'Integrate Amplitude into your workflow to track events, identify users and groups, search for users, query analytics, and retrieve revenue data.', - docsLink: 'https://docs.sim.ai/integrations/amplitude', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#1B1F3B', - iconColor: '#1F77E0', - icon: AmplitudeIcon, + ...AmplitudeBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/api.display.ts b/apps/sim/blocks/blocks/api.display.ts new file mode 100644 index 00000000000..68048b98af9 --- /dev/null +++ b/apps/sim/blocks/blocks/api.display.ts @@ -0,0 +1,16 @@ +import { ApiIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ApiBlockDisplay = { + type: 'api', + name: 'API', + description: 'Use any API', + category: 'blocks', + bgColor: '#2F55FF', + icon: ApiIcon, + longDescription: + 'This is a core workflow block. Connect to any external API with support for all standard HTTP methods and customizable request parameters. Configure headers, query parameters, and request bodies. Standard headers (User-Agent, Accept, Cache-Control, etc.) are automatically included.', + docsLink: 'https://docs.sim.ai/workflows/blocks/api', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/api.ts b/apps/sim/blocks/blocks/api.ts index cecd661e4c7..6dd16f00cce 100644 --- a/apps/sim/blocks/blocks/api.ts +++ b/apps/sim/blocks/blocks/api.ts @@ -1,22 +1,12 @@ -import { ApiIcon } from '@/components/icons' +import { ApiBlockDisplay } from '@/blocks/blocks/api.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { RequestResponse } from '@/tools/http/types' export const ApiBlock: BlockConfig = { - type: 'api', - name: 'API', - description: 'Use any API', - longDescription: - 'This is a core workflow block. Connect to any external API with support for all standard HTTP methods and customizable request parameters. Configure headers, query parameters, and request bodies. Standard headers (User-Agent, Accept, Cache-Control, etc.) are automatically included.', - docsLink: 'https://docs.sim.ai/workflows/blocks/api', + ...ApiBlockDisplay, bestPractices: ` - Curl the endpoint yourself before filling out the API block to make sure it's working IF you have the necessary authentication headers. Clarify with the user if you need any additional headers. `, - category: 'blocks', - integrationType: IntegrationType.DevOps, - bgColor: '#2F55FF', - icon: ApiIcon, subBlocks: [ { id: 'url', diff --git a/apps/sim/blocks/blocks/api_trigger.display.ts b/apps/sim/blocks/blocks/api_trigger.display.ts new file mode 100644 index 00000000000..5b94087a9be --- /dev/null +++ b/apps/sim/blocks/blocks/api_trigger.display.ts @@ -0,0 +1,15 @@ +import { ApiIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const ApiTriggerBlockDisplay = { + type: 'api_trigger', + name: 'API (Legacy)', + description: 'Legacy block for exposing HTTP API endpoint. Prefer Start block.', + category: 'triggers', + bgColor: '#2F55FF', + icon: ApiIcon, + longDescription: + 'API trigger to start the workflow via authenticated HTTP calls with structured input.', + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/api_trigger.ts b/apps/sim/blocks/blocks/api_trigger.ts index 59312c50498..097e2ccdb50 100644 --- a/apps/sim/blocks/blocks/api_trigger.ts +++ b/apps/sim/blocks/blocks/api_trigger.ts @@ -1,22 +1,13 @@ -import { ApiIcon } from '@/components/icons' +import { ApiTriggerBlockDisplay } from '@/blocks/blocks/api_trigger.display' import type { BlockConfig } from '@/blocks/types' export const ApiTriggerBlock: BlockConfig = { - type: 'api_trigger', - triggerAllowed: true, - name: 'API (Legacy)', - description: 'Legacy block for exposing HTTP API endpoint. Prefer Start block.', - longDescription: - 'API trigger to start the workflow via authenticated HTTP calls with structured input.', + ...ApiTriggerBlockDisplay, bestPractices: ` - Can run the workflow manually to test implementation when this is the trigger point. - The input format determines variables accesssible in the following blocks. E.g. . You can set the value in the input format to test the workflow manually. - In production, the curl would come in as e.g. curl -X POST -H "X-API-Key: $SIM_API_KEY" -H "Content-Type: application/json" -d '{"paramName":"example"}' https://www.staging.sim.ai/api/workflows/9e7e4f26-fc5e-4659-b270-7ea474b14f4a/execute -- If user asks to test via API, you might need to clarify the API key. `, - category: 'triggers', - hideFromToolbar: true, - bgColor: '#2F55FF', - icon: ApiIcon, subBlocks: [ { id: 'inputFormat', diff --git a/apps/sim/blocks/blocks/apify.display.ts b/apps/sim/blocks/blocks/apify.display.ts new file mode 100644 index 00000000000..0d2cb756604 --- /dev/null +++ b/apps/sim/blocks/blocks/apify.display.ts @@ -0,0 +1,16 @@ +import { ApifyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ApifyBlockDisplay = { + type: 'apify', + name: 'Apify', + description: 'Run Apify actors and retrieve results', + category: 'tools', + bgColor: '#FFFFFF', + icon: ApifyIcon, + longDescription: + 'Integrate Apify into your workflow. Run any Apify actor or saved task with custom input, fetch dataset items, and check run status. Supports both synchronous and asynchronous execution with automatic dataset fetching.', + docsLink: 'https://docs.sim.ai/integrations/apify', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/apify.ts b/apps/sim/blocks/blocks/apify.ts index 34a5f396a0b..116a7f867e0 100644 --- a/apps/sim/blocks/blocks/apify.ts +++ b/apps/sim/blocks/blocks/apify.ts @@ -1,23 +1,15 @@ import { ApifyIcon } from '@/components/icons' +import { ApifyBlockDisplay } from '@/blocks/blocks/apify.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RunActorResult } from '@/tools/apify/types' const RUN_OPERATIONS = ['apify_run_actor_sync', 'apify_run_actor_async'] const RUN_OR_TASK_OPERATIONS = [...RUN_OPERATIONS, 'apify_run_task'] export const ApifyBlock: BlockConfig = { - type: 'apify', - name: 'Apify', - description: 'Run Apify actors and retrieve results', + ...ApifyBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Apify into your workflow. Run any Apify actor or saved task with custom input, fetch dataset items, and check run status. Supports both synchronous and asynchronous execution with automatic dataset fetching.', - docsLink: 'https://docs.sim.ai/integrations/apify', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: ApifyIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/apollo.display.ts b/apps/sim/blocks/blocks/apollo.display.ts new file mode 100644 index 00000000000..29e9c5c63b3 --- /dev/null +++ b/apps/sim/blocks/blocks/apollo.display.ts @@ -0,0 +1,16 @@ +import { ApolloIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ApolloBlockDisplay = { + type: 'apollo', + name: 'Apollo', + description: 'Search, enrich, and manage contacts with Apollo.io', + category: 'tools', + bgColor: '#EBF212', + icon: ApolloIcon, + longDescription: + 'Integrates Apollo.io into the workflow. Search for people and companies, enrich contact data, manage your CRM contacts and accounts, add contacts to sequences, and create tasks.', + docsLink: 'https://docs.sim.ai/integrations/apollo', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/apollo.ts b/apps/sim/blocks/blocks/apollo.ts index 9b792a4151b..4d12c6d9aad 100644 --- a/apps/sim/blocks/blocks/apollo.ts +++ b/apps/sim/blocks/blocks/apollo.ts @@ -1,22 +1,14 @@ import { getErrorMessage } from '@sim/utils/errors' import { Users } from '@/components/emcn/icons' import { ApolloIcon } from '@/components/icons' +import { ApolloBlockDisplay } from '@/blocks/blocks/apollo.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ApolloResponse } from '@/tools/apollo/types' export const ApolloBlock: BlockConfig = { - type: 'apollo', - name: 'Apollo', - description: 'Search, enrich, and manage contacts with Apollo.io', + ...ApolloBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrates Apollo.io into the workflow. Search for people and companies, enrich contact data, manage your CRM contacts and accounts, add contacts to sequences, and create tasks.', - docsLink: 'https://docs.sim.ai/integrations/apollo', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#EBF212', - icon: ApolloIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/appconfig.display.ts b/apps/sim/blocks/blocks/appconfig.display.ts new file mode 100644 index 00000000000..783de0cb31d --- /dev/null +++ b/apps/sim/blocks/blocks/appconfig.display.ts @@ -0,0 +1,16 @@ +import { AppConfigIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AppConfigBlockDisplay = { + type: 'appconfig', + name: 'AWS AppConfig', + description: 'Manage and retrieve configuration with AWS AppConfig', + category: 'tools', + bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', + icon: AppConfigIcon, + longDescription: + 'Integrate AWS AppConfig into workflows. Manage applications, environments, and configuration profiles, create and read hosted configuration versions, run and inspect deployments, and retrieve the latest deployed configuration at runtime. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/appconfig', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/appconfig.ts b/apps/sim/blocks/blocks/appconfig.ts index 791e81e8199..8bf1276c7df 100644 --- a/apps/sim/blocks/blocks/appconfig.ts +++ b/apps/sim/blocks/blocks/appconfig.ts @@ -1,6 +1,7 @@ import { AppConfigIcon } from '@/components/icons' +import { AppConfigBlockDisplay } from '@/blocks/blocks/appconfig.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AppConfigGetConfigurationResponse, AppConfigListApplicationsResponse, @@ -9,16 +10,7 @@ import type { export const AppConfigBlock: BlockConfig< AppConfigListApplicationsResponse | AppConfigGetConfigurationResponse > = { - type: 'appconfig', - name: 'AWS AppConfig', - description: 'Manage and retrieve configuration with AWS AppConfig', - longDescription: - 'Integrate AWS AppConfig into workflows. Manage applications, environments, and configuration profiles, create and read hosted configuration versions, run and inspect deployments, and retrieve the latest deployed configuration at runtime. Requires AWS access key and secret access key.', - docsLink: 'https://docs.sim.ai/integrations/appconfig', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', - icon: AppConfigIcon, + ...AppConfigBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/arxiv.display.ts b/apps/sim/blocks/blocks/arxiv.display.ts new file mode 100644 index 00000000000..5a843e0b5af --- /dev/null +++ b/apps/sim/blocks/blocks/arxiv.display.ts @@ -0,0 +1,16 @@ +import { ArxivIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ArxivBlockDisplay = { + type: 'arxiv', + name: 'ArXiv', + description: 'Search and retrieve academic papers from ArXiv', + category: 'tools', + bgColor: '#FFFFFF', + icon: ArxivIcon, + longDescription: + 'Integrates ArXiv into the workflow. Can search for papers, get paper details, and get author papers. Does not require OAuth or an API key.', + docsLink: 'https://docs.sim.ai/integrations/arxiv', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/arxiv.ts b/apps/sim/blocks/blocks/arxiv.ts index cc3615b5515..d0eed22d526 100644 --- a/apps/sim/blocks/blocks/arxiv.ts +++ b/apps/sim/blocks/blocks/arxiv.ts @@ -1,19 +1,10 @@ import { ArxivIcon } from '@/components/icons' +import { ArxivBlockDisplay } from '@/blocks/blocks/arxiv.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { ArxivResponse } from '@/tools/arxiv/types' export const ArxivBlock: BlockConfig = { - type: 'arxiv', - name: 'ArXiv', - description: 'Search and retrieve academic papers from ArXiv', - longDescription: - 'Integrates ArXiv into the workflow. Can search for papers, get paper details, and get author papers. Does not require OAuth or an API key.', - docsLink: 'https://docs.sim.ai/integrations/arxiv', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: ArxivIcon, + ...ArxivBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/asana.display.ts b/apps/sim/blocks/blocks/asana.display.ts new file mode 100644 index 00000000000..01f5b89e027 --- /dev/null +++ b/apps/sim/blocks/blocks/asana.display.ts @@ -0,0 +1,15 @@ +import { AsanaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AsanaBlockDisplay = { + type: 'asana', + name: 'Asana', + description: 'Interact with Asana', + category: 'tools', + bgColor: '#FFFFFF', + icon: AsanaIcon, + longDescription: 'Integrate Asana into the workflow. Can read, write, and update tasks.', + docsLink: 'https://docs.sim.ai/integrations/asana', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/asana.ts b/apps/sim/blocks/blocks/asana.ts index 1695a702041..18ede16093d 100644 --- a/apps/sim/blocks/blocks/asana.ts +++ b/apps/sim/blocks/blocks/asana.ts @@ -1,20 +1,13 @@ import { AsanaIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { AsanaBlockDisplay } from '@/blocks/blocks/asana.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AsanaResponse } from '@/tools/asana/types' export const AsanaBlock: BlockConfig = { - type: 'asana', - name: 'Asana', - description: 'Interact with Asana', + ...AsanaBlockDisplay, authMode: AuthMode.OAuth, - longDescription: 'Integrate Asana into the workflow. Can read, write, and update tasks.', - docsLink: 'https://docs.sim.ai/integrations/asana', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: AsanaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/ashby.display.ts b/apps/sim/blocks/blocks/ashby.display.ts new file mode 100644 index 00000000000..4e7a85b73d9 --- /dev/null +++ b/apps/sim/blocks/blocks/ashby.display.ts @@ -0,0 +1,17 @@ +import { AshbyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AshbyBlockDisplay = { + type: 'ashby', + name: 'Ashby', + description: 'Manage candidates, jobs, and applications in Ashby', + category: 'tools', + bgColor: '#5D4ED6', + icon: AshbyIcon, + iconColor: '#5D4ED6', + longDescription: + 'Integrate Ashby into the workflow. Manage candidates (list, get, create, update, search, tag), applications (list, get, create, change stage), jobs (list, get), job postings (list, get), offers (list, get), notes (list, create), interviews (list), and reference data (sources, tags, archive reasons, custom fields, departments, locations, openings, users).', + docsLink: 'https://docs.sim.ai/integrations/ashby', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/ashby.ts b/apps/sim/blocks/blocks/ashby.ts index 60a4cbe2aad..512f1bc6daa 100644 --- a/apps/sim/blocks/blocks/ashby.ts +++ b/apps/sim/blocks/blocks/ashby.ts @@ -1,19 +1,10 @@ import { AshbyIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { AshbyBlockDisplay } from '@/blocks/blocks/ashby.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import { getTrigger } from '@/triggers' export const AshbyBlock: BlockConfig = { - type: 'ashby', - name: 'Ashby', - description: 'Manage candidates, jobs, and applications in Ashby', - longDescription: - 'Integrate Ashby into the workflow. Manage candidates (list, get, create, update, search, tag), applications (list, get, create, change stage), jobs (list, get), job postings (list, get), offers (list, get), notes (list, create), interviews (list), and reference data (sources, tags, archive reasons, custom fields, departments, locations, openings, users).', - docsLink: 'https://docs.sim.ai/integrations/ashby', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#5D4ED6', - iconColor: '#5D4ED6', - icon: AshbyIcon, + ...AshbyBlockDisplay, authMode: AuthMode.ApiKey, triggers: { diff --git a/apps/sim/blocks/blocks/athena.display.ts b/apps/sim/blocks/blocks/athena.display.ts new file mode 100644 index 00000000000..0a144badc69 --- /dev/null +++ b/apps/sim/blocks/blocks/athena.display.ts @@ -0,0 +1,17 @@ +import { AthenaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AthenaBlockDisplay = { + type: 'athena', + name: 'Athena', + description: 'Run SQL queries on data in Amazon S3 using AWS Athena', + category: 'tools', + bgColor: 'linear-gradient(45deg, #4D27A8 0%, #A166FF 100%)', + icon: AthenaIcon, + iconColor: '#A166FF', + longDescription: + 'Integrate AWS Athena into workflows. Execute SQL queries against data in S3, check query status, retrieve results, manage named queries, and list executions. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/athena', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/athena.ts b/apps/sim/blocks/blocks/athena.ts index e295464d5ae..621f2d22767 100644 --- a/apps/sim/blocks/blocks/athena.ts +++ b/apps/sim/blocks/blocks/athena.ts @@ -1,6 +1,6 @@ import { AthenaIcon } from '@/components/icons' +import { AthenaBlockDisplay } from '@/blocks/blocks/athena.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { AthenaCreateNamedQueryResponse, AthenaGetNamedQueryResponse, @@ -22,17 +22,7 @@ export const AthenaBlock: BlockConfig< | AthenaGetNamedQueryResponse | AthenaListNamedQueriesResponse > = { - type: 'athena', - name: 'Athena', - description: 'Run SQL queries on data in Amazon S3 using AWS Athena', - longDescription: - 'Integrate AWS Athena into workflows. Execute SQL queries against data in S3, check query status, retrieve results, manage named queries, and list executions. Requires AWS access key and secret access key.', - docsLink: 'https://docs.sim.ai/integrations/athena', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: 'linear-gradient(45deg, #4D27A8 0%, #A166FF 100%)', - iconColor: '#A166FF', - icon: AthenaIcon, + ...AthenaBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/attio.display.ts b/apps/sim/blocks/blocks/attio.display.ts new file mode 100644 index 00000000000..96128029a8f --- /dev/null +++ b/apps/sim/blocks/blocks/attio.display.ts @@ -0,0 +1,16 @@ +import { AttioIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AttioBlockDisplay = { + type: 'attio', + name: 'Attio', + description: 'Manage records, notes, tasks, lists, comments, and more in Attio CRM', + category: 'tools', + bgColor: '#1D1E20', + icon: AttioIcon, + longDescription: + 'Connect to Attio to manage CRM records (people, companies, custom objects), notes, tasks, lists, list entries, comments, workspace members, and webhooks.', + docsLink: 'https://docs.sim.ai/integrations/attio', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/attio.ts b/apps/sim/blocks/blocks/attio.ts index 3016a905700..415c8bca153 100644 --- a/apps/sim/blocks/blocks/attio.ts +++ b/apps/sim/blocks/blocks/attio.ts @@ -1,20 +1,12 @@ import { AttioIcon } from '@/components/icons' +import { AttioBlockDisplay } from '@/blocks/blocks/attio.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AttioResponse } from '@/tools/attio/types' import { getTrigger } from '@/triggers' export const AttioBlock: BlockConfig = { - type: 'attio', - name: 'Attio', - description: 'Manage records, notes, tasks, lists, comments, and more in Attio CRM', - longDescription: - 'Connect to Attio to manage CRM records (people, companies, custom objects), notes, tasks, lists, list entries, comments, workspace members, and webhooks.', - docsLink: 'https://docs.sim.ai/integrations/attio', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#1D1E20', - icon: AttioIcon, + ...AttioBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ diff --git a/apps/sim/blocks/blocks/azure_devops.display.ts b/apps/sim/blocks/blocks/azure_devops.display.ts new file mode 100644 index 00000000000..f15a4daa3dd --- /dev/null +++ b/apps/sim/blocks/blocks/azure_devops.display.ts @@ -0,0 +1,17 @@ +import { AzureIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const AzureDevOpsBlockDisplay = { + type: 'azure_devops', + name: 'Azure DevOps', + description: 'Interact with Azure DevOps pipelines, builds, and work items', + category: 'tools', + bgColor: '#0078D4', + icon: AzureIcon, + longDescription: + 'Integrate Azure DevOps into your workflow. List and inspect pipelines and builds, query and manage work items, and add or read comments.', + docsLink: 'https://docs.sim.ai/integrations/azure_devops', + integrationType: IntegrationType.DevOps, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/azure_devops.ts b/apps/sim/blocks/blocks/azure_devops.ts index f67997d5caf..52a61ed53fd 100644 --- a/apps/sim/blocks/blocks/azure_devops.ts +++ b/apps/sim/blocks/blocks/azure_devops.ts @@ -1,6 +1,7 @@ import { AzureIcon } from '@/components/icons' +import { AzureDevOpsBlockDisplay } from '@/blocks/blocks/azure_devops.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { AzureDevOpsBasicWorkItemType, AzureDevOpsResponse } from '@/tools/azure_devops/types' import { AZURE_DEVOPS_BASIC_WORK_ITEM_STATES } from '@/tools/azure_devops/utils' import { getTrigger } from '@/triggers' @@ -13,18 +14,8 @@ function normalizeDate(input: unknown): string | undefined { } export const AzureDevOpsBlock: BlockConfig = { - type: 'azure_devops', - name: 'Azure DevOps', - description: 'Interact with Azure DevOps pipelines, builds, and work items', - longDescription: - 'Integrate Azure DevOps into your workflow. List and inspect pipelines and builds, query and manage work items, and add or read comments.', - docsLink: 'https://docs.sim.ai/integrations/azure_devops', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#0078D4', - icon: AzureIcon, + ...AzureDevOpsBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/box.display.ts b/apps/sim/blocks/blocks/box.display.ts new file mode 100644 index 00000000000..11e442dc6f9 --- /dev/null +++ b/apps/sim/blocks/blocks/box.display.ts @@ -0,0 +1,16 @@ +import { BoxCompanyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const BoxBlockDisplay = { + type: 'box', + name: 'Box', + description: 'Manage files, folders, and e-signatures with Box', + category: 'tools', + bgColor: '#FFFFFF', + icon: BoxCompanyIcon, + longDescription: + 'Integrate Box into your workflow to manage files, folders, and e-signatures. Upload and download files, search content, create folders, send documents for e-signature, track signing status, and more.', + docsLink: 'https://docs.sim.ai/integrations/box', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/box.ts b/apps/sim/blocks/blocks/box.ts index c7af50f088e..e7066f2b5a3 100644 --- a/apps/sim/blocks/blocks/box.ts +++ b/apps/sim/blocks/blocks/box.ts @@ -1,20 +1,12 @@ import { BoxCompanyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { BoxBlockDisplay } from '@/blocks/blocks/box.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' export const BoxBlock: BlockConfig = { - type: 'box', - name: 'Box', - description: 'Manage files, folders, and e-signatures with Box', - longDescription: - 'Integrate Box into your workflow to manage files, folders, and e-signatures. Upload and download files, search content, create folders, send documents for e-signature, track signing status, and more.', - docsLink: 'https://docs.sim.ai/integrations/box', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: BoxCompanyIcon, + ...BoxBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ diff --git a/apps/sim/blocks/blocks/brandfetch.display.ts b/apps/sim/blocks/blocks/brandfetch.display.ts new file mode 100644 index 00000000000..e66d971eaaa --- /dev/null +++ b/apps/sim/blocks/blocks/brandfetch.display.ts @@ -0,0 +1,16 @@ +import { BrandfetchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const BrandfetchBlockDisplay = { + type: 'brandfetch', + name: 'Brandfetch', + description: 'Look up brand assets, logos, colors, and company info', + category: 'tools', + bgColor: '#000000', + icon: BrandfetchIcon, + longDescription: + 'Integrate Brandfetch into your workflow. Retrieve brand logos, colors, fonts, and company data by domain, ticker, or name search.', + docsLink: 'https://docs.sim.ai/integrations/brandfetch', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/brandfetch.ts b/apps/sim/blocks/blocks/brandfetch.ts index c00e2b37766..75896a6a21c 100644 --- a/apps/sim/blocks/blocks/brandfetch.ts +++ b/apps/sim/blocks/blocks/brandfetch.ts @@ -1,19 +1,11 @@ import { BrandfetchIcon } from '@/components/icons' +import { BrandfetchBlockDisplay } from '@/blocks/blocks/brandfetch.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { BrandfetchGetBrandResponse, BrandfetchSearchResponse } from '@/tools/brandfetch/types' export const BrandfetchBlock: BlockConfig = { - type: 'brandfetch', - name: 'Brandfetch', - description: 'Look up brand assets, logos, colors, and company info', - longDescription: - 'Integrate Brandfetch into your workflow. Retrieve brand logos, colors, fonts, and company data by domain, ticker, or name search.', - docsLink: 'https://docs.sim.ai/integrations/brandfetch', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#000000', - icon: BrandfetchIcon, + ...BrandfetchBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/brex.display.ts b/apps/sim/blocks/blocks/brex.display.ts new file mode 100644 index 00000000000..bb35ad45eb4 --- /dev/null +++ b/apps/sim/blocks/blocks/brex.display.ts @@ -0,0 +1,16 @@ +import { BrexIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const BrexBlockDisplay = { + type: 'brex', + name: 'Brex', + description: 'Manage expenses, receipts, transactions, and team data in Brex', + category: 'tools', + bgColor: '#171717', + icon: BrexIcon, + longDescription: + 'Integrates Brex into the workflow. List and update expenses, upload and match receipts, view card and cash transactions, accounts, budgets, spend limits, vendors, transfers, and team data.', + docsLink: 'https://docs.sim.ai/integrations/brex', + integrationType: IntegrationType.Commerce, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/brex.ts b/apps/sim/blocks/blocks/brex.ts index b8efbc74d70..5d925cdb1d9 100644 --- a/apps/sim/blocks/blocks/brex.ts +++ b/apps/sim/blocks/blocks/brex.ts @@ -1,6 +1,7 @@ import { BrexIcon } from '@/components/icons' +import { BrexBlockDisplay } from '@/blocks/blocks/brex.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { BrexResponse } from '@/tools/brex/types' @@ -23,17 +24,8 @@ const PAGINATED_OPERATIONS = new Set([ ]) export const BrexBlock: BlockConfig = { - type: 'brex', - name: 'Brex', - description: 'Manage expenses, receipts, transactions, and team data in Brex', + ...BrexBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrates Brex into the workflow. List and update expenses, upload and match receipts, view card and cash transactions, accounts, budgets, spend limits, vendors, transfers, and team data.', - docsLink: 'https://docs.sim.ai/integrations/brex', - category: 'tools', - integrationType: IntegrationType.Commerce, - bgColor: '#171717', - icon: BrexIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/brightdata.display.ts b/apps/sim/blocks/blocks/brightdata.display.ts new file mode 100644 index 00000000000..372d8f7d6fe --- /dev/null +++ b/apps/sim/blocks/blocks/brightdata.display.ts @@ -0,0 +1,16 @@ +import { BrightDataIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const BrightDataBlockDisplay = { + type: 'brightdata', + name: 'Bright Data', + description: 'Scrape websites, search engines, and extract structured data', + category: 'tools', + bgColor: '#FFFFFF', + icon: BrightDataIcon, + longDescription: + 'Integrate Bright Data into the workflow. Scrape any URL with Web Unlocker, search Google and other engines with SERP API, discover web content ranked by intent, or trigger pre-built scrapers for structured data extraction.', + docsLink: 'https://docs.sim.ai/integrations/brightdata', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/brightdata.ts b/apps/sim/blocks/blocks/brightdata.ts index 28cc33c067b..aebb5cfa086 100644 --- a/apps/sim/blocks/blocks/brightdata.ts +++ b/apps/sim/blocks/blocks/brightdata.ts @@ -1,20 +1,12 @@ import { BrightDataIcon } from '@/components/icons' +import { BrightDataBlockDisplay } from '@/blocks/blocks/brightdata.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { BrightDataResponse } from '@/tools/brightdata/types' export const BrightDataBlock: BlockConfig = { - type: 'brightdata', - name: 'Bright Data', - description: 'Scrape websites, search engines, and extract structured data', + ...BrightDataBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Bright Data into the workflow. Scrape any URL with Web Unlocker, search Google and other engines with SERP API, discover web content ranked by intent, or trigger pre-built scrapers for structured data extraction.', - docsLink: 'https://docs.sim.ai/integrations/brightdata', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: BrightDataIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/browser_use.display.ts b/apps/sim/blocks/blocks/browser_use.display.ts new file mode 100644 index 00000000000..098b3550779 --- /dev/null +++ b/apps/sim/blocks/blocks/browser_use.display.ts @@ -0,0 +1,16 @@ +import { BrowserUseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const BrowserUseBlockDisplay = { + type: 'browser_use', + name: 'Browser Use', + description: 'Run browser automation tasks', + category: 'tools', + bgColor: '#181C1E', + icon: BrowserUseIcon, + longDescription: + 'Integrate Browser Use into the workflow. Can navigate the web and perform actions as if a real user was interacting with the browser.', + docsLink: 'https://docs.sim.ai/integrations/browser_use', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/browser_use.ts b/apps/sim/blocks/blocks/browser_use.ts index afec00da53f..3e5e908edfd 100644 --- a/apps/sim/blocks/blocks/browser_use.ts +++ b/apps/sim/blocks/blocks/browser_use.ts @@ -1,19 +1,11 @@ import { BrowserUseIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { BrowserUseBlockDisplay } from '@/blocks/blocks/browser_use.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { BrowserUseResponse } from '@/tools/browser_use/types' export const BrowserUseBlock: BlockConfig = { - type: 'browser_use', - name: 'Browser Use', - description: 'Run browser automation tasks', + ...BrowserUseBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Browser Use into the workflow. Can navigate the web and perform actions as if a real user was interacting with the browser.', - docsLink: 'https://docs.sim.ai/integrations/browser_use', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: BrowserUseIcon, subBlocks: [ { id: 'task', diff --git a/apps/sim/blocks/blocks/calcom.display.ts b/apps/sim/blocks/blocks/calcom.display.ts new file mode 100644 index 00000000000..ed50519a4ef --- /dev/null +++ b/apps/sim/blocks/blocks/calcom.display.ts @@ -0,0 +1,17 @@ +import { CalComIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CalComBlockDisplay = { + type: 'calcom', + name: 'Cal.com', + description: 'Manage Cal.com bookings, event types, schedules, and availability', + category: 'tools', + bgColor: '#292929', + icon: CalComIcon, + longDescription: + 'Integrate Cal.com into your workflow. Create and manage bookings, event types, schedules, and check availability slots. Supports creating, listing, rescheduling, and canceling bookings, as well as managing event types and schedules. Can also trigger workflows based on Cal.com webhook events (booking created, cancelled, rescheduled). Connect your Cal.com account via OAuth.', + docsLink: 'https://docs.sim.ai/integrations/calcom', + integrationType: IntegrationType.Productivity, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/calcom.ts b/apps/sim/blocks/blocks/calcom.ts index 0b7fdd91db3..9ddc026d34c 100644 --- a/apps/sim/blocks/blocks/calcom.ts +++ b/apps/sim/blocks/blocks/calcom.ts @@ -1,22 +1,13 @@ import { CalComIcon } from '@/components/icons' +import { CalComBlockDisplay } from '@/blocks/blocks/calcom.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' export const CalComBlock: BlockConfig = { - type: 'calcom', - name: 'Cal.com', - description: 'Manage Cal.com bookings, event types, schedules, and availability', + ...CalComBlockDisplay, authMode: AuthMode.OAuth, - triggerAllowed: true, - longDescription: - 'Integrate Cal.com into your workflow. Create and manage bookings, event types, schedules, and check availability slots. Supports creating, listing, rescheduling, and canceling bookings, as well as managing event types and schedules. Can also trigger workflows based on Cal.com webhook events (booking created, cancelled, rescheduled). Connect your Cal.com account via OAuth.', - docsLink: 'https://docs.sim.ai/integrations/calcom', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#292929', - icon: CalComIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/calendly.display.ts b/apps/sim/blocks/blocks/calendly.display.ts new file mode 100644 index 00000000000..babebab7fff --- /dev/null +++ b/apps/sim/blocks/blocks/calendly.display.ts @@ -0,0 +1,17 @@ +import { CalendlyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CalendlyBlockDisplay = { + type: 'calendly', + name: 'Calendly', + description: 'Manage Calendly scheduling and events', + category: 'tools', + bgColor: '#FFFFFF', + icon: CalendlyIcon, + longDescription: + 'Integrate Calendly into your workflow. Manage event types, scheduled events, invitees, and webhooks. Can also trigger workflows based on Calendly webhook events (invitee scheduled, invitee canceled, routing form submitted). Requires Personal Access Token.', + docsLink: 'https://docs.sim.ai/integrations/calendly', + integrationType: IntegrationType.Productivity, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/calendly.ts b/apps/sim/blocks/blocks/calendly.ts index 2a53a9ab944..749f39dda8b 100644 --- a/apps/sim/blocks/blocks/calendly.ts +++ b/apps/sim/blocks/blocks/calendly.ts @@ -1,22 +1,13 @@ import { CalendlyIcon } from '@/components/icons' +import { CalendlyBlockDisplay } from '@/blocks/blocks/calendly.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' export const CalendlyBlock: BlockConfig = { - type: 'calendly', - name: 'Calendly', - description: 'Manage Calendly scheduling and events', + ...CalendlyBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, - longDescription: - 'Integrate Calendly into your workflow. Manage event types, scheduled events, invitees, and webhooks. Can also trigger workflows based on Calendly webhook events (invitee scheduled, invitee canceled, routing form submitted). Requires Personal Access Token.', - docsLink: 'https://docs.sim.ai/integrations/calendly', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: CalendlyIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/chat_trigger.display.ts b/apps/sim/blocks/blocks/chat_trigger.display.ts new file mode 100644 index 00000000000..9e4e13f57d0 --- /dev/null +++ b/apps/sim/blocks/blocks/chat_trigger.display.ts @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { MessageCircle } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const ChatTriggerIcon = (props: SVGProps) => createElement(MessageCircle, props) + +export const ChatTriggerBlockDisplay = { + type: 'chat_trigger', + name: 'Chat', + description: 'Legacy chat start block. Prefer the unified Start block.', + category: 'triggers', + bgColor: '#6F3DFA', + icon: ChatTriggerIcon, + longDescription: 'Chat trigger to run the workflow via deployed chat interfaces.', + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/chat_trigger.ts b/apps/sim/blocks/blocks/chat_trigger.ts index 34fa5d0cce2..02600a7e7dd 100644 --- a/apps/sim/blocks/blocks/chat_trigger.ts +++ b/apps/sim/blocks/blocks/chat_trigger.ts @@ -1,23 +1,16 @@ import type { SVGProps } from 'react' import { createElement } from 'react' import { MessageCircle } from 'lucide-react' +import { ChatTriggerBlockDisplay } from '@/blocks/blocks/chat_trigger.display' import type { BlockConfig } from '@/blocks/types' const ChatTriggerIcon = (props: SVGProps) => createElement(MessageCircle, props) export const ChatTriggerBlock: BlockConfig = { - type: 'chat_trigger', - triggerAllowed: true, - name: 'Chat', - description: 'Legacy chat start block. Prefer the unified Start block.', - longDescription: 'Chat trigger to run the workflow via deployed chat interfaces.', + ...ChatTriggerBlockDisplay, bestPractices: ` - Can run the workflow manually to test implementation when this is the trigger point by passing in a message. `, - category: 'triggers', - hideFromToolbar: true, - bgColor: '#6F3DFA', - icon: ChatTriggerIcon, subBlocks: [], tools: { access: [], diff --git a/apps/sim/blocks/blocks/circleback.display.ts b/apps/sim/blocks/blocks/circleback.display.ts new file mode 100644 index 00000000000..54c948db2c4 --- /dev/null +++ b/apps/sim/blocks/blocks/circleback.display.ts @@ -0,0 +1,17 @@ +import { CirclebackIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CirclebackBlockDisplay = { + type: 'circleback', + name: 'Circleback', + description: 'AI-powered meeting notes and action items', + category: 'triggers', + bgColor: 'linear-gradient(180deg, #E0F7FA 0%, #FFFFFF 100%)', + icon: CirclebackIcon, + longDescription: + 'Receive meeting notes, action items, transcripts, and recordings when meetings are processed. Circleback uses webhooks to push data to your workflows.', + docsLink: 'https://docs.sim.ai/integrations/circleback', + integrationType: IntegrationType.AI, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/circleback.ts b/apps/sim/blocks/blocks/circleback.ts index 56ba5ecb9b4..d09dcb87444 100644 --- a/apps/sim/blocks/blocks/circleback.ts +++ b/apps/sim/blocks/blocks/circleback.ts @@ -1,22 +1,11 @@ import { ClipboardList, Table } from '@/components/emcn/icons' import { CirclebackIcon } from '@/components/icons' +import { CirclebackBlockDisplay } from '@/blocks/blocks/circleback.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { getTrigger } from '@/triggers' export const CirclebackBlock: BlockConfig = { - type: 'circleback', - name: 'Circleback', - description: 'AI-powered meeting notes and action items', - longDescription: - 'Receive meeting notes, action items, transcripts, and recordings when meetings are processed. Circleback uses webhooks to push data to your workflows.', - category: 'triggers', - integrationType: IntegrationType.AI, - bgColor: 'linear-gradient(180deg, #E0F7FA 0%, #FFFFFF 100%)', - docsLink: 'https://docs.sim.ai/integrations/circleback', - icon: CirclebackIcon, - triggerAllowed: true, - + ...CirclebackBlockDisplay, subBlocks: [ ...getTrigger('circleback_meeting_completed').subBlocks, ...getTrigger('circleback_meeting_notes').subBlocks, diff --git a/apps/sim/blocks/blocks/clay.display.ts b/apps/sim/blocks/blocks/clay.display.ts new file mode 100644 index 00000000000..35f070dee8a --- /dev/null +++ b/apps/sim/blocks/blocks/clay.display.ts @@ -0,0 +1,15 @@ +import { ClayIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ClayBlockDisplay = { + type: 'clay', + name: 'Clay', + description: 'Populate Clay workbook', + category: 'tools', + bgColor: '#FFFFFF', + icon: ClayIcon, + longDescription: 'Integrate Clay into the workflow. Can populate a table with data.', + docsLink: 'https://docs.sim.ai/integrations/clay', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/clay.ts b/apps/sim/blocks/blocks/clay.ts index 719e961be0f..a88020743ab 100644 --- a/apps/sim/blocks/blocks/clay.ts +++ b/apps/sim/blocks/blocks/clay.ts @@ -1,18 +1,11 @@ import { ClayIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ClayBlockDisplay } from '@/blocks/blocks/clay.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ClayPopulateResponse } from '@/tools/clay/types' export const ClayBlock: BlockConfig = { - type: 'clay', - name: 'Clay', - description: 'Populate Clay workbook', + ...ClayBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Clay into the workflow. Can populate a table with data.', - docsLink: 'https://docs.sim.ai/integrations/clay', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: ClayIcon, subBlocks: [ { id: 'webhookURL', diff --git a/apps/sim/blocks/blocks/clerk.display.ts b/apps/sim/blocks/blocks/clerk.display.ts new file mode 100644 index 00000000000..7d05cb8799a --- /dev/null +++ b/apps/sim/blocks/blocks/clerk.display.ts @@ -0,0 +1,16 @@ +import { ClerkIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ClerkBlockDisplay = { + type: 'clerk', + name: 'Clerk', + description: 'Manage users, organizations, and sessions in Clerk', + category: 'tools', + bgColor: '#131316', + icon: ClerkIcon, + longDescription: + 'Integrate Clerk authentication and user management into your workflow. Create, update, delete, and list users. Manage organizations and their memberships. Monitor and control user sessions.', + docsLink: 'https://docs.sim.ai/integrations/clerk', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/clerk.ts b/apps/sim/blocks/blocks/clerk.ts index b26d6ab29ba..e6b4314df4d 100644 --- a/apps/sim/blocks/blocks/clerk.ts +++ b/apps/sim/blocks/blocks/clerk.ts @@ -1,20 +1,10 @@ import { ClerkIcon } from '@/components/icons' +import { ClerkBlockDisplay } from '@/blocks/blocks/clerk.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { ClerkResponse } from '@/tools/clerk/types' export const ClerkBlock: BlockConfig = { - type: 'clerk', - name: 'Clerk', - description: 'Manage users, organizations, and sessions in Clerk', - longDescription: - 'Integrate Clerk authentication and user management into your workflow. Create, update, delete, and list users. Manage organizations and their memberships. Monitor and control user sessions.', - docsLink: 'https://docs.sim.ai/integrations/clerk', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#131316', - icon: ClerkIcon, - + ...ClerkBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/clickhouse.display.ts b/apps/sim/blocks/blocks/clickhouse.display.ts new file mode 100644 index 00000000000..2bce79ed8ca --- /dev/null +++ b/apps/sim/blocks/blocks/clickhouse.display.ts @@ -0,0 +1,16 @@ +import { ClickHouseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ClickHouseBlockDisplay = { + type: 'clickhouse', + name: 'ClickHouse', + description: 'Connect to a ClickHouse database', + category: 'tools', + bgColor: '#f9ff69', + icon: ClickHouseIcon, + longDescription: + 'Integrate ClickHouse into the workflow. Query and insert data, manage databases and tables, inspect schemas, monitor mutations and running queries, manage partitions, and execute raw SQL over the ClickHouse HTTP interface.', + docsLink: 'https://docs.sim.ai/integrations/clickhouse', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/clickhouse.ts b/apps/sim/blocks/blocks/clickhouse.ts index 0fb67980ed9..2998537ddb8 100644 --- a/apps/sim/blocks/blocks/clickhouse.ts +++ b/apps/sim/blocks/blocks/clickhouse.ts @@ -1,8 +1,8 @@ import { getErrorMessage } from '@sim/utils/errors' import { ClipboardList, File } from '@/components/emcn/icons' import { ClickHouseIcon } from '@/components/icons' +import { ClickHouseBlockDisplay } from '@/blocks/blocks/clickhouse.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { ClickHouseResponse } from '@/tools/clickhouse/types' const CLICKHOUSE_QUERY_PROMPT = `You are an expert ClickHouse database developer. Write ClickHouse SQL queries based on the user's request. @@ -62,16 +62,7 @@ const TABLE_REQUIRED_OPERATIONS = [ ] export const ClickHouseBlock: BlockConfig = { - type: 'clickhouse', - name: 'ClickHouse', - description: 'Connect to a ClickHouse database', - longDescription: - 'Integrate ClickHouse into the workflow. Query and insert data, manage databases and tables, inspect schemas, monitor mutations and running queries, manage partitions, and execute raw SQL over the ClickHouse HTTP interface.', - docsLink: 'https://docs.sim.ai/integrations/clickhouse', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#f9ff69', - icon: ClickHouseIcon, + ...ClickHouseBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/cloudflare.display.ts b/apps/sim/blocks/blocks/cloudflare.display.ts new file mode 100644 index 00000000000..6a1d2d19563 --- /dev/null +++ b/apps/sim/blocks/blocks/cloudflare.display.ts @@ -0,0 +1,16 @@ +import { CloudflareIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CloudflareBlockDisplay = { + type: 'cloudflare', + name: 'Cloudflare', + description: 'Manage DNS, domains, certificates, and cache', + category: 'tools', + bgColor: '#F5F6FA', + icon: CloudflareIcon, + longDescription: + 'Integrate Cloudflare into the workflow. Manage zones (domains), DNS records, SSL/TLS certificates, zone settings, DNS analytics, and cache purging via the Cloudflare API.', + docsLink: 'https://docs.sim.ai/integrations/cloudflare', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/cloudflare.ts b/apps/sim/blocks/blocks/cloudflare.ts index db764d92d9f..0bba06aff02 100644 --- a/apps/sim/blocks/blocks/cloudflare.ts +++ b/apps/sim/blocks/blocks/cloudflare.ts @@ -1,19 +1,11 @@ import { CloudflareIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { CloudflareBlockDisplay } from '@/blocks/blocks/cloudflare.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { CloudflareResponse } from '@/tools/cloudflare/types' export const CloudflareBlock: BlockConfig = { - type: 'cloudflare', - name: 'Cloudflare', - description: 'Manage DNS, domains, certificates, and cache', + ...CloudflareBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Cloudflare into the workflow. Manage zones (domains), DNS records, SSL/TLS certificates, zone settings, DNS analytics, and cache purging via the Cloudflare API.', - docsLink: 'https://docs.sim.ai/integrations/cloudflare', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#F5F6FA', - icon: CloudflareIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/cloudformation.display.ts b/apps/sim/blocks/blocks/cloudformation.display.ts new file mode 100644 index 00000000000..29534978c59 --- /dev/null +++ b/apps/sim/blocks/blocks/cloudformation.display.ts @@ -0,0 +1,17 @@ +import { CloudFormationIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CloudFormationBlockDisplay = { + type: 'cloudformation', + name: 'CloudFormation', + description: 'Manage and inspect AWS CloudFormation stacks, resources, and drift', + category: 'tools', + bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', + icon: CloudFormationIcon, + iconColor: '#FF4F8B', + longDescription: + 'Integrate AWS CloudFormation into workflows. Describe stacks, list resources, detect drift, view stack events, retrieve templates, and validate templates. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/cloudformation', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/cloudformation.ts b/apps/sim/blocks/blocks/cloudformation.ts index 28e5396e6d6..bc4bea8e9b3 100644 --- a/apps/sim/blocks/blocks/cloudformation.ts +++ b/apps/sim/blocks/blocks/cloudformation.ts @@ -1,6 +1,6 @@ import { CloudFormationIcon } from '@/components/icons' +import { CloudFormationBlockDisplay } from '@/blocks/blocks/cloudformation.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { CloudFormationDescribeStackDriftDetectionStatusResponse, CloudFormationDescribeStackEventsResponse, @@ -20,17 +20,7 @@ export const CloudFormationBlock: BlockConfig< | CloudFormationGetTemplateResponse | CloudFormationValidateTemplateResponse > = { - type: 'cloudformation', - name: 'CloudFormation', - description: 'Manage and inspect AWS CloudFormation stacks, resources, and drift', - longDescription: - 'Integrate AWS CloudFormation into workflows. Describe stacks, list resources, detect drift, view stack events, retrieve templates, and validate templates. Requires AWS access key and secret access key.', - category: 'tools', - integrationType: IntegrationType.DevOps, - docsLink: 'https://docs.sim.ai/integrations/cloudformation', - bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', - iconColor: '#FF4F8B', - icon: CloudFormationIcon, + ...CloudFormationBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/cloudwatch.display.ts b/apps/sim/blocks/blocks/cloudwatch.display.ts new file mode 100644 index 00000000000..abf29fbaa63 --- /dev/null +++ b/apps/sim/blocks/blocks/cloudwatch.display.ts @@ -0,0 +1,17 @@ +import { CloudWatchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CloudWatchBlockDisplay = { + type: 'cloudwatch', + name: 'CloudWatch', + description: 'Query and monitor AWS CloudWatch logs, metrics, and alarms', + category: 'tools', + bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', + icon: CloudWatchIcon, + iconColor: '#FF4F8B', + longDescription: + 'Integrate AWS CloudWatch into workflows. Run Log Insights queries, list log groups, retrieve log events, list and get metrics, and monitor alarms. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/cloudwatch', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/cloudwatch.ts b/apps/sim/blocks/blocks/cloudwatch.ts index 04b72cba3eb..397050f0f49 100644 --- a/apps/sim/blocks/blocks/cloudwatch.ts +++ b/apps/sim/blocks/blocks/cloudwatch.ts @@ -1,6 +1,6 @@ import { CloudWatchIcon } from '@/components/icons' +import { CloudWatchBlockDisplay } from '@/blocks/blocks/cloudwatch.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { CloudWatchDescribeAlarmsResponse, CloudWatchDescribeLogGroupsResponse, @@ -26,17 +26,7 @@ export const CloudWatchBlock: BlockConfig< | CloudWatchMuteAlarmResponse | CloudWatchUnmuteAlarmResponse > = { - type: 'cloudwatch', - name: 'CloudWatch', - description: 'Query and monitor AWS CloudWatch logs, metrics, and alarms', - longDescription: - 'Integrate AWS CloudWatch into workflows. Run Log Insights queries, list log groups, retrieve log events, list and get metrics, and monitor alarms. Requires AWS access key and secret access key.', - category: 'tools', - integrationType: IntegrationType.Observability, - docsLink: 'https://docs.sim.ai/integrations/cloudwatch', - bgColor: 'linear-gradient(45deg, #B0084D 0%, #FF4F8B 100%)', - iconColor: '#FF4F8B', - icon: CloudWatchIcon, + ...CloudWatchBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/codepipeline.display.ts b/apps/sim/blocks/blocks/codepipeline.display.ts new file mode 100644 index 00000000000..1ef405074b7 --- /dev/null +++ b/apps/sim/blocks/blocks/codepipeline.display.ts @@ -0,0 +1,17 @@ +import { CodePipelineIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CodePipelineBlockDisplay = { + type: 'codepipeline', + name: 'CodePipeline', + description: 'Run, monitor, and approve AWS CodePipeline pipelines', + category: 'tools', + bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', + icon: CodePipelineIcon, + iconColor: '#527FFF', + longDescription: + 'Integrate AWS CodePipeline into workflows. Start, stop, and monitor pipeline executions, retry failed stages, and approve or reject manual approval actions. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/codepipeline', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/codepipeline.ts b/apps/sim/blocks/blocks/codepipeline.ts index 8df7d233f8b..bef7936236e 100644 --- a/apps/sim/blocks/blocks/codepipeline.ts +++ b/apps/sim/blocks/blocks/codepipeline.ts @@ -1,6 +1,7 @@ import { CodePipelineIcon } from '@/components/icons' +import { CodePipelineBlockDisplay } from '@/blocks/blocks/codepipeline.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, parseOptionalJsonInput, @@ -27,18 +28,8 @@ export const CodePipelineBlock: BlockConfig< | CodePipelineRetryStageExecutionResponse | CodePipelinePutApprovalResultResponse > = { - type: 'codepipeline', - name: 'CodePipeline', - description: 'Run, monitor, and approve AWS CodePipeline pipelines', + ...CodePipelineBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate AWS CodePipeline into workflows. Start, stop, and monitor pipeline executions, retry failed stages, and approve or reject manual approval actions. Requires AWS access key and secret access key.', - docsLink: 'https://docs.sim.ai/integrations/codepipeline', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', - iconColor: '#527FFF', - icon: CodePipelineIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/condition.display.ts b/apps/sim/blocks/blocks/condition.display.ts new file mode 100644 index 00000000000..268b06a8419 --- /dev/null +++ b/apps/sim/blocks/blocks/condition.display.ts @@ -0,0 +1,14 @@ +import { ConditionalIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const ConditionBlockDisplay = { + type: 'condition', + name: 'Condition', + description: 'Add a condition', + category: 'blocks', + bgColor: '#FF752F', + icon: ConditionalIcon, + longDescription: + 'This is a core workflow block. Add a condition to the workflow to branch the execution path based on a boolean expression.', + docsLink: 'https://docs.sim.ai/workflows/blocks/condition', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/condition.ts b/apps/sim/blocks/blocks/condition.ts index 7952b26b6fe..b7077697ae2 100644 --- a/apps/sim/blocks/blocks/condition.ts +++ b/apps/sim/blocks/blocks/condition.ts @@ -1,4 +1,4 @@ -import { ConditionalIcon } from '@/components/icons' +import { ConditionBlockDisplay } from '@/blocks/blocks/condition.display' import type { BlockConfig } from '@/blocks/types' interface ConditionBlockOutput { @@ -15,19 +15,11 @@ interface ConditionBlockOutput { } export const ConditionBlock: BlockConfig = { - type: 'condition', - name: 'Condition', - description: 'Add a condition', - longDescription: - 'This is a core workflow block. Add a condition to the workflow to branch the execution path based on a boolean expression.', + ...ConditionBlockDisplay, bestPractices: ` - Write the conditions using standard javascript syntax except referencing the outputs of previous blocks using <> syntax, and keep them as simple as possible. No hacky fallbacks. - Can reference workflow variables using syntax as usual within conditions. `, - docsLink: 'https://docs.sim.ai/workflows/blocks/condition', - bgColor: '#FF752F', - icon: ConditionalIcon, - category: 'blocks', subBlocks: [ { id: 'conditions', diff --git a/apps/sim/blocks/blocks/confluence.display.ts b/apps/sim/blocks/blocks/confluence.display.ts new file mode 100644 index 00000000000..2d29756cf48 --- /dev/null +++ b/apps/sim/blocks/blocks/confluence.display.ts @@ -0,0 +1,24 @@ +import { ConfluenceIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ConfluenceBlockDisplay = { + type: 'confluence', + name: 'Confluence (Legacy)', + description: 'Interact with Confluence', + category: 'tools', + bgColor: '#FFFFFF', + icon: ConfluenceIcon, + longDescription: + 'Integrate Confluence into the workflow. Can read, create, update, delete pages, manage comments, attachments, labels, and search content.', + docsLink: 'https://docs.sim.ai/integrations/confluence', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const ConfluenceV2BlockDisplay = { + ...ConfluenceBlockDisplay, + type: 'confluence_v2', + name: 'Confluence', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/confluence.ts b/apps/sim/blocks/blocks/confluence.ts index f0594888a1d..a156491b23b 100644 --- a/apps/sim/blocks/blocks/confluence.ts +++ b/apps/sim/blocks/blocks/confluence.ts @@ -1,25 +1,19 @@ import { Search } from '@/components/emcn/icons' import { ConfluenceIcon, PagerDutyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { + ConfluenceBlockDisplay, + ConfluenceV2BlockDisplay, +} from '@/blocks/blocks/confluence.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ConfluenceResponse } from '@/tools/confluence/types' import { getTrigger } from '@/triggers' export const ConfluenceBlock: BlockConfig = { - type: 'confluence', - name: 'Confluence (Legacy)', - description: 'Interact with Confluence', - hideFromToolbar: true, + ...ConfluenceBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Confluence into the workflow. Can read, create, update, delete pages, manage comments, attachments, labels, and search content.', - docsLink: 'https://docs.sim.ai/integrations/confluence', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: ConfluenceIcon, subBlocks: [ { id: 'operation', @@ -360,9 +354,7 @@ export const ConfluenceBlock: BlockConfig = { export const ConfluenceV2Block: BlockConfig = { ...ConfluenceBlock, - type: 'confluence_v2', - name: 'Confluence', - hideFromToolbar: false, + ...ConfluenceV2BlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/context_dev.display.ts b/apps/sim/blocks/blocks/context_dev.display.ts new file mode 100644 index 00000000000..5610df03436 --- /dev/null +++ b/apps/sim/blocks/blocks/context_dev.display.ts @@ -0,0 +1,16 @@ +import { ContextDevIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ContextDevBlockDisplay = { + type: 'context_dev', + name: 'Context.dev', + description: 'Scrape, crawl, search, extract, and enrich web and brand data', + category: 'tools', + bgColor: '#ffffff', + icon: ContextDevIcon, + longDescription: + 'Integrate Context.dev into the workflow. Scrape pages to markdown or HTML, capture screenshots, list images, crawl entire sites, map sitemaps, search the web, extract structured data and products, pull design systems, classify industries, and retrieve brand assets by domain, name, email, ticker, or transaction — all from one API.', + docsLink: 'https://docs.sim.ai/integrations/context_dev', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/context_dev.ts b/apps/sim/blocks/blocks/context_dev.ts index 26298c41ef8..deac2ff965a 100644 --- a/apps/sim/blocks/blocks/context_dev.ts +++ b/apps/sim/blocks/blocks/context_dev.ts @@ -1,6 +1,7 @@ import { ContextDevIcon } from '@/components/icons' +import { ContextDevBlockDisplay } from '@/blocks/blocks/context_dev.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ContextDevScrapeMarkdownResponse } from '@/tools/context_dev/types' /** Operations whose primary input is a full page URL. */ @@ -83,17 +84,8 @@ function toStringArray(value: unknown): string[] | undefined { } export const ContextDevBlock: BlockConfig = { - type: 'context_dev', - name: 'Context.dev', - description: 'Scrape, crawl, search, extract, and enrich web and brand data', + ...ContextDevBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Context.dev into the workflow. Scrape pages to markdown or HTML, capture screenshots, list images, crawl entire sites, map sitemaps, search the web, extract structured data and products, pull design systems, classify industries, and retrieve brand assets by domain, name, email, ticker, or transaction — all from one API.', - docsLink: 'https://docs.sim.ai/integrations/context_dev', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#ffffff', - icon: ContextDevIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/convex.display.ts b/apps/sim/blocks/blocks/convex.display.ts new file mode 100644 index 00000000000..dd34d64f826 --- /dev/null +++ b/apps/sim/blocks/blocks/convex.display.ts @@ -0,0 +1,16 @@ +import { ConvexIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ConvexBlockDisplay = { + type: 'convex', + name: 'Convex', + description: 'Use Convex database', + category: 'tools', + bgColor: '#FFFFFF', + icon: ConvexIcon, + longDescription: + 'Integrate Convex into the workflow. Run query, mutation, and action functions on your deployment, list tables with their schemas, and export documents with snapshot pagination and change deltas.', + docsLink: 'https://docs.sim.ai/integrations/convex', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/convex.ts b/apps/sim/blocks/blocks/convex.ts index 62794407e4e..13636daac36 100644 --- a/apps/sim/blocks/blocks/convex.ts +++ b/apps/sim/blocks/blocks/convex.ts @@ -1,19 +1,11 @@ import { ConvexIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ConvexBlockDisplay } from '@/blocks/blocks/convex.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ConvexResponse } from '@/tools/convex/types' export const ConvexBlock: BlockConfig = { - type: 'convex', - name: 'Convex', - description: 'Use Convex database', + ...ConvexBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Convex into the workflow. Run query, mutation, and action functions on your deployment, list tables with their schemas, and export documents with snapshot pagination and change deltas.', - docsLink: 'https://docs.sim.ai/integrations/convex', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: ConvexIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/credential.display.ts b/apps/sim/blocks/blocks/credential.display.ts new file mode 100644 index 00000000000..3cad57d71a7 --- /dev/null +++ b/apps/sim/blocks/blocks/credential.display.ts @@ -0,0 +1,14 @@ +import { CredentialIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const CredentialBlockDisplay = { + type: 'credential', + name: 'Credential', + description: 'Select or list OAuth credentials', + category: 'blocks', + bgColor: '#6366F1', + icon: CredentialIcon, + longDescription: + 'Select an OAuth credential once and pipe its ID into any downstream block that requires authentication, or list all OAuth credentials in the workspace for iteration. No secrets are ever exposed — only credential IDs and metadata.', + docsLink: 'https://docs.sim.ai/workflows/blocks/credential', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/credential.ts b/apps/sim/blocks/blocks/credential.ts index 830a8b65b65..4d6fc81b74f 100644 --- a/apps/sim/blocks/blocks/credential.ts +++ b/apps/sim/blocks/blocks/credential.ts @@ -1,6 +1,6 @@ -import { CredentialIcon } from '@/components/icons' import { getServiceConfigByProviderId } from '@/lib/oauth/utils' import { getQueryClient } from '@/app/_shell/providers/get-query-client' +import { CredentialBlockDisplay } from '@/blocks/blocks/credential.display' import type { BlockConfig } from '@/blocks/types' import { workspaceCredentialKeys } from '@/hooks/queries/utils/credential-keys' import { fetchWorkspaceCredentialList } from '@/hooks/queries/utils/fetch-workspace-credentials' @@ -22,11 +22,7 @@ interface CredentialBlockOutput { } export const CredentialBlock: BlockConfig = { - type: 'credential', - name: 'Credential', - description: 'Select or list OAuth credentials', - longDescription: - 'Select an OAuth credential once and pipe its ID into any downstream block that requires authentication, or list all OAuth credentials in the workspace for iteration. No secrets are ever exposed — only credential IDs and metadata.', + ...CredentialBlockDisplay, bestPractices: ` - Use "Select Credential" to define an OAuth credential once and reference in multiple downstream blocks instead of repeating credential IDs. - Use "List Credentials" with a ForEach loop to iterate over all OAuth accounts (e.g. all Gmail accounts). @@ -34,10 +30,6 @@ export const CredentialBlock: BlockConfig = { - The outputs are credential ID references, not secret values — they are safe to log and inspect. - To switch credentials across environments, replace the single Credential block rather than updating every downstream block. `, - docsLink: 'https://docs.sim.ai/workflows/blocks/credential', - bgColor: '#6366F1', - icon: CredentialIcon, - category: 'blocks', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/crowdstrike.display.ts b/apps/sim/blocks/blocks/crowdstrike.display.ts new file mode 100644 index 00000000000..9834c967fc6 --- /dev/null +++ b/apps/sim/blocks/blocks/crowdstrike.display.ts @@ -0,0 +1,17 @@ +import { CrowdStrikeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CrowdStrikeBlockDisplay = { + type: 'crowdstrike', + name: 'CrowdStrike', + description: 'Query CrowdStrike Identity Protection sensors and documented aggregates', + category: 'tools', + bgColor: '#E01F3D', + icon: CrowdStrikeIcon, + iconColor: '#E01F3D', + longDescription: + 'Integrate CrowdStrike Identity Protection into workflows to search sensors, fetch documented sensor details by device ID, and run documented sensor aggregate queries.', + docsLink: 'https://docs.sim.ai/integrations/crowdstrike', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/crowdstrike.ts b/apps/sim/blocks/blocks/crowdstrike.ts index bb8bca69f7a..4657f480951 100644 --- a/apps/sim/blocks/blocks/crowdstrike.ts +++ b/apps/sim/blocks/blocks/crowdstrike.ts @@ -1,21 +1,12 @@ import { CrowdStrikeIcon } from '@/components/icons' +import { CrowdStrikeBlockDisplay } from '@/blocks/blocks/crowdstrike.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { parseOptionalJsonInput, parseOptionalNumberInput } from '@/blocks/utils' import type { CrowdStrikeResponse } from '@/tools/crowdstrike/types' export const CrowdStrikeBlock: BlockConfig = { - type: 'crowdstrike', - name: 'CrowdStrike', - description: 'Query CrowdStrike Identity Protection sensors and documented aggregates', - longDescription: - 'Integrate CrowdStrike Identity Protection into workflows to search sensors, fetch documented sensor details by device ID, and run documented sensor aggregate queries.', - docsLink: 'https://docs.sim.ai/integrations/crowdstrike', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#E01F3D', - iconColor: '#E01F3D', - icon: CrowdStrikeIcon, + ...CrowdStrikeBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/cursor.display.ts b/apps/sim/blocks/blocks/cursor.display.ts new file mode 100644 index 00000000000..7b962575ef9 --- /dev/null +++ b/apps/sim/blocks/blocks/cursor.display.ts @@ -0,0 +1,27 @@ +import { CursorIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const CursorBlockDisplay = { + type: 'cursor', + name: 'Cursor (Legacy)', + description: 'Launch and manage Cursor cloud agents to work on GitHub repositories', + category: 'tools', + bgColor: '#1E1E1E', + icon: CursorIcon, + longDescription: + 'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.', + docsLink: 'https://cursor.com/docs/cloud-agent/api/endpoints', + integrationType: IntegrationType.DevOps, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const CursorV2BlockDisplay = { + ...CursorBlockDisplay, + type: 'cursor_v2', + name: 'Cursor', + description: 'Launch and manage Cursor cloud agents to work on GitHub repositories', + longDescription: + 'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/cursor.ts b/apps/sim/blocks/blocks/cursor.ts index 7383268e37f..1835398318f 100644 --- a/apps/sim/blocks/blocks/cursor.ts +++ b/apps/sim/blocks/blocks/cursor.ts @@ -1,22 +1,13 @@ import { CursorIcon } from '@/components/icons' +import { CursorBlockDisplay, CursorV2BlockDisplay } from '@/blocks/blocks/cursor.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { CursorResponse } from '@/tools/cursor/types' export const CursorBlock: BlockConfig = { - type: 'cursor', - name: 'Cursor (Legacy)', - description: 'Launch and manage Cursor cloud agents to work on GitHub repositories', - longDescription: - 'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.', - docsLink: 'https://cursor.com/docs/cloud-agent/api/endpoints', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#1E1E1E', - icon: CursorIcon, + ...CursorBlockDisplay, authMode: AuthMode.ApiKey, - hideFromToolbar: true, subBlocks: [ { id: 'operation', @@ -223,12 +214,7 @@ export const CursorBlock: BlockConfig = { export const CursorV2Block: BlockConfig = { ...CursorBlock, - type: 'cursor_v2', - name: 'Cursor', - description: 'Launch and manage Cursor cloud agents to work on GitHub repositories', - longDescription: - 'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.', - hideFromToolbar: false, + ...CursorV2BlockDisplay, tools: { ...CursorBlock.tools, access: [ diff --git a/apps/sim/blocks/blocks/dagster.display.ts b/apps/sim/blocks/blocks/dagster.display.ts new file mode 100644 index 00000000000..30a820f7658 --- /dev/null +++ b/apps/sim/blocks/blocks/dagster.display.ts @@ -0,0 +1,16 @@ +import { DagsterIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DagsterBlockDisplay = { + type: 'dagster', + name: 'Dagster', + description: 'Orchestrate data pipelines and manage job runs with Dagster', + category: 'tools', + bgColor: '#ffffff', + icon: DagsterIcon, + longDescription: + 'Connect to a Dagster instance to launch job runs, monitor run status, list available jobs across repositories, terminate or delete runs, reexecute failed runs, fetch run logs, and manage schedules and sensors. API token only required for Dagster+.', + docsLink: 'https://docs.sim.ai/integrations/dagster', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dagster.ts b/apps/sim/blocks/blocks/dagster.ts index 6ef4e43837b..f06a9f55792 100644 --- a/apps/sim/blocks/blocks/dagster.ts +++ b/apps/sim/blocks/blocks/dagster.ts @@ -1,6 +1,6 @@ import { DagsterIcon } from '@/components/icons' +import { DagsterBlockDisplay } from '@/blocks/blocks/dagster.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { DagsterResponse } from '@/tools/dagster/types' /** Coerces a subBlock value to a finite number, returning undefined for empty or non-numeric input. */ @@ -11,17 +11,7 @@ function toFiniteNumber(value: unknown): number | undefined { } export const DagsterBlock: BlockConfig = { - type: 'dagster', - name: 'Dagster', - description: 'Orchestrate data pipelines and manage job runs with Dagster', - longDescription: - 'Connect to a Dagster instance to launch job runs, monitor run status, list available jobs across repositories, terminate or delete runs, reexecute failed runs, fetch run logs, and manage schedules and sensors. API token only required for Dagster+.', - docsLink: 'https://docs.sim.ai/integrations/dagster', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#ffffff', - icon: DagsterIcon, - + ...DagsterBlockDisplay, subBlocks: [ // ── Operation selector ───────────────────────────────────────────────────── { diff --git a/apps/sim/blocks/blocks/databricks.display.ts b/apps/sim/blocks/blocks/databricks.display.ts new file mode 100644 index 00000000000..5812002a9a5 --- /dev/null +++ b/apps/sim/blocks/blocks/databricks.display.ts @@ -0,0 +1,16 @@ +import { DatabricksIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DatabricksBlockDisplay = { + type: 'databricks', + name: 'Databricks', + description: 'Run SQL queries and manage jobs on Databricks', + category: 'tools', + bgColor: '#F9F7F4', + icon: DatabricksIcon, + longDescription: + 'Connect to Databricks to execute SQL queries against SQL warehouses, trigger and monitor job runs, manage clusters, and retrieve run outputs. Requires a Personal Access Token and workspace host URL.', + docsLink: 'https://docs.sim.ai/integrations/databricks', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/databricks.ts b/apps/sim/blocks/blocks/databricks.ts index 0a5d934df4a..e7e37d07068 100644 --- a/apps/sim/blocks/blocks/databricks.ts +++ b/apps/sim/blocks/blocks/databricks.ts @@ -1,20 +1,12 @@ import { DatabricksIcon } from '@/components/icons' +import { DatabricksBlockDisplay } from '@/blocks/blocks/databricks.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { DatabricksResponse } from '@/tools/databricks/types' export const DatabricksBlock: BlockConfig = { - type: 'databricks', - name: 'Databricks', - description: 'Run SQL queries and manage jobs on Databricks', + ...DatabricksBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Connect to Databricks to execute SQL queries against SQL warehouses, trigger and monitor job runs, manage clusters, and retrieve run outputs. Requires a Personal Access Token and workspace host URL.', - docsLink: 'https://docs.sim.ai/integrations/databricks', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#F9F7F4', - icon: DatabricksIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/datadog.display.ts b/apps/sim/blocks/blocks/datadog.display.ts new file mode 100644 index 00000000000..5eced17bc3b --- /dev/null +++ b/apps/sim/blocks/blocks/datadog.display.ts @@ -0,0 +1,17 @@ +import { DatadogIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DatadogBlockDisplay = { + type: 'datadog', + name: 'Datadog', + description: 'Monitor infrastructure, applications, and logs with Datadog', + category: 'tools', + bgColor: '#632CA6', + icon: DatadogIcon, + iconColor: '#632CA6', + longDescription: + 'Integrate Datadog monitoring into workflows. Submit metrics, manage monitors, query logs, create events, handle downtimes, and more.', + docsLink: 'https://docs.sim.ai/integrations/datadog', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/datadog.ts b/apps/sim/blocks/blocks/datadog.ts index ba96cc9bfe7..b79c55a2374 100644 --- a/apps/sim/blocks/blocks/datadog.ts +++ b/apps/sim/blocks/blocks/datadog.ts @@ -1,21 +1,12 @@ import { DatadogIcon } from '@/components/icons' +import { DatadogBlockDisplay } from '@/blocks/blocks/datadog.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { DatadogResponse } from '@/tools/datadog/types' export const DatadogBlock: BlockConfig = { - type: 'datadog', - name: 'Datadog', - description: 'Monitor infrastructure, applications, and logs with Datadog', + ...DatadogBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Datadog monitoring into workflows. Submit metrics, manage monitors, query logs, create events, handle downtimes, and more.', - docsLink: 'https://docs.sim.ai/integrations/datadog', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#632CA6', - iconColor: '#632CA6', - icon: DatadogIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/datagma.display.ts b/apps/sim/blocks/blocks/datagma.display.ts new file mode 100644 index 00000000000..ecb573b4923 --- /dev/null +++ b/apps/sim/blocks/blocks/datagma.display.ts @@ -0,0 +1,16 @@ +import { DatagmaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DatagmaBlockDisplay = { + type: 'datagma', + name: 'Datagma', + description: 'Find verified B2B emails, mobile phones, and enrich person or company profiles', + category: 'tools', + bgColor: '#FFFFFF', + icon: DatagmaIcon, + longDescription: + 'Integrate Datagma to find verified work emails from a name and company, enrich person profiles via email or LinkedIn URL, enrich company data from a domain or name, look up mobile phone numbers from LinkedIn, and check your credit balance.', + docsLink: 'https://docs.sim.ai/tools/datagma', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/datagma.ts b/apps/sim/blocks/blocks/datagma.ts index 9abe2a5868e..3a6e0c437c7 100644 --- a/apps/sim/blocks/blocks/datagma.ts +++ b/apps/sim/blocks/blocks/datagma.ts @@ -1,19 +1,10 @@ -import { DatagmaIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { DatagmaBlockDisplay } from '@/blocks/blocks/datagma.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { DatagmaResponse } from '@/tools/datagma/types' export const DatagmaBlock: BlockConfig = { - type: 'datagma', - name: 'Datagma', - description: 'Find verified B2B emails, mobile phones, and enrich person or company profiles', + ...DatagmaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Datagma to find verified work emails from a name and company, enrich person profiles via email or LinkedIn URL, enrich company data from a domain or name, look up mobile phone numbers from LinkedIn, and check your credit balance.', - docsLink: 'https://docs.sim.ai/tools/datagma', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: DatagmaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/daytona.display.ts b/apps/sim/blocks/blocks/daytona.display.ts new file mode 100644 index 00000000000..619e23596da --- /dev/null +++ b/apps/sim/blocks/blocks/daytona.display.ts @@ -0,0 +1,16 @@ +import { DaytonaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DaytonaBlockDisplay = { + type: 'daytona', + name: 'Daytona', + description: 'Run code and commands in secure cloud sandboxes', + category: 'tools', + bgColor: '#FFFFFF', + icon: DaytonaIcon, + longDescription: + 'Integrate Daytona into your workflow to run AI-generated code in secure, isolated sandboxes. Create and manage sandboxes, execute shell commands, run Python, JavaScript, or TypeScript code, transfer files, and clone Git repositories.', + docsLink: 'https://docs.sim.ai/integrations/daytona', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/daytona.ts b/apps/sim/blocks/blocks/daytona.ts index 338b21b6068..90059078ad2 100644 --- a/apps/sim/blocks/blocks/daytona.ts +++ b/apps/sim/blocks/blocks/daytona.ts @@ -1,6 +1,7 @@ import { DaytonaIcon } from '@/components/icons' +import { DaytonaBlockDisplay } from '@/blocks/blocks/daytona.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' const SANDBOX_SCOPED_OPERATIONS = [ @@ -17,16 +18,7 @@ const SANDBOX_SCOPED_OPERATIONS = [ ] export const DaytonaBlock: BlockConfig = { - type: 'daytona', - name: 'Daytona', - description: 'Run code and commands in secure cloud sandboxes', - longDescription: - 'Integrate Daytona into your workflow to run AI-generated code in secure, isolated sandboxes. Create and manage sandboxes, execute shell commands, run Python, JavaScript, or TypeScript code, transfer files, and clone Git repositories.', - docsLink: 'https://docs.sim.ai/integrations/daytona', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#FFFFFF', - icon: DaytonaIcon, + ...DaytonaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/deployments.display.ts b/apps/sim/blocks/blocks/deployments.display.ts new file mode 100644 index 00000000000..b2a074edc71 --- /dev/null +++ b/apps/sim/blocks/blocks/deployments.display.ts @@ -0,0 +1,15 @@ +import { SimDeploymentsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const DeploymentsBlockDisplay = { + type: 'deployments', + name: 'Deployments', + description: 'Manage workflow deployments', + category: 'blocks', + bgColor: '#0C0C0C', + icon: SimDeploymentsIcon, + iconColor: '#33C482', + longDescription: + 'Deploy, undeploy, and roll back workflows in the current workspace. Promote a previous deployment version to live, list every version, or fetch the deployed workflow state for a specific version.', + docsLink: 'https://docs.sim.ai/workflows/deployment', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/deployments.ts b/apps/sim/blocks/blocks/deployments.ts index 4a101f1ba33..bf00f72c6ab 100644 --- a/apps/sim/blocks/blocks/deployments.ts +++ b/apps/sim/blocks/blocks/deployments.ts @@ -1,12 +1,8 @@ -import { SimDeploymentsIcon } from '@/components/icons' +import { DeploymentsBlockDisplay } from '@/blocks/blocks/deployments.display' import type { BlockConfig } from '@/blocks/types' export const DeploymentsBlock: BlockConfig = { - type: 'deployments', - name: 'Deployments', - description: 'Manage workflow deployments', - longDescription: - 'Deploy, undeploy, and roll back workflows in the current workspace. Promote a previous deployment version to live, list every version, or fetch the deployed workflow state for a specific version.', + ...DeploymentsBlockDisplay, bestPractices: ` - The block operates on workflows in the current workspace; pick one with the selector or pass an ID. - Deploy publishes the workflow's current draft as a new live version. Undeploy takes it offline. @@ -14,11 +10,6 @@ export const DeploymentsBlock: BlockConfig = { - Use 'List Versions' to discover version numbers, then feed one into 'Promote Version to Live' or 'Get Version Details'. - Deploy, undeploy, and promote require admin permission on the workspace; the read operations require workspace access. `, - bgColor: '#0C0C0C', - iconColor: '#33C482', - icon: SimDeploymentsIcon, - category: 'blocks', - docsLink: 'https://docs.sim.ai/workflows/deployment', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/devin.display.ts b/apps/sim/blocks/blocks/devin.display.ts new file mode 100644 index 00000000000..6a84c8f671d --- /dev/null +++ b/apps/sim/blocks/blocks/devin.display.ts @@ -0,0 +1,16 @@ +import { DevinIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DevinBlockDisplay = { + type: 'devin', + name: 'Devin', + description: 'Autonomous AI software engineer', + category: 'tools', + bgColor: '#12141A', + icon: DevinIcon, + longDescription: + 'Integrate Devin into your workflow. Create sessions to assign coding tasks, send messages to guide active sessions, and retrieve session status and results. Devin autonomously writes, runs, and tests code.', + docsLink: 'https://docs.sim.ai/integrations/devin', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/devin.ts b/apps/sim/blocks/blocks/devin.ts index 95c6b4bc083..704162e448f 100644 --- a/apps/sim/blocks/blocks/devin.ts +++ b/apps/sim/blocks/blocks/devin.ts @@ -1,6 +1,7 @@ import { DevinIcon } from '@/components/icons' +import { DevinBlockDisplay } from '@/blocks/blocks/devin.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' const SESSION_OBJECT_OPERATIONS = [ 'create_session', @@ -11,11 +12,7 @@ const SESSION_OBJECT_OPERATIONS = [ ] as const export const DevinBlock: BlockConfig = { - type: 'devin', - name: 'Devin', - description: 'Autonomous AI software engineer', - longDescription: - 'Integrate Devin into your workflow. Create sessions to assign coding tasks, send messages to guide active sessions, and retrieve session status and results. Devin autonomously writes, runs, and tests code.', + ...DevinBlockDisplay, bestPractices: ` - Write clear, specific prompts describing the task, expected outcome, and any constraints. - Use playbook IDs to standardize recurring task patterns across sessions. @@ -23,11 +20,6 @@ export const DevinBlock: BlockConfig = { - Use Get Session to poll for completion status before consuming structured output. - Send Message auto-resumes suspended sessions — no need to resume separately. `, - docsLink: 'https://docs.sim.ai/integrations/devin', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#12141A', - icon: DevinIcon, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/discord.display.ts b/apps/sim/blocks/blocks/discord.display.ts new file mode 100644 index 00000000000..adc90ef76f6 --- /dev/null +++ b/apps/sim/blocks/blocks/discord.display.ts @@ -0,0 +1,17 @@ +import { DiscordIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DiscordBlockDisplay = { + type: 'discord', + name: 'Discord', + description: 'Interact with Discord', + category: 'tools', + bgColor: '#5865F2', + icon: DiscordIcon, + iconColor: '#5865F2', + longDescription: + 'Comprehensive Discord integration: messages, threads, channels, roles, members, invites, and webhooks.', + docsLink: 'https://docs.sim.ai/integrations/discord', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/discord.ts b/apps/sim/blocks/blocks/discord.ts index 074041e2f01..cae933b1179 100644 --- a/apps/sim/blocks/blocks/discord.ts +++ b/apps/sim/blocks/blocks/discord.ts @@ -1,22 +1,13 @@ import { DiscordIcon } from '@/components/icons' +import { DiscordBlockDisplay } from '@/blocks/blocks/discord.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DiscordResponse } from '@/tools/discord/types' export const DiscordBlock: BlockConfig = { - type: 'discord', - name: 'Discord', - description: 'Interact with Discord', + ...DiscordBlockDisplay, authMode: AuthMode.BotToken, - longDescription: - 'Comprehensive Discord integration: messages, threads, channels, roles, members, invites, and webhooks.', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#5865F2', - iconColor: '#5865F2', - icon: DiscordIcon, - docsLink: 'https://docs.sim.ai/integrations/discord', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/docusign.display.ts b/apps/sim/blocks/blocks/docusign.display.ts new file mode 100644 index 00000000000..4c04324eeb3 --- /dev/null +++ b/apps/sim/blocks/blocks/docusign.display.ts @@ -0,0 +1,16 @@ +import { DocuSignIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DocuSignBlockDisplay = { + type: 'docusign', + name: 'DocuSign', + description: 'Send documents for e-signature via DocuSign', + category: 'tools', + bgColor: '#FFFFFF', + icon: DocuSignIcon, + longDescription: + 'Create and send envelopes for e-signature, use templates, check signing status, download signed documents, and manage recipients with DocuSign.', + docsLink: 'https://docs.sim.ai/integrations/docusign', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/docusign.ts b/apps/sim/blocks/blocks/docusign.ts index 0722ebd43e5..29b5e1ceb0c 100644 --- a/apps/sim/blocks/blocks/docusign.ts +++ b/apps/sim/blocks/blocks/docusign.ts @@ -1,21 +1,13 @@ import { DocuSignIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { DocuSignBlockDisplay } from '@/blocks/blocks/docusign.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DocuSignResponse } from '@/tools/docusign/types' export const DocuSignBlock: BlockConfig = { - type: 'docusign', - name: 'DocuSign', - description: 'Send documents for e-signature via DocuSign', - longDescription: - 'Create and send envelopes for e-signature, use templates, check signing status, download signed documents, and manage recipients with DocuSign.', - docsLink: 'https://docs.sim.ai/integrations/docusign', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: DocuSignIcon, + ...DocuSignBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ diff --git a/apps/sim/blocks/blocks/dropbox.display.ts b/apps/sim/blocks/blocks/dropbox.display.ts new file mode 100644 index 00000000000..8330ef981c7 --- /dev/null +++ b/apps/sim/blocks/blocks/dropbox.display.ts @@ -0,0 +1,17 @@ +import { DropboxIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DropboxBlockDisplay = { + type: 'dropbox', + name: 'Dropbox', + description: 'Upload, download, share, and manage files in Dropbox', + category: 'tools', + bgColor: '#0061FF', + icon: DropboxIcon, + iconColor: '#0061FF', + longDescription: + 'Integrate Dropbox into your workflow for file management, sharing, and collaboration. Upload files, download content, create folders, manage shared links, and more.', + docsLink: 'https://docs.sim.ai/integrations/dropbox', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dropbox.ts b/apps/sim/blocks/blocks/dropbox.ts index e18b895a6b9..d19d5318fc7 100644 --- a/apps/sim/blocks/blocks/dropbox.ts +++ b/apps/sim/blocks/blocks/dropbox.ts @@ -1,23 +1,14 @@ import { DropboxIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { DropboxBlockDisplay } from '@/blocks/blocks/dropbox.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DropboxResponse } from '@/tools/dropbox/types' export const DropboxBlock: BlockConfig = { - type: 'dropbox', - name: 'Dropbox', - description: 'Upload, download, share, and manage files in Dropbox', + ...DropboxBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Dropbox into your workflow for file management, sharing, and collaboration. Upload files, download content, create folders, manage shared links, and more.', - docsLink: 'https://docs.sim.ai/integrations/dropbox', - category: 'tools', - integrationType: IntegrationType.Documents, - icon: DropboxIcon, - bgColor: '#0061FF', - iconColor: '#0061FF', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/dropcontact.display.ts b/apps/sim/blocks/blocks/dropcontact.display.ts new file mode 100644 index 00000000000..a4b3e8661eb --- /dev/null +++ b/apps/sim/blocks/blocks/dropcontact.display.ts @@ -0,0 +1,16 @@ +import { DropcontactIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DropcontactBlockDisplay = { + type: 'dropcontact', + name: 'Dropcontact', + description: 'Enrich B2B contacts with verified email, phone, and company data', + category: 'tools', + bgColor: '#0066FF', + icon: DropcontactIcon, + longDescription: + 'Use Dropcontact to verify and enrich B2B contacts. Submit a contact with their name, company, website, or LinkedIn URL and receive a verified professional email, phone number, company firmographics, and LinkedIn profile. Enrichment is async: Dropcontact processes the request, then Sim polls until the result is ready. Credits are only charged when a verified email is returned.', + docsLink: 'https://docs.sim.ai/tools/dropcontact', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dropcontact.ts b/apps/sim/blocks/blocks/dropcontact.ts index be4ca04a2f2..a0214812b7b 100644 --- a/apps/sim/blocks/blocks/dropcontact.ts +++ b/apps/sim/blocks/blocks/dropcontact.ts @@ -1,19 +1,10 @@ -import { DropcontactIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { DropcontactBlockDisplay } from '@/blocks/blocks/dropcontact.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { DropcontactResponse } from '@/tools/dropcontact/types' export const DropcontactBlock: BlockConfig = { - type: 'dropcontact', - name: 'Dropcontact', - description: 'Enrich B2B contacts with verified email, phone, and company data', - longDescription: - 'Use Dropcontact to verify and enrich B2B contacts. Submit a contact with their name, company, website, or LinkedIn URL and receive a verified professional email, phone number, company firmographics, and LinkedIn profile. Enrichment is async: Dropcontact processes the request, then Sim polls until the result is ready. Credits are only charged when a verified email is returned.', - docsLink: 'https://docs.sim.ai/tools/dropcontact', - category: 'tools', - bgColor: '#0066FF', - icon: DropcontactIcon, + ...DropcontactBlockDisplay, authMode: AuthMode.ApiKey, - integrationType: IntegrationType.Sales, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/dspy.display.ts b/apps/sim/blocks/blocks/dspy.display.ts new file mode 100644 index 00000000000..2db143d1277 --- /dev/null +++ b/apps/sim/blocks/blocks/dspy.display.ts @@ -0,0 +1,16 @@ +import { DsPyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DSPyBlockDisplay = { + type: 'dspy', + name: 'DSPy', + description: 'Run predictions using self-hosted DSPy programs', + category: 'tools', + bgColor: '#FFFFFF', + icon: DsPyIcon, + longDescription: + 'Integrate with your self-hosted DSPy programs for LLM-powered predictions. Supports Predict, Chain of Thought, and ReAct agents. DSPy is the framework for programming—not prompting—language models.', + docsLink: 'https://docs.sim.ai/integrations/dspy', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dspy.ts b/apps/sim/blocks/blocks/dspy.ts index 99eaf73c4b8..550c7c0a687 100644 --- a/apps/sim/blocks/blocks/dspy.ts +++ b/apps/sim/blocks/blocks/dspy.ts @@ -1,19 +1,9 @@ import { DsPyIcon } from '@/components/icons' +import { DSPyBlockDisplay } from '@/blocks/blocks/dspy.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' export const DSPyBlock: BlockConfig = { - type: 'dspy', - name: 'DSPy', - description: 'Run predictions using self-hosted DSPy programs', - longDescription: - 'Integrate with your self-hosted DSPy programs for LLM-powered predictions. Supports Predict, Chain of Thought, and ReAct agents. DSPy is the framework for programming—not prompting—language models.', - docsLink: 'https://docs.sim.ai/integrations/dspy', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#FFFFFF', - icon: DsPyIcon, - + ...DSPyBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/dub.display.ts b/apps/sim/blocks/blocks/dub.display.ts new file mode 100644 index 00000000000..7762d09caf9 --- /dev/null +++ b/apps/sim/blocks/blocks/dub.display.ts @@ -0,0 +1,16 @@ +import { DubIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DubBlockDisplay = { + type: 'dub', + name: 'Dub', + description: 'Link management with Dub', + category: 'tools', + bgColor: '#181C1E', + icon: DubIcon, + longDescription: + 'Create, manage, and track short links with Dub. Supports custom domains, UTM parameters, link analytics, and more.', + docsLink: 'https://docs.sim.ai/integrations/dub', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dub.ts b/apps/sim/blocks/blocks/dub.ts index e7b84937b18..20657cf7874 100644 --- a/apps/sim/blocks/blocks/dub.ts +++ b/apps/sim/blocks/blocks/dub.ts @@ -1,20 +1,12 @@ import { DubIcon } from '@/components/icons' +import { DubBlockDisplay } from '@/blocks/blocks/dub.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { DubResponse } from '@/tools/dub/types' export const DubBlock: BlockConfig = { - type: 'dub', - name: 'Dub', - description: 'Link management with Dub', + ...DubBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Create, manage, and track short links with Dub. Supports custom domains, UTM parameters, link analytics, and more.', - docsLink: 'https://docs.sim.ai/integrations/dub', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#181C1E', - icon: DubIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/duckduckgo.display.ts b/apps/sim/blocks/blocks/duckduckgo.display.ts new file mode 100644 index 00000000000..9d0eac0c9f9 --- /dev/null +++ b/apps/sim/blocks/blocks/duckduckgo.display.ts @@ -0,0 +1,16 @@ +import { DuckDuckGoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DuckDuckGoBlockDisplay = { + type: 'duckduckgo', + name: 'DuckDuckGo', + description: 'Search with DuckDuckGo', + category: 'tools', + bgColor: '#FFFFFF', + icon: DuckDuckGoIcon, + longDescription: + 'Search the web using DuckDuckGo Instant Answers API. Returns instant answers, abstracts, related topics, and more. Free to use without an API key.', + docsLink: 'https://docs.sim.ai/integrations/duckduckgo', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/duckduckgo.ts b/apps/sim/blocks/blocks/duckduckgo.ts index 893feb30183..119cd3507eb 100644 --- a/apps/sim/blocks/blocks/duckduckgo.ts +++ b/apps/sim/blocks/blocks/duckduckgo.ts @@ -1,19 +1,10 @@ import { DuckDuckGoIcon } from '@/components/icons' +import { DuckDuckGoBlockDisplay } from '@/blocks/blocks/duckduckgo.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { DuckDuckGoResponse } from '@/tools/duckduckgo/types' export const DuckDuckGoBlock: BlockConfig = { - type: 'duckduckgo', - name: 'DuckDuckGo', - description: 'Search with DuckDuckGo', - longDescription: - 'Search the web using DuckDuckGo Instant Answers API. Returns instant answers, abstracts, related topics, and more. Free to use without an API key.', - docsLink: 'https://docs.sim.ai/integrations/duckduckgo', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: DuckDuckGoIcon, + ...DuckDuckGoBlockDisplay, subBlocks: [ { id: 'query', diff --git a/apps/sim/blocks/blocks/dynamodb.display.ts b/apps/sim/blocks/blocks/dynamodb.display.ts new file mode 100644 index 00000000000..c22d08235af --- /dev/null +++ b/apps/sim/blocks/blocks/dynamodb.display.ts @@ -0,0 +1,17 @@ +import { DynamoDBIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const DynamoDBBlockDisplay = { + type: 'dynamodb', + name: 'Amazon DynamoDB', + description: 'Get, put, query, scan, update, and delete items in Amazon DynamoDB tables', + category: 'tools', + bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', + icon: DynamoDBIcon, + iconColor: '#527FFF', + longDescription: + 'Integrate Amazon DynamoDB into workflows. Supports Get, Put, Query, Scan, Update, Delete, and Introspect operations on DynamoDB tables.', + docsLink: 'https://docs.sim.ai/integrations/dynamodb', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/dynamodb.ts b/apps/sim/blocks/blocks/dynamodb.ts index 0f11259cc05..632707d9267 100644 --- a/apps/sim/blocks/blocks/dynamodb.ts +++ b/apps/sim/blocks/blocks/dynamodb.ts @@ -1,22 +1,13 @@ import { toError } from '@sim/utils/errors' import { DynamoDBIcon } from '@/components/icons' +import { DynamoDBBlockDisplay } from '@/blocks/blocks/dynamodb.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { DynamoDBIntrospectResponse, DynamoDBResponse } from '@/tools/dynamodb/types' export const DynamoDBBlock: BlockConfig = { - type: 'dynamodb', - name: 'Amazon DynamoDB', - description: 'Get, put, query, scan, update, and delete items in Amazon DynamoDB tables', + ...DynamoDBBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Amazon DynamoDB into workflows. Supports Get, Put, Query, Scan, Update, Delete, and Introspect operations on DynamoDB tables.', - docsLink: 'https://docs.sim.ai/integrations/dynamodb', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', - iconColor: '#527FFF', - icon: DynamoDBIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/elasticsearch.display.ts b/apps/sim/blocks/blocks/elasticsearch.display.ts new file mode 100644 index 00000000000..64266d486d7 --- /dev/null +++ b/apps/sim/blocks/blocks/elasticsearch.display.ts @@ -0,0 +1,16 @@ +import { ElasticsearchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ElasticsearchBlockDisplay = { + type: 'elasticsearch', + name: 'Elasticsearch', + description: 'Search, index, and manage data in Elasticsearch', + category: 'tools', + bgColor: '#FFFFFF', + icon: ElasticsearchIcon, + longDescription: + 'Integrate Elasticsearch into workflows for powerful search, indexing, and data management. Supports document CRUD operations, advanced search queries, bulk operations, index management, and cluster monitoring. Works with both self-hosted and Elastic Cloud deployments.', + docsLink: 'https://docs.sim.ai/integrations/elasticsearch', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/elasticsearch.ts b/apps/sim/blocks/blocks/elasticsearch.ts index 724c158abe8..498d9810888 100644 --- a/apps/sim/blocks/blocks/elasticsearch.ts +++ b/apps/sim/blocks/blocks/elasticsearch.ts @@ -1,20 +1,12 @@ import { ElasticsearchIcon } from '@/components/icons' +import { ElasticsearchBlockDisplay } from '@/blocks/blocks/elasticsearch.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ElasticsearchResponse } from '@/tools/elasticsearch/types' export const ElasticsearchBlock: BlockConfig = { - type: 'elasticsearch', - name: 'Elasticsearch', - description: 'Search, index, and manage data in Elasticsearch', + ...ElasticsearchBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Elasticsearch into workflows for powerful search, indexing, and data management. Supports document CRUD operations, advanced search queries, bulk operations, index management, and cluster monitoring. Works with both self-hosted and Elastic Cloud deployments.', - docsLink: 'https://docs.sim.ai/integrations/elasticsearch', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: ElasticsearchIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/elevenlabs.display.ts b/apps/sim/blocks/blocks/elevenlabs.display.ts new file mode 100644 index 00000000000..0654a15a46c --- /dev/null +++ b/apps/sim/blocks/blocks/elevenlabs.display.ts @@ -0,0 +1,15 @@ +import { ElevenLabsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ElevenLabsBlockDisplay = { + type: 'elevenlabs', + name: 'ElevenLabs', + description: 'Convert text to speech with ElevenLabs', + category: 'tools', + bgColor: '#181C1E', + icon: ElevenLabsIcon, + longDescription: 'Integrate ElevenLabs into the workflow. Can convert text to speech.', + docsLink: 'https://docs.sim.ai/integrations/elevenlabs', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/elevenlabs.ts b/apps/sim/blocks/blocks/elevenlabs.ts index 20b564007a1..20fb583fc3a 100644 --- a/apps/sim/blocks/blocks/elevenlabs.ts +++ b/apps/sim/blocks/blocks/elevenlabs.ts @@ -1,18 +1,11 @@ import { ElevenLabsIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ElevenLabsBlockDisplay } from '@/blocks/blocks/elevenlabs.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ElevenLabsBlockResponse } from '@/tools/elevenlabs/types' export const ElevenLabsBlock: BlockConfig = { - type: 'elevenlabs', - name: 'ElevenLabs', - description: 'Convert text to speech with ElevenLabs', + ...ElevenLabsBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate ElevenLabs into the workflow. Can convert text to speech.', - docsLink: 'https://docs.sim.ai/integrations/elevenlabs', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: ElevenLabsIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/emailbison.display.ts b/apps/sim/blocks/blocks/emailbison.display.ts new file mode 100644 index 00000000000..481f914b23d --- /dev/null +++ b/apps/sim/blocks/blocks/emailbison.display.ts @@ -0,0 +1,17 @@ +import { EmailBisonIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const EmailBisonBlockDisplay = { + type: 'emailbison', + name: 'Email Bison', + description: 'Manage Email Bison leads, campaigns, replies, and tags', + category: 'tools', + bgColor: '#FB7A22', + icon: EmailBisonIcon, + iconColor: '#FB7A22', + longDescription: + 'Integrate Email Bison into workflows. Create and update leads, manage campaigns, attach leads to campaigns, list replies, and organize leads with tags.', + docsLink: 'https://docs.sim.ai/integrations/emailbison', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/emailbison.ts b/apps/sim/blocks/blocks/emailbison.ts index 7e515e16abb..d3880880d4f 100644 --- a/apps/sim/blocks/blocks/emailbison.ts +++ b/apps/sim/blocks/blocks/emailbison.ts @@ -1,6 +1,7 @@ import { EmailBisonIcon } from '@/components/icons' +import { EmailBisonBlockDisplay } from '@/blocks/blocks/emailbison.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { EmailBisonResponse } from '@/tools/emailbison/types' import { getTrigger } from '@/triggers' @@ -34,17 +35,7 @@ const EMAILBISON_TRIGGER_IDS = [ ] as const export const EmailBisonBlock: BlockConfig = { - type: 'emailbison', - name: 'Email Bison', - description: 'Manage Email Bison leads, campaigns, replies, and tags', - longDescription: - 'Integrate Email Bison into workflows. Create and update leads, manage campaigns, attach leads to campaigns, list replies, and organize leads with tags.', - docsLink: 'https://docs.sim.ai/integrations/emailbison', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#FB7A22', - iconColor: '#FB7A22', - icon: EmailBisonIcon, + ...EmailBisonBlockDisplay, authMode: AuthMode.ApiKey, triggers: { enabled: true, diff --git a/apps/sim/blocks/blocks/enrich.display.ts b/apps/sim/blocks/blocks/enrich.display.ts new file mode 100644 index 00000000000..b1490530b8d --- /dev/null +++ b/apps/sim/blocks/blocks/enrich.display.ts @@ -0,0 +1,16 @@ +import { EnrichSoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const EnrichBlockDisplay = { + type: 'enrich', + name: 'Enrich', + description: 'B2B data enrichment and LinkedIn intelligence with Enrich.so', + category: 'tools', + bgColor: '#E5E5E6', + icon: EnrichSoIcon, + longDescription: + 'Access real-time B2B data intelligence with Enrich.so. Enrich profiles from email addresses, find work emails from LinkedIn, verify email deliverability, search for people and companies, and analyze LinkedIn post engagement.', + docsLink: 'https://docs.enrich.so/', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/enrich.ts b/apps/sim/blocks/blocks/enrich.ts index 3caaa5897d5..9e78222a4b8 100644 --- a/apps/sim/blocks/blocks/enrich.ts +++ b/apps/sim/blocks/blocks/enrich.ts @@ -1,19 +1,11 @@ import { EnrichSoIcon } from '@/components/icons' +import { EnrichBlockDisplay } from '@/blocks/blocks/enrich.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const EnrichBlock: BlockConfig = { - type: 'enrich', - name: 'Enrich', - description: 'B2B data enrichment and LinkedIn intelligence with Enrich.so', + ...EnrichBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Access real-time B2B data intelligence with Enrich.so. Enrich profiles from email addresses, find work emails from LinkedIn, verify email deliverability, search for people and companies, and analyze LinkedIn post engagement.', - docsLink: 'https://docs.enrich.so/', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#E5E5E6', - icon: EnrichSoIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/enrichment.display.ts b/apps/sim/blocks/blocks/enrichment.display.ts new file mode 100644 index 00000000000..a4d8efdabc1 --- /dev/null +++ b/apps/sim/blocks/blocks/enrichment.display.ts @@ -0,0 +1,16 @@ +import { EnrichmentIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const EnrichmentBlockDisplay = { + type: 'enrichment', + name: 'Data Enrichment', + description: 'Enrich data with a Sim enrichment', + category: 'blocks', + bgColor: '#9333EA', + icon: EnrichmentIcon, + longDescription: + 'Run a Sim enrichment to look up data — work email, phone number, company domain, company info, and more — from the fields you map in. Uses the same provider cascade as table enrichments.', + docsLink: 'https://docs.sim.ai/integrations/enrichment', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/enrichment.ts b/apps/sim/blocks/blocks/enrichment.ts index bba2f936bce..a6905ebbf1f 100644 --- a/apps/sim/blocks/blocks/enrichment.ts +++ b/apps/sim/blocks/blocks/enrichment.ts @@ -1,6 +1,6 @@ import { EnrichmentIcon } from '@/components/icons' +import { EnrichmentBlockDisplay } from '@/blocks/blocks/enrichment.display' import type { BlockConfig, BlockMeta, OutputFieldDefinition, ParamType } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { ALL_ENRICHMENTS, getEnrichment } from '@/enrichments' import { mapFieldType } from '@/enrichments/providers' import type { EnrichmentOutputField } from '@/enrichments/types' @@ -71,17 +71,7 @@ blockOutputs.provider = { * on the workspace's hosted / BYOK key (injected server-side); no credential. */ export const EnrichmentBlock: BlockConfig = { - type: 'enrichment', - name: 'Data Enrichment', - description: 'Enrich data with a Sim enrichment', - longDescription: - 'Run a Sim enrichment to look up data — work email, phone number, company domain, company info, and more — from the fields you map in. Uses the same provider cascade as table enrichments.', - docsLink: 'https://docs.sim.ai/integrations/enrichment', - category: 'blocks', - integrationType: IntegrationType.Sales, - bgColor: '#9333EA', - icon: EnrichmentIcon, - + ...EnrichmentBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/enrow.display.ts b/apps/sim/blocks/blocks/enrow.display.ts new file mode 100644 index 00000000000..17df4ecd77a --- /dev/null +++ b/apps/sim/blocks/blocks/enrow.display.ts @@ -0,0 +1,16 @@ +import { EnrowIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const EnrowBlockDisplay = { + type: 'enrow', + name: 'Enrow', + description: 'Find and verify B2B emails with triple-verified accuracy', + category: 'tools', + bgColor: '#FFFFFF', + icon: EnrowIcon, + longDescription: + 'Integrate Enrow to find verified B2B email addresses from a full name and company, or verify the deliverability of an existing email. Enrow performs deterministic verifications including catch-all emails — no additional verifier needed.', + docsLink: 'https://enrow.readme.io', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/enrow.ts b/apps/sim/blocks/blocks/enrow.ts index 7d49e030b5d..7e210218d55 100644 --- a/apps/sim/blocks/blocks/enrow.ts +++ b/apps/sim/blocks/blocks/enrow.ts @@ -1,19 +1,10 @@ -import { EnrowIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { EnrowBlockDisplay } from '@/blocks/blocks/enrow.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { EnrowResponse } from '@/tools/enrow/types' export const EnrowBlock: BlockConfig = { - type: 'enrow', - name: 'Enrow', - description: 'Find and verify B2B emails with triple-verified accuracy', + ...EnrowBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Enrow to find verified B2B email addresses from a full name and company, or verify the deliverability of an existing email. Enrow performs deterministic verifications including catch-all emails — no additional verifier needed.', - docsLink: 'https://enrow.readme.io', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: EnrowIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/evaluator.display.ts b/apps/sim/blocks/blocks/evaluator.display.ts new file mode 100644 index 00000000000..f3f2b9e2bc6 --- /dev/null +++ b/apps/sim/blocks/blocks/evaluator.display.ts @@ -0,0 +1,14 @@ +import { ChartBarIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const EvaluatorBlockDisplay = { + type: 'evaluator', + name: 'Evaluator', + description: 'Evaluate content', + category: 'blocks', + bgColor: '#4D5FFF', + icon: ChartBarIcon, + longDescription: + 'This is a core workflow block. Assess content quality using customizable evaluation metrics and scoring criteria. Create objective evaluation frameworks with numeric scoring to measure performance across multiple dimensions.', + docsLink: 'https://docs.sim.ai/workflows/blocks/evaluator', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/evaluator.ts b/apps/sim/blocks/blocks/evaluator.ts index 01fbfc3a55b..cb01a4a9817 100644 --- a/apps/sim/blocks/blocks/evaluator.ts +++ b/apps/sim/blocks/blocks/evaluator.ts @@ -1,5 +1,5 @@ import { createLogger } from '@sim/logger' -import { ChartBarIcon } from '@/components/icons' +import { EvaluatorBlockDisplay } from '@/blocks/blocks/evaluator.display' import type { BlockConfig, ParamType } from '@/blocks/types' import { getModelOptions, @@ -148,15 +148,7 @@ const generateResponseFormat = (metrics: Metric[]) => { } export const EvaluatorBlock: BlockConfig = { - type: 'evaluator', - name: 'Evaluator', - description: 'Evaluate content', - longDescription: - 'This is a core workflow block. Assess content quality using customizable evaluation metrics and scoring criteria. Create objective evaluation frameworks with numeric scoring to measure performance across multiple dimensions.', - docsLink: 'https://docs.sim.ai/workflows/blocks/evaluator', - category: 'blocks', - bgColor: '#4D5FFF', - icon: ChartBarIcon, + ...EvaluatorBlockDisplay, subBlocks: [ { id: 'metrics', diff --git a/apps/sim/blocks/blocks/evernote.display.ts b/apps/sim/blocks/blocks/evernote.display.ts new file mode 100644 index 00000000000..1746dd99830 --- /dev/null +++ b/apps/sim/blocks/blocks/evernote.display.ts @@ -0,0 +1,16 @@ +import { EvernoteIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const EvernoteBlockDisplay = { + type: 'evernote', + name: 'Evernote', + description: 'Manage notes, notebooks, and tags in Evernote', + category: 'tools', + bgColor: '#FFFFFF', + icon: EvernoteIcon, + longDescription: + 'Integrate with Evernote to manage notes, notebooks, and tags. Create, read, update, copy, search, and delete notes. Create and list notebooks and tags.', + docsLink: 'https://docs.sim.ai/integrations/evernote', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/evernote.ts b/apps/sim/blocks/blocks/evernote.ts index d0d83654c1d..67ae534343c 100644 --- a/apps/sim/blocks/blocks/evernote.ts +++ b/apps/sim/blocks/blocks/evernote.ts @@ -1,18 +1,10 @@ import { EvernoteIcon } from '@/components/icons' +import { EvernoteBlockDisplay } from '@/blocks/blocks/evernote.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const EvernoteBlock: BlockConfig = { - type: 'evernote', - name: 'Evernote', - description: 'Manage notes, notebooks, and tags in Evernote', - longDescription: - 'Integrate with Evernote to manage notes, notebooks, and tags. Create, read, update, copy, search, and delete notes. Create and list notebooks and tags.', - docsLink: 'https://docs.sim.ai/integrations/evernote', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: EvernoteIcon, + ...EvernoteBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/exa.display.ts b/apps/sim/blocks/blocks/exa.display.ts new file mode 100644 index 00000000000..1d03c892ab2 --- /dev/null +++ b/apps/sim/blocks/blocks/exa.display.ts @@ -0,0 +1,17 @@ +import { ExaAIIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ExaBlockDisplay = { + type: 'exa', + name: 'Exa', + description: 'Search with Exa AI', + category: 'tools', + bgColor: '#1F40ED', + icon: ExaAIIcon, + iconColor: '#1F40ED', + longDescription: + 'Integrate Exa into the workflow. Can search, get contents, find similar links, answer a question, and perform research.', + docsLink: 'https://docs.sim.ai/integrations/exa', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/exa.ts b/apps/sim/blocks/blocks/exa.ts index ec016a6ae04..79bb3d12b81 100644 --- a/apps/sim/blocks/blocks/exa.ts +++ b/apps/sim/blocks/blocks/exa.ts @@ -1,21 +1,12 @@ import { ExaAIIcon } from '@/components/icons' +import { ExaBlockDisplay } from '@/blocks/blocks/exa.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ExaResponse } from '@/tools/exa/types' export const ExaBlock: BlockConfig = { - type: 'exa', - name: 'Exa', - description: 'Search with Exa AI', + ...ExaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Exa into the workflow. Can search, get contents, find similar links, answer a question, and perform research.', - docsLink: 'https://docs.sim.ai/integrations/exa', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#1F40ED', - iconColor: '#1F40ED', - icon: ExaAIIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/extend.display.ts b/apps/sim/blocks/blocks/extend.display.ts new file mode 100644 index 00000000000..3c057678c3f --- /dev/null +++ b/apps/sim/blocks/blocks/extend.display.ts @@ -0,0 +1,26 @@ +import { ExtendIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ExtendBlockDisplay = { + type: 'extend', + name: 'Extend', + description: 'Parse and extract content from documents', + category: 'tools', + bgColor: '#000000', + icon: ExtendIcon, + longDescription: + 'Integrate Extend AI into the workflow. Parse and extract structured content from documents including PDFs, images, and Office files.', + docsLink: 'https://docs.sim.ai/integrations/extend', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const ExtendV2BlockDisplay = { + ...ExtendBlockDisplay, + type: 'extend_v2', + name: 'Extend', + longDescription: + 'Integrate Extend AI into the workflow. Parse and extract structured content from documents or file references.', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/extend.ts b/apps/sim/blocks/blocks/extend.ts index 34667a5a0c6..3c302461b5f 100644 --- a/apps/sim/blocks/blocks/extend.ts +++ b/apps/sim/blocks/blocks/extend.ts @@ -1,27 +1,12 @@ import { ExtendIcon } from '@/components/icons' -import { - AuthMode, - type BlockConfig, - type BlockMeta, - IntegrationType, - type SubBlockType, -} from '@/blocks/types' +import { ExtendBlockDisplay, ExtendV2BlockDisplay } from '@/blocks/blocks/extend.display' +import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { ExtendParserOutput } from '@/tools/extend/types' export const ExtendBlock: BlockConfig = { - type: 'extend', - name: 'Extend', - description: 'Parse and extract content from documents', - hideFromToolbar: true, + ...ExtendBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Extend AI into the workflow. Parse and extract structured content from documents including PDFs, images, and Office files.', - docsLink: 'https://docs.sim.ai/integrations/extend', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#000000', - icon: ExtendIcon, subBlocks: [ { id: 'fileUpload', @@ -165,11 +150,7 @@ const extendV2SubBlocks = (ExtendBlock.subBlocks || []).flatMap((subBlock) => { export const ExtendV2Block: BlockConfig = { ...ExtendBlock, - type: 'extend_v2', - name: 'Extend', - hideFromToolbar: false, - longDescription: - 'Integrate Extend AI into the workflow. Parse and extract structured content from documents or file references.', + ...ExtendV2BlockDisplay, subBlocks: extendV2SubBlocks, tools: { access: ['extend_parser_v2'], diff --git a/apps/sim/blocks/blocks/fathom.display.ts b/apps/sim/blocks/blocks/fathom.display.ts new file mode 100644 index 00000000000..01b11ab44d7 --- /dev/null +++ b/apps/sim/blocks/blocks/fathom.display.ts @@ -0,0 +1,17 @@ +import { FathomIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const FathomBlockDisplay = { + type: 'fathom', + name: 'Fathom', + description: 'Access meeting recordings, transcripts, and summaries', + category: 'tools', + bgColor: '#181C1E', + icon: FathomIcon, + longDescription: + 'Integrate Fathom AI Notetaker into your workflow. List meetings, get transcripts and summaries, and manage team members and teams. Can also trigger workflows when new meeting content is ready.', + docsLink: 'https://docs.sim.ai/integrations/fathom', + integrationType: IntegrationType.Analytics, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/fathom.ts b/apps/sim/blocks/blocks/fathom.ts index 2bd604f6a28..7d8ee9ee046 100644 --- a/apps/sim/blocks/blocks/fathom.ts +++ b/apps/sim/blocks/blocks/fathom.ts @@ -1,22 +1,13 @@ import { FathomIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { FathomBlockDisplay } from '@/blocks/blocks/fathom.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { FathomResponse } from '@/tools/fathom/types' import { getTrigger } from '@/triggers' import { fathomTriggerOptions } from '@/triggers/fathom/utils' export const FathomBlock: BlockConfig = { - type: 'fathom', - name: 'Fathom', - description: 'Access meeting recordings, transcripts, and summaries', + ...FathomBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, - longDescription: - 'Integrate Fathom AI Notetaker into your workflow. List meetings, get transcripts and summaries, and manage team members and teams. Can also trigger workflows when new meeting content is ready.', - docsLink: 'https://docs.sim.ai/integrations/fathom', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#181C1E', - icon: FathomIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/file.display.ts b/apps/sim/blocks/blocks/file.display.ts new file mode 100644 index 00000000000..4b8342ad6dd --- /dev/null +++ b/apps/sim/blocks/blocks/file.display.ts @@ -0,0 +1,59 @@ +import { DocumentIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const FileBlockDisplay = { + type: 'file', + name: 'File (Legacy)', + description: 'Read and parse multiple files', + category: 'blocks', + bgColor: '#40916C', + icon: DocumentIcon, + longDescription: `Integrate File into the workflow. Can upload a file manually or insert a file url.`, + docsLink: 'https://docs.sim.ai/integrations/file', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const FileV2BlockDisplay = { + ...FileBlockDisplay, + type: 'file_v2', + name: 'File (Legacy)', + description: 'Read and parse multiple files', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const FileV3BlockDisplay = { + type: 'file_v3', + name: 'File', + description: 'Read and write workspace files', + category: 'blocks', + bgColor: '#40916C', + icon: DocumentIcon, + longDescription: + 'Read and parse files from uploads or URLs, write new workspace files, or append content to existing files.', + docsLink: 'https://docs.sim.ai/integrations/file', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const FileV4BlockDisplay = { + ...FileV3BlockDisplay, + type: 'file_v4', + name: 'File (Legacy)', + description: 'Read, fetch, write, and append files', + longDescription: + 'Read workspace files by picker or canonical ID, fetch and parse files from URLs with optional headers, write new workspace files, or append content to existing files.', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const FileV5BlockDisplay = { + ...FileV4BlockDisplay, + type: 'file_v5', + name: 'File', + description: + 'Read, get content, fetch, write, append, compress, decompress, and manage sharing for files', + longDescription: + 'Read workspace file objects, extract the text content of files, fetch and parse files from URLs with optional headers, write new workspace files, append content to existing files, compress files into a .zip archive, extract a .zip archive into the workspace, or manage the public share link for a file.', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/file.ts b/apps/sim/blocks/blocks/file.ts index 49ea1361a8d..1b72b54bb3b 100644 --- a/apps/sim/blocks/blocks/file.ts +++ b/apps/sim/blocks/blocks/file.ts @@ -1,8 +1,13 @@ import { createLogger } from '@sim/logger' -import { DocumentIcon } from '@/components/icons' import { inferContextFromKey } from '@/lib/uploads/utils/file-utils' +import { + FileBlockDisplay, + FileV2BlockDisplay, + FileV3BlockDisplay, + FileV4BlockDisplay, + FileV5BlockDisplay, +} from '@/blocks/blocks/file.display' import type { BlockConfig, SubBlockType } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { FileParserOutput, FileParserV3Output } from '@/tools/file/types' @@ -65,19 +70,10 @@ const resolveHttpFileUrl = (value: unknown): string => { } export const FileBlock: BlockConfig = { - type: 'file', - name: 'File (Legacy)', - description: 'Read and parse multiple files', - longDescription: `Integrate File into the workflow. Can upload a file manually or insert a file url.`, + ...FileBlockDisplay, bestPractices: ` - You should always use the File URL input method and enter the file URL if the user gives it to you or clarify if they have one. `, - docsLink: 'https://docs.sim.ai/integrations/file', - category: 'blocks', - integrationType: IntegrationType.Documents, - bgColor: '#40916C', - icon: DocumentIcon, - hideFromToolbar: true, subBlocks: [ { id: 'inputMethod', @@ -181,10 +177,7 @@ export const FileBlock: BlockConfig = { export const FileV2Block: BlockConfig = { ...FileBlock, - type: 'file_v2', - name: 'File (Legacy)', - description: 'Read and parse multiple files', - hideFromToolbar: true, + ...FileV2BlockDisplay, subBlocks: [ { id: 'file', @@ -267,17 +260,7 @@ export const FileV2Block: BlockConfig = { } export const FileV3Block: BlockConfig = { - type: 'file_v3', - name: 'File', - description: 'Read and write workspace files', - longDescription: - 'Read and parse files from uploads or URLs, write new workspace files, or append content to existing files.', - docsLink: 'https://docs.sim.ai/integrations/file', - category: 'blocks', - integrationType: IntegrationType.Documents, - bgColor: '#40916C', - icon: DocumentIcon, - hideFromToolbar: true, + ...FileV3BlockDisplay, subBlocks: [ { id: 'operation', @@ -562,12 +545,7 @@ const parseReadFileIds = (input: unknown): string | string[] | null => { export const FileV4Block: BlockConfig = { ...FileV3Block, - type: 'file_v4', - name: 'File (Legacy)', - description: 'Read, fetch, write, and append files', - longDescription: - 'Read workspace files by picker or canonical ID, fetch and parse files from URLs with optional headers, write new workspace files, or append content to existing files.', - hideFromToolbar: true, + ...FileV4BlockDisplay, bestPractices: ` - Use Read when you need an existing workspace file object by picker selection or canonical file ID. - Use Fetch for external file URLs. Add headers for authenticated downloads, for example Slack private file URLs require an Authorization Bearer token. @@ -820,13 +798,7 @@ export const FileV4Block: BlockConfig = { export const FileV5Block: BlockConfig = { ...FileV4Block, - type: 'file_v5', - name: 'File', - description: - 'Read, get content, fetch, write, append, compress, decompress, and manage sharing for files', - longDescription: - 'Read workspace file objects, extract the text content of files, fetch and parse files from URLs with optional headers, write new workspace files, append content to existing files, compress files into a .zip archive, extract a .zip archive into the workspace, or manage the public share link for a file.', - hideFromToolbar: false, + ...FileV5BlockDisplay, bestPractices: ` - Read returns workspace file objects in the "files" output and does NOT include their text. Use it to pick files or pass file references downstream (e.g. as attachments). - Get Content is how you read file text. It accepts file objects or canonical file IDs and returns a "contents" array with one extracted text string per file (PDF, DOCX, CSV, etc. are parsed automatically). diff --git a/apps/sim/blocks/blocks/findymail.display.ts b/apps/sim/blocks/blocks/findymail.display.ts new file mode 100644 index 00000000000..23915151231 --- /dev/null +++ b/apps/sim/blocks/blocks/findymail.display.ts @@ -0,0 +1,16 @@ +import { FindymailIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const FindymailBlockDisplay = { + type: 'findymail', + name: 'Findymail', + description: 'Find and verify B2B emails, phones, employees, and company data', + category: 'tools', + bgColor: '#FFFFFF', + icon: FindymailIcon, + longDescription: + 'Integrate Findymail to find verified work emails by name, domain, or LinkedIn URL, verify deliverability, reverse-lookup profiles from emails, enrich company data, find employees by job title, look up phone numbers, search technology stacks, and check credit usage.', + docsLink: 'https://docs.sim.ai/integrations/findymail', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/findymail.ts b/apps/sim/blocks/blocks/findymail.ts index fad37d3d1b2..38a88bff6f3 100644 --- a/apps/sim/blocks/blocks/findymail.ts +++ b/apps/sim/blocks/blocks/findymail.ts @@ -1,19 +1,11 @@ import { FindymailIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { FindymailBlockDisplay } from '@/blocks/blocks/findymail.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { FindymailResponse } from '@/tools/findymail/types' export const FindymailBlock: BlockConfig = { - type: 'findymail', - name: 'Findymail', - description: 'Find and verify B2B emails, phones, employees, and company data', + ...FindymailBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Findymail to find verified work emails by name, domain, or LinkedIn URL, verify deliverability, reverse-lookup profiles from emails, enrich company data, find employees by job title, look up phone numbers, search technology stacks, and check credit usage.', - docsLink: 'https://docs.sim.ai/integrations/findymail', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: FindymailIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/firecrawl.display.ts b/apps/sim/blocks/blocks/firecrawl.display.ts new file mode 100644 index 00000000000..51f7b947290 --- /dev/null +++ b/apps/sim/blocks/blocks/firecrawl.display.ts @@ -0,0 +1,16 @@ +import { FirecrawlIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const FirecrawlBlockDisplay = { + type: 'firecrawl', + name: 'Firecrawl', + description: 'Scrape, search, crawl, map, and extract web data', + category: 'tools', + bgColor: '#181C1E', + icon: FirecrawlIcon, + longDescription: + 'Integrate Firecrawl into the workflow. Scrape pages, search the web, crawl entire sites, map URL structures, and extract structured data with AI.', + docsLink: 'https://docs.sim.ai/integrations/firecrawl', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/firecrawl.ts b/apps/sim/blocks/blocks/firecrawl.ts index af9ab4d4c07..fc928c6c34b 100644 --- a/apps/sim/blocks/blocks/firecrawl.ts +++ b/apps/sim/blocks/blocks/firecrawl.ts @@ -1,21 +1,13 @@ import { FirecrawlIcon } from '@/components/icons' +import { FirecrawlBlockDisplay } from '@/blocks/blocks/firecrawl.display' import type { BlockConfig, BlockMeta, SubBlockType } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { FirecrawlResponse } from '@/tools/firecrawl/types' export const FirecrawlBlock: BlockConfig = { - type: 'firecrawl', - name: 'Firecrawl', - description: 'Scrape, search, crawl, map, and extract web data', + ...FirecrawlBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Firecrawl into the workflow. Scrape pages, search the web, crawl entire sites, map URL structures, and extract structured data with AI.', - docsLink: 'https://docs.sim.ai/integrations/firecrawl', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#181C1E', - icon: FirecrawlIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/fireflies.display.ts b/apps/sim/blocks/blocks/fireflies.display.ts new file mode 100644 index 00000000000..d3391d3751f --- /dev/null +++ b/apps/sim/blocks/blocks/fireflies.display.ts @@ -0,0 +1,27 @@ +import { FirefliesIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const FirefliesBlockDisplay = { + type: 'fireflies', + name: 'Fireflies (Legacy)', + description: 'Interact with Fireflies.ai meeting transcripts and recordings', + category: 'tools', + bgColor: '#100730', + icon: FirefliesIcon, + longDescription: + 'Integrate Fireflies.ai into the workflow. Manage meeting transcripts, add bot to live meetings, create soundbites, and more. Can also trigger workflows when transcriptions complete.', + docsLink: 'https://docs.sim.ai/integrations/fireflies', + integrationType: IntegrationType.Productivity, + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay + +export const FirefliesV2BlockDisplay = { + ...FirefliesBlockDisplay, + type: 'fireflies_v2', + name: 'Fireflies', + description: 'Interact with Fireflies.ai meeting transcripts and recordings', + integrationType: IntegrationType.Productivity, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/fireflies.ts b/apps/sim/blocks/blocks/fireflies.ts index ddfefa7ddd5..feaed4aa934 100644 --- a/apps/sim/blocks/blocks/fireflies.ts +++ b/apps/sim/blocks/blocks/fireflies.ts @@ -1,25 +1,15 @@ import { FirefliesIcon } from '@/components/icons' import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils' +import { FirefliesBlockDisplay, FirefliesV2BlockDisplay } from '@/blocks/blocks/fireflies.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { FirefliesResponse } from '@/tools/fireflies/types' import { getTrigger } from '@/triggers' export const FirefliesBlock: BlockConfig = { - type: 'fireflies', - name: 'Fireflies (Legacy)', - description: 'Interact with Fireflies.ai meeting transcripts and recordings', - hideFromToolbar: true, + ...FirefliesBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, - longDescription: - 'Integrate Fireflies.ai into the workflow. Manage meeting transcripts, add bot to live meetings, create soundbites, and more. Can also trigger workflows when transcriptions complete.', - docsLink: 'https://docs.sim.ai/integrations/fireflies', - category: 'tools', - integrationType: IntegrationType.Productivity, - icon: FirefliesIcon, - bgColor: '#100730', subBlocks: [ { id: 'operation', @@ -646,11 +636,7 @@ const firefliesV2Inputs = FirefliesBlock.inputs export const FirefliesV2Block: BlockConfig = { ...FirefliesBlock, - type: 'fireflies_v2', - name: 'Fireflies', - description: 'Interact with Fireflies.ai meeting transcripts and recordings', - hideFromToolbar: false, - integrationType: IntegrationType.Productivity, + ...FirefliesV2BlockDisplay, subBlocks: firefliesV2SubBlocks, tools: { ...FirefliesBlock.tools, diff --git a/apps/sim/blocks/blocks/function.display.ts b/apps/sim/blocks/blocks/function.display.ts new file mode 100644 index 00000000000..e08ab522d9b --- /dev/null +++ b/apps/sim/blocks/blocks/function.display.ts @@ -0,0 +1,14 @@ +import { CodeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const FunctionBlockDisplay = { + type: 'function', + name: 'Function', + description: 'Run custom logic', + category: 'blocks', + bgColor: '#FF402F', + icon: CodeIcon, + longDescription: + 'This is a core workflow block. Execute custom JavaScript or Python code within your workflow. JavaScript without imports runs locally for fast execution, while code with imports or Python uses E2B sandbox.', + docsLink: 'https://docs.sim.ai/workflows/blocks/function', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/function.ts b/apps/sim/blocks/blocks/function.ts index f4a8e72b77d..f7b4223ff4b 100644 --- a/apps/sim/blocks/blocks/function.ts +++ b/apps/sim/blocks/blocks/function.ts @@ -1,24 +1,16 @@ -import { CodeIcon } from '@/components/icons' import { CodeLanguage, getLanguageDisplayName } from '@/lib/execution/languages' +import { FunctionBlockDisplay } from '@/blocks/blocks/function.display' import type { BlockConfig } from '@/blocks/types' import type { CodeExecutionOutput } from '@/tools/function/types' export const FunctionBlock: BlockConfig = { - type: 'function', - name: 'Function', - description: 'Run custom logic', - longDescription: - 'This is a core workflow block. Execute custom JavaScript or Python code within your workflow. JavaScript without imports runs locally for fast execution, while code with imports or Python uses E2B sandbox.', + ...FunctionBlockDisplay, bestPractices: ` - JavaScript code without external imports runs in a local VM for fastest execution. - JavaScript code with import/require statements requires E2B and runs in a secure sandbox. - Python code always requires E2B and runs in a secure sandbox. - Can reference workflow variables using syntax as usual within code. Avoid XML/HTML tags. `, - docsLink: 'https://docs.sim.ai/workflows/blocks/function', - category: 'blocks', - bgColor: '#FF402F', - icon: CodeIcon, subBlocks: [ { id: 'language', diff --git a/apps/sim/blocks/blocks/gamma.display.ts b/apps/sim/blocks/blocks/gamma.display.ts new file mode 100644 index 00000000000..daa1ff45b4f --- /dev/null +++ b/apps/sim/blocks/blocks/gamma.display.ts @@ -0,0 +1,16 @@ +import { GammaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GammaBlockDisplay = { + type: 'gamma', + name: 'Gamma', + description: 'Generate presentations, documents, and webpages with AI', + category: 'tools', + bgColor: '#002253', + icon: GammaIcon, + longDescription: + 'Integrate Gamma into the workflow. Can generate presentations, documents, webpages, and social posts from text, create from templates, check generation status, and browse themes and folders.', + docsLink: 'https://docs.sim.ai/integrations/gamma', + integrationType: IntegrationType.Marketing, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/gamma.ts b/apps/sim/blocks/blocks/gamma.ts index 6b33c2f7c68..ff49a54c2d0 100644 --- a/apps/sim/blocks/blocks/gamma.ts +++ b/apps/sim/blocks/blocks/gamma.ts @@ -1,18 +1,10 @@ import { GammaIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GammaBlockDisplay } from '@/blocks/blocks/gamma.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { GammaResponse } from '@/tools/gamma/types' export const GammaBlock: BlockConfig = { - type: 'gamma', - name: 'Gamma', - description: 'Generate presentations, documents, and webpages with AI', - longDescription: - 'Integrate Gamma into the workflow. Can generate presentations, documents, webpages, and social posts from text, create from templates, check generation status, and browse themes and folders.', - docsLink: 'https://docs.sim.ai/integrations/gamma', - category: 'tools', - integrationType: IntegrationType.Marketing, - bgColor: '#002253', - icon: GammaIcon, + ...GammaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/generic_webhook.display.ts b/apps/sim/blocks/blocks/generic_webhook.display.ts new file mode 100644 index 00000000000..c25da2d1e46 --- /dev/null +++ b/apps/sim/blocks/blocks/generic_webhook.display.ts @@ -0,0 +1,17 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { Webhook } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const WebhookIcon = (props: SVGProps) => createElement(Webhook, props) + +export const GenericWebhookBlockDisplay = { + type: 'generic_webhook', + name: 'Webhook', + description: 'Receive webhooks from any service by configuring a custom webhook.', + category: 'triggers', + bgColor: '#10B981', + icon: WebhookIcon, + docsLink: 'https://docs.sim.ai/workflows/triggers/webhook', + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/generic_webhook.ts b/apps/sim/blocks/blocks/generic_webhook.ts index 5fa4a94e8a5..73b9743eac2 100644 --- a/apps/sim/blocks/blocks/generic_webhook.ts +++ b/apps/sim/blocks/blocks/generic_webhook.ts @@ -1,20 +1,9 @@ -import type { SVGProps } from 'react' -import { createElement } from 'react' -import { Webhook } from 'lucide-react' +import { GenericWebhookBlockDisplay } from '@/blocks/blocks/generic_webhook.display' import type { BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' -const WebhookIcon = (props: SVGProps) => createElement(Webhook, props) - export const GenericWebhookBlock: BlockConfig = { - type: 'generic_webhook', - name: 'Webhook', - description: 'Receive webhooks from any service by configuring a custom webhook.', - category: 'triggers', - icon: WebhookIcon, - bgColor: '#10B981', // Green color for triggers - docsLink: 'https://docs.sim.ai/workflows/triggers/webhook', - triggerAllowed: true, + ...GenericWebhookBlockDisplay, bestPractices: ` - You can test the webhook by sending a request to the webhook URL. E.g. depending on authorization: curl -X POST http://localhost:3000/api/webhooks/trigger/d8abcf0d-1ee5-4b77-bb07-b1e8142ea4e9 -H "Content-Type: application/json" -H "X-Sim-Secret: 1234" -d '{"message": "Test webhook trigger", "data": {"key": "v"}}' - Continuing example above, the body can be accessed in downstream block using dot notation. E.g. and diff --git a/apps/sim/blocks/blocks/github.display.ts b/apps/sim/blocks/blocks/github.display.ts new file mode 100644 index 00000000000..1da5145d082 --- /dev/null +++ b/apps/sim/blocks/blocks/github.display.ts @@ -0,0 +1,26 @@ +import { GithubIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GitHubBlockDisplay = { + type: 'github', + name: 'GitHub (Legacy)', + description: 'Interact with GitHub or trigger workflows from GitHub events', + category: 'tools', + bgColor: '#181C1E', + icon: GithubIcon, + longDescription: + 'Integrate Github into the workflow. Can get get PR details, create PR comment, get repository info, and get latest commit. Can be used in trigger mode to trigger a workflow when a PR is created, commented on, or a commit is pushed.', + docsLink: 'https://docs.sim.ai/integrations/github', + integrationType: IntegrationType.DevOps, + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay + +export const GitHubV2BlockDisplay = { + ...GitHubBlockDisplay, + type: 'github_v2', + name: 'GitHub', + integrationType: IntegrationType.DevOps, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/github.ts b/apps/sim/blocks/blocks/github.ts index 4d3735f731f..0574948d868 100644 --- a/apps/sim/blocks/blocks/github.ts +++ b/apps/sim/blocks/blocks/github.ts @@ -1,25 +1,15 @@ import { Calendar } from '@/components/emcn/icons' import { GithubIcon, NotionIcon } from '@/components/icons' +import { GitHubBlockDisplay, GitHubV2BlockDisplay } from '@/blocks/blocks/github.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { GitHubResponse } from '@/tools/github/types' import { getTrigger } from '@/triggers' export const GitHubBlock: BlockConfig = { - type: 'github', - name: 'GitHub (Legacy)', - description: 'Interact with GitHub or trigger workflows from GitHub events', + ...GitHubBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Github into the workflow. Can get get PR details, create PR comment, get repository info, and get latest commit. Can be used in trigger mode to trigger a workflow when a PR is created, commented on, or a commit is pushed.', - docsLink: 'https://docs.sim.ai/integrations/github', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#181C1E', - icon: GithubIcon, - triggerAllowed: true, - hideFromToolbar: true, subBlocks: [ { id: 'operation', @@ -2022,10 +2012,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, export const GitHubV2Block: BlockConfig = { ...GitHubBlock, - type: 'github_v2', - name: 'GitHub', - hideFromToolbar: false, - integrationType: IntegrationType.DevOps, + ...GitHubV2BlockDisplay, tools: { ...GitHubBlock.tools, access: (GitHubBlock.tools?.access || []).map((toolId) => `${toolId}_v2`), diff --git a/apps/sim/blocks/blocks/gitlab.display.ts b/apps/sim/blocks/blocks/gitlab.display.ts new file mode 100644 index 00000000000..eff1b5c4411 --- /dev/null +++ b/apps/sim/blocks/blocks/gitlab.display.ts @@ -0,0 +1,17 @@ +import { GitLabIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GitLabBlockDisplay = { + type: 'gitlab', + name: 'GitLab', + description: 'Interact with GitLab projects, issues, merge requests, and pipelines', + category: 'tools', + bgColor: '#FFFFFF', + icon: GitLabIcon, + longDescription: + 'Integrate GitLab into the workflow. Can manage projects, issues, merge requests, pipelines, and add comments. Supports all core GitLab DevOps operations.', + docsLink: 'https://docs.sim.ai/integrations/gitlab', + integrationType: IntegrationType.DevOps, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/gitlab.ts b/apps/sim/blocks/blocks/gitlab.ts index 078422bedac..df26c5c2cbd 100644 --- a/apps/sim/blocks/blocks/gitlab.ts +++ b/apps/sim/blocks/blocks/gitlab.ts @@ -1,22 +1,13 @@ import { GitLabIcon } from '@/components/icons' +import { GitLabBlockDisplay } from '@/blocks/blocks/gitlab.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { GitLabResponse } from '@/tools/gitlab/types' import { getTrigger } from '@/triggers' export const GitLabBlock: BlockConfig = { - type: 'gitlab', - name: 'GitLab', - description: 'Interact with GitLab projects, issues, merge requests, and pipelines', + ...GitLabBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, - longDescription: - 'Integrate GitLab into the workflow. Can manage projects, issues, merge requests, pipelines, and add comments. Supports all core GitLab DevOps operations.', - docsLink: 'https://docs.sim.ai/integrations/gitlab', - category: 'tools', - integrationType: IntegrationType.DevOps, - icon: GitLabIcon, - bgColor: '#FFFFFF', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/gmail.display.ts b/apps/sim/blocks/blocks/gmail.display.ts new file mode 100644 index 00000000000..54d180b3f60 --- /dev/null +++ b/apps/sim/blocks/blocks/gmail.display.ts @@ -0,0 +1,26 @@ +import { GmailIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GmailBlockDisplay = { + type: 'gmail', + name: 'Gmail (Legacy)', + description: 'Send, read, search, and move Gmail messages or trigger workflows from Gmail events', + category: 'tools', + bgColor: '#FFFFFF', + icon: GmailIcon, + longDescription: + 'Integrate Gmail into the workflow. Can send, read, search, and move emails. Can be used in trigger mode to trigger a workflow when a new email is received.', + docsLink: 'https://docs.sim.ai/integrations/gmail', + integrationType: IntegrationType.Email, + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay + +export const GmailV2BlockDisplay = { + ...GmailBlockDisplay, + type: 'gmail_v2', + name: 'Gmail', + integrationType: IntegrationType.Email, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/gmail.ts b/apps/sim/blocks/blocks/gmail.ts index 3ac0825abdc..4dbaea9bf48 100644 --- a/apps/sim/blocks/blocks/gmail.ts +++ b/apps/sim/blocks/blocks/gmail.ts @@ -1,8 +1,9 @@ import { Card } from '@/components/emcn/icons' import { GmailIcon, LemlistIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GmailBlockDisplay, GmailV2BlockDisplay } from '@/blocks/blocks/gmail.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput, @@ -45,19 +46,8 @@ function selectGmailToolId(params: Record): string { } export const GmailBlock: BlockConfig = { - type: 'gmail', - name: 'Gmail (Legacy)', - description: 'Send, read, search, and move Gmail messages or trigger workflows from Gmail events', + ...GmailBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Gmail into the workflow. Can send, read, search, and move emails. Can be used in trigger mode to trigger a workflow when a new email is received.', - docsLink: 'https://docs.sim.ai/integrations/gmail', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#FFFFFF', - icon: GmailIcon, - hideFromToolbar: true, - triggerAllowed: true, subBlocks: [ // Operation selector { @@ -575,10 +565,7 @@ Return ONLY the search query - no explanations, no extra text.`, export const GmailV2Block: BlockConfig = { ...GmailBlock, - type: 'gmail_v2', - name: 'Gmail', - hideFromToolbar: false, - integrationType: IntegrationType.Email, + ...GmailV2BlockDisplay, tools: { ...GmailBlock.tools, access: [ diff --git a/apps/sim/blocks/blocks/gong.display.ts b/apps/sim/blocks/blocks/gong.display.ts new file mode 100644 index 00000000000..e5ad9ee1707 --- /dev/null +++ b/apps/sim/blocks/blocks/gong.display.ts @@ -0,0 +1,18 @@ +import { GongIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GongBlockDisplay = { + type: 'gong', + name: 'Gong', + description: 'Revenue intelligence and conversation analytics', + category: 'tools', + bgColor: '#8039DF', + icon: GongIcon, + iconColor: '#8039DF', + longDescription: + 'Integrate Gong into your workflow. Access call recordings, transcripts, user data, activity stats, scorecards, trackers, library content, coaching metrics, and more via the Gong API.', + docsLink: 'https://docs.sim.ai/integrations/gong', + integrationType: IntegrationType.Sales, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index 2a367701f40..540fa514beb 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -1,22 +1,12 @@ import { GongIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GongBlockDisplay } from '@/blocks/blocks/gong.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { GongResponse } from '@/tools/gong/types' import { getTrigger } from '@/triggers' export const GongBlock: BlockConfig = { - type: 'gong', - name: 'Gong', - description: 'Revenue intelligence and conversation analytics', + ...GongBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Gong into your workflow. Access call recordings, transcripts, user data, activity stats, scorecards, trackers, library content, coaching metrics, and more via the Gong API.', - docsLink: 'https://docs.sim.ai/integrations/gong', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#8039DF', - iconColor: '#8039DF', - icon: GongIcon, - triggerAllowed: true, subBlocks: [ ...getTrigger('gong_webhook').subBlocks, ...getTrigger('gong_call_completed').subBlocks, diff --git a/apps/sim/blocks/blocks/google.display.ts b/apps/sim/blocks/blocks/google.display.ts new file mode 100644 index 00000000000..343336266d5 --- /dev/null +++ b/apps/sim/blocks/blocks/google.display.ts @@ -0,0 +1,15 @@ +import { GoogleIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleSearchBlockDisplay = { + type: 'google_search', + name: 'Google Search', + description: 'Search the web', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleIcon, + longDescription: 'Integrate Google Search into the workflow. Can search the web.', + docsLink: 'https://docs.sim.ai/integrations/google_search', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google.ts b/apps/sim/blocks/blocks/google.ts index 5c5a4da597d..f5ec8a42b03 100644 --- a/apps/sim/blocks/blocks/google.ts +++ b/apps/sim/blocks/blocks/google.ts @@ -1,19 +1,12 @@ import { GoogleIcon } from '@/components/icons' +import { GoogleSearchBlockDisplay } from '@/blocks/blocks/google.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { GoogleSearchResponse } from '@/tools/google/types' export const GoogleSearchBlock: BlockConfig = { - type: 'google_search', - name: 'Google Search', - description: 'Search the web', + ...GoogleSearchBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Google Search into the workflow. Can search the web.', - docsLink: 'https://docs.sim.ai/integrations/google_search', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: GoogleIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_ads.display.ts b/apps/sim/blocks/blocks/google_ads.display.ts new file mode 100644 index 00000000000..3c9558c7857 --- /dev/null +++ b/apps/sim/blocks/blocks/google_ads.display.ts @@ -0,0 +1,16 @@ +import { GoogleAdsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleAdsBlockDisplay = { + type: 'google_ads', + name: 'Google Ads', + description: 'Query campaigns, ad groups, and performance metrics', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleAdsIcon, + longDescription: + 'Connect to Google Ads to list accessible accounts, list campaigns, view ad group details, get performance metrics, and run custom GAQL queries.', + docsLink: 'https://docs.sim.ai/integrations/google_ads', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_ads.ts b/apps/sim/blocks/blocks/google_ads.ts index c4337e313dd..01ecde790ce 100644 --- a/apps/sim/blocks/blocks/google_ads.ts +++ b/apps/sim/blocks/blocks/google_ads.ts @@ -1,19 +1,11 @@ import { GoogleAdsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleAdsBlockDisplay } from '@/blocks/blocks/google_ads.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const GoogleAdsBlock: BlockConfig = { - type: 'google_ads', - name: 'Google Ads', - description: 'Query campaigns, ad groups, and performance metrics', - longDescription: - 'Connect to Google Ads to list accessible accounts, list campaigns, view ad group details, get performance metrics, and run custom GAQL queries.', - docsLink: 'https://docs.sim.ai/integrations/google_ads', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#FFFFFF', - icon: GoogleAdsIcon, + ...GoogleAdsBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_bigquery.display.ts b/apps/sim/blocks/blocks/google_bigquery.display.ts new file mode 100644 index 00000000000..c53470ce7bc --- /dev/null +++ b/apps/sim/blocks/blocks/google_bigquery.display.ts @@ -0,0 +1,16 @@ +import { GoogleBigQueryIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleBigQueryBlockDisplay = { + type: 'google_bigquery', + name: 'Google BigQuery', + description: 'Query, list, and insert data in Google BigQuery', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleBigQueryIcon, + longDescription: + 'Connect to Google BigQuery to run SQL queries, list datasets and tables, get table metadata, and insert rows.', + docsLink: 'https://docs.sim.ai/integrations/google_bigquery', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_bigquery.ts b/apps/sim/blocks/blocks/google_bigquery.ts index 0f2fad19920..c2ad98b3326 100644 --- a/apps/sim/blocks/blocks/google_bigquery.ts +++ b/apps/sim/blocks/blocks/google_bigquery.ts @@ -1,19 +1,11 @@ import { GoogleBigQueryIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleBigQueryBlockDisplay } from '@/blocks/blocks/google_bigquery.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const GoogleBigQueryBlock: BlockConfig = { - type: 'google_bigquery', - name: 'Google BigQuery', - description: 'Query, list, and insert data in Google BigQuery', - longDescription: - 'Connect to Google BigQuery to run SQL queries, list datasets and tables, get table metadata, and insert rows.', - docsLink: 'https://docs.sim.ai/integrations/google_bigquery', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: GoogleBigQueryIcon, + ...GoogleBigQueryBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_books.display.ts b/apps/sim/blocks/blocks/google_books.display.ts new file mode 100644 index 00000000000..107c24718d2 --- /dev/null +++ b/apps/sim/blocks/blocks/google_books.display.ts @@ -0,0 +1,16 @@ +import { GoogleBooksIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleBooksBlockDisplay = { + type: 'google_books', + name: 'Google Books', + description: 'Search and retrieve book information', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleBooksIcon, + longDescription: + 'Search for books using the Google Books API. Find volumes by title, author, ISBN, or keywords, and retrieve detailed information about specific books including descriptions, ratings, and publication details.', + docsLink: 'https://docs.sim.ai/integrations/google_books', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_books.ts b/apps/sim/blocks/blocks/google_books.ts index 47b6754dd4b..caeedcbfe27 100644 --- a/apps/sim/blocks/blocks/google_books.ts +++ b/apps/sim/blocks/blocks/google_books.ts @@ -1,19 +1,11 @@ import { GoogleBooksIcon } from '@/components/icons' +import { GoogleBooksBlockDisplay } from '@/blocks/blocks/google_books.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const GoogleBooksBlock: BlockConfig = { - type: 'google_books', - name: 'Google Books', - description: 'Search and retrieve book information', + ...GoogleBooksBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Search for books using the Google Books API. Find volumes by title, author, ISBN, or keywords, and retrieve detailed information about specific books including descriptions, ratings, and publication details.', - docsLink: 'https://docs.sim.ai/integrations/google_books', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: GoogleBooksIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_calendar.display.ts b/apps/sim/blocks/blocks/google_calendar.display.ts new file mode 100644 index 00000000000..9701ccaeec1 --- /dev/null +++ b/apps/sim/blocks/blocks/google_calendar.display.ts @@ -0,0 +1,25 @@ +import { GoogleCalendarIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleCalendarBlockDisplay = { + type: 'google_calendar', + name: 'Google Calendar (Legacy)', + description: 'Manage Google Calendar events', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleCalendarIcon, + longDescription: + 'Integrate Google Calendar into the workflow. Can create, read, update, and list calendar events.', + docsLink: 'https://docs.sim.ai/integrations/google_calendar', + integrationType: IntegrationType.Productivity, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const GoogleCalendarV2BlockDisplay = { + ...GoogleCalendarBlockDisplay, + type: 'google_calendar_v2', + name: 'Google Calendar', + integrationType: IntegrationType.Productivity, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_calendar.ts b/apps/sim/blocks/blocks/google_calendar.ts index 05bd744dde5..9f7baae93fd 100644 --- a/apps/sim/blocks/blocks/google_calendar.ts +++ b/apps/sim/blocks/blocks/google_calendar.ts @@ -1,24 +1,18 @@ import { GoogleCalendarIcon, TwilioIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { + GoogleCalendarBlockDisplay, + GoogleCalendarV2BlockDisplay, +} from '@/blocks/blocks/google_calendar.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleCalendarResponse } from '@/tools/google_calendar/types' import { getTrigger } from '@/triggers' export const GoogleCalendarBlock: BlockConfig = { - type: 'google_calendar', - name: 'Google Calendar (Legacy)', - description: 'Manage Google Calendar events', + ...GoogleCalendarBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Google Calendar into the workflow. Can create, read, update, and list calendar events.', - docsLink: 'https://docs.sim.ai/integrations/google_calendar', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: GoogleCalendarIcon, - hideFromToolbar: true, subBlocks: [ { id: 'operation', @@ -888,10 +882,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, export const GoogleCalendarV2Block: BlockConfig = { ...GoogleCalendarBlock, - type: 'google_calendar_v2', - name: 'Google Calendar', - hideFromToolbar: false, - integrationType: IntegrationType.Productivity, + ...GoogleCalendarV2BlockDisplay, tools: { ...GoogleCalendarBlock.tools, access: [ diff --git a/apps/sim/blocks/blocks/google_contacts.display.ts b/apps/sim/blocks/blocks/google_contacts.display.ts new file mode 100644 index 00000000000..a60490973c8 --- /dev/null +++ b/apps/sim/blocks/blocks/google_contacts.display.ts @@ -0,0 +1,16 @@ +import { GoogleContactsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleContactsBlockDisplay = { + type: 'google_contacts', + name: 'Google Contacts', + description: 'Manage Google Contacts', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleContactsIcon, + longDescription: + 'Integrate Google Contacts into the workflow. Can create, read, update, delete, list, and search contacts.', + docsLink: 'https://docs.sim.ai/integrations/google_contacts', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_contacts.ts b/apps/sim/blocks/blocks/google_contacts.ts index 5a1ffb49204..d4cf59de5e3 100644 --- a/apps/sim/blocks/blocks/google_contacts.ts +++ b/apps/sim/blocks/blocks/google_contacts.ts @@ -1,22 +1,14 @@ import { GoogleContactsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleContactsBlockDisplay } from '@/blocks/blocks/google_contacts.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleContactsResponse } from '@/tools/google_contacts/types' export const GoogleContactsBlock: BlockConfig = { - type: 'google_contacts', - name: 'Google Contacts', - description: 'Manage Google Contacts', + ...GoogleContactsBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Google Contacts into the workflow. Can create, read, update, delete, list, and search contacts.', - docsLink: 'https://docs.sim.ai/integrations/google_contacts', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: GoogleContactsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/google_docs.display.ts b/apps/sim/blocks/blocks/google_docs.display.ts new file mode 100644 index 00000000000..3364e957120 --- /dev/null +++ b/apps/sim/blocks/blocks/google_docs.display.ts @@ -0,0 +1,16 @@ +import { GoogleDocsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleDocsBlockDisplay = { + type: 'google_docs', + name: 'Google Docs', + description: 'Read, write, and create documents', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleDocsIcon, + longDescription: + 'Integrate Google Docs into the workflow. Can read, write, and create documents.', + docsLink: 'https://docs.sim.ai/integrations/google_docs', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_docs.ts b/apps/sim/blocks/blocks/google_docs.ts index 9cece1fb364..56047cf5531 100644 --- a/apps/sim/blocks/blocks/google_docs.ts +++ b/apps/sim/blocks/blocks/google_docs.ts @@ -1,22 +1,14 @@ import { GoogleDocsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleDocsBlockDisplay } from '@/blocks/blocks/google_docs.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleDocsResponse } from '@/tools/google_docs/types' export const GoogleDocsBlock: BlockConfig = { - type: 'google_docs', - name: 'Google Docs', - description: 'Read, write, and create documents', + ...GoogleDocsBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Google Docs into the workflow. Can read, write, and create documents.', - docsLink: 'https://docs.sim.ai/integrations/google_docs', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleDocsIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/google_drive.display.ts b/apps/sim/blocks/blocks/google_drive.display.ts new file mode 100644 index 00000000000..7d7b55dc230 --- /dev/null +++ b/apps/sim/blocks/blocks/google_drive.display.ts @@ -0,0 +1,16 @@ +import { GoogleDriveIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleDriveBlockDisplay = { + type: 'google_drive', + name: 'Google Drive', + description: 'Manage files, folders, and permissions', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleDriveIcon, + longDescription: + 'Integrate Google Drive into the workflow. Can create, upload, download, copy, move, delete, share files and manage permissions.', + docsLink: 'https://docs.sim.ai/integrations/google_drive', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_drive.ts b/apps/sim/blocks/blocks/google_drive.ts index dc23d930e39..94ad7cc6c44 100644 --- a/apps/sim/blocks/blocks/google_drive.ts +++ b/apps/sim/blocks/blocks/google_drive.ts @@ -1,24 +1,16 @@ import { BookOpen } from '@/components/emcn/icons' import { GoogleDriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleDriveBlockDisplay } from '@/blocks/blocks/google_drive.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleDriveResponse } from '@/tools/google_drive/types' import { getTrigger } from '@/triggers' export const GoogleDriveBlock: BlockConfig = { - type: 'google_drive', - name: 'Google Drive', - description: 'Manage files, folders, and permissions', + ...GoogleDriveBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Google Drive into the workflow. Can create, upload, download, copy, move, delete, share files and manage permissions.', - docsLink: 'https://docs.sim.ai/integrations/google_drive', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleDriveIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/google_forms.display.ts b/apps/sim/blocks/blocks/google_forms.display.ts new file mode 100644 index 00000000000..7b58ada5910 --- /dev/null +++ b/apps/sim/blocks/blocks/google_forms.display.ts @@ -0,0 +1,16 @@ +import { GoogleFormsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleFormsBlockDisplay = { + type: 'google_forms', + name: 'Google Forms', + description: 'Manage Google Forms and responses', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleFormsIcon, + longDescription: + 'Integrate Google Forms into your workflow. Read form structure, get responses, create forms, update content, and manage notification watches.', + docsLink: 'https://docs.sim.ai/integrations/google_forms', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_forms.ts b/apps/sim/blocks/blocks/google_forms.ts index 66ac9e760bc..2db6f65cea6 100644 --- a/apps/sim/blocks/blocks/google_forms.ts +++ b/apps/sim/blocks/blocks/google_forms.ts @@ -1,21 +1,12 @@ import { GoogleFormsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleFormsBlockDisplay } from '@/blocks/blocks/google_forms.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import { getTrigger } from '@/triggers' export const GoogleFormsBlock: BlockConfig = { - type: 'google_forms', - name: 'Google Forms', - description: 'Manage Google Forms and responses', - longDescription: - 'Integrate Google Forms into your workflow. Read form structure, get responses, create forms, update content, and manage notification watches.', - docsLink: 'https://docs.sim.ai/integrations/google_forms', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleFormsIcon, + ...GoogleFormsBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/google_groups.display.ts b/apps/sim/blocks/blocks/google_groups.display.ts new file mode 100644 index 00000000000..ff008ee86bc --- /dev/null +++ b/apps/sim/blocks/blocks/google_groups.display.ts @@ -0,0 +1,16 @@ +import { GoogleGroupsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleGroupsBlockDisplay = { + type: 'google_groups', + name: 'Google Groups', + description: 'Manage Google Workspace Groups and their members', + category: 'tools', + bgColor: '#E8F0FE', + icon: GoogleGroupsIcon, + longDescription: + 'Connect to Google Workspace to create, update, and manage groups and their members using the Admin SDK Directory API.', + docsLink: 'https://developers.google.com/admin-sdk/directory/v1/guides/manage-groups', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_groups.ts b/apps/sim/blocks/blocks/google_groups.ts index 537ae4a0123..e6bbae31882 100644 --- a/apps/sim/blocks/blocks/google_groups.ts +++ b/apps/sim/blocks/blocks/google_groups.ts @@ -1,21 +1,13 @@ import { GoogleGroupsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleGroupsBlockDisplay } from '@/blocks/blocks/google_groups.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' export const GoogleGroupsBlock: BlockConfig = { - type: 'google_groups', - name: 'Google Groups', - description: 'Manage Google Workspace Groups and their members', + ...GoogleGroupsBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Connect to Google Workspace to create, update, and manage groups and their members using the Admin SDK Directory API.', - docsLink: 'https://developers.google.com/admin-sdk/directory/v1/guides/manage-groups', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#E8F0FE', - icon: GoogleGroupsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/google_maps.display.ts b/apps/sim/blocks/blocks/google_maps.display.ts new file mode 100644 index 00000000000..22382347632 --- /dev/null +++ b/apps/sim/blocks/blocks/google_maps.display.ts @@ -0,0 +1,16 @@ +import { GoogleMapsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleMapsBlockDisplay = { + type: 'google_maps', + name: 'Google Maps', + description: 'Geocoding, directions, places, and distance calculations', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleMapsIcon, + longDescription: + 'Integrate Google Maps Platform APIs into your workflow. Supports geocoding addresses to coordinates, reverse geocoding, getting directions between locations, calculating distance matrices, searching for places, retrieving place details, elevation data, and timezone information.', + docsLink: 'https://docs.sim.ai/integrations/google_maps', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_maps.ts b/apps/sim/blocks/blocks/google_maps.ts index 26d3259b7f6..f514b1c2938 100644 --- a/apps/sim/blocks/blocks/google_maps.ts +++ b/apps/sim/blocks/blocks/google_maps.ts @@ -1,19 +1,9 @@ import { GoogleMapsIcon } from '@/components/icons' +import { GoogleMapsBlockDisplay } from '@/blocks/blocks/google_maps.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' export const GoogleMapsBlock: BlockConfig = { - type: 'google_maps', - name: 'Google Maps', - description: 'Geocoding, directions, places, and distance calculations', - longDescription: - 'Integrate Google Maps Platform APIs into your workflow. Supports geocoding addresses to coordinates, reverse geocoding, getting directions between locations, calculating distance matrices, searching for places, retrieving place details, elevation data, and timezone information.', - docsLink: 'https://docs.sim.ai/integrations/google_maps', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#FFFFFF', - icon: GoogleMapsIcon, - + ...GoogleMapsBlockDisplay, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/google_meet.display.ts b/apps/sim/blocks/blocks/google_meet.display.ts new file mode 100644 index 00000000000..5805bd853e0 --- /dev/null +++ b/apps/sim/blocks/blocks/google_meet.display.ts @@ -0,0 +1,16 @@ +import { GoogleMeetIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleMeetBlockDisplay = { + type: 'google_meet', + name: 'Google Meet', + description: 'Create and manage Google Meet meetings', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleMeetIcon, + longDescription: + 'Integrate Google Meet into your workflow. Create meeting spaces, get space details, end conferences, list conference records, and view participants.', + docsLink: 'https://docs.sim.ai/integrations/google_meet', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_meet.ts b/apps/sim/blocks/blocks/google_meet.ts index 12a684515e0..9b6469749bc 100644 --- a/apps/sim/blocks/blocks/google_meet.ts +++ b/apps/sim/blocks/blocks/google_meet.ts @@ -1,21 +1,13 @@ import { GoogleMeetIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleMeetBlockDisplay } from '@/blocks/blocks/google_meet.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleMeetResponse } from '@/tools/google_meet/types' export const GoogleMeetBlock: BlockConfig = { - type: 'google_meet', - name: 'Google Meet', - description: 'Create and manage Google Meet meetings', - longDescription: - 'Integrate Google Meet into your workflow. Create meeting spaces, get space details, end conferences, list conference records, and view participants.', - docsLink: 'https://docs.sim.ai/integrations/google_meet', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#FFFFFF', - icon: GoogleMeetIcon, + ...GoogleMeetBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_pagespeed.display.ts b/apps/sim/blocks/blocks/google_pagespeed.display.ts new file mode 100644 index 00000000000..5aaca4f6330 --- /dev/null +++ b/apps/sim/blocks/blocks/google_pagespeed.display.ts @@ -0,0 +1,16 @@ +import { GooglePagespeedIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GooglePagespeedBlockDisplay = { + type: 'google_pagespeed', + name: 'Google PageSpeed', + description: 'Analyze webpage performance with Google PageSpeed Insights', + category: 'tools', + bgColor: '#FFFFFF', + icon: GooglePagespeedIcon, + longDescription: + 'Analyze web pages for performance, accessibility, SEO, and best practices using Google PageSpeed Insights API powered by Lighthouse.', + docsLink: 'https://docs.sim.ai/integrations/google_pagespeed', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_pagespeed.ts b/apps/sim/blocks/blocks/google_pagespeed.ts index ab1e3ff58ee..e75734c5602 100644 --- a/apps/sim/blocks/blocks/google_pagespeed.ts +++ b/apps/sim/blocks/blocks/google_pagespeed.ts @@ -1,18 +1,10 @@ import { GooglePagespeedIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GooglePagespeedBlockDisplay } from '@/blocks/blocks/google_pagespeed.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { GooglePagespeedAnalyzeResponse } from '@/tools/google_pagespeed/types' export const GooglePagespeedBlock: BlockConfig = { - type: 'google_pagespeed', - name: 'Google PageSpeed', - description: 'Analyze webpage performance with Google PageSpeed Insights', - longDescription: - 'Analyze web pages for performance, accessibility, SEO, and best practices using Google PageSpeed Insights API powered by Lighthouse.', - docsLink: 'https://docs.sim.ai/integrations/google_pagespeed', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#FFFFFF', - icon: GooglePagespeedIcon, + ...GooglePagespeedBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/google_sheets.display.ts b/apps/sim/blocks/blocks/google_sheets.display.ts new file mode 100644 index 00000000000..1642acb93bc --- /dev/null +++ b/apps/sim/blocks/blocks/google_sheets.display.ts @@ -0,0 +1,31 @@ +import { GoogleSheetsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleSheetsBlockDisplay = { + type: 'google_sheets', + name: 'Google Sheets (Legacy)', + description: 'Read, write, and update data', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleSheetsIcon, + longDescription: + 'Integrate Google Sheets into the workflow. Can read, write, append, and update data.', + docsLink: 'https://docs.sim.ai/integrations/google_sheets', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const GoogleSheetsV2BlockDisplay = { + type: 'google_sheets_v2', + name: 'Google Sheets', + description: 'Read, write, and update data with sheet selection', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleSheetsIcon, + longDescription: + 'Integrate Google Sheets into the workflow with explicit sheet selection. Can read, write, append, update, clear data, create spreadsheets, get spreadsheet info, and copy sheets.', + docsLink: 'https://docs.sim.ai/integrations/google_sheets', + integrationType: IntegrationType.Documents, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_sheets.ts b/apps/sim/blocks/blocks/google_sheets.ts index 18397fbe736..4470a5b33fa 100644 --- a/apps/sim/blocks/blocks/google_sheets.ts +++ b/apps/sim/blocks/blocks/google_sheets.ts @@ -1,25 +1,19 @@ import { GoogleSheetsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { + GoogleSheetsBlockDisplay, + GoogleSheetsV2BlockDisplay, +} from '@/blocks/blocks/google_sheets.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleSheetsResponse, GoogleSheetsV2Response } from '@/tools/google_sheets/types' import { getTrigger } from '@/triggers' // Legacy block - hidden from toolbar export const GoogleSheetsBlock: BlockConfig = { - type: 'google_sheets', - name: 'Google Sheets (Legacy)', - description: 'Read, write, and update data', + ...GoogleSheetsBlockDisplay, authMode: AuthMode.OAuth, - hideFromToolbar: true, - longDescription: - 'Integrate Google Sheets into the workflow. Can read, write, append, and update data.', - docsLink: 'https://docs.sim.ai/integrations/google_sheets', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleSheetsIcon, subBlocks: [ // Operation selector { @@ -296,18 +290,8 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`, } export const GoogleSheetsV2Block: BlockConfig = { - type: 'google_sheets_v2', - name: 'Google Sheets', - description: 'Read, write, and update data with sheet selection', + ...GoogleSheetsV2BlockDisplay, authMode: AuthMode.OAuth, - hideFromToolbar: false, - longDescription: - 'Integrate Google Sheets into the workflow with explicit sheet selection. Can read, write, append, update, clear data, create spreadsheets, get spreadsheet info, and copy sheets.', - docsLink: 'https://docs.sim.ai/integrations/google_sheets', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleSheetsIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/google_slides.display.ts b/apps/sim/blocks/blocks/google_slides.display.ts new file mode 100644 index 00000000000..0b2f5bc3a27 --- /dev/null +++ b/apps/sim/blocks/blocks/google_slides.display.ts @@ -0,0 +1,26 @@ +import { GoogleSlidesIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleSlidesBlockDisplay = { + type: 'google_slides', + name: 'Google Slides (Legacy)', + description: 'Read, write, and create presentations', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleSlidesIcon, + longDescription: + 'Build, edit, and export branded Google Slides presentations end-to-end. Copy a template, replace text and image tokens, embed Sheets charts, style text and shapes with brand fonts and colors, manage tables and layouts, group elements, run atomic batch updates, and export to PDF or PPTX.', + docsLink: 'https://docs.sim.ai/integrations/google_slides', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const GoogleSlidesV2BlockDisplay = { + ...GoogleSlidesBlockDisplay, + type: 'google_slides_v2', + name: 'Google Slides', + description: 'Read, write, and create presentations', + integrationType: IntegrationType.Documents, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_slides.ts b/apps/sim/blocks/blocks/google_slides.ts index b05ecf8fde9..55b5e63b3ab 100644 --- a/apps/sim/blocks/blocks/google_slides.ts +++ b/apps/sim/blocks/blocks/google_slides.ts @@ -1,24 +1,18 @@ import { GoogleSlidesIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils' +import { + GoogleSlidesBlockDisplay, + GoogleSlidesV2BlockDisplay, +} from '@/blocks/blocks/google_slides.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleSlidesResponse } from '@/tools/google_slides/types' export const GoogleSlidesBlock: BlockConfig = { - type: 'google_slides', - name: 'Google Slides (Legacy)', - description: 'Read, write, and create presentations', - hideFromToolbar: true, + ...GoogleSlidesBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Build, edit, and export branded Google Slides presentations end-to-end. Copy a template, replace text and image tokens, embed Sheets charts, style text and shapes with brand fonts and colors, manage tables and layouts, group elements, run atomic batch updates, and export to PDF or PPTX.', - docsLink: 'https://docs.sim.ai/integrations/google_slides', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: GoogleSlidesIcon, subBlocks: [ // Operation selector { @@ -3454,11 +3448,7 @@ const googleSlidesV2Inputs = GoogleSlidesBlock.inputs export const GoogleSlidesV2Block: BlockConfig = { ...GoogleSlidesBlock, - type: 'google_slides_v2', - name: 'Google Slides', - description: 'Read, write, and create presentations', - hideFromToolbar: false, - integrationType: IntegrationType.Documents, + ...GoogleSlidesV2BlockDisplay, subBlocks: googleSlidesV2SubBlocks, tools: { access: GoogleSlidesBlock.tools!.access, diff --git a/apps/sim/blocks/blocks/google_tasks.display.ts b/apps/sim/blocks/blocks/google_tasks.display.ts new file mode 100644 index 00000000000..e08096a91d2 --- /dev/null +++ b/apps/sim/blocks/blocks/google_tasks.display.ts @@ -0,0 +1,16 @@ +import { GoogleTasksIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleTasksBlockDisplay = { + type: 'google_tasks', + name: 'Google Tasks', + description: 'Manage Google Tasks', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleTasksIcon, + longDescription: + 'Integrate Google Tasks into your workflow. Create, read, update, delete, and list tasks and task lists.', + docsLink: 'https://docs.sim.ai/integrations/google_tasks', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_tasks.ts b/apps/sim/blocks/blocks/google_tasks.ts index d5ec0b9fd05..d1287933344 100644 --- a/apps/sim/blocks/blocks/google_tasks.ts +++ b/apps/sim/blocks/blocks/google_tasks.ts @@ -1,21 +1,13 @@ import { GoogleTasksIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleTasksBlockDisplay } from '@/blocks/blocks/google_tasks.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleTasksResponse } from '@/tools/google_tasks/types' export const GoogleTasksBlock: BlockConfig = { - type: 'google_tasks', - name: 'Google Tasks', - description: 'Manage Google Tasks', - longDescription: - 'Integrate Google Tasks into your workflow. Create, read, update, delete, and list tasks and task lists.', - docsLink: 'https://docs.sim.ai/integrations/google_tasks', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: GoogleTasksIcon, + ...GoogleTasksBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ diff --git a/apps/sim/blocks/blocks/google_translate.display.ts b/apps/sim/blocks/blocks/google_translate.display.ts new file mode 100644 index 00000000000..41258ffc81f --- /dev/null +++ b/apps/sim/blocks/blocks/google_translate.display.ts @@ -0,0 +1,16 @@ +import { GoogleTranslateIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleTranslateBlockDisplay = { + type: 'google_translate', + name: 'Google Translate', + description: 'Translate text using Google Cloud Translation', + category: 'tools', + bgColor: '#FFFFFF', + icon: GoogleTranslateIcon, + longDescription: + 'Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.', + docsLink: 'https://docs.sim.ai/integrations/google_translate', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_translate.ts b/apps/sim/blocks/blocks/google_translate.ts index f8aa0a7023d..c48ef432450 100644 --- a/apps/sim/blocks/blocks/google_translate.ts +++ b/apps/sim/blocks/blocks/google_translate.ts @@ -1,5 +1,6 @@ import { GoogleTranslateIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GoogleTranslateBlockDisplay } from '@/blocks/blocks/google_translate.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' const SUPPORTED_LANGUAGES = [ { label: 'Afrikaans', id: 'af' }, @@ -138,16 +139,7 @@ const SUPPORTED_LANGUAGES = [ ] satisfies { label: string; id: string }[] export const GoogleTranslateBlock: BlockConfig = { - type: 'google_translate', - name: 'Google Translate', - description: 'Translate text using Google Cloud Translation', - longDescription: - 'Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.', - docsLink: 'https://docs.sim.ai/integrations/google_translate', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#FFFFFF', - icon: GoogleTranslateIcon, + ...GoogleTranslateBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/google_vault.display.ts b/apps/sim/blocks/blocks/google_vault.display.ts new file mode 100644 index 00000000000..99a454fb4af --- /dev/null +++ b/apps/sim/blocks/blocks/google_vault.display.ts @@ -0,0 +1,16 @@ +import { GoogleVaultIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GoogleVaultBlockDisplay = { + type: 'google_vault', + name: 'Google Vault', + description: 'Search, export, and manage holds/exports for Vault matters', + category: 'tools', + bgColor: '#E8F0FE', + icon: GoogleVaultIcon, + longDescription: + 'Connect Google Vault to create exports, list exports, and manage holds within matters.', + docsLink: 'https://developers.google.com/vault', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/google_vault.ts b/apps/sim/blocks/blocks/google_vault.ts index 24c03daa7f3..2561defa1c9 100644 --- a/apps/sim/blocks/blocks/google_vault.ts +++ b/apps/sim/blocks/blocks/google_vault.ts @@ -1,22 +1,13 @@ import { ShieldCheck } from '@/components/emcn/icons' -import { GoogleVaultIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { GoogleVaultBlockDisplay } from '@/blocks/blocks/google_vault.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' export const GoogleVaultBlock: BlockConfig = { - type: 'google_vault', - name: 'Google Vault', - description: 'Search, export, and manage holds/exports for Vault matters', + ...GoogleVaultBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Connect Google Vault to create exports, list exports, and manage holds within matters.', - docsLink: 'https://developers.google.com/vault', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#E8F0FE', - icon: GoogleVaultIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/grafana.display.ts b/apps/sim/blocks/blocks/grafana.display.ts new file mode 100644 index 00000000000..0420e80a6c6 --- /dev/null +++ b/apps/sim/blocks/blocks/grafana.display.ts @@ -0,0 +1,16 @@ +import { GrafanaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GrafanaBlockDisplay = { + type: 'grafana', + name: 'Grafana', + description: 'Interact with Grafana dashboards, alerts, and annotations', + category: 'tools', + bgColor: '#F46800', + icon: GrafanaIcon, + longDescription: + 'Integrate Grafana into workflows. Manage dashboards, alerts, annotations, data sources, folders, and monitor health status.', + docsLink: 'https://docs.sim.ai/integrations/grafana', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/grafana.ts b/apps/sim/blocks/blocks/grafana.ts index 9cb12c810ce..538292ea4d8 100644 --- a/apps/sim/blocks/blocks/grafana.ts +++ b/apps/sim/blocks/blocks/grafana.ts @@ -1,20 +1,12 @@ import { GrafanaIcon } from '@/components/icons' +import { GrafanaBlockDisplay } from '@/blocks/blocks/grafana.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { GrafanaResponse } from '@/tools/grafana/types' export const GrafanaBlock: BlockConfig = { - type: 'grafana', - name: 'Grafana', - description: 'Interact with Grafana dashboards, alerts, and annotations', + ...GrafanaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Grafana into workflows. Manage dashboards, alerts, annotations, data sources, folders, and monitor health status.', - docsLink: 'https://docs.sim.ai/integrations/grafana', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#F46800', - icon: GrafanaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/grain.display.ts b/apps/sim/blocks/blocks/grain.display.ts new file mode 100644 index 00000000000..4bf9030b57d --- /dev/null +++ b/apps/sim/blocks/blocks/grain.display.ts @@ -0,0 +1,17 @@ +import { GrainIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GrainBlockDisplay = { + type: 'grain', + name: 'Grain', + description: 'Access meeting recordings, transcripts, and AI summaries', + category: 'tools', + bgColor: '#F6FAF9', + icon: GrainIcon, + longDescription: + 'Integrate Grain into your workflow. Access meeting recordings, transcripts, highlights, and AI-generated summaries. Can also trigger workflows based on Grain webhook events.', + docsLink: 'https://docs.sim.ai/integrations/grain', + integrationType: IntegrationType.Productivity, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/grain.ts b/apps/sim/blocks/blocks/grain.ts index 494ab8b3e58..8a9c70ace0e 100644 --- a/apps/sim/blocks/blocks/grain.ts +++ b/apps/sim/blocks/blocks/grain.ts @@ -1,22 +1,13 @@ import { GrainIcon } from '@/components/icons' +import { GrainBlockDisplay } from '@/blocks/blocks/grain.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' import { grainTriggerOptions } from '@/triggers/grain/utils' export const GrainBlock: BlockConfig = { - type: 'grain', - name: 'Grain', - description: 'Access meeting recordings, transcripts, and AI summaries', + ...GrainBlockDisplay, authMode: AuthMode.ApiKey, - triggerAllowed: true, - longDescription: - 'Integrate Grain into your workflow. Access meeting recordings, transcripts, highlights, and AI-generated summaries. Can also trigger workflows based on Grain webhook events.', - category: 'tools', - integrationType: IntegrationType.Productivity, - docsLink: 'https://docs.sim.ai/integrations/grain', - icon: GrainIcon, - bgColor: '#F6FAF9', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/granola.display.ts b/apps/sim/blocks/blocks/granola.display.ts new file mode 100644 index 00000000000..d6cb3fddd6c --- /dev/null +++ b/apps/sim/blocks/blocks/granola.display.ts @@ -0,0 +1,16 @@ +import { GranolaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GranolaBlockDisplay = { + type: 'granola', + name: 'Granola', + description: 'Access meeting notes and transcripts from Granola', + category: 'tools', + bgColor: '#B2C147', + icon: GranolaIcon, + longDescription: + 'Integrate Granola into your workflow to retrieve meeting notes, summaries, attendees, and transcripts.', + docsLink: 'https://docs.sim.ai/integrations/granola', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/granola.ts b/apps/sim/blocks/blocks/granola.ts index bf38da6e49d..65c970eadf8 100644 --- a/apps/sim/blocks/blocks/granola.ts +++ b/apps/sim/blocks/blocks/granola.ts @@ -1,17 +1,9 @@ import { GranolaIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GranolaBlockDisplay } from '@/blocks/blocks/granola.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' export const GranolaBlock: BlockConfig = { - type: 'granola', - name: 'Granola', - description: 'Access meeting notes and transcripts from Granola', - longDescription: - 'Integrate Granola into your workflow to retrieve meeting notes, summaries, attendees, and transcripts.', - docsLink: 'https://docs.sim.ai/integrations/granola', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#B2C147', - icon: GranolaIcon, + ...GranolaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/greenhouse.display.ts b/apps/sim/blocks/blocks/greenhouse.display.ts new file mode 100644 index 00000000000..d0d369d1adf --- /dev/null +++ b/apps/sim/blocks/blocks/greenhouse.display.ts @@ -0,0 +1,17 @@ +import { GreenhouseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GreenhouseBlockDisplay = { + type: 'greenhouse', + name: 'Greenhouse', + description: 'Manage candidates, jobs, and applications in Greenhouse', + category: 'tools', + bgColor: '#469776', + icon: GreenhouseIcon, + iconColor: '#469776', + longDescription: + 'Integrate Greenhouse into the workflow. List and retrieve candidates, jobs, applications, users, departments, offices, and job stages from your Greenhouse ATS account.', + docsLink: 'https://docs.sim.ai/integrations/greenhouse', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/greenhouse.ts b/apps/sim/blocks/blocks/greenhouse.ts index bd5767507db..209a028d7be 100644 --- a/apps/sim/blocks/blocks/greenhouse.ts +++ b/apps/sim/blocks/blocks/greenhouse.ts @@ -1,20 +1,11 @@ import { GreenhouseIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { GreenhouseBlockDisplay } from '@/blocks/blocks/greenhouse.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { GreenhouseResponse } from '@/tools/greenhouse/types' import { getTrigger } from '@/triggers' export const GreenhouseBlock: BlockConfig = { - type: 'greenhouse', - name: 'Greenhouse', - description: 'Manage candidates, jobs, and applications in Greenhouse', - longDescription: - 'Integrate Greenhouse into the workflow. List and retrieve candidates, jobs, applications, users, departments, offices, and job stages from your Greenhouse ATS account.', - docsLink: 'https://docs.sim.ai/integrations/greenhouse', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#469776', - iconColor: '#469776', - icon: GreenhouseIcon, + ...GreenhouseBlockDisplay, authMode: AuthMode.ApiKey, triggers: { diff --git a/apps/sim/blocks/blocks/greptile.display.ts b/apps/sim/blocks/blocks/greptile.display.ts new file mode 100644 index 00000000000..be50795d5bb --- /dev/null +++ b/apps/sim/blocks/blocks/greptile.display.ts @@ -0,0 +1,16 @@ +import { GreptileIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const GreptileBlockDisplay = { + type: 'greptile', + name: 'Greptile', + description: 'AI-powered codebase search and Q&A', + category: 'tools', + bgColor: '#181C1E', + icon: GreptileIcon, + longDescription: + 'Query and search codebases using natural language with Greptile. Get AI-generated answers about your code, find relevant files, and understand complex codebases.', + docsLink: 'https://docs.sim.ai/integrations/greptile', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/greptile.ts b/apps/sim/blocks/blocks/greptile.ts index 9152c09c42e..cf38adcb418 100644 --- a/apps/sim/blocks/blocks/greptile.ts +++ b/apps/sim/blocks/blocks/greptile.ts @@ -1,21 +1,13 @@ import { ClipboardList } from '@/components/emcn/icons' import { GreptileIcon, SlackIcon } from '@/components/icons' +import { GreptileBlockDisplay } from '@/blocks/blocks/greptile.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { GreptileResponse } from '@/tools/greptile/types' export const GreptileBlock: BlockConfig = { - type: 'greptile', - name: 'Greptile', - description: 'AI-powered codebase search and Q&A', + ...GreptileBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Query and search codebases using natural language with Greptile. Get AI-generated answers about your code, find relevant files, and understand complex codebases.', - docsLink: 'https://docs.sim.ai/integrations/greptile', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#181C1E', - icon: GreptileIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/guardrails.display.ts b/apps/sim/blocks/blocks/guardrails.display.ts new file mode 100644 index 00000000000..ae4766012af --- /dev/null +++ b/apps/sim/blocks/blocks/guardrails.display.ts @@ -0,0 +1,14 @@ +import { ShieldCheckIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const GuardrailsBlockDisplay = { + type: 'guardrails', + name: 'Guardrails', + description: 'Validate content with guardrails', + category: 'blocks', + bgColor: '#3D642D', + icon: ShieldCheckIcon, + longDescription: + 'Validate content using guardrails. Check if content is valid JSON, matches a regex pattern, detect hallucinations using RAG + LLM scoring, or detect PII.', + docsLink: 'https://docs.sim.ai/workflows/blocks/guardrails', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/guardrails.ts b/apps/sim/blocks/blocks/guardrails.ts index 7acd5a89013..77e474dce93 100644 --- a/apps/sim/blocks/blocks/guardrails.ts +++ b/apps/sim/blocks/blocks/guardrails.ts @@ -1,5 +1,5 @@ -import { ShieldCheckIcon } from '@/components/icons' import { PII_ENTITY_GROUPS, PII_LANGUAGES } from '@/lib/guardrails/pii-entities' +import { GuardrailsBlockDisplay } from '@/blocks/blocks/guardrails.display' import type { BlockConfig } from '@/blocks/types' import { getModelOptions, @@ -20,11 +20,7 @@ export interface GuardrailsResponse extends ToolResponse { } export const GuardrailsBlock: BlockConfig = { - type: 'guardrails', - name: 'Guardrails', - description: 'Validate content with guardrails', - longDescription: - 'Validate content using guardrails. Check if content is valid JSON, matches a regex pattern, detect hallucinations using RAG + LLM scoring, or detect PII.', + ...GuardrailsBlockDisplay, bestPractices: ` - Reference block outputs using syntax in the Content field - Use JSON validation to ensure structured output from LLMs before parsing @@ -36,10 +32,6 @@ export const GuardrailsBlock: BlockConfig = { - For PII detection, access and - Chain with Condition block to handle validation failures `, - docsLink: 'https://docs.sim.ai/workflows/blocks/guardrails', - category: 'blocks', - bgColor: '#3D642D', - icon: ShieldCheckIcon, subBlocks: [ { id: 'input', diff --git a/apps/sim/blocks/blocks/hex.display.ts b/apps/sim/blocks/blocks/hex.display.ts new file mode 100644 index 00000000000..899b802e6de --- /dev/null +++ b/apps/sim/blocks/blocks/hex.display.ts @@ -0,0 +1,16 @@ +import { HexIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const HexBlockDisplay = { + type: 'hex', + name: 'Hex', + description: 'Run and manage Hex projects', + category: 'tools', + bgColor: '#14151A', + icon: HexIcon, + longDescription: + 'Integrate Hex into your workflow. Run projects, check run status, manage collections and groups, list users, and view data connections. Requires a Hex API token.', + docsLink: 'https://docs.sim.ai/integrations/hex', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/hex.ts b/apps/sim/blocks/blocks/hex.ts index 2bb36f75ef6..ae7ceefa4d7 100644 --- a/apps/sim/blocks/blocks/hex.ts +++ b/apps/sim/blocks/blocks/hex.ts @@ -1,19 +1,11 @@ import { HexIcon } from '@/components/icons' +import { HexBlockDisplay } from '@/blocks/blocks/hex.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { HexResponse } from '@/tools/hex/types' export const HexBlock: BlockConfig = { - type: 'hex', - name: 'Hex', - description: 'Run and manage Hex projects', - longDescription: - 'Integrate Hex into your workflow. Run projects, check run status, manage collections and groups, list users, and view data connections. Requires a Hex API token.', - docsLink: 'https://docs.sim.ai/integrations/hex', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#14151A', - icon: HexIcon, + ...HexBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/hubspot.display.ts b/apps/sim/blocks/blocks/hubspot.display.ts new file mode 100644 index 00000000000..b42e721f26a --- /dev/null +++ b/apps/sim/blocks/blocks/hubspot.display.ts @@ -0,0 +1,18 @@ +import { HubspotIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const HubSpotBlockDisplay = { + type: 'hubspot', + name: 'HubSpot', + description: 'Interact with HubSpot CRM or trigger workflows from HubSpot events', + category: 'tools', + bgColor: '#FF7A59', + icon: HubspotIcon, + iconColor: '#FF7A59', + longDescription: + 'Integrate HubSpot into your workflow. Manage contacts, companies, deals, tickets, and other CRM objects with powerful automation capabilities. Can be used in trigger mode to start workflows when records are created, updated, a specific property changes, or a contact joins a list.', + docsLink: 'https://docs.sim.ai/integrations/hubspot', + integrationType: IntegrationType.Sales, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/hubspot.ts b/apps/sim/blocks/blocks/hubspot.ts index 367ee0a4004..908ffd2440d 100644 --- a/apps/sim/blocks/blocks/hubspot.ts +++ b/apps/sim/blocks/blocks/hubspot.ts @@ -1,23 +1,14 @@ import { HubspotIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { HubSpotBlockDisplay } from '@/blocks/blocks/hubspot.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { HubSpotResponse } from '@/tools/hubspot/types' import { getTrigger } from '@/triggers' export const HubSpotBlock: BlockConfig = { - type: 'hubspot', - name: 'HubSpot', - description: 'Interact with HubSpot CRM or trigger workflows from HubSpot events', + ...HubSpotBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate HubSpot into your workflow. Manage contacts, companies, deals, tickets, and other CRM objects with powerful automation capabilities. Can be used in trigger mode to start workflows when records are created, updated, a specific property changes, or a contact joins a list.', - docsLink: 'https://docs.sim.ai/integrations/hubspot', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FF7A59', - iconColor: '#FF7A59', - icon: HubspotIcon, subBlocks: [ { id: 'operation', @@ -1475,7 +1466,6 @@ Return ONLY the JSON array of property names - no explanations, no markdown, no metadata: { type: 'json', description: 'Operation metadata' }, success: { type: 'boolean', description: 'Operation success status' }, } as any, - triggerAllowed: true, triggers: { enabled: true, available: ['hubspot_poller'], diff --git a/apps/sim/blocks/blocks/huggingface.display.ts b/apps/sim/blocks/blocks/huggingface.display.ts new file mode 100644 index 00000000000..88eebcbc091 --- /dev/null +++ b/apps/sim/blocks/blocks/huggingface.display.ts @@ -0,0 +1,16 @@ +import { HuggingFaceIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const HuggingFaceBlockDisplay = { + type: 'huggingface', + name: 'Hugging Face', + description: 'Use Hugging Face Inference API', + category: 'tools', + bgColor: '#0B0F19', + icon: HuggingFaceIcon, + longDescription: + 'Integrate Hugging Face into the workflow. Can generate completions using the Hugging Face Inference API.', + docsLink: 'https://docs.sim.ai/integrations/huggingface', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/huggingface.ts b/apps/sim/blocks/blocks/huggingface.ts index a30a0fdf854..9a4393eff7c 100644 --- a/apps/sim/blocks/blocks/huggingface.ts +++ b/apps/sim/blocks/blocks/huggingface.ts @@ -1,20 +1,12 @@ import { HuggingFaceIcon } from '@/components/icons' +import { HuggingFaceBlockDisplay } from '@/blocks/blocks/huggingface.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { HuggingFaceChatResponse } from '@/tools/huggingface/types' export const HuggingFaceBlock: BlockConfig = { - type: 'huggingface', - name: 'Hugging Face', - description: 'Use Hugging Face Inference API', + ...HuggingFaceBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Hugging Face into the workflow. Can generate completions using the Hugging Face Inference API.', - docsLink: 'https://docs.sim.ai/integrations/huggingface', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#0B0F19', - icon: HuggingFaceIcon, subBlocks: [ { id: 'systemPrompt', diff --git a/apps/sim/blocks/blocks/human_in_the_loop.display.ts b/apps/sim/blocks/blocks/human_in_the_loop.display.ts new file mode 100644 index 00000000000..5e335eb10de --- /dev/null +++ b/apps/sim/blocks/blocks/human_in_the_loop.display.ts @@ -0,0 +1,14 @@ +import { HumanInTheLoopIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const HumanInTheLoopBlockDisplay = { + type: 'human_in_the_loop', + name: 'Human in the Loop', + description: 'Pause workflow execution and wait for human input', + category: 'blocks', + bgColor: '#10B981', + icon: HumanInTheLoopIcon, + longDescription: + 'Combines response and start functionality. Sends structured responses and allows workflow to resume from this point.', + docsLink: 'https://docs.sim.ai/workflows/blocks/human-in-the-loop', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/human_in_the_loop.ts b/apps/sim/blocks/blocks/human_in_the_loop.ts index 99310a4913f..6b6c02cbe69 100644 --- a/apps/sim/blocks/blocks/human_in_the_loop.ts +++ b/apps/sim/blocks/blocks/human_in_the_loop.ts @@ -1,17 +1,9 @@ -import { HumanInTheLoopIcon } from '@/components/icons' +import { HumanInTheLoopBlockDisplay } from '@/blocks/blocks/human_in_the_loop.display' import type { BlockConfig } from '@/blocks/types' import type { ResponseBlockOutput } from '@/tools/response/types' export const HumanInTheLoopBlock: BlockConfig = { - type: 'human_in_the_loop', - name: 'Human in the Loop', - description: 'Pause workflow execution and wait for human input', - longDescription: - 'Combines response and start functionality. Sends structured responses and allows workflow to resume from this point.', - category: 'blocks', - bgColor: '#10B981', - docsLink: 'https://docs.sim.ai/workflows/blocks/human-in-the-loop', - icon: HumanInTheLoopIcon, + ...HumanInTheLoopBlockDisplay, subBlocks: [ // Operation dropdown hidden - block defaults to human approval mode // { diff --git a/apps/sim/blocks/blocks/hunter.display.ts b/apps/sim/blocks/blocks/hunter.display.ts new file mode 100644 index 00000000000..c517456c829 --- /dev/null +++ b/apps/sim/blocks/blocks/hunter.display.ts @@ -0,0 +1,16 @@ +import { HunterIOIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const HunterBlockDisplay = { + type: 'hunter', + name: 'Hunter.io', + description: 'Find and verify professional email addresses', + category: 'tools', + bgColor: '#FFFFFF', + icon: HunterIOIcon, + longDescription: + 'Integrate Hunter into the workflow. Can search domains, find email addresses, verify email addresses, discover companies, find companies, and count email addresses.', + docsLink: 'https://docs.sim.ai/integrations/hunter', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/hunter.ts b/apps/sim/blocks/blocks/hunter.ts index 32804073a4f..1941ce0dbf8 100644 --- a/apps/sim/blocks/blocks/hunter.ts +++ b/apps/sim/blocks/blocks/hunter.ts @@ -1,19 +1,11 @@ import { HunterIOIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { HunterBlockDisplay } from '@/blocks/blocks/hunter.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { HunterResponse } from '@/tools/hunter/types' export const HunterBlock: BlockConfig = { - type: 'hunter', - name: 'Hunter.io', - description: 'Find and verify professional email addresses', + ...HunterBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Hunter into the workflow. Can search domains, find email addresses, verify email addresses, discover companies, find companies, and count email addresses.', - docsLink: 'https://docs.sim.ai/integrations/hunter', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: HunterIOIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/iam.display.ts b/apps/sim/blocks/blocks/iam.display.ts new file mode 100644 index 00000000000..ca35346ae3c --- /dev/null +++ b/apps/sim/blocks/blocks/iam.display.ts @@ -0,0 +1,16 @@ +import { IAMIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const IAMBlockDisplay = { + type: 'iam', + name: 'AWS IAM', + description: 'Manage AWS IAM users, roles, policies, and groups', + category: 'tools', + bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', + icon: IAMIcon, + longDescription: + 'Integrate AWS Identity and Access Management into your workflow. Create and manage users, roles, policies, groups, and access keys.', + docsLink: 'https://docs.sim.ai/integrations/iam', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/iam.ts b/apps/sim/blocks/blocks/iam.ts index ac61f51f1bd..ef4faf772d8 100644 --- a/apps/sim/blocks/blocks/iam.ts +++ b/apps/sim/blocks/blocks/iam.ts @@ -1,19 +1,11 @@ import { IAMIcon } from '@/components/icons' +import { IAMBlockDisplay } from '@/blocks/blocks/iam.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { IAMBaseResponse } from '@/tools/iam/types' export const IAMBlock: BlockConfig = { - type: 'iam', - name: 'AWS IAM', - description: 'Manage AWS IAM users, roles, policies, and groups', - longDescription: - 'Integrate AWS Identity and Access Management into your workflow. Create and manage users, roles, policies, groups, and access keys.', - docsLink: 'https://docs.sim.ai/integrations/iam', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', - icon: IAMIcon, + ...IAMBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/icypeas.display.ts b/apps/sim/blocks/blocks/icypeas.display.ts new file mode 100644 index 00000000000..8213500d73e --- /dev/null +++ b/apps/sim/blocks/blocks/icypeas.display.ts @@ -0,0 +1,16 @@ +import { IcypeasIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const IcypeasBlockDisplay = { + type: 'icypeas', + name: 'Icypeas', + description: 'Find and verify professional email addresses', + category: 'tools', + bgColor: '#d4d4d4', + icon: IcypeasIcon, + longDescription: + 'Integrate Icypeas to find a professional email address from a name and company domain, or verify whether an existing email is valid and deliverable. Results are returned asynchronously via polling.', + docsLink: 'https://docs.sim.ai/tools/icypeas', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/icypeas.ts b/apps/sim/blocks/blocks/icypeas.ts index 373d0bf5f06..da234f7e032 100644 --- a/apps/sim/blocks/blocks/icypeas.ts +++ b/apps/sim/blocks/blocks/icypeas.ts @@ -1,18 +1,9 @@ -import { IcypeasIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { IcypeasBlockDisplay } from '@/blocks/blocks/icypeas.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { IcypeasResponse } from '@/tools/icypeas/types' export const IcypeasBlock: BlockConfig = { - type: 'icypeas', - name: 'Icypeas', - description: 'Find and verify professional email addresses', - longDescription: - 'Integrate Icypeas to find a professional email address from a name and company domain, or verify whether an existing email is valid and deliverable. Results are returned asynchronously via polling.', - docsLink: 'https://docs.sim.ai/tools/icypeas', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#d4d4d4', - icon: IcypeasIcon, + ...IcypeasBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/identity_center.display.ts b/apps/sim/blocks/blocks/identity_center.display.ts new file mode 100644 index 00000000000..8218ea2711f --- /dev/null +++ b/apps/sim/blocks/blocks/identity_center.display.ts @@ -0,0 +1,16 @@ +import { IdentityCenterIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const IdentityCenterBlockDisplay = { + type: 'identity_center', + name: 'AWS Identity Center', + description: 'Manage temporary elevated access in AWS IAM Identity Center', + category: 'tools', + bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', + icon: IdentityCenterIcon, + longDescription: + 'Provision and revoke temporary access to AWS accounts via IAM Identity Center (SSO). Assign permission sets to users or groups, look up users by email, and list accounts and permission sets for access request workflows.', + docsLink: 'https://docs.sim.ai/integrations/identity_center', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/identity_center.ts b/apps/sim/blocks/blocks/identity_center.ts index 5e4e714d9e8..d7fde95a167 100644 --- a/apps/sim/blocks/blocks/identity_center.ts +++ b/apps/sim/blocks/blocks/identity_center.ts @@ -1,19 +1,11 @@ import { IdentityCenterIcon } from '@/components/icons' +import { IdentityCenterBlockDisplay } from '@/blocks/blocks/identity_center.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { IdentityCenterBaseResponse } from '@/tools/identity_center/types' export const IdentityCenterBlock: BlockConfig = { - type: 'identity_center', - name: 'AWS Identity Center', - description: 'Manage temporary elevated access in AWS IAM Identity Center', - longDescription: - 'Provision and revoke temporary access to AWS accounts via IAM Identity Center (SSO). Assign permission sets to users or groups, look up users by email, and list accounts and permission sets for access request workflows.', - docsLink: 'https://docs.sim.ai/integrations/identity_center', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', - icon: IdentityCenterIcon, + ...IdentityCenterBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/image_generator.display.ts b/apps/sim/blocks/blocks/image_generator.display.ts new file mode 100644 index 00000000000..3633374c678 --- /dev/null +++ b/apps/sim/blocks/blocks/image_generator.display.ts @@ -0,0 +1,30 @@ +import { ImageIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ImageGeneratorBlockDisplay = { + type: 'image_generator', + name: 'Image Generator', + description: 'Generate images', + category: 'blocks', + bgColor: '#4D5FFF', + icon: ImageIcon, + longDescription: + 'Integrate Image Generator into the workflow. Can generate images using DALL-E 3 and GPT Image models.', + docsLink: 'https://docs.sim.ai/integrations/image_generator', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const ImageGeneratorV2BlockDisplay = { + type: 'image_generator_v2', + name: 'Image Generator', + description: 'Generate images', + category: 'blocks', + bgColor: '#4D5FFF', + icon: ImageIcon, + longDescription: + 'Generate images using OpenAI GPT Image, Google Nano Banana, or Fal.ai image models.', + docsLink: 'https://docs.sim.ai/integrations/image_generator', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/image_generator.ts b/apps/sim/blocks/blocks/image_generator.ts index dbeb940d47b..7a7239aa81b 100644 --- a/apps/sim/blocks/blocks/image_generator.ts +++ b/apps/sim/blocks/blocks/image_generator.ts @@ -1,5 +1,8 @@ -import { ImageIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' +import { + ImageGeneratorBlockDisplay, + ImageGeneratorV2BlockDisplay, +} from '@/blocks/blocks/image_generator.display' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { parseOptionalBooleanInput } from '@/blocks/utils' import type { ImageGenerationResponse } from '@/tools/image/types' import type { DalleResponse } from '@/tools/openai/types' @@ -53,18 +56,8 @@ const OUTPUT_FORMAT_OPTIONS = [ ] export const ImageGeneratorBlock: BlockConfig = { - type: 'image_generator', - name: 'Image Generator', - description: 'Generate images', - hideFromToolbar: true, + ...ImageGeneratorBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Image Generator into the workflow. Can generate images using DALL-E 3 and GPT Image models.', - docsLink: 'https://docs.sim.ai/integrations/image_generator', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#4D5FFF', - icon: ImageIcon, subBlocks: [ { id: 'model', @@ -310,17 +303,8 @@ export const ImageGeneratorBlock: BlockConfig = { } export const ImageGeneratorV2Block: BlockConfig = { - type: 'image_generator_v2', - name: 'Image Generator', - description: 'Generate images', + ...ImageGeneratorV2BlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Generate images using OpenAI GPT Image, Google Nano Banana, or Fal.ai image models.', - docsLink: 'https://docs.sim.ai/integrations/image_generator', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#4D5FFF', - icon: ImageIcon, subBlocks: [ { id: 'provider', diff --git a/apps/sim/blocks/blocks/imap.display.ts b/apps/sim/blocks/blocks/imap.display.ts new file mode 100644 index 00000000000..0c42405785b --- /dev/null +++ b/apps/sim/blocks/blocks/imap.display.ts @@ -0,0 +1,18 @@ +import { MailServerIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ImapBlockDisplay = { + type: 'imap', + name: 'IMAP Email', + description: 'Trigger workflows when new emails arrive via IMAP (works with any email provider)', + category: 'triggers', + bgColor: '#6366F1', + icon: MailServerIcon, + longDescription: + 'Connect to any email server via IMAP protocol to trigger workflows when new emails are received. Supports Gmail, Outlook, Yahoo, and any other IMAP-compatible email provider.', + docsLink: 'https://docs.sim.ai/integrations/imap', + integrationType: IntegrationType.Email, + hideFromToolbar: false, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/imap.ts b/apps/sim/blocks/blocks/imap.ts index 80c291ab15b..ac454aabf95 100644 --- a/apps/sim/blocks/blocks/imap.ts +++ b/apps/sim/blocks/blocks/imap.ts @@ -1,22 +1,11 @@ import { ClipboardList, Table } from '@/components/emcn/icons' import { MailServerIcon } from '@/components/icons' +import { ImapBlockDisplay } from '@/blocks/blocks/imap.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { getTrigger } from '@/triggers' export const ImapBlock: BlockConfig = { - type: 'imap', - name: 'IMAP Email', - description: 'Trigger workflows when new emails arrive via IMAP (works with any email provider)', - longDescription: - 'Connect to any email server via IMAP protocol to trigger workflows when new emails are received. Supports Gmail, Outlook, Yahoo, and any other IMAP-compatible email provider.', - category: 'triggers', - integrationType: IntegrationType.Email, - bgColor: '#6366F1', - icon: MailServerIcon, - triggerAllowed: true, - docsLink: 'https://docs.sim.ai/integrations/imap', - hideFromToolbar: false, + ...ImapBlockDisplay, subBlocks: [...getTrigger('imap_poller').subBlocks], tools: { access: [], diff --git a/apps/sim/blocks/blocks/incidentio.display.ts b/apps/sim/blocks/blocks/incidentio.display.ts new file mode 100644 index 00000000000..5868dae3d7e --- /dev/null +++ b/apps/sim/blocks/blocks/incidentio.display.ts @@ -0,0 +1,16 @@ +import { IncidentioIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const IncidentioBlockDisplay = { + type: 'incidentio', + name: 'incident.io', + description: 'Manage incidents with incident.io', + category: 'tools', + bgColor: '#FFFFFF', + icon: IncidentioIcon, + longDescription: + 'Integrate incident.io into the workflow. Manage incidents, actions, follow-ups, workflows, schedules, escalations, custom fields, and more.', + docsLink: 'https://docs.sim.ai/integrations/incidentio', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/incidentio.ts b/apps/sim/blocks/blocks/incidentio.ts index 2de769b8c32..58b8973acad 100644 --- a/apps/sim/blocks/blocks/incidentio.ts +++ b/apps/sim/blocks/blocks/incidentio.ts @@ -1,20 +1,12 @@ import { IncidentioIcon } from '@/components/icons' +import { IncidentioBlockDisplay } from '@/blocks/blocks/incidentio.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { IncidentioResponse } from '@/tools/incidentio/types' export const IncidentioBlock: BlockConfig = { - type: 'incidentio', - name: 'incident.io', - description: 'Manage incidents with incident.io', + ...IncidentioBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate incident.io into the workflow. Manage incidents, actions, follow-ups, workflows, schedules, escalations, custom fields, and more.', - docsLink: 'https://docs.sim.ai/integrations/incidentio', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#FFFFFF', - icon: IncidentioIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/infisical.display.ts b/apps/sim/blocks/blocks/infisical.display.ts new file mode 100644 index 00000000000..af9042d297f --- /dev/null +++ b/apps/sim/blocks/blocks/infisical.display.ts @@ -0,0 +1,16 @@ +import { InfisicalIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const InfisicalBlockDisplay = { + type: 'infisical', + name: 'Infisical', + description: 'Manage secrets with Infisical', + category: 'tools', + bgColor: '#F7FE62', + icon: InfisicalIcon, + longDescription: + 'Integrate Infisical into your workflow. List, get, create, update, and delete secrets across project environments.', + docsLink: 'https://docs.sim.ai/integrations/infisical', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/infisical.ts b/apps/sim/blocks/blocks/infisical.ts index eadcc90ee35..1c5eaf41fc4 100644 --- a/apps/sim/blocks/blocks/infisical.ts +++ b/apps/sim/blocks/blocks/infisical.ts @@ -1,19 +1,11 @@ import { InfisicalIcon } from '@/components/icons' +import { InfisicalBlockDisplay } from '@/blocks/blocks/infisical.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { InfisicalResponse } from '@/tools/infisical/types' export const InfisicalBlock: BlockConfig = { - type: 'infisical', - name: 'Infisical', - description: 'Manage secrets with Infisical', - longDescription: - 'Integrate Infisical into your workflow. List, get, create, update, and delete secrets across project environments.', - docsLink: 'https://docs.sim.ai/integrations/infisical', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#F7FE62', - icon: InfisicalIcon, + ...InfisicalBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/input_trigger.display.ts b/apps/sim/blocks/blocks/input_trigger.display.ts new file mode 100644 index 00000000000..16d44f5b13d --- /dev/null +++ b/apps/sim/blocks/blocks/input_trigger.display.ts @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { FormInput } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const InputTriggerIcon = (props: SVGProps) => createElement(FormInput, props) + +export const InputTriggerBlockDisplay = { + type: 'input_trigger', + name: 'Input Form (Legacy)', + description: 'Legacy manual start block with structured input. Prefer Start block.', + category: 'triggers', + bgColor: '#3B82F6', + icon: InputTriggerIcon, + longDescription: + 'Manually trigger the workflow from the editor with a structured input schema. This enables typed inputs for parent workflows to map into.', + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/input_trigger.ts b/apps/sim/blocks/blocks/input_trigger.ts index 51de24d6e86..5b2ba9aff9b 100644 --- a/apps/sim/blocks/blocks/input_trigger.ts +++ b/apps/sim/blocks/blocks/input_trigger.ts @@ -1,26 +1,18 @@ import type { SVGProps } from 'react' import { createElement } from 'react' import { FormInput } from 'lucide-react' +import { InputTriggerBlockDisplay } from '@/blocks/blocks/input_trigger.display' import type { BlockConfig } from '@/blocks/types' const InputTriggerIcon = (props: SVGProps) => createElement(FormInput, props) export const InputTriggerBlock: BlockConfig = { - type: 'input_trigger', - triggerAllowed: true, - name: 'Input Form (Legacy)', - description: 'Legacy manual start block with structured input. Prefer Start block.', - longDescription: - 'Manually trigger the workflow from the editor with a structured input schema. This enables typed inputs for parent workflows to map into.', + ...InputTriggerBlockDisplay, bestPractices: ` - Can run the workflow manually to test implementation when this is the trigger point. - The input format determines variables accesssible in the following blocks. E.g. . You can set the value in the input format to test the workflow manually. - Also used in child workflows to map variables from the parent workflow. `, - category: 'triggers', - hideFromToolbar: true, - bgColor: '#3B82F6', - icon: InputTriggerIcon, subBlocks: [ { id: 'inputFormat', diff --git a/apps/sim/blocks/blocks/instantly.display.ts b/apps/sim/blocks/blocks/instantly.display.ts new file mode 100644 index 00000000000..5b38148e96f --- /dev/null +++ b/apps/sim/blocks/blocks/instantly.display.ts @@ -0,0 +1,16 @@ +import { InstantlyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const InstantlyBlockDisplay = { + type: 'instantly', + name: 'Instantly', + description: 'Manage Instantly leads, campaigns, emails, and lead lists', + category: 'tools', + bgColor: '#FFFFFF', + icon: InstantlyIcon, + longDescription: + 'Integrate Instantly API V2 into workflows. Create and list leads, manage lead interest status, delete leads in bulk, list and create campaigns, reply to emails, and manage lead lists.', + docsLink: 'https://docs.sim.ai/integrations/instantly', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/instantly.ts b/apps/sim/blocks/blocks/instantly.ts index bdef8922b35..b2d2285607d 100644 --- a/apps/sim/blocks/blocks/instantly.ts +++ b/apps/sim/blocks/blocks/instantly.ts @@ -1,7 +1,8 @@ import { isRecordLike } from '@sim/utils/object' import { InstantlyIcon } from '@/components/icons' +import { InstantlyBlockDisplay } from '@/blocks/blocks/instantly.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { InstantlyResponse } from '@/tools/instantly/types' import { getTrigger } from '@/triggers' @@ -47,16 +48,7 @@ const INSTANTLY_TRIGGER_IDS = [ ] as const export const InstantlyBlock: BlockConfig = { - type: 'instantly', - name: 'Instantly', - description: 'Manage Instantly leads, campaigns, emails, and lead lists', - longDescription: - 'Integrate Instantly API V2 into workflows. Create and list leads, manage lead interest status, delete leads in bulk, list and create campaigns, reply to emails, and manage lead lists.', - docsLink: 'https://docs.sim.ai/integrations/instantly', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#FFFFFF', - icon: InstantlyIcon, + ...InstantlyBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/intercom.display.ts b/apps/sim/blocks/blocks/intercom.display.ts new file mode 100644 index 00000000000..a24e8562c35 --- /dev/null +++ b/apps/sim/blocks/blocks/intercom.display.ts @@ -0,0 +1,25 @@ +import { IntercomIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const IntercomBlockDisplay = { + type: 'intercom', + name: 'Intercom (Legacy)', + description: 'Manage contacts, companies, conversations, tickets, and messages in Intercom', + category: 'tools', + bgColor: '#FFFFFF', + icon: IntercomIcon, + longDescription: + 'Integrate Intercom into the workflow. Can create, get, update, list, search, and delete contacts; create, get, and list companies; get, list, reply, and search conversations; create and get tickets; and create messages.', + docsLink: 'https://docs.sim.ai/integrations/intercom', + integrationType: IntegrationType.Support, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const IntercomV2BlockDisplay = { + ...IntercomBlockDisplay, + type: 'intercom_v2', + name: 'Intercom', + integrationType: IntegrationType.Support, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/intercom.ts b/apps/sim/blocks/blocks/intercom.ts index 56d101484ee..6d5976bf9c0 100644 --- a/apps/sim/blocks/blocks/intercom.ts +++ b/apps/sim/blocks/blocks/intercom.ts @@ -1,22 +1,13 @@ import { IntercomIcon } from '@/components/icons' +import { IntercomBlockDisplay, IntercomV2BlockDisplay } from '@/blocks/blocks/intercom.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import { getTrigger } from '@/triggers' export const IntercomBlock: BlockConfig = { - type: 'intercom', - name: 'Intercom (Legacy)', - hideFromToolbar: true, - description: 'Manage contacts, companies, conversations, tickets, and messages in Intercom', - longDescription: - 'Integrate Intercom into the workflow. Can create, get, update, list, search, and delete contacts; create, get, and list companies; get, list, reply, and search conversations; create and get tickets; and create messages.', - docsLink: 'https://docs.sim.ai/integrations/intercom', + ...IntercomBlockDisplay, authMode: AuthMode.ApiKey, - category: 'tools', - integrationType: IntegrationType.Support, - bgColor: '#FFFFFF', - icon: IntercomIcon, subBlocks: [ { id: 'operation', @@ -1404,10 +1395,7 @@ Return ONLY the numeric timestamp.`, export const IntercomV2Block: BlockConfig = { ...IntercomBlock, - type: 'intercom_v2', - name: 'Intercom', - integrationType: IntegrationType.Support, - hideFromToolbar: false, + ...IntercomV2BlockDisplay, subBlocks: [ ...IntercomBlock.subBlocks, ...getTrigger('intercom_conversation_created').subBlocks, diff --git a/apps/sim/blocks/blocks/jina.display.ts b/apps/sim/blocks/blocks/jina.display.ts new file mode 100644 index 00000000000..51dcfb66310 --- /dev/null +++ b/apps/sim/blocks/blocks/jina.display.ts @@ -0,0 +1,16 @@ +import { JinaAIIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const JinaBlockDisplay = { + type: 'jina', + name: 'Jina', + description: 'Search the web or extract content from URLs', + category: 'tools', + bgColor: '#333333', + icon: JinaAIIcon, + longDescription: + 'Integrate Jina AI into the workflow. Search the web and get LLM-friendly results, or extract clean content from specific URLs with advanced parsing options.', + docsLink: 'https://docs.sim.ai/integrations/jina', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/jina.ts b/apps/sim/blocks/blocks/jina.ts index d7a3f9d306d..e009b3fc816 100644 --- a/apps/sim/blocks/blocks/jina.ts +++ b/apps/sim/blocks/blocks/jina.ts @@ -1,19 +1,11 @@ import { JinaAIIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { JinaBlockDisplay } from '@/blocks/blocks/jina.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ReadUrlResponse, SearchResponse } from '@/tools/jina/types' export const JinaBlock: BlockConfig = { - type: 'jina', - name: 'Jina', - description: 'Search the web or extract content from URLs', + ...JinaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Jina AI into the workflow. Search the web and get LLM-friendly results, or extract clean content from specific URLs with advanced parsing options.', - docsLink: 'https://docs.sim.ai/integrations/jina', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#333333', - icon: JinaAIIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/jira.display.ts b/apps/sim/blocks/blocks/jira.display.ts new file mode 100644 index 00000000000..35c34f7621d --- /dev/null +++ b/apps/sim/blocks/blocks/jira.display.ts @@ -0,0 +1,17 @@ +import { JiraIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const JiraBlockDisplay = { + type: 'jira', + name: 'Jira', + description: 'Interact with Jira', + category: 'tools', + bgColor: '#FFFFFF', + icon: JiraIcon, + longDescription: + 'Integrate Jira into the workflow. Can read, write, and update issues. Can also trigger workflows based on Jira webhook events.', + docsLink: 'https://docs.sim.ai/integrations/jira', + integrationType: IntegrationType.Productivity, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/jira.ts b/apps/sim/blocks/blocks/jira.ts index b9c61b3cd3d..25a862e52a0 100644 --- a/apps/sim/blocks/blocks/jira.ts +++ b/apps/sim/blocks/blocks/jira.ts @@ -1,24 +1,15 @@ import { JiraIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { JiraBlockDisplay } from '@/blocks/blocks/jira.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { JiraResponse } from '@/tools/jira/types' import { getTrigger } from '@/triggers' export const JiraBlock: BlockConfig = { - type: 'jira', - name: 'Jira', - description: 'Interact with Jira', + ...JiraBlockDisplay, authMode: AuthMode.OAuth, - triggerAllowed: true, - longDescription: - 'Integrate Jira into the workflow. Can read, write, and update issues. Can also trigger workflows based on Jira webhook events.', - docsLink: 'https://docs.sim.ai/integrations/jira', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: JiraIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/jira_service_management.display.ts b/apps/sim/blocks/blocks/jira_service_management.display.ts new file mode 100644 index 00000000000..a61e4630324 --- /dev/null +++ b/apps/sim/blocks/blocks/jira_service_management.display.ts @@ -0,0 +1,16 @@ +import { JiraServiceManagementIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const JiraServiceManagementBlockDisplay = { + type: 'jira_service_management', + name: 'Jira Service Management', + description: 'Interact with Jira Service Management', + category: 'tools', + bgColor: '#FFFFFF', + icon: JiraServiceManagementIcon, + longDescription: + 'Integrate with Jira Service Management for IT service management. Create and manage service requests, handle customers and organizations, track SLAs, and manage queues.', + docsLink: 'https://docs.sim.ai/integrations/jira_service_management', + integrationType: IntegrationType.Support, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/jira_service_management.ts b/apps/sim/blocks/blocks/jira_service_management.ts index a32841ec48c..a9585d56e81 100644 --- a/apps/sim/blocks/blocks/jira_service_management.ts +++ b/apps/sim/blocks/blocks/jira_service_management.ts @@ -1,7 +1,8 @@ import { JiraServiceManagementIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { JiraServiceManagementBlockDisplay } from '@/blocks/blocks/jira_service_management.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { JsmResponse } from '@/tools/jsm/types' import { getTrigger } from '@/triggers' @@ -38,17 +39,8 @@ function parseAssetAttributes(value: unknown): unknown[] { } export const JiraServiceManagementBlock: BlockConfig = { - type: 'jira_service_management', - name: 'Jira Service Management', - description: 'Interact with Jira Service Management', + ...JiraServiceManagementBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with Jira Service Management for IT service management. Create and manage service requests, handle customers and organizations, track SLAs, and manage queues.', - docsLink: 'https://docs.sim.ai/integrations/jira_service_management', - category: 'tools', - integrationType: IntegrationType.Support, - bgColor: '#FFFFFF', - icon: JiraServiceManagementIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/kalshi.display.ts b/apps/sim/blocks/blocks/kalshi.display.ts new file mode 100644 index 00000000000..0d716781e55 --- /dev/null +++ b/apps/sim/blocks/blocks/kalshi.display.ts @@ -0,0 +1,29 @@ +import { KalshiIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const KalshiBlockDisplay = { + type: 'kalshi', + name: 'Kalshi (Legacy)', + description: 'Access prediction markets and trade on Kalshi', + category: 'tools', + bgColor: '#09C285', + icon: KalshiIcon, + iconColor: '#09C285', + longDescription: + 'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.', + docsLink: 'https://docs.sim.ai/integrations/kalshi', + integrationType: IntegrationType.Analytics, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const KalshiV2BlockDisplay = { + ...KalshiBlockDisplay, + type: 'kalshi_v2', + name: 'Kalshi', + description: 'Access prediction markets and trade on Kalshi', + longDescription: + 'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.', + integrationType: IntegrationType.Analytics, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/kalshi.ts b/apps/sim/blocks/blocks/kalshi.ts index 527bd35941e..cabe4b270fd 100644 --- a/apps/sim/blocks/blocks/kalshi.ts +++ b/apps/sim/blocks/blocks/kalshi.ts @@ -1,22 +1,12 @@ import { KalshiIcon } from '@/components/icons' +import { KalshiBlockDisplay, KalshiV2BlockDisplay } from '@/blocks/blocks/kalshi.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' export const KalshiBlock: BlockConfig = { - type: 'kalshi', - name: 'Kalshi (Legacy)', - description: 'Access prediction markets and trade on Kalshi', - longDescription: - 'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.', - docsLink: 'https://docs.sim.ai/integrations/kalshi', + ...KalshiBlockDisplay, authMode: AuthMode.ApiKey, - category: 'tools', - integrationType: IntegrationType.Analytics, - hideFromToolbar: true, - bgColor: '#09C285', - iconColor: '#09C285', - icon: KalshiIcon, subBlocks: [ { id: 'operation', @@ -762,13 +752,7 @@ Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations, export const KalshiV2Block: BlockConfig = { ...KalshiBlock, - type: 'kalshi_v2', - name: 'Kalshi', - description: 'Access prediction markets and trade on Kalshi', - longDescription: - 'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.', - integrationType: IntegrationType.Analytics, - hideFromToolbar: false, + ...KalshiV2BlockDisplay, tools: { ...KalshiBlock.tools, access: [ diff --git a/apps/sim/blocks/blocks/ketch.display.ts b/apps/sim/blocks/blocks/ketch.display.ts new file mode 100644 index 00000000000..8456460cf70 --- /dev/null +++ b/apps/sim/blocks/blocks/ketch.display.ts @@ -0,0 +1,16 @@ +import { KetchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const KetchBlockDisplay = { + type: 'ketch', + name: 'Ketch', + description: 'Manage privacy consent, subscriptions, and data subject rights', + category: 'tools', + bgColor: '#9B5CFF', + icon: KetchIcon, + longDescription: + 'Integrate Ketch into the workflow. Retrieve and update consent preferences, manage subscription topics and controls, and submit data subject rights requests for access, deletion, correction, or processing restriction.', + docsLink: 'https://docs.sim.ai/integrations/ketch', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/ketch.ts b/apps/sim/blocks/blocks/ketch.ts index f07fccdfbfb..a34f4adea36 100644 --- a/apps/sim/blocks/blocks/ketch.ts +++ b/apps/sim/blocks/blocks/ketch.ts @@ -1,19 +1,10 @@ import { KetchIcon } from '@/components/icons' +import { KetchBlockDisplay } from '@/blocks/blocks/ketch.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { KetchResponse } from '@/tools/ketch/types' export const KetchBlock: BlockConfig = { - type: 'ketch', - name: 'Ketch', - description: 'Manage privacy consent, subscriptions, and data subject rights', - longDescription: - 'Integrate Ketch into the workflow. Retrieve and update consent preferences, manage subscription topics and controls, and submit data subject rights requests for access, deletion, correction, or processing restriction.', - docsLink: 'https://docs.sim.ai/integrations/ketch', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#9B5CFF', - icon: KetchIcon, + ...KetchBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/knowledge.display.ts b/apps/sim/blocks/blocks/knowledge.display.ts new file mode 100644 index 00000000000..e285b33e5ed --- /dev/null +++ b/apps/sim/blocks/blocks/knowledge.display.ts @@ -0,0 +1,14 @@ +import { PackageSearchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const KnowledgeBlockDisplay = { + type: 'knowledge', + name: 'Knowledge', + description: 'Use vector search', + category: 'blocks', + bgColor: '#00B0B0', + icon: PackageSearchIcon, + longDescription: + 'Integrate Knowledge into the workflow. Perform full CRUD operations on documents, chunks, and tags.', + docsLink: 'https://docs.sim.ai/integrations/knowledge', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/knowledge.ts b/apps/sim/blocks/blocks/knowledge.ts index 659f479dc0d..938697c9328 100644 --- a/apps/sim/blocks/blocks/knowledge.ts +++ b/apps/sim/blocks/blocks/knowledge.ts @@ -1,14 +1,10 @@ -import { PackageSearchIcon } from '@/components/icons' import { DEFAULT_RERANKER_MODEL, SUPPORTED_RERANKER_MODELS } from '@/lib/knowledge/reranker-models' +import { KnowledgeBlockDisplay } from '@/blocks/blocks/knowledge.display' import type { BlockConfig } from '@/blocks/types' import { getCohereRerankerApiKeyCondition } from '@/blocks/utils' export const KnowledgeBlock: BlockConfig = { - type: 'knowledge', - name: 'Knowledge', - description: 'Use vector search', - longDescription: - 'Integrate Knowledge into the workflow. Perform full CRUD operations on documents, chunks, and tags.', + ...KnowledgeBlockDisplay, bestPractices: ` - Clarify which tags are available for the knowledge base to understand whether to use tag filters on a search. - Use List Documents to enumerate documents before operating on them. @@ -17,10 +13,6 @@ export const KnowledgeBlock: BlockConfig = { - Use List Connectors to see which external sources are syncing documents into the knowledge base. - Use Get Connector to check sync health and review recent sync logs. `, - bgColor: '#00B0B0', - icon: PackageSearchIcon, - category: 'blocks', - docsLink: 'https://docs.sim.ai/integrations/knowledge', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/langsmith.display.ts b/apps/sim/blocks/blocks/langsmith.display.ts new file mode 100644 index 00000000000..eb650b515c6 --- /dev/null +++ b/apps/sim/blocks/blocks/langsmith.display.ts @@ -0,0 +1,16 @@ +import { LangsmithIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LangsmithBlockDisplay = { + type: 'langsmith', + name: 'LangSmith', + description: 'Forward workflow runs to LangSmith for observability', + category: 'tools', + bgColor: '#181C1E', + icon: LangsmithIcon, + longDescription: + 'Send run data to LangSmith to trace executions, attach metadata, and monitor workflow performance.', + docsLink: 'https://docs.sim.ai/integrations/langsmith', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/langsmith.ts b/apps/sim/blocks/blocks/langsmith.ts index cb8d20dff6b..83426d84ecf 100644 --- a/apps/sim/blocks/blocks/langsmith.ts +++ b/apps/sim/blocks/blocks/langsmith.ts @@ -1,19 +1,11 @@ import { toError } from '@sim/utils/errors' import { LangsmithIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { LangsmithBlockDisplay } from '@/blocks/blocks/langsmith.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { LangsmithResponse } from '@/tools/langsmith/types' export const LangsmithBlock: BlockConfig = { - type: 'langsmith', - name: 'LangSmith', - description: 'Forward workflow runs to LangSmith for observability', - longDescription: - 'Send run data to LangSmith to trace executions, attach metadata, and monitor workflow performance.', - docsLink: 'https://docs.sim.ai/integrations/langsmith', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#181C1E', - icon: LangsmithIcon, + ...LangsmithBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/latex.display.ts b/apps/sim/blocks/blocks/latex.display.ts new file mode 100644 index 00000000000..9396e3cd6ec --- /dev/null +++ b/apps/sim/blocks/blocks/latex.display.ts @@ -0,0 +1,16 @@ +import { LatexIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LatexBlockDisplay = { + type: 'latex', + name: 'LaTeX', + description: 'Compile LaTeX documents into PDFs', + category: 'tools', + bgColor: '#FFFFFF', + icon: LatexIcon, + longDescription: + 'Integrates LaTeX into the workflow. Compiles LaTeX source into a PDF file with pdflatex, xelatex, lualatex, platex, uplatex, or context, and supports additional resources such as images, included .tex files, and bibliographies. Can also look up the TeX Live packages and system fonts available to the compiler. Does not require OAuth or an API key. Compilation runs on the public LaTeX-on-HTTP service (latex.ytotech.com), so document source and resources are sent to that third-party service.', + docsLink: 'https://docs.sim.ai/integrations/latex', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/latex.ts b/apps/sim/blocks/blocks/latex.ts index cb077d881f3..33a7454b6f7 100644 --- a/apps/sim/blocks/blocks/latex.ts +++ b/apps/sim/blocks/blocks/latex.ts @@ -1,19 +1,10 @@ import { LatexIcon } from '@/components/icons' +import { LatexBlockDisplay } from '@/blocks/blocks/latex.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { LatexResponse } from '@/tools/latex/types' export const LatexBlock: BlockConfig = { - type: 'latex', - name: 'LaTeX', - description: 'Compile LaTeX documents into PDFs', - longDescription: - 'Integrates LaTeX into the workflow. Compiles LaTeX source into a PDF file with pdflatex, xelatex, lualatex, platex, uplatex, or context, and supports additional resources such as images, included .tex files, and bibliographies. Can also look up the TeX Live packages and system fonts available to the compiler. Does not require OAuth or an API key. Compilation runs on the public LaTeX-on-HTTP service (latex.ytotech.com), so document source and resources are sent to that third-party service.', - docsLink: 'https://docs.sim.ai/integrations/latex', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: LatexIcon, + ...LatexBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/launchdarkly.display.ts b/apps/sim/blocks/blocks/launchdarkly.display.ts new file mode 100644 index 00000000000..f47bc3e63c6 --- /dev/null +++ b/apps/sim/blocks/blocks/launchdarkly.display.ts @@ -0,0 +1,17 @@ +import { LaunchDarklyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LaunchDarklyBlockDisplay = { + type: 'launchdarkly', + name: 'LaunchDarkly', + description: 'Manage feature flags with LaunchDarkly.', + category: 'tools', + bgColor: '#191919', + icon: LaunchDarklyIcon, + iconColor: '#405BFF', + longDescription: + 'Integrate LaunchDarkly into your workflow. List, create, update, toggle, and delete feature flags. Manage projects, environments, segments, members, and audit logs. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/launchdarkly', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/launchdarkly.ts b/apps/sim/blocks/blocks/launchdarkly.ts index 9911eeb07ea..bd1dfb1ab77 100644 --- a/apps/sim/blocks/blocks/launchdarkly.ts +++ b/apps/sim/blocks/blocks/launchdarkly.ts @@ -1,19 +1,10 @@ import { LaunchDarklyIcon } from '@/components/icons' +import { LaunchDarklyBlockDisplay } from '@/blocks/blocks/launchdarkly.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const LaunchDarklyBlock: BlockConfig = { - type: 'launchdarkly', - name: 'LaunchDarkly', - description: 'Manage feature flags with LaunchDarkly.', - longDescription: - 'Integrate LaunchDarkly into your workflow. List, create, update, toggle, and delete feature flags. Manage projects, environments, segments, members, and audit logs. Requires API Key.', - docsLink: 'https://docs.sim.ai/integrations/launchdarkly', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#191919', - iconColor: '#405BFF', - icon: LaunchDarklyIcon, + ...LaunchDarklyBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/leadmagic.display.ts b/apps/sim/blocks/blocks/leadmagic.display.ts new file mode 100644 index 00000000000..9c1b2dcfcbc --- /dev/null +++ b/apps/sim/blocks/blocks/leadmagic.display.ts @@ -0,0 +1,16 @@ +import { LeadMagicIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LeadMagicBlockDisplay = { + type: 'leadmagic', + name: 'LeadMagic', + description: 'Find and enrich B2B contacts, emails, mobile numbers, and company data', + category: 'tools', + bgColor: '#FFFFFF', + icon: LeadMagicIcon, + longDescription: + 'Integrate LeadMagic to find verified work emails by name or company, validate email deliverability, find direct mobile numbers, enrich LinkedIn profiles, reverse-lookup profiles from emails, search companies by domain, identify role holders at accounts, and check account credit balance.', + docsLink: 'https://docs.sim.ai/tools/leadmagic', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/leadmagic.ts b/apps/sim/blocks/blocks/leadmagic.ts index eaac36043d7..13978ab653d 100644 --- a/apps/sim/blocks/blocks/leadmagic.ts +++ b/apps/sim/blocks/blocks/leadmagic.ts @@ -1,19 +1,10 @@ -import { LeadMagicIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { LeadMagicBlockDisplay } from '@/blocks/blocks/leadmagic.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { LeadMagicResponse } from '@/tools/leadmagic/types' export const LeadMagicBlock: BlockConfig = { - type: 'leadmagic', - name: 'LeadMagic', - description: 'Find and enrich B2B contacts, emails, mobile numbers, and company data', + ...LeadMagicBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate LeadMagic to find verified work emails by name or company, validate email deliverability, find direct mobile numbers, enrich LinkedIn profiles, reverse-lookup profiles from emails, search companies by domain, identify role holders at accounts, and check account credit balance.', - docsLink: 'https://docs.sim.ai/tools/leadmagic', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: LeadMagicIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/lemlist.display.ts b/apps/sim/blocks/blocks/lemlist.display.ts new file mode 100644 index 00000000000..ea150ff2363 --- /dev/null +++ b/apps/sim/blocks/blocks/lemlist.display.ts @@ -0,0 +1,16 @@ +import { LemlistIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LemlistBlockDisplay = { + type: 'lemlist', + name: 'Lemlist', + description: 'Manage outreach activities, leads, and send emails via Lemlist', + category: 'tools', + bgColor: '#316BFF', + icon: LemlistIcon, + longDescription: + 'Integrate Lemlist into your workflow. Retrieve campaign activities and replies, get lead information, and send emails through the Lemlist inbox.', + docsLink: 'https://docs.sim.ai/integrations/lemlist', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/lemlist.ts b/apps/sim/blocks/blocks/lemlist.ts index 6bbe0956326..61f47deb5b0 100644 --- a/apps/sim/blocks/blocks/lemlist.ts +++ b/apps/sim/blocks/blocks/lemlist.ts @@ -1,20 +1,12 @@ import { LemlistIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { LemlistBlockDisplay } from '@/blocks/blocks/lemlist.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { LemlistResponse } from '@/tools/lemlist/types' import { getTrigger } from '@/triggers' export const LemlistBlock: BlockConfig = { - type: 'lemlist', - name: 'Lemlist', - description: 'Manage outreach activities, leads, and send emails via Lemlist', + ...LemlistBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Lemlist into your workflow. Retrieve campaign activities and replies, get lead information, and send emails through the Lemlist inbox.', - docsLink: 'https://docs.sim.ai/integrations/lemlist', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#316BFF', - icon: LemlistIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/linear.display.ts b/apps/sim/blocks/blocks/linear.display.ts new file mode 100644 index 00000000000..940313d264e --- /dev/null +++ b/apps/sim/blocks/blocks/linear.display.ts @@ -0,0 +1,25 @@ +import { LinearIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LinearBlockDisplay = { + type: 'linear', + name: 'Linear (Legacy)', + description: 'Interact with Linear issues, projects, and more', + category: 'tools', + bgColor: '#5E6AD2', + icon: LinearIcon, + longDescription: + 'Integrate Linear into the workflow. Can manage issues, comments, projects, labels, workflow states, cycles, attachments, and more. Can also trigger workflows based on Linear webhook events.', + docsLink: 'https://docs.sim.ai/integrations/linear', + integrationType: IntegrationType.Productivity, + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay + +export const LinearV2BlockDisplay = { + ...LinearBlockDisplay, + type: 'linear_v2', + name: 'Linear', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/linear.ts b/apps/sim/blocks/blocks/linear.ts index 809dadc786d..007a8805ba0 100644 --- a/apps/sim/blocks/blocks/linear.ts +++ b/apps/sim/blocks/blocks/linear.ts @@ -1,25 +1,15 @@ import { DevinIcon, LinearIcon, SlackIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { LinearBlockDisplay, LinearV2BlockDisplay } from '@/blocks/blocks/linear.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { LinearResponse } from '@/tools/linear/types' import { getTrigger } from '@/triggers' export const LinearBlock: BlockConfig = { - type: 'linear', - name: 'Linear (Legacy)', - description: 'Interact with Linear issues, projects, and more', - hideFromToolbar: true, + ...LinearBlockDisplay, authMode: AuthMode.OAuth, - triggerAllowed: true, - longDescription: - 'Integrate Linear into the workflow. Can manage issues, comments, projects, labels, workflow states, cycles, attachments, and more. Can also trigger workflows based on Linear webhook events.', - docsLink: 'https://docs.sim.ai/integrations/linear', - category: 'tools', - integrationType: IntegrationType.Productivity, - icon: LinearIcon, - bgColor: '#5E6AD2', subBlocks: [ { id: 'operation', @@ -2561,9 +2551,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n */ export const LinearV2Block: BlockConfig = { ...LinearBlock, - type: 'linear_v2', - name: 'Linear', - hideFromToolbar: false, + ...LinearV2BlockDisplay, subBlocks: [ ...LinearBlock.subBlocks.filter( (sb) => diff --git a/apps/sim/blocks/blocks/linkedin.display.ts b/apps/sim/blocks/blocks/linkedin.display.ts new file mode 100644 index 00000000000..d82d534f4f9 --- /dev/null +++ b/apps/sim/blocks/blocks/linkedin.display.ts @@ -0,0 +1,17 @@ +import { LinkedInIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LinkedInBlockDisplay = { + type: 'linkedin', + name: 'LinkedIn', + description: 'Share posts and manage your LinkedIn presence', + category: 'tools', + bgColor: '#0072B1', + icon: LinkedInIcon, + iconColor: '#0072B1', + longDescription: + 'Integrate LinkedIn into workflows. Share posts to your personal feed and access your LinkedIn profile information.', + docsLink: 'https://docs.sim.ai/integrations/linkedin', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/linkedin.ts b/apps/sim/blocks/blocks/linkedin.ts index 79195726432..eb9b6e87211 100644 --- a/apps/sim/blocks/blocks/linkedin.ts +++ b/apps/sim/blocks/blocks/linkedin.ts @@ -1,22 +1,13 @@ import { LinkedInIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { LinkedInBlockDisplay } from '@/blocks/blocks/linkedin.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { LinkedInResponse } from '@/tools/linkedin/types' export const LinkedInBlock: BlockConfig = { - type: 'linkedin', - name: 'LinkedIn', - description: 'Share posts and manage your LinkedIn presence', + ...LinkedInBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate LinkedIn into workflows. Share posts to your personal feed and access your LinkedIn profile information.', - docsLink: 'https://docs.sim.ai/integrations/linkedin', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#0072B1', - iconColor: '#0072B1', - icon: LinkedInIcon, subBlocks: [ // Operation selection { diff --git a/apps/sim/blocks/blocks/linkup.display.ts b/apps/sim/blocks/blocks/linkup.display.ts new file mode 100644 index 00000000000..41f0454db85 --- /dev/null +++ b/apps/sim/blocks/blocks/linkup.display.ts @@ -0,0 +1,15 @@ +import { LinkupIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LinkupBlockDisplay = { + type: 'linkup', + name: 'Linkup', + description: 'Search the web with Linkup', + category: 'tools', + bgColor: '#D6D3C7', + icon: LinkupIcon, + longDescription: 'Integrate Linkup into the workflow. Can search the web.', + docsLink: 'https://docs.sim.ai/integrations/linkup', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/linkup.ts b/apps/sim/blocks/blocks/linkup.ts index d05f5712567..3c85133b02e 100644 --- a/apps/sim/blocks/blocks/linkup.ts +++ b/apps/sim/blocks/blocks/linkup.ts @@ -1,18 +1,11 @@ import { LinkupIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { LinkupBlockDisplay } from '@/blocks/blocks/linkup.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { LinkupSearchToolResponse } from '@/tools/linkup/types' export const LinkupBlock: BlockConfig = { - type: 'linkup', - name: 'Linkup', - description: 'Search the web with Linkup', + ...LinkupBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Linkup into the workflow. Can search the web.', - docsLink: 'https://docs.sim.ai/integrations/linkup', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#D6D3C7', - icon: LinkupIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/linq.display.ts b/apps/sim/blocks/blocks/linq.display.ts new file mode 100644 index 00000000000..1e2a31aa03a --- /dev/null +++ b/apps/sim/blocks/blocks/linq.display.ts @@ -0,0 +1,16 @@ +import { LinqIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LinqBlockDisplay = { + type: 'linq', + name: 'Linq', + description: 'Send iMessage, SMS, and RCS messages and manage conversations with Linq', + category: 'tools', + bgColor: '#000000', + icon: LinqIcon, + longDescription: + 'Reach people on iMessage, SMS, and RCS through Linq. Start chats, send messages with media, links, effects, and replies, send voice memos, react with tapbacks, manage group participants, check iMessage/RCS capability, configure contact cards, and subscribe to webhook events — all through a single Linq API key.', + docsLink: 'https://docs.sim.ai/integrations/linq', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/linq.ts b/apps/sim/blocks/blocks/linq.ts index 01dddba3942..1e64b55d8e6 100644 --- a/apps/sim/blocks/blocks/linq.ts +++ b/apps/sim/blocks/blocks/linq.ts @@ -1,6 +1,7 @@ import { LinqIcon } from '@/components/icons' +import { LinqBlockDisplay } from '@/blocks/blocks/linq.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' const CHAT_ID_OPS = [ @@ -55,16 +56,7 @@ const splitHandles = (value: unknown): string[] => .filter(Boolean) export const LinqBlock: BlockConfig = { - type: 'linq', - name: 'Linq', - description: 'Send iMessage, SMS, and RCS messages and manage conversations with Linq', - longDescription: - 'Reach people on iMessage, SMS, and RCS through Linq. Start chats, send messages with media, links, effects, and replies, send voice memos, react with tapbacks, manage group participants, check iMessage/RCS capability, configure contact cards, and subscribe to webhook events — all through a single Linq API key.', - docsLink: 'https://docs.sim.ai/integrations/linq', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#000000', - icon: LinqIcon, + ...LinqBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/logs.display.ts b/apps/sim/blocks/blocks/logs.display.ts new file mode 100644 index 00000000000..1929f636d65 --- /dev/null +++ b/apps/sim/blocks/blocks/logs.display.ts @@ -0,0 +1,27 @@ +import { Library } from '@/components/emcn/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const LogsBlockDisplay = { + type: 'logs', + name: 'Logs', + description: 'Query workflow execution logs', + category: 'blocks', + bgColor: '#EAB308', + icon: Library, + longDescription: + 'Search workflow execution logs in the current workspace, fetch a single log by id, or load full execution details with the per-block state snapshot.', + docsLink: 'https://docs.sim.ai/api-reference/logs/getExecutionDetails', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const LogsV2BlockDisplay = { + type: 'logs_v2', + name: 'Logs', + description: 'Query workflow runs and fetch run details', + category: 'blocks', + bgColor: '#EAB308', + icon: Library, + longDescription: + 'Query workflow run logs in the current workspace with the same filters as the Logs page, returning matching run IDs. Fetch full details for a single run, including its trace spans.', + docsLink: 'https://docs.sim.ai/integrations/logs', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/logs.ts b/apps/sim/blocks/blocks/logs.ts index 2c41251e2ec..afa23280744 100644 --- a/apps/sim/blocks/blocks/logs.ts +++ b/apps/sim/blocks/blocks/logs.ts @@ -1,24 +1,15 @@ -import { Library } from '@/components/emcn/icons' import { fetchWorkspaceWorkflowOptions } from '@/lib/workflows/subblocks/options' +import { LogsBlockDisplay, LogsV2BlockDisplay } from '@/blocks/blocks/logs.display' import type { BlockConfig } from '@/blocks/types' export const LogsBlock: BlockConfig = { - type: 'logs', - name: 'Logs', - hideFromToolbar: true, - description: 'Query workflow execution logs', - longDescription: - 'Search workflow execution logs in the current workspace, fetch a single log by id, or load full execution details with the per-block state snapshot.', - bgColor: '#EAB308', + ...LogsBlockDisplay, bestPractices: ` - The block always operates on the current workspace; you cannot query other workspaces. - 'Query Logs' returns summary rows. To get a full log entry (executionData, files), use 'Get Log by ID' on a row's id. - Use 'Get Execution Details' (with an executionId) to inspect per-block state for a single run. - Pagination is cursor-based: pass the previous response's nextCursor as Cursor to fetch the next page. `, - icon: Library, - category: 'blocks', - docsLink: 'https://docs.sim.ai/api-reference/logs/getExecutionDetails', subBlocks: [ { id: 'operation', @@ -287,21 +278,13 @@ function joinIds(value: unknown): string | undefined { } export const LogsV2Block: BlockConfig = { - type: 'logs_v2', - name: 'Logs', - description: 'Query workflow runs and fetch run details', - longDescription: - 'Query workflow run logs in the current workspace with the same filters as the Logs page, returning matching run IDs. Fetch full details for a single run, including its trace spans.', - bgColor: '#EAB308', + ...LogsV2BlockDisplay, bestPractices: ` - The block always operates on the current workspace; you cannot query other workspaces. - 'Query Logs' returns only run IDs, ordered by the sort settings (newest first by default). Feed an ID into 'Get Run Details' for the full picture. - 'Get Run Details' returns the run summary plus the full trace spans (per-block inputs, outputs, and timings). - Cost filters and outputs are denominated in credits. `, - icon: Library, - category: 'blocks', - docsLink: 'https://docs.sim.ai/integrations/logs', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/loops.display.ts b/apps/sim/blocks/blocks/loops.display.ts new file mode 100644 index 00000000000..db93be14d45 --- /dev/null +++ b/apps/sim/blocks/blocks/loops.display.ts @@ -0,0 +1,16 @@ +import { LoopsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LoopsBlockDisplay = { + type: 'loops', + name: 'Loops', + description: 'Manage contacts and send emails with Loops', + category: 'tools', + bgColor: '#FAFAF9', + icon: LoopsIcon, + longDescription: + 'Integrate Loops into the workflow. Create and manage contacts, send transactional emails, and trigger event-based automations.', + docsLink: 'https://docs.sim.ai/integrations/loops', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/loops.ts b/apps/sim/blocks/blocks/loops.ts index a71760f2bd9..0657f0f7f3b 100644 --- a/apps/sim/blocks/blocks/loops.ts +++ b/apps/sim/blocks/blocks/loops.ts @@ -1,20 +1,12 @@ import { LoopsIcon } from '@/components/icons' +import { LoopsBlockDisplay } from '@/blocks/blocks/loops.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { LoopsResponse } from '@/tools/loops/types' export const LoopsBlock: BlockConfig = { - type: 'loops', - name: 'Loops', - description: 'Manage contacts and send emails with Loops', + ...LoopsBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Loops into the workflow. Create and manage contacts, send transactional emails, and trigger event-based automations.', - docsLink: 'https://docs.sim.ai/integrations/loops', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#FAFAF9', - icon: LoopsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/luma.display.ts b/apps/sim/blocks/blocks/luma.display.ts new file mode 100644 index 00000000000..6809101f94f --- /dev/null +++ b/apps/sim/blocks/blocks/luma.display.ts @@ -0,0 +1,16 @@ +import { LumaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const LumaBlockDisplay = { + type: 'luma', + name: 'Luma', + description: 'Manage events and guests on Luma', + category: 'tools', + bgColor: '#000000', + icon: LumaIcon, + longDescription: + 'Integrate Luma into the workflow. Can create, update, look up, and cancel events, list calendar events, manage guest lists (get one or many, add guests, send invites, and update approval status).', + docsLink: 'https://docs.sim.ai/integrations/luma', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/luma.ts b/apps/sim/blocks/blocks/luma.ts index 4cc0dc8578b..d76f5b0b3d6 100644 --- a/apps/sim/blocks/blocks/luma.ts +++ b/apps/sim/blocks/blocks/luma.ts @@ -1,17 +1,9 @@ import { LumaIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { LumaBlockDisplay } from '@/blocks/blocks/luma.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' export const LumaBlock: BlockConfig = { - type: 'luma', - name: 'Luma', - description: 'Manage events and guests on Luma', - longDescription: - 'Integrate Luma into the workflow. Can create, update, look up, and cancel events, list calendar events, manage guest lists (get one or many, add guests, send invites, and update approval status).', - docsLink: 'https://docs.sim.ai/integrations/luma', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#000000', - icon: LumaIcon, + ...LumaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/mailchimp.display.ts b/apps/sim/blocks/blocks/mailchimp.display.ts new file mode 100644 index 00000000000..595b24daddd --- /dev/null +++ b/apps/sim/blocks/blocks/mailchimp.display.ts @@ -0,0 +1,16 @@ +import { MailchimpIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MailchimpBlockDisplay = { + type: 'mailchimp', + name: 'Mailchimp', + description: 'Manage audiences, campaigns, and marketing automation in Mailchimp', + category: 'tools', + bgColor: '#FFE01B', + icon: MailchimpIcon, + longDescription: + 'Integrate Mailchimp into the workflow. Can manage audiences (lists), list members, campaigns, automation workflows, templates, reports, segments, tags, merge fields, interest categories, landing pages, signup forms, and batch operations.', + docsLink: 'https://docs.sim.ai/integrations/mailchimp', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mailchimp.ts b/apps/sim/blocks/blocks/mailchimp.ts index 7f07ab83941..8b9075b160d 100644 --- a/apps/sim/blocks/blocks/mailchimp.ts +++ b/apps/sim/blocks/blocks/mailchimp.ts @@ -1,20 +1,12 @@ import { Mail } from '@/components/emcn/icons' import { MailchimpIcon } from '@/components/icons' +import { MailchimpBlockDisplay } from '@/blocks/blocks/mailchimp.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const MailchimpBlock: BlockConfig = { - type: 'mailchimp', - name: 'Mailchimp', - description: 'Manage audiences, campaigns, and marketing automation in Mailchimp', - longDescription: - 'Integrate Mailchimp into the workflow. Can manage audiences (lists), list members, campaigns, automation workflows, templates, reports, segments, tags, merge fields, interest categories, landing pages, signup forms, and batch operations.', - docsLink: 'https://docs.sim.ai/integrations/mailchimp', + ...MailchimpBlockDisplay, authMode: AuthMode.ApiKey, - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#FFE01B', - icon: MailchimpIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/mailgun.display.ts b/apps/sim/blocks/blocks/mailgun.display.ts new file mode 100644 index 00000000000..be4d031187f --- /dev/null +++ b/apps/sim/blocks/blocks/mailgun.display.ts @@ -0,0 +1,16 @@ +import { MailgunIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MailgunBlockDisplay = { + type: 'mailgun', + name: 'Mailgun', + description: 'Send emails and manage mailing lists with Mailgun', + category: 'tools', + bgColor: '#C12126', + icon: MailgunIcon, + longDescription: + 'Integrate Mailgun into your workflow. Send transactional emails, manage mailing lists and members, view domain information, and track email events. Supports text and HTML emails, tags for tracking, and comprehensive list management.', + docsLink: 'https://docs.sim.ai/integrations/mailgun', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mailgun.ts b/apps/sim/blocks/blocks/mailgun.ts index b96decf1f1f..a95a7a886d9 100644 --- a/apps/sim/blocks/blocks/mailgun.ts +++ b/apps/sim/blocks/blocks/mailgun.ts @@ -1,20 +1,10 @@ import { MailgunIcon } from '@/components/icons' +import { MailgunBlockDisplay } from '@/blocks/blocks/mailgun.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { SendMessageResult } from '@/tools/mailgun/types' export const MailgunBlock: BlockConfig = { - type: 'mailgun', - name: 'Mailgun', - description: 'Send emails and manage mailing lists with Mailgun', - longDescription: - 'Integrate Mailgun into your workflow. Send transactional emails, manage mailing lists and members, view domain information, and track email events. Supports text and HTML emails, tags for tracking, and comprehensive list management.', - docsLink: 'https://docs.sim.ai/integrations/mailgun', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#C12126', - icon: MailgunIcon, - + ...MailgunBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/manual_trigger.display.ts b/apps/sim/blocks/blocks/manual_trigger.display.ts new file mode 100644 index 00000000000..386cd79a04e --- /dev/null +++ b/apps/sim/blocks/blocks/manual_trigger.display.ts @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { Play } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const ManualTriggerIcon = (props: SVGProps) => createElement(Play, props) + +export const ManualTriggerBlockDisplay = { + type: 'manual_trigger', + name: 'Manual (Legacy)', + description: 'Legacy manual start block. Prefer the Start block.', + category: 'triggers', + bgColor: '#2563EB', + icon: ManualTriggerIcon, + longDescription: + 'Trigger the workflow manually without defining an input schema. Useful for simple runs where no structured input is needed.', + hideFromToolbar: true, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/manual_trigger.ts b/apps/sim/blocks/blocks/manual_trigger.ts index ded5616efb9..d0a88684af4 100644 --- a/apps/sim/blocks/blocks/manual_trigger.ts +++ b/apps/sim/blocks/blocks/manual_trigger.ts @@ -1,25 +1,17 @@ import type { SVGProps } from 'react' import { createElement } from 'react' import { Play } from 'lucide-react' +import { ManualTriggerBlockDisplay } from '@/blocks/blocks/manual_trigger.display' import type { BlockConfig } from '@/blocks/types' const ManualTriggerIcon = (props: SVGProps) => createElement(Play, props) export const ManualTriggerBlock: BlockConfig = { - type: 'manual_trigger', - triggerAllowed: true, - name: 'Manual (Legacy)', - description: 'Legacy manual start block. Prefer the Start block.', - longDescription: - 'Trigger the workflow manually without defining an input schema. Useful for simple runs where no structured input is needed.', + ...ManualTriggerBlockDisplay, bestPractices: ` - Use when you want a simple manual start without defining an input format. - If you need structured inputs or child workflows to map variables from, prefer the Input Form Trigger. `, - category: 'triggers', - hideFromToolbar: true, - bgColor: '#2563EB', - icon: ManualTriggerIcon, subBlocks: [], tools: { access: [], diff --git a/apps/sim/blocks/blocks/mcp.display.ts b/apps/sim/blocks/blocks/mcp.display.ts new file mode 100644 index 00000000000..8e2186458be --- /dev/null +++ b/apps/sim/blocks/blocks/mcp.display.ts @@ -0,0 +1,16 @@ +import { McpIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const McpBlockDisplay = { + type: 'mcp', + name: 'MCP Tool', + description: 'Execute tools from Model Context Protocol (MCP) servers', + category: 'blocks', + bgColor: '#181C1E', + icon: McpIcon, + longDescription: + 'Integrate MCP into the workflow. Can execute tools from MCP servers. Requires MCP servers in workspace settings.', + docsLink: 'https://docs.sim.ai/agents/mcp', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mcp.ts b/apps/sim/blocks/blocks/mcp.ts index d90ebe2911b..55315e6efba 100644 --- a/apps/sim/blocks/blocks/mcp.ts +++ b/apps/sim/blocks/blocks/mcp.ts @@ -1,7 +1,6 @@ -import { McpIcon } from '@/components/icons' import { createMcpToolId } from '@/lib/mcp/shared' +import { McpBlockDisplay } from '@/blocks/blocks/mcp.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' export interface McpResponse extends ToolResponse { @@ -9,16 +8,7 @@ export interface McpResponse extends ToolResponse { } export const McpBlock: BlockConfig = { - type: 'mcp', - name: 'MCP Tool', - description: 'Execute tools from Model Context Protocol (MCP) servers', - longDescription: - 'Integrate MCP into the workflow. Can execute tools from MCP servers. Requires MCP servers in workspace settings.', - docsLink: 'https://docs.sim.ai/agents/mcp', - category: 'blocks', - integrationType: IntegrationType.DevOps, - bgColor: '#181C1E', - icon: McpIcon, + ...McpBlockDisplay, subBlocks: [ { id: 'server', diff --git a/apps/sim/blocks/blocks/mem0.display.ts b/apps/sim/blocks/blocks/mem0.display.ts new file mode 100644 index 00000000000..3fbc6468451 --- /dev/null +++ b/apps/sim/blocks/blocks/mem0.display.ts @@ -0,0 +1,15 @@ +import { Mem0Icon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const Mem0BlockDisplay = { + type: 'mem0', + name: 'Mem0', + description: 'Agent memory management', + category: 'tools', + bgColor: '#181C1E', + icon: Mem0Icon, + longDescription: 'Integrate Mem0 into the workflow. Can add, search, and retrieve memories.', + docsLink: 'https://docs.sim.ai/integrations/mem0', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mem0.ts b/apps/sim/blocks/blocks/mem0.ts index d8197775d06..347603428ea 100644 --- a/apps/sim/blocks/blocks/mem0.ts +++ b/apps/sim/blocks/blocks/mem0.ts @@ -1,20 +1,13 @@ import { toError } from '@sim/utils/errors' import { Mem0Icon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { Mem0BlockDisplay } from '@/blocks/blocks/mem0.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { Mem0Response } from '@/tools/mem0/types' import { parseMem0Messages } from '@/tools/mem0/utils' export const Mem0Block: BlockConfig = { - type: 'mem0', - name: 'Mem0', - description: 'Agent memory management', + ...Mem0BlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Mem0 into the workflow. Can add, search, and retrieve memories.', - bgColor: '#181C1E', - icon: Mem0Icon, - category: 'tools', - integrationType: IntegrationType.AI, - docsLink: 'https://docs.sim.ai/integrations/mem0', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/memory.display.ts b/apps/sim/blocks/blocks/memory.display.ts new file mode 100644 index 00000000000..4a6d484b816 --- /dev/null +++ b/apps/sim/blocks/blocks/memory.display.ts @@ -0,0 +1,14 @@ +import { BrainIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const MemoryBlockDisplay = { + type: 'memory', + name: 'Memory', + description: 'Add memory store', + category: 'blocks', + bgColor: '#F64F9E', + icon: BrainIcon, + longDescription: + 'Integrate Memory into the workflow. Can add, get a memory, get all memories, and delete memories.', + docsLink: 'https://docs.sim.ai/integrations/memory', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/memory.ts b/apps/sim/blocks/blocks/memory.ts index 62944e24e69..9ab1a18988e 100644 --- a/apps/sim/blocks/blocks/memory.ts +++ b/apps/sim/blocks/blocks/memory.ts @@ -1,20 +1,12 @@ -import { BrainIcon } from '@/components/icons' +import { MemoryBlockDisplay } from '@/blocks/blocks/memory.display' import type { BlockConfig } from '@/blocks/types' export const MemoryBlock: BlockConfig = { - type: 'memory', - name: 'Memory', - description: 'Add memory store', - longDescription: - 'Integrate Memory into the workflow. Can add, get a memory, get all memories, and delete memories.', - bgColor: '#F64F9E', + ...MemoryBlockDisplay, bestPractices: ` - Do not use this block unless the user explicitly asks for it. - Used in conjunction with agent blocks to inject artificial memory into the conversation. For natural conversations, use the agent block memories modes directly instead. `, - icon: BrainIcon, - category: 'blocks', - docsLink: 'https://docs.sim.ai/integrations/memory', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/microsoft_ad.display.ts b/apps/sim/blocks/blocks/microsoft_ad.display.ts new file mode 100644 index 00000000000..fc5827d0da5 --- /dev/null +++ b/apps/sim/blocks/blocks/microsoft_ad.display.ts @@ -0,0 +1,16 @@ +import { AzureIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MicrosoftAdBlockDisplay = { + type: 'microsoft_ad', + name: 'Azure AD', + description: 'Manage users and groups in Azure AD (Microsoft Entra ID)', + category: 'tools', + bgColor: '#0078D4', + icon: AzureIcon, + longDescription: + 'Integrate Azure Active Directory into your workflows. List, create, update, and delete users and groups. Manage group memberships programmatically.', + docsLink: 'https://docs.sim.ai/integrations/microsoft_ad', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/microsoft_ad.ts b/apps/sim/blocks/blocks/microsoft_ad.ts index f5b662dacac..15fa52a1176 100644 --- a/apps/sim/blocks/blocks/microsoft_ad.ts +++ b/apps/sim/blocks/blocks/microsoft_ad.ts @@ -1,20 +1,12 @@ import { AzureIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { MicrosoftAdBlockDisplay } from '@/blocks/blocks/microsoft_ad.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { MicrosoftAdResponse } from '@/tools/microsoft_ad/types' export const MicrosoftAdBlock: BlockConfig = { - type: 'microsoft_ad', - name: 'Azure AD', - description: 'Manage users and groups in Azure AD (Microsoft Entra ID)', - longDescription: - 'Integrate Azure Active Directory into your workflows. List, create, update, and delete users and groups. Manage group memberships programmatically.', - docsLink: 'https://docs.sim.ai/integrations/microsoft_ad', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#0078D4', - icon: AzureIcon, + ...MicrosoftAdBlockDisplay, authMode: AuthMode.OAuth, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/microsoft_dataverse.display.ts b/apps/sim/blocks/blocks/microsoft_dataverse.display.ts new file mode 100644 index 00000000000..8b220fb9c69 --- /dev/null +++ b/apps/sim/blocks/blocks/microsoft_dataverse.display.ts @@ -0,0 +1,16 @@ +import { MicrosoftDataverseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MicrosoftDataverseBlockDisplay = { + type: 'microsoft_dataverse', + name: 'Microsoft Dataverse', + description: 'Manage records in Microsoft Dataverse tables', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftDataverseIcon, + longDescription: + 'Integrate Microsoft Dataverse into your workflow. Create, read, update, delete, upsert, associate, query, search, and execute actions and functions against Dataverse tables using the Web API. Supports bulk operations, FetchXML, file uploads, and relevance search. Works with Dynamics 365, Power Platform, and custom Dataverse environments.', + docsLink: 'https://docs.sim.ai/integrations/microsoft_dataverse', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/microsoft_dataverse.ts b/apps/sim/blocks/blocks/microsoft_dataverse.ts index 34781e98366..9cfab9f99ca 100644 --- a/apps/sim/blocks/blocks/microsoft_dataverse.ts +++ b/apps/sim/blocks/blocks/microsoft_dataverse.ts @@ -1,22 +1,14 @@ import { MicrosoftDataverseIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { MicrosoftDataverseBlockDisplay } from '@/blocks/blocks/microsoft_dataverse.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DataverseResponse } from '@/tools/microsoft_dataverse/types' export const MicrosoftDataverseBlock: BlockConfig = { - type: 'microsoft_dataverse', - name: 'Microsoft Dataverse', - description: 'Manage records in Microsoft Dataverse tables', + ...MicrosoftDataverseBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Microsoft Dataverse into your workflow. Create, read, update, delete, upsert, associate, query, search, and execute actions and functions against Dataverse tables using the Web API. Supports bulk operations, FetchXML, file uploads, and relevance search. Works with Dynamics 365, Power Platform, and custom Dataverse environments.', - docsLink: 'https://docs.sim.ai/integrations/microsoft_dataverse', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: MicrosoftDataverseIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/microsoft_excel.display.ts b/apps/sim/blocks/blocks/microsoft_excel.display.ts new file mode 100644 index 00000000000..4657ea12e06 --- /dev/null +++ b/apps/sim/blocks/blocks/microsoft_excel.display.ts @@ -0,0 +1,31 @@ +import { MicrosoftExcelIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MicrosoftExcelBlockDisplay = { + type: 'microsoft_excel', + name: 'Microsoft Excel (Legacy)', + description: 'Read, write, and update data', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftExcelIcon, + longDescription: + 'Integrate Microsoft Excel into the workflow. Can read, write, update, add to table, and create new worksheets.', + docsLink: 'https://docs.sim.ai/integrations/microsoft_excel', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const MicrosoftExcelV2BlockDisplay = { + type: 'microsoft_excel_v2', + name: 'Microsoft Excel', + description: 'Read and write data with sheet selection', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftExcelIcon, + longDescription: + 'Integrate Microsoft Excel into the workflow with explicit sheet selection. Can read and write data in specific sheets.', + docsLink: 'https://docs.sim.ai/integrations/microsoft_excel', + integrationType: IntegrationType.Documents, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/microsoft_excel.ts b/apps/sim/blocks/blocks/microsoft_excel.ts index da57efcb1a0..99e6be38430 100644 --- a/apps/sim/blocks/blocks/microsoft_excel.ts +++ b/apps/sim/blocks/blocks/microsoft_excel.ts @@ -1,7 +1,11 @@ import { MicrosoftExcelIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { + MicrosoftExcelBlockDisplay, + MicrosoftExcelV2BlockDisplay, +} from '@/blocks/blocks/microsoft_excel.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { MicrosoftExcelResponse, @@ -9,18 +13,8 @@ import type { } from '@/tools/microsoft_excel/types' export const MicrosoftExcelBlock: BlockConfig = { - type: 'microsoft_excel', - name: 'Microsoft Excel (Legacy)', - description: 'Read, write, and update data', + ...MicrosoftExcelBlockDisplay, authMode: AuthMode.OAuth, - hideFromToolbar: true, - longDescription: - 'Integrate Microsoft Excel into the workflow. Can read, write, update, add to table, and create new worksheets.', - docsLink: 'https://docs.sim.ai/integrations/microsoft_excel', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: MicrosoftExcelIcon, subBlocks: [ { id: 'operation', @@ -347,18 +341,8 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`, } export const MicrosoftExcelV2Block: BlockConfig = { - type: 'microsoft_excel_v2', - name: 'Microsoft Excel', - description: 'Read and write data with sheet selection', + ...MicrosoftExcelV2BlockDisplay, authMode: AuthMode.OAuth, - hideFromToolbar: false, - longDescription: - 'Integrate Microsoft Excel into the workflow with explicit sheet selection. Can read and write data in specific sheets.', - docsLink: 'https://docs.sim.ai/integrations/microsoft_excel', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: MicrosoftExcelIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/microsoft_planner.display.ts b/apps/sim/blocks/blocks/microsoft_planner.display.ts new file mode 100644 index 00000000000..f1855742fb1 --- /dev/null +++ b/apps/sim/blocks/blocks/microsoft_planner.display.ts @@ -0,0 +1,16 @@ +import { MicrosoftPlannerIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MicrosoftPlannerBlockDisplay = { + type: 'microsoft_planner', + name: 'Microsoft Planner', + description: 'Manage tasks, plans, and buckets in Microsoft Planner', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftPlannerIcon, + longDescription: + 'Integrate Microsoft Planner into the workflow. Manage tasks, plans, buckets, and task details including checklists and references.', + docsLink: 'https://docs.sim.ai/integrations/microsoft_planner', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/microsoft_planner.ts b/apps/sim/blocks/blocks/microsoft_planner.ts index 4c6e800f5de..46bbf5984f9 100644 --- a/apps/sim/blocks/blocks/microsoft_planner.ts +++ b/apps/sim/blocks/blocks/microsoft_planner.ts @@ -1,7 +1,8 @@ import { MicrosoftPlannerIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { MicrosoftPlannerBlockDisplay } from '@/blocks/blocks/microsoft_planner.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { MicrosoftPlannerResponse } from '@/tools/microsoft_planner/types' interface MicrosoftPlannerBlockParams { @@ -27,17 +28,8 @@ interface MicrosoftPlannerBlockParams { } export const MicrosoftPlannerBlock: BlockConfig = { - type: 'microsoft_planner', - name: 'Microsoft Planner', - description: 'Manage tasks, plans, and buckets in Microsoft Planner', + ...MicrosoftPlannerBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Microsoft Planner into the workflow. Manage tasks, plans, buckets, and task details including checklists and references.', - docsLink: 'https://docs.sim.ai/integrations/microsoft_planner', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: MicrosoftPlannerIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/microsoft_teams.display.ts b/apps/sim/blocks/blocks/microsoft_teams.display.ts new file mode 100644 index 00000000000..3c4b9c2d941 --- /dev/null +++ b/apps/sim/blocks/blocks/microsoft_teams.display.ts @@ -0,0 +1,17 @@ +import { MicrosoftTeamsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MicrosoftTeamsBlockDisplay = { + type: 'microsoft_teams', + name: 'Microsoft Teams', + description: 'Manage messages, reactions, and members in Teams', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftTeamsIcon, + longDescription: + 'Integrate Microsoft Teams into the workflow. Read, write, update, and delete chat and channel messages. Reply to messages, add reactions, and list team/channel members. Can be used in trigger mode to trigger a workflow when a message is sent to a chat or channel. To mention users in messages, wrap their name in `` tags: `userName`', + docsLink: 'https://docs.sim.ai/integrations/microsoft_teams', + integrationType: IntegrationType.Communication, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/microsoft_teams.ts b/apps/sim/blocks/blocks/microsoft_teams.ts index 08aec574153..2d5ad5f6853 100644 --- a/apps/sim/blocks/blocks/microsoft_teams.ts +++ b/apps/sim/blocks/blocks/microsoft_teams.ts @@ -1,24 +1,15 @@ import { MicrosoftTeamsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { MicrosoftTeamsBlockDisplay } from '@/blocks/blocks/microsoft_teams.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { MicrosoftTeamsResponse } from '@/tools/microsoft_teams/types' import { getTrigger } from '@/triggers' export const MicrosoftTeamsBlock: BlockConfig = { - type: 'microsoft_teams', - name: 'Microsoft Teams', - description: 'Manage messages, reactions, and members in Teams', + ...MicrosoftTeamsBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Microsoft Teams into the workflow. Read, write, update, and delete chat and channel messages. Reply to messages, add reactions, and list team/channel members. Can be used in trigger mode to trigger a workflow when a message is sent to a chat or channel. To mention users in messages, wrap their name in `` tags: `userName`', - docsLink: 'https://docs.sim.ai/integrations/microsoft_teams', - category: 'tools', - integrationType: IntegrationType.Communication, - triggerAllowed: true, - bgColor: '#FFFFFF', - icon: MicrosoftTeamsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/millionverifier.display.ts b/apps/sim/blocks/blocks/millionverifier.display.ts new file mode 100644 index 00000000000..d0571fac424 --- /dev/null +++ b/apps/sim/blocks/blocks/millionverifier.display.ts @@ -0,0 +1,16 @@ +import { MillionVerifierIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MillionVerifierBlockDisplay = { + type: 'millionverifier', + name: 'MillionVerifier', + description: 'Verify email deliverability and check account credits', + category: 'tools', + bgColor: '#FFFFFF', + icon: MillionVerifierIcon, + longDescription: + 'Integrate MillionVerifier to verify email deliverability in real time — classify addresses as valid, invalid, catch-all, disposable, or unknown — and check your remaining verification credits.', + docsLink: 'https://docs.sim.ai/integrations/millionverifier', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/millionverifier.ts b/apps/sim/blocks/blocks/millionverifier.ts index 286d60e52d7..b4d336da59c 100644 --- a/apps/sim/blocks/blocks/millionverifier.ts +++ b/apps/sim/blocks/blocks/millionverifier.ts @@ -1,19 +1,10 @@ -import { MillionVerifierIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { MillionVerifierBlockDisplay } from '@/blocks/blocks/millionverifier.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { MillionVerifierResponse } from '@/tools/millionverifier/types' export const MillionVerifierBlock: BlockConfig = { - type: 'millionverifier', - name: 'MillionVerifier', - description: 'Verify email deliverability and check account credits', + ...MillionVerifierBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate MillionVerifier to verify email deliverability in real time — classify addresses as valid, invalid, catch-all, disposable, or unknown — and check your remaining verification credits.', - docsLink: 'https://docs.sim.ai/integrations/millionverifier', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: MillionVerifierIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/mistral_parse.display.ts b/apps/sim/blocks/blocks/mistral_parse.display.ts new file mode 100644 index 00000000000..e1c83a163a7 --- /dev/null +++ b/apps/sim/blocks/blocks/mistral_parse.display.ts @@ -0,0 +1,32 @@ +import { MistralIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MistralParseBlockDisplay = { + type: 'mistral_parse', + name: 'Mistral Parser (Legacy)', + description: 'Extract text from PDF documents', + category: 'tools', + bgColor: '#000000', + icon: MistralIcon, + longDescription: `Integrate Mistral Parse into the workflow. Can extract text from uploaded PDF documents, or from a URL.`, + docsLink: 'https://docs.sim.ai/integrations/mistral_parse', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const MistralParseV2BlockDisplay = { + ...MistralParseBlockDisplay, + type: 'mistral_parse_v2', + name: 'Mistral Parser', + description: 'Extract text from PDF documents', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const MistralParseV3BlockDisplay = { + ...MistralParseBlockDisplay, + type: 'mistral_parse_v3', + name: 'Mistral Parser', + description: 'Extract text from PDF documents', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mistral_parse.ts b/apps/sim/blocks/blocks/mistral_parse.ts index a182ef8b2ec..972dd65a1a2 100644 --- a/apps/sim/blocks/blocks/mistral_parse.ts +++ b/apps/sim/blocks/blocks/mistral_parse.ts @@ -1,27 +1,17 @@ import { toError } from '@sim/utils/errors' import { MistralIcon } from '@/components/icons' import { - AuthMode, - type BlockConfig, - type BlockMeta, - IntegrationType, - type SubBlockType, -} from '@/blocks/types' + MistralParseBlockDisplay, + MistralParseV2BlockDisplay, + MistralParseV3BlockDisplay, +} from '@/blocks/blocks/mistral_parse.display' +import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { MistralParserOutput } from '@/tools/mistral/types' export const MistralParseBlock: BlockConfig = { - type: 'mistral_parse', - name: 'Mistral Parser (Legacy)', - description: 'Extract text from PDF documents', - hideFromToolbar: true, + ...MistralParseBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: `Integrate Mistral Parse into the workflow. Can extract text from uploaded PDF documents, or from a URL.`, - docsLink: 'https://docs.sim.ai/integrations/mistral_parse', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#000000', - icon: MistralIcon, subBlocks: [ { id: 'inputMethod', @@ -157,10 +147,7 @@ export const MistralParseBlock: BlockConfig = { */ export const MistralParseV2Block: BlockConfig = { ...MistralParseBlock, - type: 'mistral_parse_v2', - name: 'Mistral Parser', - description: 'Extract text from PDF documents', - hideFromToolbar: true, + ...MistralParseV2BlockDisplay, subBlocks: [ { id: 'fileUpload', @@ -287,10 +274,7 @@ export const MistralParseV2Block: BlockConfig = { */ export const MistralParseV3Block: BlockConfig = { ...MistralParseBlock, - type: 'mistral_parse_v3', - name: 'Mistral Parser', - description: 'Extract text from PDF documents', - hideFromToolbar: false, + ...MistralParseV3BlockDisplay, subBlocks: [ { id: 'fileUpload', diff --git a/apps/sim/blocks/blocks/monday.display.ts b/apps/sim/blocks/blocks/monday.display.ts new file mode 100644 index 00000000000..da18c6538fc --- /dev/null +++ b/apps/sim/blocks/blocks/monday.display.ts @@ -0,0 +1,16 @@ +import { MondayIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MondayBlockDisplay = { + type: 'monday', + name: 'Monday', + description: 'Manage Monday.com boards, items, and groups', + category: 'tools', + bgColor: '#FFFFFF', + icon: MondayIcon, + longDescription: + 'Integrate with Monday.com to list boards, get board details, fetch and search items, create and update items, archive or delete items, create subitems, move items between groups, add updates, and create groups.', + docsLink: 'https://docs.sim.ai/integrations/monday', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/monday.ts b/apps/sim/blocks/blocks/monday.ts index 1753a05c5ba..da5e1cd4337 100644 --- a/apps/sim/blocks/blocks/monday.ts +++ b/apps/sim/blocks/blocks/monday.ts @@ -1,7 +1,8 @@ import { MondayIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { MondayBlockDisplay } from '@/blocks/blocks/monday.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { MondayArchiveItemResponse, MondayCreateGroupResponse, @@ -53,17 +54,8 @@ const ITEM_ID_OPS = [ ] export const MondayBlock: BlockConfig = { - type: 'monday', - name: 'Monday', - description: 'Manage Monday.com boards, items, and groups', + ...MondayBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with Monday.com to list boards, get board details, fetch and search items, create and update items, archive or delete items, create subitems, move items between groups, add updates, and create groups.', - docsLink: 'https://docs.sim.ai/integrations/monday', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: MondayIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/mongodb.display.ts b/apps/sim/blocks/blocks/mongodb.display.ts new file mode 100644 index 00000000000..169e43c4d91 --- /dev/null +++ b/apps/sim/blocks/blocks/mongodb.display.ts @@ -0,0 +1,16 @@ +import { MongoDBIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MongoDBBlockDisplay = { + type: 'mongodb', + name: 'MongoDB', + description: 'Connect to MongoDB database', + category: 'tools', + bgColor: '#FFFFFF', + icon: MongoDBIcon, + longDescription: + 'Integrate MongoDB into the workflow. Can find, insert, update, delete, and aggregate data.', + docsLink: 'https://docs.sim.ai/integrations/mongodb', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mongodb.ts b/apps/sim/blocks/blocks/mongodb.ts index 732017c4e64..063b754fc03 100644 --- a/apps/sim/blocks/blocks/mongodb.ts +++ b/apps/sim/blocks/blocks/mongodb.ts @@ -1,20 +1,11 @@ import { getErrorMessage } from '@sim/utils/errors' import { MongoDBIcon } from '@/components/icons' +import { MongoDBBlockDisplay } from '@/blocks/blocks/mongodb.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { MongoDBIntrospectResponse, MongoDBResponse } from '@/tools/mongodb/types' export const MongoDBBlock: BlockConfig = { - type: 'mongodb', - name: 'MongoDB', - description: 'Connect to MongoDB database', - longDescription: - 'Integrate MongoDB into the workflow. Can find, insert, update, delete, and aggregate data.', - docsLink: 'https://docs.sim.ai/integrations/mongodb', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: MongoDBIcon, + ...MongoDBBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/mothership.display.ts b/apps/sim/blocks/blocks/mothership.display.ts new file mode 100644 index 00000000000..454f4321d36 --- /dev/null +++ b/apps/sim/blocks/blocks/mothership.display.ts @@ -0,0 +1,13 @@ +import { Blimp } from '@/components/emcn' +import type { BlockDisplay } from '@/blocks/manifest' + +export const MothershipBlockDisplay = { + type: 'mothership', + name: 'Sim', + description: 'Talk to Sim', + category: 'blocks', + bgColor: '#802FDE', + icon: Blimp, + longDescription: + 'The Sim block sends messages to Sim, which has access to subagents, integration tools, memory, and workspace context. Use it to perform complex multi-step reasoning, cross-service queries, or any task that benefits from the full Sim intelligence within a workflow.', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mothership.ts b/apps/sim/blocks/blocks/mothership.ts index cee2eee9a37..66ac4fd6d0a 100644 --- a/apps/sim/blocks/blocks/mothership.ts +++ b/apps/sim/blocks/blocks/mothership.ts @@ -1,4 +1,4 @@ -import { Blimp } from '@/components/emcn' +import { MothershipBlockDisplay } from '@/blocks/blocks/mothership.display' import type { BlockConfig } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' @@ -16,18 +16,11 @@ interface MothershipResponse extends ToolResponse { } export const MothershipBlock: BlockConfig = { - type: 'mothership', - name: 'Sim', - description: 'Talk to Sim', - longDescription: - 'The Sim block sends messages to Sim, which has access to subagents, integration tools, memory, and workspace context. Use it to perform complex multi-step reasoning, cross-service queries, or any task that benefits from the full Sim intelligence within a workflow.', + ...MothershipBlockDisplay, bestPractices: ` - Use for tasks that require multi-step reasoning, tool use, or cross-service coordination. - Sim picks its own model and tools internally — you only provide a prompt. `, - category: 'blocks', - bgColor: '#802FDE', - icon: Blimp, subBlocks: [ { id: 'prompt', diff --git a/apps/sim/blocks/blocks/mysql.display.ts b/apps/sim/blocks/blocks/mysql.display.ts new file mode 100644 index 00000000000..09b376d5a70 --- /dev/null +++ b/apps/sim/blocks/blocks/mysql.display.ts @@ -0,0 +1,16 @@ +import { MySQLIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const MySQLBlockDisplay = { + type: 'mysql', + name: 'MySQL', + description: 'Connect to MySQL database', + category: 'tools', + bgColor: '#FFFFFF', + icon: MySQLIcon, + longDescription: + 'Integrate MySQL into the workflow. Can query, insert, update, delete, and execute raw SQL.', + docsLink: 'https://docs.sim.ai/integrations/mysql', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/mysql.ts b/apps/sim/blocks/blocks/mysql.ts index 10b9673f3bb..d7f9edab741 100644 --- a/apps/sim/blocks/blocks/mysql.ts +++ b/apps/sim/blocks/blocks/mysql.ts @@ -1,20 +1,10 @@ import { getErrorMessage } from '@sim/utils/errors' -import { MySQLIcon } from '@/components/icons' +import { MySQLBlockDisplay } from '@/blocks/blocks/mysql.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { MySQLResponse } from '@/tools/mysql/types' export const MySQLBlock: BlockConfig = { - type: 'mysql', - name: 'MySQL', - description: 'Connect to MySQL database', - longDescription: - 'Integrate MySQL into the workflow. Can query, insert, update, delete, and execute raw SQL.', - docsLink: 'https://docs.sim.ai/integrations/mysql', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: MySQLIcon, + ...MySQLBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/neo4j.display.ts b/apps/sim/blocks/blocks/neo4j.display.ts new file mode 100644 index 00000000000..9f1e3d2d1ba --- /dev/null +++ b/apps/sim/blocks/blocks/neo4j.display.ts @@ -0,0 +1,16 @@ +import { Neo4jIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const Neo4jBlockDisplay = { + type: 'neo4j', + name: 'Neo4j', + description: 'Connect to Neo4j graph database', + category: 'tools', + bgColor: '#FFFFFF', + icon: Neo4jIcon, + longDescription: + 'Integrate Neo4j graph database into the workflow. Can query, create, merge, update, and delete nodes and relationships.', + docsLink: 'https://docs.sim.ai/integrations/neo4j', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/neo4j.ts b/apps/sim/blocks/blocks/neo4j.ts index 5d9f9092875..34a39bd78cd 100644 --- a/apps/sim/blocks/blocks/neo4j.ts +++ b/apps/sim/blocks/blocks/neo4j.ts @@ -1,20 +1,11 @@ import { getErrorMessage } from '@sim/utils/errors' import { Neo4jIcon } from '@/components/icons' +import { Neo4jBlockDisplay } from '@/blocks/blocks/neo4j.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { Neo4jIntrospectResponse, Neo4jResponse } from '@/tools/neo4j/types' export const Neo4jBlock: BlockConfig = { - type: 'neo4j', - name: 'Neo4j', - description: 'Connect to Neo4j graph database', - longDescription: - 'Integrate Neo4j graph database into the workflow. Can query, create, merge, update, and delete nodes and relationships.', - docsLink: 'https://docs.sim.ai/integrations/neo4j', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FFFFFF', - icon: Neo4jIcon, + ...Neo4jBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/neverbounce.display.ts b/apps/sim/blocks/blocks/neverbounce.display.ts new file mode 100644 index 00000000000..c5846c3b008 --- /dev/null +++ b/apps/sim/blocks/blocks/neverbounce.display.ts @@ -0,0 +1,16 @@ +import { NeverBounceIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const NeverBounceBlockDisplay = { + type: 'neverbounce', + name: 'NeverBounce', + description: 'Verify email deliverability and check account credits', + category: 'tools', + bgColor: '#064AF4', + icon: NeverBounceIcon, + longDescription: + 'Integrate NeverBounce to verify email deliverability in real time — classify addresses as valid, invalid, catch-all, disposable, or unknown — and check your remaining verification credits.', + docsLink: 'https://docs.sim.ai/integrations/neverbounce', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/neverbounce.ts b/apps/sim/blocks/blocks/neverbounce.ts index 69027a4c2a0..e3fda9f92b2 100644 --- a/apps/sim/blocks/blocks/neverbounce.ts +++ b/apps/sim/blocks/blocks/neverbounce.ts @@ -1,19 +1,10 @@ -import { NeverBounceIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { NeverBounceBlockDisplay } from '@/blocks/blocks/neverbounce.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { NeverBounceResponse } from '@/tools/neverbounce/types' export const NeverBounceBlock: BlockConfig = { - type: 'neverbounce', - name: 'NeverBounce', - description: 'Verify email deliverability and check account credits', + ...NeverBounceBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate NeverBounce to verify email deliverability in real time — classify addresses as valid, invalid, catch-all, disposable, or unknown — and check your remaining verification credits.', - docsLink: 'https://docs.sim.ai/integrations/neverbounce', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#064AF4', - icon: NeverBounceIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/new_relic.display.ts b/apps/sim/blocks/blocks/new_relic.display.ts new file mode 100644 index 00000000000..d4c21066179 --- /dev/null +++ b/apps/sim/blocks/blocks/new_relic.display.ts @@ -0,0 +1,16 @@ +import { NewRelicIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const NewRelicBlockDisplay = { + type: 'new_relic', + name: 'New Relic', + description: 'Query observability data and record deployments in New Relic', + category: 'tools', + bgColor: '#000000', + icon: NewRelicIcon, + longDescription: + 'Integrate New Relic into workflows. Run NRQL queries, search monitored entities, fetch entity details, and record deployment change events.', + docsLink: 'https://docs.sim.ai/integrations/new_relic', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/new_relic.ts b/apps/sim/blocks/blocks/new_relic.ts index f8912cd08ca..53fd3d031dd 100644 --- a/apps/sim/blocks/blocks/new_relic.ts +++ b/apps/sim/blocks/blocks/new_relic.ts @@ -1,6 +1,7 @@ import { NewRelicIcon } from '@/components/icons' +import { NewRelicBlockDisplay } from '@/blocks/blocks/new_relic.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { NewRelicCustomAttributes, NewRelicResponse } from '@/tools/new_relic/types' function parseCustomAttributes(value: unknown): NewRelicCustomAttributes | undefined { @@ -20,17 +21,8 @@ function parseCustomAttributes(value: unknown): NewRelicCustomAttributes | undef } export const NewRelicBlock: BlockConfig = { - type: 'new_relic', - name: 'New Relic', - description: 'Query observability data and record deployments in New Relic', - longDescription: - 'Integrate New Relic into workflows. Run NRQL queries, search monitored entities, fetch entity details, and record deployment change events.', - docsLink: 'https://docs.sim.ai/integrations/new_relic', - category: 'tools', + ...NewRelicBlockDisplay, authMode: AuthMode.ApiKey, - integrationType: IntegrationType.Observability, - bgColor: '#000000', - icon: NewRelicIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/note.display.ts b/apps/sim/blocks/blocks/note.display.ts new file mode 100644 index 00000000000..15aa01f0e05 --- /dev/null +++ b/apps/sim/blocks/blocks/note.display.ts @@ -0,0 +1,13 @@ +import { NoteIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const NoteBlockDisplay = { + type: 'note', + name: 'Note', + description: 'Add contextual annotations directly onto the workflow canvas.', + category: 'blocks', + bgColor: '#F59E0B', + icon: NoteIcon, + longDescription: + 'Use Note blocks to document decisions, share instructions, or leave context for collaborators directly on the workflow canvas. Notes support Markdown rendering and YouTube video embeds.', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/note.ts b/apps/sim/blocks/blocks/note.ts index e41dbc04840..3baf51741d9 100644 --- a/apps/sim/blocks/blocks/note.ts +++ b/apps/sim/blocks/blocks/note.ts @@ -1,15 +1,8 @@ -import { NoteIcon } from '@/components/icons' +import { NoteBlockDisplay } from '@/blocks/blocks/note.display' import type { BlockConfig } from '@/blocks/types' export const NoteBlock: BlockConfig = { - type: 'note', - name: 'Note', - description: 'Add contextual annotations directly onto the workflow canvas.', - longDescription: - 'Use Note blocks to document decisions, share instructions, or leave context for collaborators directly on the workflow canvas. Notes support Markdown rendering and YouTube video embeds.', - category: 'blocks', - bgColor: '#F59E0B', - icon: NoteIcon, + ...NoteBlockDisplay, subBlocks: [ { id: 'content', diff --git a/apps/sim/blocks/blocks/notion.display.ts b/apps/sim/blocks/blocks/notion.display.ts new file mode 100644 index 00000000000..8f4772dee60 --- /dev/null +++ b/apps/sim/blocks/blocks/notion.display.ts @@ -0,0 +1,31 @@ +import { NotionIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const NotionBlockDisplay = { + type: 'notion', + name: 'Notion (Legacy)', + description: 'Manage Notion pages', + category: 'tools', + bgColor: '#FFFFFF', + icon: NotionIcon, + longDescription: + 'Integrate with Notion into the workflow. Can read page, read database, create page, create database, append content, query database, and search workspace.', + docsLink: 'https://docs.sim.ai/integrations/notion', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const NotionV2BlockDisplay = { + type: 'notion_v2', + name: 'Notion', + description: 'Manage Notion pages', + category: 'tools', + bgColor: '#FFFFFF', + icon: NotionIcon, + longDescription: + 'Integrate with Notion into the workflow. Can read page, read database, create page, create database, append content, query database, and search workspace.', + docsLink: 'https://docs.sim.ai/integrations/notion', + integrationType: IntegrationType.Documents, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/notion.ts b/apps/sim/blocks/blocks/notion.ts index 822e84b38f7..191b49081e3 100644 --- a/apps/sim/blocks/blocks/notion.ts +++ b/apps/sim/blocks/blocks/notion.ts @@ -1,26 +1,17 @@ import { toError } from '@sim/utils/errors' import { Send } from '@/components/emcn/icons' import { NotionIcon } from '@/components/icons' +import { NotionBlockDisplay, NotionV2BlockDisplay } from '@/blocks/blocks/notion.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { NotionResponse } from '@/tools/notion/types' import { getTrigger } from '@/triggers' // Legacy block - hidden from toolbar export const NotionBlock: BlockConfig = { - type: 'notion', - name: 'Notion (Legacy)', - hideFromToolbar: true, - description: 'Manage Notion pages', + ...NotionBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with Notion into the workflow. Can read page, read database, create page, create database, append content, query database, and search workspace.', - docsLink: 'https://docs.sim.ai/integrations/notion', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: NotionIcon, subBlocks: [ { id: 'operation', @@ -421,18 +412,8 @@ export const NotionBlock: BlockConfig = { // V2 Block with API-aligned outputs export const NotionV2Block: BlockConfig = { - type: 'notion_v2', - name: 'Notion', - description: 'Manage Notion pages', + ...NotionV2BlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with Notion into the workflow. Can read page, read database, create page, create database, append content, query database, and search workspace.', - docsLink: 'https://docs.sim.ai/integrations/notion', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: NotionIcon, - hideFromToolbar: false, subBlocks: [ ...NotionBlock.subBlocks, diff --git a/apps/sim/blocks/blocks/obsidian.display.ts b/apps/sim/blocks/blocks/obsidian.display.ts new file mode 100644 index 00000000000..9ec48e9a0b9 --- /dev/null +++ b/apps/sim/blocks/blocks/obsidian.display.ts @@ -0,0 +1,16 @@ +import { ObsidianIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ObsidianBlockDisplay = { + type: 'obsidian', + name: 'Obsidian', + description: 'Interact with your Obsidian vault via the Local REST API', + category: 'tools', + bgColor: '#0F0F0F', + icon: ObsidianIcon, + longDescription: + 'Read, create, update, search, and delete notes in your Obsidian vault. Manage periodic notes, execute commands, and patch content at specific locations. Requires the Obsidian Local REST API plugin.', + docsLink: 'https://docs.sim.ai/integrations/obsidian', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/obsidian.ts b/apps/sim/blocks/blocks/obsidian.ts index 1d4e5dee6d9..bbfa692767c 100644 --- a/apps/sim/blocks/blocks/obsidian.ts +++ b/apps/sim/blocks/blocks/obsidian.ts @@ -1,18 +1,10 @@ import { ObsidianIcon } from '@/components/icons' +import { ObsidianBlockDisplay } from '@/blocks/blocks/obsidian.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const ObsidianBlock: BlockConfig = { - type: 'obsidian', - name: 'Obsidian', - description: 'Interact with your Obsidian vault via the Local REST API', - longDescription: - 'Read, create, update, search, and delete notes in your Obsidian vault. Manage periodic notes, execute commands, and patch content at specific locations. Requires the Obsidian Local REST API plugin.', - docsLink: 'https://docs.sim.ai/integrations/obsidian', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#0F0F0F', - icon: ObsidianIcon, + ...ObsidianBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/okta.display.ts b/apps/sim/blocks/blocks/okta.display.ts new file mode 100644 index 00000000000..aa6ee04b653 --- /dev/null +++ b/apps/sim/blocks/blocks/okta.display.ts @@ -0,0 +1,17 @@ +import { OktaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const OktaBlockDisplay = { + type: 'okta', + name: 'Okta', + description: 'Manage users and groups in Okta', + category: 'tools', + bgColor: '#191919', + icon: OktaIcon, + iconColor: '#007DC1', + longDescription: + 'Integrate Okta identity management into your workflow. List, create, update, activate, suspend, and delete users. Reset passwords. Manage groups and group membership.', + docsLink: 'https://docs.sim.ai/integrations/okta', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/okta.ts b/apps/sim/blocks/blocks/okta.ts index a5e82b5dba5..b876b6fe1ca 100644 --- a/apps/sim/blocks/blocks/okta.ts +++ b/apps/sim/blocks/blocks/okta.ts @@ -1,21 +1,10 @@ import { OktaIcon } from '@/components/icons' +import { OktaBlockDisplay } from '@/blocks/blocks/okta.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { OktaResponse } from '@/tools/okta/types' export const OktaBlock: BlockConfig = { - type: 'okta', - name: 'Okta', - description: 'Manage users and groups in Okta', - longDescription: - 'Integrate Okta identity management into your workflow. List, create, update, activate, suspend, and delete users. Reset passwords. Manage groups and group membership.', - docsLink: 'https://docs.sim.ai/integrations/okta', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#191919', - iconColor: '#007DC1', - icon: OktaIcon, - + ...OktaBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/onedrive.display.ts b/apps/sim/blocks/blocks/onedrive.display.ts new file mode 100644 index 00000000000..7a87de41f4f --- /dev/null +++ b/apps/sim/blocks/blocks/onedrive.display.ts @@ -0,0 +1,16 @@ +import { MicrosoftOneDriveIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const OneDriveBlockDisplay = { + type: 'onedrive', + name: 'OneDrive', + description: 'Create, upload, download, list, and delete files', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftOneDriveIcon, + longDescription: + 'Integrate OneDrive into the workflow. Can create text and Excel files, upload files, download files, list files, and delete files or folders.', + docsLink: 'https://docs.sim.ai/integrations/onedrive', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/onedrive.ts b/apps/sim/blocks/blocks/onedrive.ts index 30f8d82a428..fc635f292d8 100644 --- a/apps/sim/blocks/blocks/onedrive.ts +++ b/apps/sim/blocks/blocks/onedrive.ts @@ -1,8 +1,9 @@ import { createLogger } from '@sim/logger' import { MicrosoftOneDriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { OneDriveBlockDisplay } from '@/blocks/blocks/onedrive.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { OneDriveResponse } from '@/tools/onedrive/types' import { normalizeExcelValuesForToolParams } from '@/tools/onedrive/utils' @@ -10,17 +11,8 @@ import { normalizeExcelValuesForToolParams } from '@/tools/onedrive/utils' const logger = createLogger('OneDriveBlock') export const OneDriveBlock: BlockConfig = { - type: 'onedrive', - name: 'OneDrive', - description: 'Create, upload, download, list, and delete files', + ...OneDriveBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate OneDrive into the workflow. Can create text and Excel files, upload files, download files, list files, and delete files or folders.', - docsLink: 'https://docs.sim.ai/integrations/onedrive', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: MicrosoftOneDriveIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/onepassword.display.ts b/apps/sim/blocks/blocks/onepassword.display.ts new file mode 100644 index 00000000000..f5531fd60ac --- /dev/null +++ b/apps/sim/blocks/blocks/onepassword.display.ts @@ -0,0 +1,16 @@ +import { OnePasswordIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const OnePasswordBlockDisplay = { + type: 'onepassword', + name: '1Password', + description: 'Manage secrets and items in 1Password vaults', + category: 'tools', + bgColor: '#FFFFFF', + icon: OnePasswordIcon, + longDescription: + 'Access and manage secrets stored in 1Password vaults using the Connect API or Service Account SDK. List vaults, retrieve items with their fields and secrets, create new items, update existing ones, delete items, and resolve secret references.', + docsLink: 'https://docs.sim.ai/integrations/onepassword', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/onepassword.ts b/apps/sim/blocks/blocks/onepassword.ts index c5e9b61271d..dd814de8b11 100644 --- a/apps/sim/blocks/blocks/onepassword.ts +++ b/apps/sim/blocks/blocks/onepassword.ts @@ -1,17 +1,9 @@ import { OnePasswordIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { OnePasswordBlockDisplay } from '@/blocks/blocks/onepassword.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' export const OnePasswordBlock: BlockConfig = { - type: 'onepassword', - name: '1Password', - description: 'Manage secrets and items in 1Password vaults', - longDescription: - 'Access and manage secrets stored in 1Password vaults using the Connect API or Service Account SDK. List vaults, retrieve items with their fields and secrets, create new items, update existing ones, delete items, and resolve secret references.', - docsLink: 'https://docs.sim.ai/integrations/onepassword', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#FFFFFF', - icon: OnePasswordIcon, + ...OnePasswordBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/openai.display.ts b/apps/sim/blocks/blocks/openai.display.ts new file mode 100644 index 00000000000..8b3a278e7c3 --- /dev/null +++ b/apps/sim/blocks/blocks/openai.display.ts @@ -0,0 +1,15 @@ +import { OpenAIIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const OpenAIBlockDisplay = { + type: 'openai', + name: 'Embeddings', + description: 'Generate Open AI embeddings', + category: 'tools', + bgColor: '#000000', + icon: OpenAIIcon, + longDescription: 'Integrate Embeddings into the workflow. Can generate embeddings from text.', + docsLink: 'https://docs.sim.ai/integrations/openai', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/openai.ts b/apps/sim/blocks/blocks/openai.ts index 983130773a9..bd63287ca63 100644 --- a/apps/sim/blocks/blocks/openai.ts +++ b/apps/sim/blocks/blocks/openai.ts @@ -1,18 +1,11 @@ import { OpenAIIcon } from '@/components/icons' +import { OpenAIBlockDisplay } from '@/blocks/blocks/openai.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const OpenAIBlock: BlockConfig = { - type: 'openai', - name: 'Embeddings', - description: 'Generate Open AI embeddings', + ...OpenAIBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Embeddings into the workflow. Can generate embeddings from text.', - category: 'tools', - integrationType: IntegrationType.AI, - docsLink: 'https://docs.sim.ai/integrations/openai', - bgColor: '#000000', - icon: OpenAIIcon, subBlocks: [ { id: 'input', diff --git a/apps/sim/blocks/blocks/outlook.display.ts b/apps/sim/blocks/blocks/outlook.display.ts new file mode 100644 index 00000000000..65ccddca500 --- /dev/null +++ b/apps/sim/blocks/blocks/outlook.display.ts @@ -0,0 +1,17 @@ +import { OutlookIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const OutlookBlockDisplay = { + type: 'outlook', + name: 'Outlook', + description: 'Send, read, draft, forward, and move Outlook email messages', + category: 'tools', + bgColor: '#FFFFFF', + icon: OutlookIcon, + longDescription: + 'Integrate Outlook into the workflow. Can read, draft, send, forward, and move email messages. Can be used in trigger mode to trigger a workflow when a new email is received.', + docsLink: 'https://docs.sim.ai/integrations/outlook', + integrationType: IntegrationType.Email, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/outlook.ts b/apps/sim/blocks/blocks/outlook.ts index 1426ce4fe01..120fd98d81a 100644 --- a/apps/sim/blocks/blocks/outlook.ts +++ b/apps/sim/blocks/blocks/outlook.ts @@ -1,24 +1,15 @@ import { OutlookIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { OutlookBlockDisplay } from '@/blocks/blocks/outlook.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { OutlookResponse } from '@/tools/outlook/types' import { getTrigger } from '@/triggers' export const OutlookBlock: BlockConfig = { - type: 'outlook', - name: 'Outlook', - description: 'Send, read, draft, forward, and move Outlook email messages', + ...OutlookBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Outlook into the workflow. Can read, draft, send, forward, and move email messages. Can be used in trigger mode to trigger a workflow when a new email is received.', - docsLink: 'https://docs.sim.ai/integrations/outlook', - category: 'tools', - integrationType: IntegrationType.Email, - triggerAllowed: true, - bgColor: '#FFFFFF', - icon: OutlookIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/pagerduty.display.ts b/apps/sim/blocks/blocks/pagerduty.display.ts new file mode 100644 index 00000000000..8e21c8edbc7 --- /dev/null +++ b/apps/sim/blocks/blocks/pagerduty.display.ts @@ -0,0 +1,18 @@ +import { PagerDutyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PagerDutyBlockDisplay = { + type: 'pagerduty', + name: 'PagerDuty', + description: 'Manage incidents and on-call schedules with PagerDuty', + category: 'tools', + bgColor: '#06AC38', + icon: PagerDutyIcon, + iconColor: '#06AC38', + longDescription: + 'Integrate PagerDuty into your workflow to list, create, and update incidents, add notes, list services, and check on-call schedules.', + docsLink: 'https://docs.sim.ai/integrations/pagerduty', + integrationType: IntegrationType.Observability, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/pagerduty.ts b/apps/sim/blocks/blocks/pagerduty.ts index 2ed88a7b96c..1c07505dfda 100644 --- a/apps/sim/blocks/blocks/pagerduty.ts +++ b/apps/sim/blocks/blocks/pagerduty.ts @@ -1,20 +1,10 @@ import { PagerDutyIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { PagerDutyBlockDisplay } from '@/blocks/blocks/pagerduty.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import { getTrigger } from '@/triggers' export const PagerDutyBlock: BlockConfig = { - type: 'pagerduty', - name: 'PagerDuty', - description: 'Manage incidents and on-call schedules with PagerDuty', - triggerAllowed: true, - longDescription: - 'Integrate PagerDuty into your workflow to list, create, and update incidents, add notes, list services, and check on-call schedules.', - docsLink: 'https://docs.sim.ai/integrations/pagerduty', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#06AC38', - iconColor: '#06AC38', - icon: PagerDutyIcon, + ...PagerDutyBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/parallel.display.ts b/apps/sim/blocks/blocks/parallel.display.ts new file mode 100644 index 00000000000..b56525a26c6 --- /dev/null +++ b/apps/sim/blocks/blocks/parallel.display.ts @@ -0,0 +1,16 @@ +import { ParallelIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ParallelBlockDisplay = { + type: 'parallel_ai', + name: 'Parallel AI', + description: 'Web research with Parallel AI', + category: 'tools', + bgColor: '#1D1C1A', + icon: ParallelIcon, + longDescription: + 'Integrate Parallel AI into the workflow. Can search the web, extract information from URLs, and conduct deep research.', + docsLink: 'https://docs.sim.ai/integrations/parallel_ai', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/parallel.ts b/apps/sim/blocks/blocks/parallel.ts index f9a370bbfe4..b3416ad20a1 100644 --- a/apps/sim/blocks/blocks/parallel.ts +++ b/apps/sim/blocks/blocks/parallel.ts @@ -1,19 +1,11 @@ import { ParallelIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ParallelBlockDisplay } from '@/blocks/blocks/parallel.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' export const ParallelBlock: BlockConfig = { - type: 'parallel_ai', - name: 'Parallel AI', - description: 'Web research with Parallel AI', + ...ParallelBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Parallel AI into the workflow. Can search the web, extract information from URLs, and conduct deep research.', - docsLink: 'https://docs.sim.ai/integrations/parallel_ai', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#1D1C1A', - icon: ParallelIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/peopledatalabs.display.ts b/apps/sim/blocks/blocks/peopledatalabs.display.ts new file mode 100644 index 00000000000..2f6adb42939 --- /dev/null +++ b/apps/sim/blocks/blocks/peopledatalabs.display.ts @@ -0,0 +1,17 @@ +import { PeopleDataLabsIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PeopleDataLabsBlockDisplay = { + type: 'peopledatalabs', + name: 'People Data Labs', + description: 'Enrich and search people and companies', + category: 'tools', + bgColor: '#4831C3', + icon: PeopleDataLabsIcon, + iconColor: '#4831C3', + longDescription: + 'Enrich a single person or company with People Data Labs, or search the global person and company datasets with SQL or Elasticsearch DSL. Useful for sales enrichment, contact lookup, and CRM hygiene.', + docsLink: 'https://docs.sim.ai/integrations/peopledatalabs', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/peopledatalabs.ts b/apps/sim/blocks/blocks/peopledatalabs.ts index 9fdda69fcc6..b62d0fd3268 100644 --- a/apps/sim/blocks/blocks/peopledatalabs.ts +++ b/apps/sim/blocks/blocks/peopledatalabs.ts @@ -1,21 +1,12 @@ import { PeopleDataLabsIcon } from '@/components/icons' +import { PeopleDataLabsBlockDisplay } from '@/blocks/blocks/peopledatalabs.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { PdlPersonEnrichResponse } from '@/tools/peopledatalabs/types' export const PeopleDataLabsBlock: BlockConfig = { - type: 'peopledatalabs', - name: 'People Data Labs', - description: 'Enrich and search people and companies', + ...PeopleDataLabsBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Enrich a single person or company with People Data Labs, or search the global person and company datasets with SQL or Elasticsearch DSL. Useful for sales enrichment, contact lookup, and CRM hygiene.', - docsLink: 'https://docs.sim.ai/integrations/peopledatalabs', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#4831C3', - iconColor: '#4831C3', - icon: PeopleDataLabsIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/perplexity.display.ts b/apps/sim/blocks/blocks/perplexity.display.ts new file mode 100644 index 00000000000..c6f52c63024 --- /dev/null +++ b/apps/sim/blocks/blocks/perplexity.display.ts @@ -0,0 +1,17 @@ +import { PerplexityIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PerplexityBlockDisplay = { + type: 'perplexity', + name: 'Perplexity', + description: 'Use Perplexity AI for chat and search', + category: 'tools', + bgColor: '#20808D', + icon: PerplexityIcon, + iconColor: '#20808D', + longDescription: + 'Integrate Perplexity into the workflow. Can generate completions using Perplexity AI chat models or perform web searches with advanced filtering.', + docsLink: 'https://docs.sim.ai/integrations/perplexity', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/perplexity.ts b/apps/sim/blocks/blocks/perplexity.ts index 89c72e8a047..924db15eef5 100644 --- a/apps/sim/blocks/blocks/perplexity.ts +++ b/apps/sim/blocks/blocks/perplexity.ts @@ -1,22 +1,13 @@ import { PerplexityIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { PerplexityBlockDisplay } from '@/blocks/blocks/perplexity.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { PerplexityChatResponse, PerplexitySearchResponse } from '@/tools/perplexity/types' type PerplexityResponse = PerplexityChatResponse | PerplexitySearchResponse export const PerplexityBlock: BlockConfig = { - type: 'perplexity', - name: 'Perplexity', - description: 'Use Perplexity AI for chat and search', - longDescription: - 'Integrate Perplexity into the workflow. Can generate completions using Perplexity AI chat models or perform web searches with advanced filtering.', - authMode: AuthMode.ApiKey, - docsLink: 'https://docs.sim.ai/integrations/perplexity', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#20808D', // Perplexity turquoise color - iconColor: '#20808D', - icon: PerplexityIcon, + ...PerplexityBlockDisplay, + authMode: AuthMode.ApiKey, // Perplexity turquoise color subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/persona.display.ts b/apps/sim/blocks/blocks/persona.display.ts new file mode 100644 index 00000000000..5f6445006dc --- /dev/null +++ b/apps/sim/blocks/blocks/persona.display.ts @@ -0,0 +1,16 @@ +import { PersonaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PersonaBlockDisplay = { + type: 'persona', + name: 'Persona', + description: 'Verify identities with Persona', + category: 'tools', + bgColor: '#FFFFFF', + icon: PersonaIcon, + longDescription: + 'Integrate Persona identity verification into the workflow. Manage the full inquiry lifecycle (create, update, approve, decline, review, resume, expire, redact), generate one-time verification links and PDF summaries, manage accounts including CSV bulk import, run watchlist and adverse media reports, review cases, retrieve verifications and documents, and discover inquiry templates.', + docsLink: 'https://docs.sim.ai/integrations/persona', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/persona.ts b/apps/sim/blocks/blocks/persona.ts index 19094d46948..b88fa8159c3 100644 --- a/apps/sim/blocks/blocks/persona.ts +++ b/apps/sim/blocks/blocks/persona.ts @@ -1,19 +1,11 @@ import { PersonaIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { PersonaBlockDisplay } from '@/blocks/blocks/persona.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { PersonaResponse } from '@/tools/persona/types' export const PersonaBlock: BlockConfig = { - type: 'persona', - name: 'Persona', - description: 'Verify identities with Persona', - longDescription: - 'Integrate Persona identity verification into the workflow. Manage the full inquiry lifecycle (create, update, approve, decline, review, resume, expire, redact), generate one-time verification links and PDF summaries, manage accounts including CSV bulk import, run watchlist and adverse media reports, review cases, retrieve verifications and documents, and discover inquiry templates.', - docsLink: 'https://docs.sim.ai/integrations/persona', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#FFFFFF', - icon: PersonaIcon, + ...PersonaBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/pi.display.ts b/apps/sim/blocks/blocks/pi.display.ts new file mode 100644 index 00000000000..cf8dceb5411 --- /dev/null +++ b/apps/sim/blocks/blocks/pi.display.ts @@ -0,0 +1,15 @@ +import { PiIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PiBlockDisplay = { + type: 'pi', + name: 'Pi Coding Agent', + description: 'Run an autonomous coding agent on a repo', + category: 'blocks', + bgColor: '#000000', + icon: PiIcon, + longDescription: + 'The Pi Coding Agent runs the Pi harness against a real repository. In Cloud mode it spins up an isolated sandbox, clones a connected GitHub repo, edits and tests with native shell + git, and opens a pull request. In Local mode it edits files on your own machine over SSH. Both modes stream progress and reuse your models, skills, and multi-turn memory.', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/pi.ts b/apps/sim/blocks/blocks/pi.ts index f040e78ae13..307912eb959 100644 --- a/apps/sim/blocks/blocks/pi.ts +++ b/apps/sim/blocks/blocks/pi.ts @@ -1,7 +1,7 @@ -import { PiIcon } from '@/components/icons' import { getEnv, isTruthy } from '@/lib/core/config/env' +import { PiBlockDisplay } from '@/blocks/blocks/pi.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getPiModelOptions, getProviderCredentialSubBlocks, @@ -40,21 +40,13 @@ const LOCAL: { field: 'mode'; value: 'local' } = { field: 'mode', value: 'local' const MEMORY_TYPES = ['conversation', 'sliding_window', 'sliding_window_tokens'] export const PiBlock: BlockConfig = { - type: 'pi', - name: 'Pi Coding Agent', - description: 'Run an autonomous coding agent on a repo', + ...PiBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'The Pi Coding Agent runs the Pi harness against a real repository. In Cloud mode it spins up an isolated sandbox, clones a connected GitHub repo, edits and tests with native shell + git, and opens a pull request. In Local mode it edits files on your own machine over SSH. Both modes stream progress and reuse your models, skills, and multi-turn memory.', bestPractices: ` - Use Cloud mode for hands-off changes against a GitHub repo where a reviewable PR is the deliverable. - Use Local mode to edit a repo on your own machine; expose the machine on a public hostname/tunnel so Sim can reach it over SSH. - Cloud mode requires your own provider API key (BYOK); the model key is never injected as a hosted key into the sandbox. `, - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#000000', - icon: PiIcon, subBlocks: [ { id: 'mode', diff --git a/apps/sim/blocks/blocks/pinecone.display.ts b/apps/sim/blocks/blocks/pinecone.display.ts new file mode 100644 index 00000000000..011be489c36 --- /dev/null +++ b/apps/sim/blocks/blocks/pinecone.display.ts @@ -0,0 +1,16 @@ +import { PineconeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PineconeBlockDisplay = { + type: 'pinecone', + name: 'Pinecone', + description: 'Use Pinecone vector database', + category: 'tools', + bgColor: '#0D1117', + icon: PineconeIcon, + longDescription: + 'Integrate Pinecone into the workflow. Can generate embeddings, upsert text, search with text, fetch vectors, and search with vectors.', + docsLink: 'https://docs.sim.ai/integrations/pinecone', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/pinecone.ts b/apps/sim/blocks/blocks/pinecone.ts index 31007af65dd..97df02be4f9 100644 --- a/apps/sim/blocks/blocks/pinecone.ts +++ b/apps/sim/blocks/blocks/pinecone.ts @@ -1,20 +1,12 @@ import { PineconeIcon } from '@/components/icons' +import { PineconeBlockDisplay } from '@/blocks/blocks/pinecone.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { PineconeResponse } from '@/tools/pinecone/types' export const PineconeBlock: BlockConfig = { - type: 'pinecone', - name: 'Pinecone', - description: 'Use Pinecone vector database', + ...PineconeBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Pinecone into the workflow. Can generate embeddings, upsert text, search with text, fetch vectors, and search with vectors.', - docsLink: 'https://docs.sim.ai/integrations/pinecone', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#0D1117', - icon: PineconeIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/pipedrive.display.ts b/apps/sim/blocks/blocks/pipedrive.display.ts new file mode 100644 index 00000000000..0e19a033700 --- /dev/null +++ b/apps/sim/blocks/blocks/pipedrive.display.ts @@ -0,0 +1,17 @@ +import { PipedriveIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PipedriveBlockDisplay = { + type: 'pipedrive', + name: 'Pipedrive', + description: 'Interact with Pipedrive CRM', + category: 'tools', + bgColor: '#2E6936', + icon: PipedriveIcon, + iconColor: '#26A65B', + longDescription: + 'Integrate Pipedrive into your workflow. Manage deals, contacts, sales pipeline, projects, activities, files, and communications with powerful CRM capabilities.', + docsLink: 'https://docs.sim.ai/integrations/pipedrive', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/pipedrive.ts b/apps/sim/blocks/blocks/pipedrive.ts index 7be3946d0b0..4e6abed8c76 100644 --- a/apps/sim/blocks/blocks/pipedrive.ts +++ b/apps/sim/blocks/blocks/pipedrive.ts @@ -1,22 +1,13 @@ import { PipedriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { PipedriveBlockDisplay } from '@/blocks/blocks/pipedrive.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { PipedriveResponse } from '@/tools/pipedrive/types' export const PipedriveBlock: BlockConfig = { - type: 'pipedrive', - name: 'Pipedrive', - description: 'Interact with Pipedrive CRM', + ...PipedriveBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Pipedrive into your workflow. Manage deals, contacts, sales pipeline, projects, activities, files, and communications with powerful CRM capabilities.', - docsLink: 'https://docs.sim.ai/integrations/pipedrive', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#2E6936', - iconColor: '#26A65B', - icon: PipedriveIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/polymarket.display.ts b/apps/sim/blocks/blocks/polymarket.display.ts new file mode 100644 index 00000000000..4ad48d02099 --- /dev/null +++ b/apps/sim/blocks/blocks/polymarket.display.ts @@ -0,0 +1,17 @@ +import { PolymarketIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PolymarketBlockDisplay = { + type: 'polymarket', + name: 'Polymarket', + description: 'Access prediction markets data from Polymarket', + category: 'tools', + bgColor: '#4C82FB', + icon: PolymarketIcon, + iconColor: '#4C82FB', + longDescription: + 'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.', + docsLink: 'https://docs.sim.ai/integrations/polymarket', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/polymarket.ts b/apps/sim/blocks/blocks/polymarket.ts index 098eb076955..b61deb35f6e 100644 --- a/apps/sim/blocks/blocks/polymarket.ts +++ b/apps/sim/blocks/blocks/polymarket.ts @@ -1,19 +1,9 @@ import { PolymarketIcon } from '@/components/icons' +import { PolymarketBlockDisplay } from '@/blocks/blocks/polymarket.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' export const PolymarketBlock: BlockConfig = { - type: 'polymarket', - name: 'Polymarket', - description: 'Access prediction markets data from Polymarket', - longDescription: - 'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.', - docsLink: 'https://docs.sim.ai/integrations/polymarket', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#4C82FB', - iconColor: '#4C82FB', - icon: PolymarketIcon, + ...PolymarketBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/postgresql.display.ts b/apps/sim/blocks/blocks/postgresql.display.ts new file mode 100644 index 00000000000..14c445b233b --- /dev/null +++ b/apps/sim/blocks/blocks/postgresql.display.ts @@ -0,0 +1,16 @@ +import { PostgresIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PostgreSQLBlockDisplay = { + type: 'postgresql', + name: 'PostgreSQL', + description: 'Connect to PostgreSQL database', + category: 'tools', + bgColor: '#336791', + icon: PostgresIcon, + longDescription: + 'Integrate PostgreSQL into the workflow. Can query, insert, update, delete, and execute raw SQL.', + docsLink: 'https://docs.sim.ai/integrations/postgresql', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/postgresql.ts b/apps/sim/blocks/blocks/postgresql.ts index 8d9ecf79c58..7c0ddd9aea9 100644 --- a/apps/sim/blocks/blocks/postgresql.ts +++ b/apps/sim/blocks/blocks/postgresql.ts @@ -1,20 +1,10 @@ import { getErrorMessage } from '@sim/utils/errors' -import { PostgresIcon } from '@/components/icons' +import { PostgreSQLBlockDisplay } from '@/blocks/blocks/postgresql.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { PostgresResponse } from '@/tools/postgresql/types' export const PostgreSQLBlock: BlockConfig = { - type: 'postgresql', - name: 'PostgreSQL', - description: 'Connect to PostgreSQL database', - longDescription: - 'Integrate PostgreSQL into the workflow. Can query, insert, update, delete, and execute raw SQL.', - docsLink: 'https://docs.sim.ai/integrations/postgresql', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#336791', - icon: PostgresIcon, + ...PostgreSQLBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/posthog.display.ts b/apps/sim/blocks/blocks/posthog.display.ts new file mode 100644 index 00000000000..abe2c238973 --- /dev/null +++ b/apps/sim/blocks/blocks/posthog.display.ts @@ -0,0 +1,16 @@ +import { PosthogIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PostHogBlockDisplay = { + type: 'posthog', + name: 'PostHog', + description: 'Product analytics and feature management', + category: 'tools', + bgColor: '#FFFFFF', + icon: PosthogIcon, + longDescription: + 'Integrate PostHog into your workflow. Track events, manage feature flags, analyze user behavior, run experiments, create surveys, and access session recordings.', + docsLink: 'https://docs.sim.ai/integrations/posthog', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/posthog.ts b/apps/sim/blocks/blocks/posthog.ts index 42c75de04c2..5bf8adb6cd3 100644 --- a/apps/sim/blocks/blocks/posthog.ts +++ b/apps/sim/blocks/blocks/posthog.ts @@ -1,20 +1,12 @@ import { PosthogIcon } from '@/components/icons' +import { PostHogBlockDisplay } from '@/blocks/blocks/posthog.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { PostHogResponse } from '@/tools/posthog/types' export const PostHogBlock: BlockConfig = { - type: 'posthog', - name: 'PostHog', - description: 'Product analytics and feature management', + ...PostHogBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate PostHog into your workflow. Track events, manage feature flags, analyze user behavior, run experiments, create surveys, and access session recordings.', - docsLink: 'https://docs.sim.ai/integrations/posthog', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#FFFFFF', - icon: PosthogIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/profound.display.ts b/apps/sim/blocks/blocks/profound.display.ts new file mode 100644 index 00000000000..42da7f1c098 --- /dev/null +++ b/apps/sim/blocks/blocks/profound.display.ts @@ -0,0 +1,16 @@ +import { ProfoundIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ProfoundBlockDisplay = { + type: 'profound', + name: 'Profound', + description: 'AI visibility and analytics with Profound', + category: 'tools', + bgColor: '#000000', + icon: ProfoundIcon, + longDescription: + 'Track how your brand appears across AI platforms. Monitor visibility scores, sentiment, citations, bot traffic, referrals, content optimization, and prompt volumes with Profound.', + docsLink: 'https://docs.sim.ai/integrations/profound', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/profound.ts b/apps/sim/blocks/blocks/profound.ts index 1d3f3e01a09..1f0dd638ec5 100644 --- a/apps/sim/blocks/blocks/profound.ts +++ b/apps/sim/blocks/blocks/profound.ts @@ -1,6 +1,7 @@ import { ProfoundIcon } from '@/components/icons' +import { ProfoundBlockDisplay } from '@/blocks/blocks/profound.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' const CATEGORY_REPORT_OPS = [ 'visibility_report', @@ -59,16 +60,7 @@ const DIMENSION_OPS = [ const FILTER_OPS = [...ALL_REPORT_OPS, 'prompt_volume'] as const export const ProfoundBlock: BlockConfig = { - type: 'profound', - name: 'Profound', - description: 'AI visibility and analytics with Profound', - longDescription: - 'Track how your brand appears across AI platforms. Monitor visibility scores, sentiment, citations, bot traffic, referrals, content optimization, and prompt volumes with Profound.', - docsLink: 'https://docs.sim.ai/integrations/profound', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#000000', - icon: ProfoundIcon, + ...ProfoundBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/prospeo.display.ts b/apps/sim/blocks/blocks/prospeo.display.ts new file mode 100644 index 00000000000..92d63efe414 --- /dev/null +++ b/apps/sim/blocks/blocks/prospeo.display.ts @@ -0,0 +1,16 @@ +import { ProspeoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ProspeoBlockDisplay = { + type: 'prospeo', + name: 'Prospeo', + description: 'Enrich and search B2B contacts and companies', + category: 'tools', + bgColor: '#FF1A26', + icon: ProspeoIcon, + longDescription: + 'Find verified work emails and mobile numbers, enrich person and company profiles, and search a B2B database of leads and companies using 20+ filters.', + docsLink: 'https://docs.sim.ai/integrations/prospeo', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/prospeo.ts b/apps/sim/blocks/blocks/prospeo.ts index bd1b1efee40..8a30573d443 100644 --- a/apps/sim/blocks/blocks/prospeo.ts +++ b/apps/sim/blocks/blocks/prospeo.ts @@ -1,19 +1,11 @@ import { ProspeoIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ProspeoBlockDisplay } from '@/blocks/blocks/prospeo.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ProspeoResponse } from '@/tools/prospeo/types' export const ProspeoBlock: BlockConfig = { - type: 'prospeo', - name: 'Prospeo', - description: 'Enrich and search B2B contacts and companies', + ...ProspeoBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Find verified work emails and mobile numbers, enrich person and company profiles, and search a B2B database of leads and companies using 20+ filters.', - docsLink: 'https://docs.sim.ai/integrations/prospeo', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FF1A26', - icon: ProspeoIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/pulse.display.ts b/apps/sim/blocks/blocks/pulse.display.ts new file mode 100644 index 00000000000..07be9fcef25 --- /dev/null +++ b/apps/sim/blocks/blocks/pulse.display.ts @@ -0,0 +1,26 @@ +import { PulseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const PulseBlockDisplay = { + type: 'pulse', + name: 'Pulse', + description: 'Extract text from documents using Pulse OCR', + category: 'tools', + bgColor: '#FFFFFF', + icon: PulseIcon, + longDescription: + 'Integrate Pulse into the workflow. Extract text from PDF documents, images, and Office files via URL or upload.', + docsLink: 'https://docs.sim.ai/integrations/pulse', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const PulseV2BlockDisplay = { + ...PulseBlockDisplay, + type: 'pulse_v2', + name: 'Pulse', + longDescription: + 'Integrate Pulse into the workflow. Extract text from PDF documents, images, and Office files via upload or file references.', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/pulse.ts b/apps/sim/blocks/blocks/pulse.ts index f16ff5d4441..f9ca933a644 100644 --- a/apps/sim/blocks/blocks/pulse.ts +++ b/apps/sim/blocks/blocks/pulse.ts @@ -1,27 +1,12 @@ import { PulseIcon } from '@/components/icons' -import { - AuthMode, - type BlockConfig, - type BlockMeta, - IntegrationType, - type SubBlockType, -} from '@/blocks/types' +import { PulseBlockDisplay, PulseV2BlockDisplay } from '@/blocks/blocks/pulse.display' +import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { PulseParserOutput } from '@/tools/pulse/types' export const PulseBlock: BlockConfig = { - type: 'pulse', - name: 'Pulse', - description: 'Extract text from documents using Pulse OCR', - hideFromToolbar: true, + ...PulseBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Pulse into the workflow. Extract text from PDF documents, images, and Office files via URL or upload.', - docsLink: 'https://docs.sim.ai/integrations/pulse', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#FFFFFF', - icon: PulseIcon, subBlocks: [ { id: 'fileUpload', @@ -162,11 +147,7 @@ const pulseV2SubBlocks = (PulseBlock.subBlocks || []).flatMap((subBlock) => { export const PulseV2Block: BlockConfig = { ...PulseBlock, - type: 'pulse_v2', - name: 'Pulse', - hideFromToolbar: false, - longDescription: - 'Integrate Pulse into the workflow. Extract text from PDF documents, images, and Office files via upload or file references.', + ...PulseV2BlockDisplay, subBlocks: pulseV2SubBlocks, tools: { access: ['pulse_parser_v2'], diff --git a/apps/sim/blocks/blocks/qdrant.display.ts b/apps/sim/blocks/blocks/qdrant.display.ts new file mode 100644 index 00000000000..98e1e824875 --- /dev/null +++ b/apps/sim/blocks/blocks/qdrant.display.ts @@ -0,0 +1,15 @@ +import { QdrantIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const QdrantBlockDisplay = { + type: 'qdrant', + name: 'Qdrant', + description: 'Use Qdrant vector database', + category: 'tools', + bgColor: '#1A223F', + icon: QdrantIcon, + longDescription: 'Integrate Qdrant into the workflow. Can upsert, search, and fetch points.', + docsLink: 'https://qdrant.tech/documentation/', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/qdrant.ts b/apps/sim/blocks/blocks/qdrant.ts index 6b8552b769a..ff8143a3fa4 100644 --- a/apps/sim/blocks/blocks/qdrant.ts +++ b/apps/sim/blocks/blocks/qdrant.ts @@ -1,19 +1,12 @@ import { QdrantIcon } from '@/components/icons' +import { QdrantBlockDisplay } from '@/blocks/blocks/qdrant.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { QdrantResponse } from '@/tools/qdrant/types' export const QdrantBlock: BlockConfig = { - type: 'qdrant', - name: 'Qdrant', - description: 'Use Qdrant vector database', + ...QdrantBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Qdrant into the workflow. Can upsert, search, and fetch points.', - docsLink: 'https://qdrant.tech/documentation/', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#1A223F', - icon: QdrantIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/quartr.display.ts b/apps/sim/blocks/blocks/quartr.display.ts new file mode 100644 index 00000000000..3af8e97cfce --- /dev/null +++ b/apps/sim/blocks/blocks/quartr.display.ts @@ -0,0 +1,16 @@ +import { QuartrIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const QuartrBlockDisplay = { + type: 'quartr', + name: 'Quartr', + description: 'Access earnings calls, transcripts, filings, and slides', + category: 'tools', + bgColor: '#000000', + icon: QuartrIcon, + longDescription: + 'Integrate Quartr into the workflow. Look up public companies, corporate events, and event types; fetch AI-generated event summaries; list and download filings, reports, slide decks, and transcripts; and access archived audio and live event streams. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/quartr', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/quartr.ts b/apps/sim/blocks/blocks/quartr.ts index e4a7c72b8e0..996542bbff2 100644 --- a/apps/sim/blocks/blocks/quartr.ts +++ b/apps/sim/blocks/blocks/quartr.ts @@ -1,6 +1,7 @@ import { QuartrIcon } from '@/components/icons' +import { QuartrBlockDisplay } from '@/blocks/blocks/quartr.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' const ALL_LIST_OPERATIONS = [ @@ -46,17 +47,8 @@ const DATE_RANGE_LIST_OPERATIONS = [ const UPDATED_RANGE_LIST_OPERATIONS = ['list_companies', ...DATE_RANGE_LIST_OPERATIONS] export const QuartrBlock: BlockConfig = { - type: 'quartr', - name: 'Quartr', - description: 'Access earnings calls, transcripts, filings, and slides', + ...QuartrBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Quartr into the workflow. Look up public companies, corporate events, and event types; fetch AI-generated event summaries; list and download filings, reports, slide decks, and transcripts; and access archived audio and live event streams. Requires API Key.', - category: 'tools', - integrationType: IntegrationType.Analytics, - docsLink: 'https://docs.sim.ai/integrations/quartr', - bgColor: '#000000', - icon: QuartrIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/quiver.display.ts b/apps/sim/blocks/blocks/quiver.display.ts new file mode 100644 index 00000000000..d247b589f0b --- /dev/null +++ b/apps/sim/blocks/blocks/quiver.display.ts @@ -0,0 +1,16 @@ +import { QuiverIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const QuiverBlockDisplay = { + type: 'quiver', + name: 'Quiver', + description: 'Generate and vectorize SVGs', + category: 'tools', + bgColor: '#FFFFFF', + icon: QuiverIcon, + longDescription: + 'Generate SVG images from text prompts or vectorize raster images into SVGs using QuiverAI. Supports reference images, style instructions, and multiple output generation.', + docsLink: 'https://docs.sim.ai/integrations/quiver', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/quiver.ts b/apps/sim/blocks/blocks/quiver.ts index e2ce522a4d4..84476b05937 100644 --- a/apps/sim/blocks/blocks/quiver.ts +++ b/apps/sim/blocks/blocks/quiver.ts @@ -1,20 +1,12 @@ import { QuiverIcon } from '@/components/icons' +import { QuiverBlockDisplay } from '@/blocks/blocks/quiver.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { QuiverSvgResponse } from '@/tools/quiver/types' export const QuiverBlock: BlockConfig = { - type: 'quiver', - name: 'Quiver', - description: 'Generate and vectorize SVGs', - longDescription: - 'Generate SVG images from text prompts or vectorize raster images into SVGs using QuiverAI. Supports reference images, style instructions, and multiple output generation.', - docsLink: 'https://docs.sim.ai/integrations/quiver', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#FFFFFF', - icon: QuiverIcon, + ...QuiverBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/railway.display.ts b/apps/sim/blocks/blocks/railway.display.ts new file mode 100644 index 00000000000..894c80bc67c --- /dev/null +++ b/apps/sim/blocks/blocks/railway.display.ts @@ -0,0 +1,16 @@ +import { RailwayIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RailwayBlockDisplay = { + type: 'railway', + name: 'Railway', + description: 'Manage Railway projects, services, deployments, and variables', + category: 'tools', + bgColor: '#000000', + icon: RailwayIcon, + longDescription: + 'Integrate Railway into workflows to list projects, manage services and environments, monitor deployments, trigger and roll back service deployments, and manage environment variables.', + docsLink: 'https://docs.sim.ai/integrations/railway', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/railway.ts b/apps/sim/blocks/blocks/railway.ts index ba19886ad51..2f5ae367f05 100644 --- a/apps/sim/blocks/blocks/railway.ts +++ b/apps/sim/blocks/blocks/railway.ts @@ -1,19 +1,11 @@ import { RailwayIcon } from '@/components/icons' +import { RailwayBlockDisplay } from '@/blocks/blocks/railway.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RailwayResponse } from '@/tools/railway/types' export const RailwayBlock: BlockConfig = { - type: 'railway', - name: 'Railway', - description: 'Manage Railway projects, services, deployments, and variables', - longDescription: - 'Integrate Railway into workflows to list projects, manage services and environments, monitor deployments, trigger and roll back service deployments, and manage environment variables.', - docsLink: 'https://docs.sim.ai/integrations/railway', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#000000', - icon: RailwayIcon, + ...RailwayBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/rb2b.display.ts b/apps/sim/blocks/blocks/rb2b.display.ts new file mode 100644 index 00000000000..fd5fff7163d --- /dev/null +++ b/apps/sim/blocks/blocks/rb2b.display.ts @@ -0,0 +1,16 @@ +import { RB2BIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RB2BBlockDisplay = { + type: 'rb2b', + name: 'RB2B', + description: 'Identify and enrich website visitors', + category: 'tools', + bgColor: '#51FF00', + icon: RB2BIcon, + longDescription: + 'Resolve IP addresses, hashed emails, and LinkedIn profiles into person-level identity and B2B enrichment data using the RB2B API. Convert IPs to hashed emails, MAIDs, and company domains; enrich emails into LinkedIn profiles, business profiles, and mobile IDs; and look up emails or phone numbers from LinkedIn. Requires an RB2B API key.', + docsLink: 'https://docs.sim.ai/integrations/rb2b', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/rb2b.ts b/apps/sim/blocks/blocks/rb2b.ts index ead406dab74..7cf9695d811 100644 --- a/apps/sim/blocks/blocks/rb2b.ts +++ b/apps/sim/blocks/blocks/rb2b.ts @@ -1,6 +1,7 @@ import { RB2BIcon } from '@/components/icons' +import { RB2BBlockDisplay } from '@/blocks/blocks/rb2b.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { Rb2bResponse } from '@/tools/rb2b/types' const EMAIL_OPERATIONS = [ @@ -21,17 +22,8 @@ const LINKEDIN_OPERATIONS = [ const IP_OPERATIONS = ['ip_to_hem', 'ip_to_maid', 'ip_to_company'] export const RB2BBlock: BlockConfig = { - type: 'rb2b', - name: 'RB2B', - description: 'Identify and enrich website visitors', + ...RB2BBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Resolve IP addresses, hashed emails, and LinkedIn profiles into person-level identity and B2B enrichment data using the RB2B API. Convert IPs to hashed emails, MAIDs, and company domains; enrich emails into LinkedIn profiles, business profiles, and mobile IDs; and look up emails or phone numbers from LinkedIn. Requires an RB2B API key.', - category: 'tools', - integrationType: IntegrationType.Sales, - docsLink: 'https://docs.sim.ai/integrations/rb2b', - bgColor: '#51FF00', - icon: RB2BIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/rds.display.ts b/apps/sim/blocks/blocks/rds.display.ts new file mode 100644 index 00000000000..0699c9e915f --- /dev/null +++ b/apps/sim/blocks/blocks/rds.display.ts @@ -0,0 +1,17 @@ +import { RDSIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RDSBlockDisplay = { + type: 'rds', + name: 'Amazon RDS', + description: 'Connect to Amazon RDS via Data API', + category: 'tools', + bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', + icon: RDSIcon, + iconColor: '#527FFF', + longDescription: + 'Integrate Amazon RDS Aurora Serverless into the workflow using the Data API. Can query, insert, update, delete, and execute raw SQL without managing database connections.', + docsLink: 'https://docs.sim.ai/integrations/rds', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/rds.ts b/apps/sim/blocks/blocks/rds.ts index 484e8e28132..738a7f27ea3 100644 --- a/apps/sim/blocks/blocks/rds.ts +++ b/apps/sim/blocks/blocks/rds.ts @@ -1,21 +1,11 @@ import { getErrorMessage } from '@sim/utils/errors' import { RDSIcon } from '@/components/icons' +import { RDSBlockDisplay } from '@/blocks/blocks/rds.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { RdsIntrospectResponse, RdsResponse } from '@/tools/rds/types' export const RDSBlock: BlockConfig = { - type: 'rds', - name: 'Amazon RDS', - description: 'Connect to Amazon RDS via Data API', - longDescription: - 'Integrate Amazon RDS Aurora Serverless into the workflow using the Data API. Can query, insert, update, delete, and execute raw SQL without managing database connections.', - docsLink: 'https://docs.sim.ai/integrations/rds', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', - iconColor: '#527FFF', - icon: RDSIcon, + ...RDSBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/reddit.display.ts b/apps/sim/blocks/blocks/reddit.display.ts new file mode 100644 index 00000000000..0199fd75b30 --- /dev/null +++ b/apps/sim/blocks/blocks/reddit.display.ts @@ -0,0 +1,17 @@ +import { RedditIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RedditBlockDisplay = { + type: 'reddit', + name: 'Reddit', + description: 'Access Reddit data and content', + category: 'tools', + bgColor: '#FF5700', + icon: RedditIcon, + iconColor: '#FF5700', + longDescription: + 'Integrate Reddit into workflows. Read posts, comments, and search content. Submit posts, vote, reply, edit, manage messages, and access user and subreddit info.', + docsLink: 'https://docs.sim.ai/integrations/reddit', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/reddit.ts b/apps/sim/blocks/blocks/reddit.ts index 5431fc351ac..58f4eb894a9 100644 --- a/apps/sim/blocks/blocks/reddit.ts +++ b/apps/sim/blocks/blocks/reddit.ts @@ -1,22 +1,13 @@ import { RedditIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { RedditBlockDisplay } from '@/blocks/blocks/reddit.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RedditResponse } from '@/tools/reddit/types' export const RedditBlock: BlockConfig = { - type: 'reddit', - name: 'Reddit', - description: 'Access Reddit data and content', + ...RedditBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Reddit into workflows. Read posts, comments, and search content. Submit posts, vote, reply, edit, manage messages, and access user and subreddit info.', - docsLink: 'https://docs.sim.ai/integrations/reddit', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#FF5700', - iconColor: '#FF5700', - icon: RedditIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/redis.display.ts b/apps/sim/blocks/blocks/redis.display.ts new file mode 100644 index 00000000000..f53b6a78c62 --- /dev/null +++ b/apps/sim/blocks/blocks/redis.display.ts @@ -0,0 +1,17 @@ +import { RedisIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RedisBlockDisplay = { + type: 'redis', + name: 'Redis', + description: 'Key-value operations with Redis', + category: 'tools', + bgColor: '#FF4438', + icon: RedisIcon, + iconColor: '#FF4438', + longDescription: + 'Connect to any Redis instance to perform key-value, hash, list, and utility operations via a direct connection.', + docsLink: 'https://docs.sim.ai/integrations/redis', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/redis.ts b/apps/sim/blocks/blocks/redis.ts index 65557092324..251cc6ab02e 100644 --- a/apps/sim/blocks/blocks/redis.ts +++ b/apps/sim/blocks/blocks/redis.ts @@ -1,6 +1,7 @@ import { RedisIcon } from '@/components/icons' +import { RedisBlockDisplay } from '@/blocks/blocks/redis.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RedisCommandResponse, RedisDeleteResponse, @@ -74,18 +75,8 @@ const KEY_OPERATIONS = [ ] as const export const RedisBlock: BlockConfig = { - type: 'redis', - name: 'Redis', - description: 'Key-value operations with Redis', - longDescription: - 'Connect to any Redis instance to perform key-value, hash, list, and utility operations via a direct connection.', - docsLink: 'https://docs.sim.ai/integrations/redis', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#FF4438', - iconColor: '#FF4438', + ...RedisBlockDisplay, authMode: AuthMode.ApiKey, - icon: RedisIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/reducto.display.ts b/apps/sim/blocks/blocks/reducto.display.ts new file mode 100644 index 00000000000..830c0b24a35 --- /dev/null +++ b/apps/sim/blocks/blocks/reducto.display.ts @@ -0,0 +1,24 @@ +import { ReductoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ReductoBlockDisplay = { + type: 'reducto', + name: 'Reducto', + description: 'Extract text from PDF documents', + category: 'tools', + bgColor: '#5c0c5c', + icon: ReductoIcon, + longDescription: `Integrate Reducto Parse into the workflow. Can extract text from uploaded PDF documents, or from a URL.`, + docsLink: 'https://docs.sim.ai/integrations/reducto', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const ReductoV2BlockDisplay = { + ...ReductoBlockDisplay, + type: 'reducto_v2', + name: 'Reducto', + longDescription: `Integrate Reducto Parse into the workflow. Can extract text from uploaded PDF documents or file references.`, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/reducto.ts b/apps/sim/blocks/blocks/reducto.ts index 521b50b5495..b553a7c9156 100644 --- a/apps/sim/blocks/blocks/reducto.ts +++ b/apps/sim/blocks/blocks/reducto.ts @@ -1,27 +1,13 @@ import { toError } from '@sim/utils/errors' import { ReductoIcon } from '@/components/icons' -import { - AuthMode, - type BlockConfig, - type BlockMeta, - IntegrationType, - type SubBlockType, -} from '@/blocks/types' +import { ReductoBlockDisplay, ReductoV2BlockDisplay } from '@/blocks/blocks/reducto.display' +import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { ReductoParserOutput } from '@/tools/reducto/types' export const ReductoBlock: BlockConfig = { - type: 'reducto', - name: 'Reducto', - description: 'Extract text from PDF documents', - hideFromToolbar: true, + ...ReductoBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: `Integrate Reducto Parse into the workflow. Can extract text from uploaded PDF documents, or from a URL.`, - docsLink: 'https://docs.sim.ai/integrations/reducto', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#5c0c5c', - icon: ReductoIcon, subBlocks: [ { id: 'fileUpload', @@ -168,10 +154,7 @@ const reductoV2SubBlocks = (ReductoBlock.subBlocks || []).flatMap((subBlock) => export const ReductoV2Block: BlockConfig = { ...ReductoBlock, - type: 'reducto_v2', - name: 'Reducto', - hideFromToolbar: false, - longDescription: `Integrate Reducto Parse into the workflow. Can extract text from uploaded PDF documents or file references.`, + ...ReductoV2BlockDisplay, subBlocks: reductoV2SubBlocks, tools: { access: ['reducto_parser_v2'], diff --git a/apps/sim/blocks/blocks/resend.display.ts b/apps/sim/blocks/blocks/resend.display.ts new file mode 100644 index 00000000000..52dd96f4b6e --- /dev/null +++ b/apps/sim/blocks/blocks/resend.display.ts @@ -0,0 +1,16 @@ +import { ResendIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ResendBlockDisplay = { + type: 'resend', + name: 'Resend', + description: 'Send emails and manage contacts with Resend.', + category: 'tools', + bgColor: '#181C1E', + icon: ResendIcon, + longDescription: + 'Integrate Resend into your workflow. Send emails, retrieve email status, manage contacts, and view domains. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/resend', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/resend.ts b/apps/sim/blocks/blocks/resend.ts index 0e1fe69f472..545a837193d 100644 --- a/apps/sim/blocks/blocks/resend.ts +++ b/apps/sim/blocks/blocks/resend.ts @@ -1,19 +1,11 @@ import { ResendIcon } from '@/components/icons' +import { ResendBlockDisplay } from '@/blocks/blocks/resend.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' export const ResendBlock: BlockConfig = { - type: 'resend', - name: 'Resend', - description: 'Send emails and manage contacts with Resend.', - longDescription: - 'Integrate Resend into your workflow. Send emails, retrieve email status, manage contacts, and view domains. Requires API Key.', - docsLink: 'https://docs.sim.ai/integrations/resend', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#181C1E', - icon: ResendIcon, + ...ResendBlockDisplay, authMode: AuthMode.ApiKey, triggers: { diff --git a/apps/sim/blocks/blocks/response.display.ts b/apps/sim/blocks/blocks/response.display.ts new file mode 100644 index 00000000000..e410057222b --- /dev/null +++ b/apps/sim/blocks/blocks/response.display.ts @@ -0,0 +1,14 @@ +import { ResponseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const ResponseBlockDisplay = { + type: 'response', + name: 'Response', + description: 'Send structured API response', + category: 'blocks', + bgColor: '#2F55FF', + icon: ResponseIcon, + longDescription: + 'Integrate Response into the workflow. Can send build or edit structured responses into a final workflow response.', + docsLink: 'https://docs.sim.ai/workflows/blocks/response', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/response.ts b/apps/sim/blocks/blocks/response.ts index 5ab6477cc45..ada102d8382 100644 --- a/apps/sim/blocks/blocks/response.ts +++ b/apps/sim/blocks/blocks/response.ts @@ -1,14 +1,9 @@ -import { ResponseIcon } from '@/components/icons' +import { ResponseBlockDisplay } from '@/blocks/blocks/response.display' import type { BlockConfig } from '@/blocks/types' import type { ResponseBlockOutput } from '@/tools/response/types' export const ResponseBlock: BlockConfig = { - type: 'response', - name: 'Response', - description: 'Send structured API response', - longDescription: - 'Integrate Response into the workflow. Can send build or edit structured responses into a final workflow response.', - docsLink: 'https://docs.sim.ai/workflows/blocks/response', + ...ResponseBlockDisplay, bestPractices: ` - Only use this if the trigger block is the API Trigger. - Prefer the builder mode over the editor mode. @@ -16,9 +11,6 @@ export const ResponseBlock: BlockConfig = { - Multiple Response blocks can be placed on different branches (e.g. after a Router or Condition). The first one to execute determines the API response and ends the workflow. - If a Response block is on a parallel branch, there are no guarantees about whether other parallel blocks will run. Avoid placing Response blocks in parallel with blocks that have important side effects. `, - category: 'blocks', - bgColor: '#2F55FF', - icon: ResponseIcon, subBlocks: [ { id: 'dataMode', diff --git a/apps/sim/blocks/blocks/revenuecat.display.ts b/apps/sim/blocks/blocks/revenuecat.display.ts new file mode 100644 index 00000000000..5441d3108aa --- /dev/null +++ b/apps/sim/blocks/blocks/revenuecat.display.ts @@ -0,0 +1,17 @@ +import { RevenueCatIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RevenueCatBlockDisplay = { + type: 'revenuecat', + name: 'RevenueCat', + description: 'Manage in-app subscriptions and entitlements', + category: 'tools', + bgColor: '#F25A5A', + icon: RevenueCatIcon, + iconColor: '#F25A5A', + longDescription: + 'Integrate RevenueCat into the workflow. Manage subscribers, entitlements, offerings, and Google Play subscriptions. Retrieve customer subscription status, grant or revoke promotional entitlements, record purchases, update subscriber attributes, and manage Google Play subscription billing.', + docsLink: 'https://docs.sim.ai/integrations/revenuecat', + integrationType: IntegrationType.Commerce, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/revenuecat.ts b/apps/sim/blocks/blocks/revenuecat.ts index a8b8bd6e26e..97c2c1b6388 100644 --- a/apps/sim/blocks/blocks/revenuecat.ts +++ b/apps/sim/blocks/blocks/revenuecat.ts @@ -1,21 +1,12 @@ import { RevenueCatIcon } from '@/components/icons' +import { RevenueCatBlockDisplay } from '@/blocks/blocks/revenuecat.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RevenueCatResponse } from '@/tools/revenuecat/types' export const RevenueCatBlock: BlockConfig = { - type: 'revenuecat', - name: 'RevenueCat', - description: 'Manage in-app subscriptions and entitlements', + ...RevenueCatBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate RevenueCat into the workflow. Manage subscribers, entitlements, offerings, and Google Play subscriptions. Retrieve customer subscription status, grant or revoke promotional entitlements, record purchases, update subscriber attributes, and manage Google Play subscription billing.', - docsLink: 'https://docs.sim.ai/integrations/revenuecat', - category: 'tools', - integrationType: IntegrationType.Commerce, - bgColor: '#F25A5A', - iconColor: '#F25A5A', - icon: RevenueCatIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/rippling.display.ts b/apps/sim/blocks/blocks/rippling.display.ts new file mode 100644 index 00000000000..bfce8e95ac7 --- /dev/null +++ b/apps/sim/blocks/blocks/rippling.display.ts @@ -0,0 +1,16 @@ +import { RipplingIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RipplingBlockDisplay = { + type: 'rippling', + name: 'Rippling', + description: 'Manage workers, departments, custom objects, and company data in Rippling', + category: 'tools', + bgColor: '#502D3C', + icon: RipplingIcon, + longDescription: + 'Integrate Rippling Platform into your workflow. Manage workers, users, departments, teams, titles, work locations, business partners, supergroups, custom objects, custom apps, custom pages, custom settings, object categories, reports, and draft hires.', + docsLink: 'https://docs.sim.ai/integrations/rippling', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/rippling.ts b/apps/sim/blocks/blocks/rippling.ts index 4c092db2aeb..5099a93ef5e 100644 --- a/apps/sim/blocks/blocks/rippling.ts +++ b/apps/sim/blocks/blocks/rippling.ts @@ -1,6 +1,7 @@ import { RipplingIcon } from '@/components/icons' +import { RipplingBlockDisplay } from '@/blocks/blocks/rippling.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' /** Operations that support the filter query parameter */ const FILTER_OPS = ['list_workers', 'list_business_partners', 'list_supergroups'] as const @@ -190,16 +191,7 @@ const DATA_PASSTHROUGH_OPS = [ ] as const export const RipplingBlock: BlockConfig = { - type: 'rippling', - name: 'Rippling', - description: 'Manage workers, departments, custom objects, and company data in Rippling', - longDescription: - 'Integrate Rippling Platform into your workflow. Manage workers, users, departments, teams, titles, work locations, business partners, supergroups, custom objects, custom apps, custom pages, custom settings, object categories, reports, and draft hires.', - docsLink: 'https://docs.sim.ai/integrations/rippling', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#502D3C', - icon: RipplingIcon, + ...RipplingBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/rootly.display.ts b/apps/sim/blocks/blocks/rootly.display.ts new file mode 100644 index 00000000000..64299e8b205 --- /dev/null +++ b/apps/sim/blocks/blocks/rootly.display.ts @@ -0,0 +1,17 @@ +import { RootlyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RootlyBlockDisplay = { + type: 'rootly', + name: 'Rootly', + description: 'Manage incidents, alerts, and on-call with Rootly', + category: 'tools', + bgColor: '#6C72C8', + icon: RootlyIcon, + iconColor: '#6C72C8', + longDescription: + 'Integrate Rootly incident management into workflows. Create and manage incidents, alerts, services, severities, and retrospectives.', + docsLink: 'https://docs.sim.ai/integrations/rootly', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/rootly.ts b/apps/sim/blocks/blocks/rootly.ts index 86f562fddf4..340b8e5c9b1 100644 --- a/apps/sim/blocks/blocks/rootly.ts +++ b/apps/sim/blocks/blocks/rootly.ts @@ -1,21 +1,12 @@ import { RootlyIcon } from '@/components/icons' +import { RootlyBlockDisplay } from '@/blocks/blocks/rootly.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { RootlyResponse } from '@/tools/rootly/types' export const RootlyBlock: BlockConfig = { - type: 'rootly', - name: 'Rootly', - description: 'Manage incidents, alerts, and on-call with Rootly', + ...RootlyBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Rootly incident management into workflows. Create and manage incidents, alerts, services, severities, and retrospectives.', - docsLink: 'https://docs.sim.ai/integrations/rootly', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#6C72C8', - iconColor: '#6C72C8', - icon: RootlyIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/router.display.ts b/apps/sim/blocks/blocks/router.display.ts new file mode 100644 index 00000000000..303e673fc05 --- /dev/null +++ b/apps/sim/blocks/blocks/router.display.ts @@ -0,0 +1,27 @@ +import { ConnectIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const RouterBlockDisplay = { + type: 'router', + name: 'Router (Legacy)', + description: 'Route workflow', + category: 'blocks', + bgColor: '#28C43F', + icon: ConnectIcon, + longDescription: + 'This is a core workflow block. Intelligently direct workflow execution to different paths based on input analysis. Use natural language to instruct the router to route to certain blocks based on the input.', + docsLink: 'https://docs.sim.ai/workflows/blocks/router', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const RouterV2BlockDisplay = { + type: 'router_v2', + name: 'Router', + description: 'Route workflow based on context', + category: 'blocks', + bgColor: '#28C43F', + icon: ConnectIcon, + longDescription: + 'Intelligently route workflow execution to different paths based on context analysis. Define multiple routes with descriptions, and an LLM will determine which route to take based on the provided context.', + docsLink: 'https://docs.sim.ai/workflows/blocks/router', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/router.ts b/apps/sim/blocks/blocks/router.ts index 16e567029d7..e30cbd8ae90 100644 --- a/apps/sim/blocks/blocks/router.ts +++ b/apps/sim/blocks/blocks/router.ts @@ -1,4 +1,4 @@ -import { ConnectIcon } from '@/components/icons' +import { RouterBlockDisplay, RouterV2BlockDisplay } from '@/blocks/blocks/router.display' import { AuthMode, type BlockConfig } from '@/blocks/types' import { getModelOptions, @@ -142,21 +142,12 @@ Respond with a JSON object containing: * Hidden from toolbar but still supported for existing workflows. */ export const RouterBlock: BlockConfig = { - type: 'router', - name: 'Router (Legacy)', - description: 'Route workflow', + ...RouterBlockDisplay, authMode: AuthMode.ApiKey, - docsLink: 'https://docs.sim.ai/workflows/blocks/router', - longDescription: - 'This is a core workflow block. Intelligently direct workflow execution to different paths based on input analysis. Use natural language to instruct the router to route to certain blocks based on the input.', bestPractices: ` - For the prompt, make it almost programmatic. Use the system prompt to define the routing criteria. Should be very specific with no ambiguity. - Use the target block *names* to define the routing criteria. - `, - category: 'blocks', - bgColor: '#28C43F', - icon: ConnectIcon, - hideFromToolbar: true, // Hide legacy version from toolbar + `, // Hide legacy version from toolbar subBlocks: [ { id: 'prompt', @@ -264,22 +255,14 @@ interface RouterV2Response extends ToolResponse { } export const RouterV2Block: BlockConfig = { - type: 'router_v2', - name: 'Router', - description: 'Route workflow based on context', + ...RouterV2BlockDisplay, authMode: AuthMode.ApiKey, - docsLink: 'https://docs.sim.ai/workflows/blocks/router', - longDescription: - 'Intelligently route workflow execution to different paths based on context analysis. Define multiple routes with descriptions, and an LLM will determine which route to take based on the provided context.', bestPractices: ` - Write clear, specific descriptions for each route - The context field should contain all relevant information for routing decisions - Route descriptions should be mutually exclusive when possible - Use descriptive route names to make the workflow readable `, - category: 'blocks', - bgColor: '#28C43F', - icon: ConnectIcon, subBlocks: [ { id: 'context', diff --git a/apps/sim/blocks/blocks/rss.display.ts b/apps/sim/blocks/blocks/rss.display.ts new file mode 100644 index 00000000000..b1c5ce0dac9 --- /dev/null +++ b/apps/sim/blocks/blocks/rss.display.ts @@ -0,0 +1,17 @@ +import { RssIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const RssBlockDisplay = { + type: 'rss', + name: 'RSS Feed', + description: 'Monitor RSS feeds and trigger workflows when new items are published', + category: 'triggers', + bgColor: '#F97316', + icon: RssIcon, + longDescription: + 'Subscribe to any RSS or Atom feed and automatically trigger your workflow when new content is published. Perfect for monitoring blogs, news sites, podcasts, and any content that publishes an RSS feed.', + docsLink: 'https://docs.sim.ai/workflows/triggers/rss', + integrationType: IntegrationType.Search, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/rss.ts b/apps/sim/blocks/blocks/rss.ts index fb9cc38fc7a..0343d760b78 100644 --- a/apps/sim/blocks/blocks/rss.ts +++ b/apps/sim/blocks/blocks/rss.ts @@ -1,22 +1,11 @@ import { BookOpen, Table } from '@/components/emcn/icons' import { RssIcon } from '@/components/icons' +import { RssBlockDisplay } from '@/blocks/blocks/rss.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { getTrigger } from '@/triggers' export const RssBlock: BlockConfig = { - type: 'rss', - name: 'RSS Feed', - description: 'Monitor RSS feeds and trigger workflows when new items are published', - longDescription: - 'Subscribe to any RSS or Atom feed and automatically trigger your workflow when new content is published. Perfect for monitoring blogs, news sites, podcasts, and any content that publishes an RSS feed.', - category: 'triggers', - integrationType: IntegrationType.Search, - bgColor: '#F97316', - icon: RssIcon, - triggerAllowed: true, - docsLink: 'https://docs.sim.ai/workflows/triggers/rss', - + ...RssBlockDisplay, subBlocks: [...getTrigger('rss_poller').subBlocks], tools: { diff --git a/apps/sim/blocks/blocks/s3.display.ts b/apps/sim/blocks/blocks/s3.display.ts new file mode 100644 index 00000000000..62db1dc769d --- /dev/null +++ b/apps/sim/blocks/blocks/s3.display.ts @@ -0,0 +1,16 @@ +import { S3Icon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const S3BlockDisplay = { + type: 's3', + name: 'S3', + description: 'Upload, download, list, and manage S3 files', + category: 'tools', + bgColor: 'linear-gradient(45deg, #1B660F 0%, #6CAE3E 100%)', + icon: S3Icon, + longDescription: + 'Integrate S3 into the workflow. Upload files, download objects, list bucket contents, delete objects, and copy objects between buckets. Requires AWS access key and secret access key.', + docsLink: 'https://docs.sim.ai/integrations/s3', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/s3.ts b/apps/sim/blocks/blocks/s3.ts index 266331ff0ea..9a9e45c6151 100644 --- a/apps/sim/blocks/blocks/s3.ts +++ b/apps/sim/blocks/blocks/s3.ts @@ -1,21 +1,13 @@ import { S3Icon } from '@/components/icons' +import { S3BlockDisplay } from '@/blocks/blocks/s3.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { S3Response } from '@/tools/s3/types' export const S3Block: BlockConfig = { - type: 's3', - name: 'S3', - description: 'Upload, download, list, and manage S3 files', + ...S3BlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate S3 into the workflow. Upload files, download objects, list bucket contents, delete objects, and copy objects between buckets. Requires AWS access key and secret access key.', - docsLink: 'https://docs.sim.ai/integrations/s3', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: 'linear-gradient(45deg, #1B660F 0%, #6CAE3E 100%)', - icon: S3Icon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/salesforce.display.ts b/apps/sim/blocks/blocks/salesforce.display.ts new file mode 100644 index 00000000000..b2899327d54 --- /dev/null +++ b/apps/sim/blocks/blocks/salesforce.display.ts @@ -0,0 +1,16 @@ +import { SalesforceIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SalesforceBlockDisplay = { + type: 'salesforce', + name: 'Salesforce', + description: 'Interact with Salesforce CRM', + category: 'tools', + bgColor: '#FFFFFF', + icon: SalesforceIcon, + longDescription: + 'Integrate Salesforce into your workflow. Manage accounts, contacts, leads, opportunities, cases, and tasks, run reports and SOQL queries, and manage org schema by creating custom fields and objects via the Tooling API.', + docsLink: 'https://docs.sim.ai/integrations/salesforce', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/salesforce.ts b/apps/sim/blocks/blocks/salesforce.ts index 100ac47cad6..b63edcd01ff 100644 --- a/apps/sim/blocks/blocks/salesforce.ts +++ b/apps/sim/blocks/blocks/salesforce.ts @@ -1,22 +1,14 @@ import { SalesforceIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { SalesforceBlockDisplay } from '@/blocks/blocks/salesforce.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { SalesforceResponse } from '@/tools/salesforce/types' import { getTrigger } from '@/triggers' export const SalesforceBlock: BlockConfig = { - type: 'salesforce', - name: 'Salesforce', - description: 'Interact with Salesforce CRM', + ...SalesforceBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Salesforce into your workflow. Manage accounts, contacts, leads, opportunities, cases, and tasks, run reports and SOQL queries, and manage org schema by creating custom fields and objects via the Tooling API.', - docsLink: 'https://docs.sim.ai/integrations/salesforce', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: SalesforceIcon, triggers: { enabled: true, available: [ diff --git a/apps/sim/blocks/blocks/sap_concur.display.ts b/apps/sim/blocks/blocks/sap_concur.display.ts new file mode 100644 index 00000000000..42a49c03ed6 --- /dev/null +++ b/apps/sim/blocks/blocks/sap_concur.display.ts @@ -0,0 +1,16 @@ +import { SapConcurIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SapConcurBlockDisplay = { + type: 'sap_concur', + name: 'SAP Concur', + description: 'Manage expense reports, travel requests, cash advances, and more in SAP Concur', + category: 'tools', + bgColor: '#FFFFFF', + icon: SapConcurIcon, + longDescription: + 'Connect SAP Concur via OAuth 2.0. Manage expense reports and line items, allocations, attendees, comments, exceptions, quick expenses, receipts, travel requests and expected expenses, cash advances, itineraries, user identities, custom lists, budgets, exchange rates, and purchase requests across every Concur datacenter.', + docsLink: 'https://docs.sim.ai/integrations/sap_concur', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sap_concur.ts b/apps/sim/blocks/blocks/sap_concur.ts index ef7d640b124..bedbd8242f1 100644 --- a/apps/sim/blocks/blocks/sap_concur.ts +++ b/apps/sim/blocks/blocks/sap_concur.ts @@ -1,6 +1,7 @@ import { SapConcurIcon } from '@/components/icons' +import { SapConcurBlockDisplay } from '@/blocks/blocks/sap_concur.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SapConcurProxyResponse, UserFileLike } from '@/tools/sap_concur/types' @@ -156,17 +157,8 @@ const BODY_OPS = [ ] export const SapConcurBlock: BlockConfig = { - type: 'sap_concur', - name: 'SAP Concur', - description: 'Manage expense reports, travel requests, cash advances, and more in SAP Concur', + ...SapConcurBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Connect SAP Concur via OAuth 2.0. Manage expense reports and line items, allocations, attendees, comments, exceptions, quick expenses, receipts, travel requests and expected expenses, cash advances, itineraries, user identities, custom lists, budgets, exchange rates, and purchase requests across every Concur datacenter.', - docsLink: 'https://docs.sim.ai/integrations/sap_concur', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#FFFFFF', - icon: SapConcurIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sap_s4hana.display.ts b/apps/sim/blocks/blocks/sap_s4hana.display.ts new file mode 100644 index 00000000000..097db3065d6 --- /dev/null +++ b/apps/sim/blocks/blocks/sap_s4hana.display.ts @@ -0,0 +1,16 @@ +import { SapS4HanaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SapS4HanaBlockDisplay = { + type: 'sap_s4hana', + name: 'SAP S4HANA', + description: 'Read and write SAP S4HANA Cloud business data via OData', + category: 'tools', + bgColor: '#FFFFFF', + icon: SapS4HanaIcon, + longDescription: + 'Connect SAP S4HANA Cloud Public Edition with per-tenant OAuth 2.0 client credentials configured in your Communication Arrangements. Read and create business partners, customers, suppliers, sales orders, deliveries (inbound/outbound), billing documents, products, stock and material documents, purchase requisitions, purchase orders, and supplier invoices, or run arbitrary OData v2 queries against any whitelisted Communication Scenario.', + docsLink: 'https://docs.sim.ai/integrations/sap_s4hana', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sap_s4hana.ts b/apps/sim/blocks/blocks/sap_s4hana.ts index 4f144f2f8e7..cfb983f6795 100644 --- a/apps/sim/blocks/blocks/sap_s4hana.ts +++ b/apps/sim/blocks/blocks/sap_s4hana.ts @@ -1,20 +1,12 @@ import { SapS4HanaIcon } from '@/components/icons' +import { SapS4HanaBlockDisplay } from '@/blocks/blocks/sap_s4hana.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { SapProxyResponse } from '@/tools/sap_s4hana/types' export const SapS4HanaBlock: BlockConfig = { - type: 'sap_s4hana', - name: 'SAP S4HANA', - description: 'Read and write SAP S4HANA Cloud business data via OData', + ...SapS4HanaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Connect SAP S4HANA Cloud Public Edition with per-tenant OAuth 2.0 client credentials configured in your Communication Arrangements. Read and create business partners, customers, suppliers, sales orders, deliveries (inbound/outbound), billing documents, products, stock and material documents, purchase requisitions, purchase orders, and supplier invoices, or run arbitrary OData v2 queries against any whitelisted Communication Scenario.', - docsLink: 'https://docs.sim.ai/integrations/sap_s4hana', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#FFFFFF', - icon: SapS4HanaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/schedule.display.ts b/apps/sim/blocks/blocks/schedule.display.ts new file mode 100644 index 00000000000..39430766982 --- /dev/null +++ b/apps/sim/blocks/blocks/schedule.display.ts @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { Clock } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const ScheduleIcon = (props: SVGProps) => createElement(Clock, props) + +export const ScheduleBlockDisplay = { + type: 'schedule', + name: 'Schedule', + description: 'Trigger workflow execution on a schedule', + category: 'triggers', + bgColor: '#6366F1', + icon: ScheduleIcon, + longDescription: + 'Integrate Schedule into the workflow. Can trigger a workflow on a schedule configuration.', + docsLink: 'https://docs.sim.ai/workflows/triggers/schedule', + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/schedule.ts b/apps/sim/blocks/blocks/schedule.ts index a65ac58792f..f2f3610df33 100644 --- a/apps/sim/blocks/blocks/schedule.ts +++ b/apps/sim/blocks/blocks/schedule.ts @@ -1,25 +1,17 @@ import type { SVGProps } from 'react' import { createElement } from 'react' import { Clock } from 'lucide-react' +import { ScheduleBlockDisplay } from '@/blocks/blocks/schedule.display' import type { BlockConfig } from '@/blocks/types' const ScheduleIcon = (props: SVGProps) => createElement(Clock, props) export const ScheduleBlock: BlockConfig = { - type: 'schedule', - triggerAllowed: true, - name: 'Schedule', - description: 'Trigger workflow execution on a schedule', - docsLink: 'https://docs.sim.ai/workflows/triggers/schedule', - longDescription: - 'Integrate Schedule into the workflow. Can trigger a workflow on a schedule configuration.', + ...ScheduleBlockDisplay, bestPractices: ` - Prefer the custom cron expression input method over the other schedule configuration methods. - Clarify the timezone if the user doesn't specify it. `, - category: 'triggers', - bgColor: '#6366F1', - icon: ScheduleIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/search.display.ts b/apps/sim/blocks/blocks/search.display.ts new file mode 100644 index 00000000000..5d23ac183c4 --- /dev/null +++ b/apps/sim/blocks/blocks/search.display.ts @@ -0,0 +1,15 @@ +import { SearchIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SearchBlockDisplay = { + type: 'search', + name: 'Search', + description: 'Search the web ($0.01 per search)', + category: 'blocks', + bgColor: '#3B82F6', + icon: SearchIcon, + longDescription: 'Search the web using the Search tool. Each search costs $0.01 per query.', + docsLink: 'https://docs.sim.ai/integrations/search', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/search.ts b/apps/sim/blocks/blocks/search.ts index 93d75904f49..5d8704c1226 100644 --- a/apps/sim/blocks/blocks/search.ts +++ b/apps/sim/blocks/blocks/search.ts @@ -1,17 +1,8 @@ -import { SearchIcon } from '@/components/icons' +import { SearchBlockDisplay } from '@/blocks/blocks/search.display' import type { BlockConfig } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' export const SearchBlock: BlockConfig = { - type: 'search', - name: 'Search', - description: 'Search the web ($0.01 per search)', - longDescription: 'Search the web using the Search tool. Each search costs $0.01 per query.', - bgColor: '#3B82F6', - icon: SearchIcon, - category: 'blocks', - integrationType: IntegrationType.Search, - docsLink: 'https://docs.sim.ai/integrations/search', + ...SearchBlockDisplay, subBlocks: [ { id: 'query', diff --git a/apps/sim/blocks/blocks/secrets_manager.display.ts b/apps/sim/blocks/blocks/secrets_manager.display.ts new file mode 100644 index 00000000000..2f4a9ce75df --- /dev/null +++ b/apps/sim/blocks/blocks/secrets_manager.display.ts @@ -0,0 +1,16 @@ +import { SecretsManagerIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SecretsManagerBlockDisplay = { + type: 'secrets_manager', + name: 'AWS Secrets Manager', + description: 'Connect to AWS Secrets Manager', + category: 'tools', + bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', + icon: SecretsManagerIcon, + longDescription: + 'Integrate AWS Secrets Manager into the workflow. Can retrieve, create, update, list, and delete secrets.', + docsLink: 'https://docs.sim.ai/integrations/secrets_manager', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/secrets_manager.ts b/apps/sim/blocks/blocks/secrets_manager.ts index ccf2c4ae230..2ff71c711ef 100644 --- a/apps/sim/blocks/blocks/secrets_manager.ts +++ b/apps/sim/blocks/blocks/secrets_manager.ts @@ -1,19 +1,10 @@ import { SecretsManagerIcon } from '@/components/icons' +import { SecretsManagerBlockDisplay } from '@/blocks/blocks/secrets_manager.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { SecretsManagerBaseResponse } from '@/tools/secrets_manager/types' export const SecretsManagerBlock: BlockConfig = { - type: 'secrets_manager', - name: 'AWS Secrets Manager', - description: 'Connect to AWS Secrets Manager', - longDescription: - 'Integrate AWS Secrets Manager into the workflow. Can retrieve, create, update, list, and delete secrets.', - docsLink: 'https://docs.sim.ai/integrations/secrets_manager', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', - icon: SecretsManagerIcon, + ...SecretsManagerBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sendblue.display.ts b/apps/sim/blocks/blocks/sendblue.display.ts new file mode 100644 index 00000000000..29c0998d50e --- /dev/null +++ b/apps/sim/blocks/blocks/sendblue.display.ts @@ -0,0 +1,16 @@ +import { SendblueIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SendblueBlockDisplay = { + type: 'sendblue', + name: 'Sendblue', + description: 'Send and receive iMessage and SMS', + category: 'tools', + bgColor: '#008BFF', + icon: SendblueIcon, + longDescription: + 'Send iMessages and SMS to individuals or groups, check whether a number supports iMessage, show typing indicators, and look up message status with Sendblue. Trigger workflows on inbound messages and delivery status updates.', + docsLink: 'https://docs.sim.ai/integrations/sendblue', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sendblue.ts b/apps/sim/blocks/blocks/sendblue.ts index 3e558cae9dd..b79e85c9a28 100644 --- a/apps/sim/blocks/blocks/sendblue.ts +++ b/apps/sim/blocks/blocks/sendblue.ts @@ -1,6 +1,7 @@ import { SendblueIcon } from '@/components/icons' +import { SendblueBlockDisplay } from '@/blocks/blocks/sendblue.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' const SEND_STYLE_OPTIONS = [ @@ -21,16 +22,7 @@ const SEND_STYLE_OPTIONS = [ ] as const export const SendblueBlock: BlockConfig = { - type: 'sendblue', - name: 'Sendblue', - description: 'Send and receive iMessage and SMS', - longDescription: - 'Send iMessages and SMS to individuals or groups, check whether a number supports iMessage, show typing indicators, and look up message status with Sendblue. Trigger workflows on inbound messages and delivery status updates.', - docsLink: 'https://docs.sim.ai/integrations/sendblue', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#008BFF', - icon: SendblueIcon, + ...SendblueBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/sendgrid.display.ts b/apps/sim/blocks/blocks/sendgrid.display.ts new file mode 100644 index 00000000000..aa2c5988799 --- /dev/null +++ b/apps/sim/blocks/blocks/sendgrid.display.ts @@ -0,0 +1,16 @@ +import { SendgridIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SendGridBlockDisplay = { + type: 'sendgrid', + name: 'SendGrid', + description: 'Send emails and manage contacts, lists, and templates with SendGrid', + category: 'tools', + bgColor: '#1A82E2', + icon: SendgridIcon, + longDescription: + 'Integrate SendGrid into your workflow. Send transactional emails, manage marketing contacts and lists, and work with email templates. Supports dynamic templates, attachments, and comprehensive contact management.', + docsLink: 'https://docs.sim.ai/integrations/sendgrid', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sendgrid.ts b/apps/sim/blocks/blocks/sendgrid.ts index 9378083564d..24a42e9f431 100644 --- a/apps/sim/blocks/blocks/sendgrid.ts +++ b/apps/sim/blocks/blocks/sendgrid.ts @@ -1,21 +1,11 @@ import { SendgridIcon } from '@/components/icons' +import { SendGridBlockDisplay } from '@/blocks/blocks/sendgrid.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SendMailResult } from '@/tools/sendgrid/types' export const SendGridBlock: BlockConfig = { - type: 'sendgrid', - name: 'SendGrid', - description: 'Send emails and manage contacts, lists, and templates with SendGrid', - longDescription: - 'Integrate SendGrid into your workflow. Send transactional emails, manage marketing contacts and lists, and work with email templates. Supports dynamic templates, attachments, and comprehensive contact management.', - docsLink: 'https://docs.sim.ai/integrations/sendgrid', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#1A82E2', - icon: SendgridIcon, - + ...SendGridBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sentry.display.ts b/apps/sim/blocks/blocks/sentry.display.ts new file mode 100644 index 00000000000..1d3564b84e3 --- /dev/null +++ b/apps/sim/blocks/blocks/sentry.display.ts @@ -0,0 +1,16 @@ +import { SentryIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SentryBlockDisplay = { + type: 'sentry', + name: 'Sentry', + description: 'Manage Sentry issues, projects, events, and releases', + category: 'tools', + bgColor: '#362D59', + icon: SentryIcon, + longDescription: + 'Integrate Sentry into the workflow. Monitor issues, manage projects, track events, and coordinate releases across your applications.', + docsLink: 'https://docs.sim.ai/integrations/sentry', + integrationType: IntegrationType.Observability, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sentry.ts b/apps/sim/blocks/blocks/sentry.ts index 2fb97925ce1..ad51ba3dcc9 100644 --- a/apps/sim/blocks/blocks/sentry.ts +++ b/apps/sim/blocks/blocks/sentry.ts @@ -1,21 +1,13 @@ import { Bug } from '@/components/emcn/icons' import { SentryIcon } from '@/components/icons' +import { SentryBlockDisplay } from '@/blocks/blocks/sentry.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { SentryResponse } from '@/tools/sentry/types' export const SentryBlock: BlockConfig = { - type: 'sentry', - name: 'Sentry', - description: 'Manage Sentry issues, projects, events, and releases', + ...SentryBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Sentry into the workflow. Monitor issues, manage projects, track events, and coordinate releases across your applications.', - docsLink: 'https://docs.sim.ai/integrations/sentry', - category: 'tools', - integrationType: IntegrationType.Observability, - bgColor: '#362D59', - icon: SentryIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/serper.display.ts b/apps/sim/blocks/blocks/serper.display.ts new file mode 100644 index 00000000000..f0c54436af4 --- /dev/null +++ b/apps/sim/blocks/blocks/serper.display.ts @@ -0,0 +1,15 @@ +import { SerperIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SerperBlockDisplay = { + type: 'serper', + name: 'Serper', + description: 'Search the web using Serper', + category: 'tools', + bgColor: '#2B3543', + icon: SerperIcon, + longDescription: 'Integrate Serper into the workflow. Can search the web.', + docsLink: 'https://docs.sim.ai/integrations/serper', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/serper.ts b/apps/sim/blocks/blocks/serper.ts index 47df4e8e12b..20dcda8b927 100644 --- a/apps/sim/blocks/blocks/serper.ts +++ b/apps/sim/blocks/blocks/serper.ts @@ -1,19 +1,12 @@ import { SerperIcon } from '@/components/icons' +import { SerperBlockDisplay } from '@/blocks/blocks/serper.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { SearchResponse } from '@/tools/serper/types' export const SerperBlock: BlockConfig = { - type: 'serper', - name: 'Serper', - description: 'Search the web using Serper', + ...SerperBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Serper into the workflow. Can search the web.', - docsLink: 'https://docs.sim.ai/integrations/serper', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#2B3543', - icon: SerperIcon, subBlocks: [ { id: 'query', diff --git a/apps/sim/blocks/blocks/servicenow.display.ts b/apps/sim/blocks/blocks/servicenow.display.ts new file mode 100644 index 00000000000..88efbaac230 --- /dev/null +++ b/apps/sim/blocks/blocks/servicenow.display.ts @@ -0,0 +1,16 @@ +import { ServiceNowIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ServiceNowBlockDisplay = { + type: 'servicenow', + name: 'ServiceNow', + description: 'Create, read, update, and delete ServiceNow records', + category: 'tools', + bgColor: '#032D42', + icon: ServiceNowIcon, + longDescription: + 'Integrate ServiceNow into your workflow. Create, read, update, and delete records in any ServiceNow table including incidents, tasks, change requests, users, and more.', + docsLink: 'https://docs.sim.ai/integrations/servicenow', + integrationType: IntegrationType.Support, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/servicenow.ts b/apps/sim/blocks/blocks/servicenow.ts index 88d510fec70..2e9d95f664f 100644 --- a/apps/sim/blocks/blocks/servicenow.ts +++ b/apps/sim/blocks/blocks/servicenow.ts @@ -1,22 +1,14 @@ import { ServiceNowIcon } from '@/components/icons' +import { ServiceNowBlockDisplay } from '@/blocks/blocks/servicenow.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ServiceNowResponse } from '@/tools/servicenow/types' import { getTrigger } from '@/triggers' export const ServiceNowBlock: BlockConfig = { - type: 'servicenow', - name: 'ServiceNow', - description: 'Create, read, update, and delete ServiceNow records', - longDescription: - 'Integrate ServiceNow into your workflow. Create, read, update, and delete records in any ServiceNow table including incidents, tasks, change requests, users, and more.', - docsLink: 'https://docs.sim.ai/integrations/servicenow', - category: 'tools', - integrationType: IntegrationType.Support, + ...ServiceNowBlockDisplay, authMode: AuthMode.ApiKey, - bgColor: '#032D42', - icon: ServiceNowIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/ses.display.ts b/apps/sim/blocks/blocks/ses.display.ts new file mode 100644 index 00000000000..6065a13176e --- /dev/null +++ b/apps/sim/blocks/blocks/ses.display.ts @@ -0,0 +1,16 @@ +import { SESIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SESBlockDisplay = { + type: 'ses', + name: 'AWS SES', + description: 'Send emails and manage templates with AWS Simple Email Service', + category: 'tools', + bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', + icon: SESIcon, + longDescription: + 'Integrate AWS SES v2 into the workflow. Send simple, templated, and bulk emails. Manage email templates and retrieve account sending quota and verified identity information.', + docsLink: 'https://docs.sim.ai/integrations/ses', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/ses.ts b/apps/sim/blocks/blocks/ses.ts index 2f7ad5ff10f..662c8ac7821 100644 --- a/apps/sim/blocks/blocks/ses.ts +++ b/apps/sim/blocks/blocks/ses.ts @@ -1,20 +1,12 @@ import { SESIcon } from '@/components/icons' +import { SESBlockDisplay } from '@/blocks/blocks/ses.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' export const SESBlock: BlockConfig = { - type: 'ses', - name: 'AWS SES', - description: 'Send emails and manage templates with AWS Simple Email Service', - longDescription: - 'Integrate AWS SES v2 into the workflow. Send simple, templated, and bulk emails. Manage email templates and retrieve account sending quota and verified identity information.', - docsLink: 'https://docs.sim.ai/integrations/ses', - category: 'tools', - integrationType: IntegrationType.Email, + ...SESBlockDisplay, authMode: AuthMode.ApiKey, - bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', - icon: SESIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sftp.display.ts b/apps/sim/blocks/blocks/sftp.display.ts new file mode 100644 index 00000000000..353def6c6c8 --- /dev/null +++ b/apps/sim/blocks/blocks/sftp.display.ts @@ -0,0 +1,16 @@ +import { SftpIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SftpBlockDisplay = { + type: 'sftp', + name: 'SFTP', + description: 'Transfer files via SFTP (SSH File Transfer Protocol)', + category: 'tools', + bgColor: '#2D3748', + icon: SftpIcon, + longDescription: + 'Upload, download, list, and manage files on remote servers via SFTP. Supports both password and private key authentication for secure file transfers.', + docsLink: 'https://docs.sim.ai/integrations/sftp', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sftp.ts b/apps/sim/blocks/blocks/sftp.ts index c80b33eb454..8b514a8380c 100644 --- a/apps/sim/blocks/blocks/sftp.ts +++ b/apps/sim/blocks/blocks/sftp.ts @@ -1,20 +1,11 @@ -import { SftpIcon } from '@/components/icons' +import { SftpBlockDisplay } from '@/blocks/blocks/sftp.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SftpUploadResult } from '@/tools/sftp/types' export const SftpBlock: BlockConfig = { - type: 'sftp', - name: 'SFTP', - description: 'Transfer files via SFTP (SSH File Transfer Protocol)', - longDescription: - 'Upload, download, list, and manage files on remote servers via SFTP. Supports both password and private key authentication for secure file transfers.', - docsLink: 'https://docs.sim.ai/integrations/sftp', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#2D3748', - icon: SftpIcon, + ...SftpBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/sharepoint.display.ts b/apps/sim/blocks/blocks/sharepoint.display.ts new file mode 100644 index 00000000000..7ee699c2eab --- /dev/null +++ b/apps/sim/blocks/blocks/sharepoint.display.ts @@ -0,0 +1,24 @@ +import { MicrosoftSharepointIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SharepointBlockDisplay = { + type: 'sharepoint', + name: 'Sharepoint', + description: 'Work with pages and lists', + category: 'tools', + bgColor: '#FFFFFF', + icon: MicrosoftSharepointIcon, + longDescription: + 'Integrate SharePoint into the workflow. Read/create pages, list sites, and work with lists (read, create, update items). Requires OAuth.', + docsLink: 'https://docs.sim.ai/integrations/sharepoint', + integrationType: IntegrationType.Documents, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const SharepointV2BlockDisplay = { + ...SharepointBlockDisplay, + type: 'sharepoint_v2', + name: 'SharePoint', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sharepoint.ts b/apps/sim/blocks/blocks/sharepoint.ts index 489b45ebcee..afdfd6308c8 100644 --- a/apps/sim/blocks/blocks/sharepoint.ts +++ b/apps/sim/blocks/blocks/sharepoint.ts @@ -2,26 +2,20 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { MicrosoftSharepointIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { + SharepointBlockDisplay, + SharepointV2BlockDisplay, +} from '@/blocks/blocks/sharepoint.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SharepointResponse } from '@/tools/sharepoint/types' const logger = createLogger('SharepointBlock') export const SharepointBlock: BlockConfig = { - type: 'sharepoint', - name: 'Sharepoint', - description: 'Work with pages and lists', + ...SharepointBlockDisplay, authMode: AuthMode.OAuth, - hideFromToolbar: true, - longDescription: - 'Integrate SharePoint into the workflow. Read/create pages, list sites, and work with lists (read, create, update items). Requires OAuth.', - docsLink: 'https://docs.sim.ai/integrations/sharepoint', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#FFFFFF', - icon: MicrosoftSharepointIcon, subBlocks: [ { id: 'operation', @@ -588,9 +582,7 @@ const SHAREPOINT_V2_LIST_ITEM_OPERATIONS = [ export const SharepointV2Block: BlockConfig = { ...SharepointBlock, - type: 'sharepoint_v2', - name: 'SharePoint', - hideFromToolbar: false, + ...SharepointV2BlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/shopify.display.ts b/apps/sim/blocks/blocks/shopify.display.ts new file mode 100644 index 00000000000..954ea61291d --- /dev/null +++ b/apps/sim/blocks/blocks/shopify.display.ts @@ -0,0 +1,16 @@ +import { ShopifyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ShopifyBlockDisplay = { + type: 'shopify', + name: 'Shopify', + description: 'Manage products, orders, customers, and inventory in your Shopify store', + category: 'tools', + bgColor: '#FFFFFF', + icon: ShopifyIcon, + longDescription: + 'Integrate Shopify into your workflow. Manage products, orders, customers, and inventory. Create, read, update, and delete products. List and manage orders. Handle customer data and adjust inventory levels.', + docsLink: 'https://docs.sim.ai/integrations/shopify', + integrationType: IntegrationType.Commerce, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/shopify.ts b/apps/sim/blocks/blocks/shopify.ts index ea0fbec664c..c1d8ead2728 100644 --- a/apps/sim/blocks/blocks/shopify.ts +++ b/apps/sim/blocks/blocks/shopify.ts @@ -1,7 +1,8 @@ import { ShopifyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { ShopifyBlockDisplay } from '@/blocks/blocks/shopify.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, parseOptionalNumberInput } from '@/blocks/utils' interface ShopifyResponse { @@ -20,17 +21,8 @@ const LIST_OPERATIONS = [ ] as const export const ShopifyBlock: BlockConfig = { - type: 'shopify', - name: 'Shopify', - description: 'Manage products, orders, customers, and inventory in your Shopify store', + ...ShopifyBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Shopify into your workflow. Manage products, orders, customers, and inventory. Create, read, update, and delete products. List and manage orders. Handle customer data and adjust inventory levels.', - docsLink: 'https://docs.sim.ai/integrations/shopify', - category: 'tools', - integrationType: IntegrationType.Commerce, - icon: ShopifyIcon, - bgColor: '#FFFFFF', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sim_workspace_event.display.ts b/apps/sim/blocks/blocks/sim_workspace_event.display.ts new file mode 100644 index 00000000000..fed585d5cc2 --- /dev/null +++ b/apps/sim/blocks/blocks/sim_workspace_event.display.ts @@ -0,0 +1,14 @@ +import { SimTriggerIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const SimWorkspaceEventBlockDisplay = { + type: 'sim_workspace_event', + name: 'Sim Workspace Events', + description: + 'Run this workflow when workspace events occur: run errors or successes, deployments, and alert conditions like latency or cost spikes.', + category: 'triggers', + bgColor: '#33C482', + icon: SimTriggerIcon, + docsLink: 'https://docs.sim.ai/workflows/triggers/sim', + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sim_workspace_event.ts b/apps/sim/blocks/blocks/sim_workspace_event.ts index 0a86aa777f5..b81bebd57e0 100644 --- a/apps/sim/blocks/blocks/sim_workspace_event.ts +++ b/apps/sim/blocks/blocks/sim_workspace_event.ts @@ -1,21 +1,13 @@ -import { SimTriggerIcon } from '@/components/icons' import { SIM_WORKSPACE_EVENT_TRIGGER_ID } from '@/lib/workspace-events/constants' +import { SimWorkspaceEventBlockDisplay } from '@/blocks/blocks/sim_workspace_event.display' import type { BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const SimWorkspaceEventBlock: BlockConfig = { + ...SimWorkspaceEventBlockDisplay, // Literal (not SIM_WORKSPACE_EVENT_TRIGGER_ID) so scripts/generate-docs.ts // can scrape the type for icon-map keys; a test asserts it stays equal to // the constant. - type: 'sim_workspace_event', - name: 'Sim Workspace Events', - description: - 'Run this workflow when workspace events occur: run errors or successes, deployments, and alert conditions like latency or cost spikes.', - category: 'triggers', - icon: SimTriggerIcon, - bgColor: '#33C482', - docsLink: 'https://docs.sim.ai/workflows/triggers/sim', - triggerAllowed: true, bestPractices: ` - Events are scoped to this workspace. Pick an event type, then optionally narrow to specific workflows (empty selection watches all). - This workflow must be deployed for the trigger to fire, and it never receives events about itself. diff --git a/apps/sim/blocks/blocks/similarweb.display.ts b/apps/sim/blocks/blocks/similarweb.display.ts new file mode 100644 index 00000000000..2fab0b2bb92 --- /dev/null +++ b/apps/sim/blocks/blocks/similarweb.display.ts @@ -0,0 +1,16 @@ +import { SimilarwebIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SimilarwebBlockDisplay = { + type: 'similarweb', + name: 'Similarweb', + description: 'Website traffic and analytics data', + category: 'tools', + bgColor: '#000922', + icon: SimilarwebIcon, + longDescription: + 'Access comprehensive website analytics including traffic estimates, engagement metrics, rankings, and traffic sources using the Similarweb API.', + docsLink: 'https://developers.similarweb.com/docs/similarweb-web-traffic-api', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/similarweb.ts b/apps/sim/blocks/blocks/similarweb.ts index 535a706ca69..847ffe4b687 100644 --- a/apps/sim/blocks/blocks/similarweb.ts +++ b/apps/sim/blocks/blocks/similarweb.ts @@ -1,18 +1,10 @@ import { SimilarwebIcon } from '@/components/icons' +import { SimilarwebBlockDisplay } from '@/blocks/blocks/similarweb.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const SimilarwebBlock: BlockConfig = { - type: 'similarweb', - name: 'Similarweb', - description: 'Website traffic and analytics data', - longDescription: - 'Access comprehensive website analytics including traffic estimates, engagement metrics, rankings, and traffic sources using the Similarweb API.', - docsLink: 'https://developers.similarweb.com/docs/similarweb-web-traffic-api', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#000922', - icon: SimilarwebIcon, + ...SimilarwebBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/sixtyfour.display.ts b/apps/sim/blocks/blocks/sixtyfour.display.ts new file mode 100644 index 00000000000..4957e68ef8f --- /dev/null +++ b/apps/sim/blocks/blocks/sixtyfour.display.ts @@ -0,0 +1,16 @@ +import { SixtyfourIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SixtyfourBlockDisplay = { + type: 'sixtyfour', + name: 'Sixtyfour AI', + description: 'Enrich leads and companies with AI-powered research', + category: 'tools', + bgColor: '#000000', + icon: SixtyfourIcon, + longDescription: + 'Find emails, phone numbers, and enrich lead or company data with contact information, social profiles, and detailed research using Sixtyfour AI.', + docsLink: 'https://docs.sim.ai/integrations/sixtyfour', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sixtyfour.ts b/apps/sim/blocks/blocks/sixtyfour.ts index e0a29f15e63..f0518e03e7e 100644 --- a/apps/sim/blocks/blocks/sixtyfour.ts +++ b/apps/sim/blocks/blocks/sixtyfour.ts @@ -1,17 +1,9 @@ import { SixtyfourIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { SixtyfourBlockDisplay } from '@/blocks/blocks/sixtyfour.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' export const SixtyfourBlock: BlockConfig = { - type: 'sixtyfour', - name: 'Sixtyfour AI', - description: 'Enrich leads and companies with AI-powered research', - longDescription: - 'Find emails, phone numbers, and enrich lead or company data with contact information, social profiles, and detailed research using Sixtyfour AI.', - docsLink: 'https://docs.sim.ai/integrations/sixtyfour', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#000000', - icon: SixtyfourIcon, + ...SixtyfourBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/slack.display.ts b/apps/sim/blocks/blocks/slack.display.ts new file mode 100644 index 00000000000..7da2ceaed62 --- /dev/null +++ b/apps/sim/blocks/blocks/slack.display.ts @@ -0,0 +1,18 @@ +import { SlackIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SlackBlockDisplay = { + type: 'slack', + name: 'Slack', + description: + 'Send, update, delete messages, manage views and modals, add or remove reactions, manage canvases, get channel info and user presence in Slack', + category: 'tools', + bgColor: '#611f69', + icon: SlackIcon, + longDescription: + 'Integrate Slack into the workflow. Can send, update, and delete messages, send ephemeral messages visible only to a specific user, open/update/push modal views, publish Home tab views, create canvases, read messages, and add or remove reactions. Requires Bot Token instead of OAuth in advanced mode. Can be used in trigger mode to trigger a workflow when a message is sent to a channel.', + docsLink: 'https://docs.sim.ai/integrations/slack', + integrationType: IntegrationType.Communication, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/slack.ts b/apps/sim/blocks/blocks/slack.ts index 2a523bfa304..aee0e858832 100644 --- a/apps/sim/blocks/blocks/slack.ts +++ b/apps/sim/blocks/blocks/slack.ts @@ -1,26 +1,16 @@ import { BookOpen, ClipboardList, File, Table, Users } from '@/components/emcn/icons' import { GoogleTranslateIcon, GreptileIcon, LinearIcon, SlackIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { SlackBlockDisplay } from '@/blocks/blocks/slack.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SlackResponse } from '@/tools/slack/types' import { getTrigger } from '@/triggers' export const SlackBlock: BlockConfig = { - type: 'slack', - name: 'Slack', - description: - 'Send, update, delete messages, manage views and modals, add or remove reactions, manage canvases, get channel info and user presence in Slack', + ...SlackBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Slack into the workflow. Can send, update, and delete messages, send ephemeral messages visible only to a specific user, open/update/push modal views, publish Home tab views, create canvases, read messages, and add or remove reactions. Requires Bot Token instead of OAuth in advanced mode. Can be used in trigger mode to trigger a workflow when a message is sent to a channel.', - docsLink: 'https://docs.sim.ai/integrations/slack', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#611f69', - icon: SlackIcon, - triggerAllowed: true, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/smtp.display.ts b/apps/sim/blocks/blocks/smtp.display.ts new file mode 100644 index 00000000000..0286ec3a77c --- /dev/null +++ b/apps/sim/blocks/blocks/smtp.display.ts @@ -0,0 +1,16 @@ +import { SmtpIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SmtpBlockDisplay = { + type: 'smtp', + name: 'SMTP', + description: 'Send emails via any SMTP mail server', + category: 'tools', + bgColor: '#2D3748', + icon: SmtpIcon, + longDescription: + 'Send emails using any SMTP server (Gmail, Outlook, custom servers, etc.). Configure SMTP connection settings and send emails with full control over content, recipients, and attachments.', + docsLink: 'https://docs.sim.ai/integrations/smtp', + integrationType: IntegrationType.Email, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/smtp.ts b/apps/sim/blocks/blocks/smtp.ts index 5f42b65afef..694d39aa0ea 100644 --- a/apps/sim/blocks/blocks/smtp.ts +++ b/apps/sim/blocks/blocks/smtp.ts @@ -1,20 +1,11 @@ -import { SmtpIcon } from '@/components/icons' +import { SmtpBlockDisplay } from '@/blocks/blocks/smtp.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SmtpSendMailResult } from '@/tools/smtp/types' export const SmtpBlock: BlockConfig = { - type: 'smtp', - name: 'SMTP', - description: 'Send emails via any SMTP mail server', - longDescription: - 'Send emails using any SMTP server (Gmail, Outlook, custom servers, etc.). Configure SMTP connection settings and send emails with full control over content, recipients, and attachments.', - docsLink: 'https://docs.sim.ai/integrations/smtp', - category: 'tools', - integrationType: IntegrationType.Email, - bgColor: '#2D3748', - icon: SmtpIcon, + ...SmtpBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/sportmonks.display.ts b/apps/sim/blocks/blocks/sportmonks.display.ts new file mode 100644 index 00000000000..32f1842a134 --- /dev/null +++ b/apps/sim/blocks/blocks/sportmonks.display.ts @@ -0,0 +1,16 @@ +import { SportmonksIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SportmonksBlockDisplay = { + type: 'sportmonks', + name: 'Sportmonks', + description: 'Access Sportmonks football, motorsport, odds, and reference data', + category: 'tools', + bgColor: '#171534', + icon: SportmonksIcon, + longDescription: + 'Integrate the Sportmonks sports data APIs into the workflow from a single block. Football: fixtures, livescores, leagues, seasons, stages, rounds, teams, squads, players, coaches, referees, venues, standings, topscorers, transfers, schedules, commentaries, TV stations, rivals, expected goals (xG), and predictions. Motorsport: sessions, drivers, teams, championship standings, laps, and pitstops. Odds: pre-match and in-play odds, bookmakers, and markets. Core: continents, countries, regions, cities, types, and time zones.', + docsLink: 'https://docs.sim.ai/integrations/sportmonks', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sportmonks.ts b/apps/sim/blocks/blocks/sportmonks.ts index 4fc5f097db8..2c747718b4e 100644 --- a/apps/sim/blocks/blocks/sportmonks.ts +++ b/apps/sim/blocks/blocks/sportmonks.ts @@ -1,5 +1,6 @@ import { SportmonksIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { SportmonksBlockDisplay } from '@/blocks/blocks/sportmonks.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' const DATE_WAND_CONFIG = { enabled: true, @@ -803,16 +804,7 @@ const TYPE_ID_OPS = ['core_get_type'] const VENUE_ID_OPS = ['football_get_venue', 'motorsport_get_venue'] export const SportmonksBlock: BlockConfig = { - type: 'sportmonks', - name: 'Sportmonks', - description: 'Access Sportmonks football, motorsport, odds, and reference data', - longDescription: - 'Integrate the Sportmonks sports data APIs into the workflow from a single block. Football: fixtures, livescores, leagues, seasons, stages, rounds, teams, squads, players, coaches, referees, venues, standings, topscorers, transfers, schedules, commentaries, TV stations, rivals, expected goals (xG), and predictions. Motorsport: sessions, drivers, teams, championship standings, laps, and pitstops. Odds: pre-match and in-play odds, bookmakers, and markets. Core: continents, countries, regions, cities, types, and time zones.', - docsLink: 'https://docs.sim.ai/integrations/sportmonks', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#171534', - icon: SportmonksIcon, + ...SportmonksBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/spotify.display.ts b/apps/sim/blocks/blocks/spotify.display.ts new file mode 100644 index 00000000000..dfd27a4eded --- /dev/null +++ b/apps/sim/blocks/blocks/spotify.display.ts @@ -0,0 +1,17 @@ +import { SpotifyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SpotifyBlockDisplay = { + type: 'spotify', + name: 'Spotify', + description: 'Search music, manage playlists, control playback, and access your library', + category: 'tools', + bgColor: '#000000', + icon: SpotifyIcon, + longDescription: + 'Integrate Spotify into your workflow. Search for tracks, albums, artists, and playlists. Manage playlists, access your library, control playback, browse podcasts and audiobooks.', + docsLink: 'https://docs.sim.ai/integrations/spotify', + integrationType: IntegrationType.Communication, + hideFromToolbar: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/spotify.ts b/apps/sim/blocks/blocks/spotify.ts index f3d2b4fa74f..2605107056c 100644 --- a/apps/sim/blocks/blocks/spotify.ts +++ b/apps/sim/blocks/blocks/spotify.ts @@ -1,22 +1,13 @@ import { SpotifyIcon } from '@/components/icons' +import { SpotifyBlockDisplay } from '@/blocks/blocks/spotify.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ToolResponse } from '@/tools/types' export const SpotifyBlock: BlockConfig = { - type: 'spotify', - name: 'Spotify', - description: 'Search music, manage playlists, control playback, and access your library', + ...SpotifyBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Spotify into your workflow. Search for tracks, albums, artists, and playlists. Manage playlists, access your library, control playback, browse podcasts and audiobooks.', - docsLink: 'https://docs.sim.ai/integrations/spotify', - category: 'tools', - integrationType: IntegrationType.Communication, - hideFromToolbar: true, - bgColor: '#000000', - icon: SpotifyIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sqs.display.ts b/apps/sim/blocks/blocks/sqs.display.ts new file mode 100644 index 00000000000..46a425e3ef9 --- /dev/null +++ b/apps/sim/blocks/blocks/sqs.display.ts @@ -0,0 +1,16 @@ +import { SQSIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SQSBlockDisplay = { + type: 'sqs', + name: 'Amazon SQS', + description: 'Connect to Amazon SQS', + category: 'tools', + bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', + icon: SQSIcon, + iconColor: '#527FFF', + longDescription: 'Integrate Amazon SQS into the workflow. Can send messages to SQS queues.', + docsLink: 'https://docs.sim.ai/integrations/sqs', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sqs.ts b/apps/sim/blocks/blocks/sqs.ts index 445ba7ac593..3ac5f4657e6 100644 --- a/apps/sim/blocks/blocks/sqs.ts +++ b/apps/sim/blocks/blocks/sqs.ts @@ -1,20 +1,11 @@ import { getErrorMessage } from '@sim/utils/errors' import { SQSIcon } from '@/components/icons' +import { SQSBlockDisplay } from '@/blocks/blocks/sqs.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { SqsResponse } from '@/tools/sqs/types' export const SQSBlock: BlockConfig = { - type: 'sqs', - name: 'Amazon SQS', - description: 'Connect to Amazon SQS', - longDescription: 'Integrate Amazon SQS into the workflow. Can send messages to SQS queues.', - docsLink: 'https://docs.sim.ai/integrations/sqs', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: 'linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)', - iconColor: '#527FFF', - icon: SQSIcon, + ...SQSBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/square.display.ts b/apps/sim/blocks/blocks/square.display.ts new file mode 100644 index 00000000000..699be804b7d --- /dev/null +++ b/apps/sim/blocks/blocks/square.display.ts @@ -0,0 +1,16 @@ +import { SquareIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SquareBlockDisplay = { + type: 'square', + name: 'Square', + description: 'Process payments and manage Square commerce data', + category: 'tools', + bgColor: '#000000', + icon: SquareIcon, + longDescription: + 'Integrate Square into the workflow. Take and refund payments, manage customers, build catalog items and images, create and search orders, and issue invoices. Authenticate with a Square access token (personal access token).', + docsLink: 'https://docs.sim.ai/integrations/square', + integrationType: IntegrationType.Commerce, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/square.ts b/apps/sim/blocks/blocks/square.ts index 17d4f7c295e..96ff3fb33fc 100644 --- a/apps/sim/blocks/blocks/square.ts +++ b/apps/sim/blocks/blocks/square.ts @@ -1,21 +1,13 @@ import { SquareIcon } from '@/components/icons' +import { SquareBlockDisplay } from '@/blocks/blocks/square.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SquareResponse } from '@/tools/square/types' export const SquareBlock: BlockConfig = { - type: 'square', - name: 'Square', - description: 'Process payments and manage Square commerce data', + ...SquareBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Square into the workflow. Take and refund payments, manage customers, build catalog items and images, create and search orders, and issue invoices. Authenticate with a Square access token (personal access token).', - docsLink: 'https://docs.sim.ai/integrations/square', - category: 'tools', - integrationType: IntegrationType.Commerce, - bgColor: '#000000', - icon: SquareIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/ssh.display.ts b/apps/sim/blocks/blocks/ssh.display.ts new file mode 100644 index 00000000000..4e1fec7ddfd --- /dev/null +++ b/apps/sim/blocks/blocks/ssh.display.ts @@ -0,0 +1,16 @@ +import { SshIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SSHBlockDisplay = { + type: 'ssh', + name: 'SSH', + description: 'Connect to remote servers via SSH', + category: 'tools', + bgColor: '#000000', + icon: SshIcon, + longDescription: + 'Execute commands, transfer files, and manage remote servers via SSH. Supports password and private key authentication for secure server access.', + docsLink: 'https://docs.sim.ai/integrations/ssh', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/ssh.ts b/apps/sim/blocks/blocks/ssh.ts index 9bf5233d7ef..5eca1db00d4 100644 --- a/apps/sim/blocks/blocks/ssh.ts +++ b/apps/sim/blocks/blocks/ssh.ts @@ -1,20 +1,11 @@ -import { SshIcon } from '@/components/icons' +import { SSHBlockDisplay } from '@/blocks/blocks/ssh.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { SSHResponse } from '@/tools/ssh/types' export const SSHBlock: BlockConfig = { - type: 'ssh', - name: 'SSH', - description: 'Connect to remote servers via SSH', + ...SSHBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Execute commands, transfer files, and manage remote servers via SSH. Supports password and private key authentication for secure server access.', - docsLink: 'https://docs.sim.ai/integrations/ssh', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#000000', - icon: SshIcon, subBlocks: [ // Operation selector { diff --git a/apps/sim/blocks/blocks/stagehand.display.ts b/apps/sim/blocks/blocks/stagehand.display.ts new file mode 100644 index 00000000000..aadef21d108 --- /dev/null +++ b/apps/sim/blocks/blocks/stagehand.display.ts @@ -0,0 +1,16 @@ +import { StagehandIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const StagehandBlockDisplay = { + type: 'stagehand', + name: 'Stagehand', + description: 'Web automation and data extraction', + category: 'tools', + bgColor: '#FFC83C', + icon: StagehandIcon, + longDescription: + 'Integrate Stagehand into the workflow. Can extract structured data from webpages or run an autonomous agent to perform tasks.', + docsLink: 'https://docs.sim.ai/integrations/stagehand', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/stagehand.ts b/apps/sim/blocks/blocks/stagehand.ts index c12d0d68d0e..da8e97d1fd9 100644 --- a/apps/sim/blocks/blocks/stagehand.ts +++ b/apps/sim/blocks/blocks/stagehand.ts @@ -1,21 +1,13 @@ import { StagehandIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { StagehandBlockDisplay } from '@/blocks/blocks/stagehand.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { StagehandAgentResponse, StagehandExtractResponse } from '@/tools/stagehand/types' export type StagehandResponse = StagehandExtractResponse | StagehandAgentResponse export const StagehandBlock: BlockConfig = { - type: 'stagehand', - name: 'Stagehand', - description: 'Web automation and data extraction', + ...StagehandBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Stagehand into the workflow. Can extract structured data from webpages or run an autonomous agent to perform tasks.', - docsLink: 'https://docs.sim.ai/integrations/stagehand', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: '#FFC83C', - icon: StagehandIcon, subBlocks: [ // Operation selection { diff --git a/apps/sim/blocks/blocks/start_trigger.display.ts b/apps/sim/blocks/blocks/start_trigger.display.ts new file mode 100644 index 00000000000..44a5ddf7026 --- /dev/null +++ b/apps/sim/blocks/blocks/start_trigger.display.ts @@ -0,0 +1,16 @@ +import { StartIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const StartTriggerBlockDisplay = { + type: 'start_trigger', + name: 'Start', + description: 'Unified workflow entry point for chat, manual and API runs', + category: 'triggers', + bgColor: '#34B5FF', + icon: StartIcon, + longDescription: + 'Collect structured inputs and power manual runs, API executions, and deployed chat experiences from a single start block.', + docsLink: 'https://docs.sim.ai/workflows/triggers/start', + hideFromToolbar: false, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/start_trigger.ts b/apps/sim/blocks/blocks/start_trigger.ts index 4ade3613a58..42f5f95b2fc 100644 --- a/apps/sim/blocks/blocks/start_trigger.ts +++ b/apps/sim/blocks/blocks/start_trigger.ts @@ -1,23 +1,13 @@ -import { StartIcon } from '@/components/icons' +import { StartTriggerBlockDisplay } from '@/blocks/blocks/start_trigger.display' import type { BlockConfig } from '@/blocks/types' export const StartTriggerBlock: BlockConfig = { - type: 'start_trigger', - triggerAllowed: true, - name: 'Start', - description: 'Unified workflow entry point for chat, manual and API runs', - longDescription: - 'Collect structured inputs and power manual runs, API executions, and deployed chat experiences from a single start block.', + ...StartTriggerBlockDisplay, bestPractices: ` - The Start block always exposes "input", "conversationId", and "files" fields for chat compatibility. - Add custom input format fields to collect additional structured data. - Test manual runs by pre-filling default values inside the input format fields. `, - category: 'triggers', - bgColor: '#34B5FF', - docsLink: 'https://docs.sim.ai/workflows/triggers/start', - icon: StartIcon, - hideFromToolbar: false, subBlocks: [ { id: 'inputFormat', diff --git a/apps/sim/blocks/blocks/starter.display.ts b/apps/sim/blocks/blocks/starter.display.ts new file mode 100644 index 00000000000..ddb852eea2c --- /dev/null +++ b/apps/sim/blocks/blocks/starter.display.ts @@ -0,0 +1,13 @@ +import { StartIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const StarterBlockDisplay = { + type: 'starter', + name: 'Starter', + description: 'Start workflow', + category: 'blocks', + bgColor: '#2FB3FF', + icon: StartIcon, + longDescription: 'Initiate your workflow manually with optional structured input.', + hideFromToolbar: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/starter.ts b/apps/sim/blocks/blocks/starter.ts index 7e5395889f6..cd273a4e8a4 100644 --- a/apps/sim/blocks/blocks/starter.ts +++ b/apps/sim/blocks/blocks/starter.ts @@ -1,15 +1,8 @@ -import { StartIcon } from '@/components/icons' +import { StarterBlockDisplay } from '@/blocks/blocks/starter.display' import type { BlockConfig } from '@/blocks/types' export const StarterBlock: BlockConfig = { - type: 'starter', - name: 'Starter', - description: 'Start workflow', - longDescription: 'Initiate your workflow manually with optional structured input.', - category: 'blocks', - bgColor: '#2FB3FF', - icon: StartIcon, - hideFromToolbar: true, + ...StarterBlockDisplay, subBlocks: [ // Main trigger selector { diff --git a/apps/sim/blocks/blocks/stripe.display.ts b/apps/sim/blocks/blocks/stripe.display.ts new file mode 100644 index 00000000000..a7e4d1c48c6 --- /dev/null +++ b/apps/sim/blocks/blocks/stripe.display.ts @@ -0,0 +1,17 @@ +import { StripeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const StripeBlockDisplay = { + type: 'stripe', + name: 'Stripe', + description: 'Process payments and manage Stripe data', + category: 'tools', + bgColor: '#635BFF', + icon: StripeIcon, + iconColor: '#635BFF', + longDescription: + 'Integrates Stripe into the workflow. Manage payment intents, customers, subscriptions, invoices, charges, products, prices, and events. Can be used in trigger mode to trigger a workflow when a Stripe event occurs.', + docsLink: 'https://docs.sim.ai/integrations/stripe', + integrationType: IntegrationType.Commerce, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/stripe.ts b/apps/sim/blocks/blocks/stripe.ts index bc1eacb09c5..293f9838b83 100644 --- a/apps/sim/blocks/blocks/stripe.ts +++ b/apps/sim/blocks/blocks/stripe.ts @@ -1,22 +1,13 @@ import { GoogleSheetsIcon, StripeIcon } from '@/components/icons' +import { StripeBlockDisplay } from '@/blocks/blocks/stripe.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { StripeResponse } from '@/tools/stripe/types' import { getTrigger } from '@/triggers' export const StripeBlock: BlockConfig = { - type: 'stripe', - name: 'Stripe', - description: 'Process payments and manage Stripe data', + ...StripeBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrates Stripe into the workflow. Manage payment intents, customers, subscriptions, invoices, charges, products, prices, and events. Can be used in trigger mode to trigger a workflow when a Stripe event occurs.', - docsLink: 'https://docs.sim.ai/integrations/stripe', - category: 'tools', - integrationType: IntegrationType.Commerce, - bgColor: '#635BFF', - iconColor: '#635BFF', - icon: StripeIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/sts.display.ts b/apps/sim/blocks/blocks/sts.display.ts new file mode 100644 index 00000000000..df1e17eea63 --- /dev/null +++ b/apps/sim/blocks/blocks/sts.display.ts @@ -0,0 +1,16 @@ +import { STSIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const STSBlockDisplay = { + type: 'sts', + name: 'AWS STS', + description: 'Connect to AWS Security Token Service', + category: 'tools', + bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', + icon: STSIcon, + longDescription: + 'Integrate AWS STS into the workflow. Assume roles, get temporary credentials, verify caller identity, and look up access key information.', + docsLink: 'https://docs.sim.ai/integrations/sts', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/sts.ts b/apps/sim/blocks/blocks/sts.ts index 4ad25a9eb03..8f64edf0b98 100644 --- a/apps/sim/blocks/blocks/sts.ts +++ b/apps/sim/blocks/blocks/sts.ts @@ -1,20 +1,12 @@ import { STSIcon } from '@/components/icons' +import { STSBlockDisplay } from '@/blocks/blocks/sts.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { STSBaseResponse } from '@/tools/sts/types' export const STSBlock: BlockConfig = { - type: 'sts', - name: 'AWS STS', - description: 'Connect to AWS Security Token Service', - longDescription: - 'Integrate AWS STS into the workflow. Assume roles, get temporary credentials, verify caller identity, and look up access key information.', - docsLink: 'https://docs.sim.ai/integrations/sts', - category: 'tools', - integrationType: IntegrationType.Security, + ...STSBlockDisplay, authMode: AuthMode.ApiKey, - bgColor: 'linear-gradient(45deg, #BD0816 0%, #FF5252 100%)', - icon: STSIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/stt.display.ts b/apps/sim/blocks/blocks/stt.display.ts new file mode 100644 index 00000000000..52f101288cd --- /dev/null +++ b/apps/sim/blocks/blocks/stt.display.ts @@ -0,0 +1,24 @@ +import { STTIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SttBlockDisplay = { + type: 'stt', + name: 'Speech-to-Text', + description: 'Convert speech to text using AI', + category: 'blocks', + bgColor: '#181C1E', + icon: STTIcon, + longDescription: + 'Transcribe audio and video files to text using leading AI providers. Supports multiple languages, timestamps, and speaker diarization.', + docsLink: 'https://docs.sim.ai/integrations/stt', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const SttV2BlockDisplay = { + ...SttBlockDisplay, + type: 'stt_v2', + name: 'Speech-to-Text', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/stt.ts b/apps/sim/blocks/blocks/stt.ts index c92446598eb..3bdbdcf8f89 100644 --- a/apps/sim/blocks/blocks/stt.ts +++ b/apps/sim/blocks/blocks/stt.ts @@ -1,21 +1,11 @@ -import { STTIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' +import { SttBlockDisplay, SttV2BlockDisplay } from '@/blocks/blocks/stt.display' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { SttBlockResponse } from '@/tools/stt/types' export const SttBlock: BlockConfig = { - type: 'stt', - name: 'Speech-to-Text', - description: 'Convert speech to text using AI', - hideFromToolbar: true, + ...SttBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Transcribe audio and video files to text using leading AI providers. Supports multiple languages, timestamps, and speaker diarization.', - docsLink: 'https://docs.sim.ai/integrations/stt', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: STTIcon, subBlocks: [ // Provider selection @@ -361,9 +351,7 @@ const sttV2SubBlocks = (SttBlock.subBlocks || []).filter((subBlock) => subBlock. export const SttV2Block: BlockConfig = { ...SttBlock, - type: 'stt_v2', - name: 'Speech-to-Text', - hideFromToolbar: false, + ...SttV2BlockDisplay, subBlocks: sttV2SubBlocks, tools: { access: [ diff --git a/apps/sim/blocks/blocks/supabase.display.ts b/apps/sim/blocks/blocks/supabase.display.ts new file mode 100644 index 00000000000..736a9ff1467 --- /dev/null +++ b/apps/sim/blocks/blocks/supabase.display.ts @@ -0,0 +1,16 @@ +import { SupabaseIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const SupabaseBlockDisplay = { + type: 'supabase', + name: 'Supabase', + description: 'Use Supabase database', + category: 'tools', + bgColor: '#1C1C1C', + icon: SupabaseIcon, + longDescription: + 'Integrate Supabase into the workflow. Supports database operations (query, insert, update, delete, upsert), full-text search, RPC functions, Edge Function invocation, row counting, vector search, and complete storage management (upload, download, list, move, copy, delete files and buckets).', + docsLink: 'https://docs.sim.ai/integrations/supabase', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/supabase.ts b/apps/sim/blocks/blocks/supabase.ts index 9f0d5eac72e..18fc76be7ff 100644 --- a/apps/sim/blocks/blocks/supabase.ts +++ b/apps/sim/blocks/blocks/supabase.ts @@ -1,24 +1,16 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import { SupabaseIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { SupabaseBlockDisplay } from '@/blocks/blocks/supabase.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SupabaseResponse } from '@/tools/supabase/types' const logger = createLogger('SupabaseBlock') export const SupabaseBlock: BlockConfig = { - type: 'supabase', - name: 'Supabase', - description: 'Use Supabase database', + ...SupabaseBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Supabase into the workflow. Supports database operations (query, insert, update, delete, upsert), full-text search, RPC functions, Edge Function invocation, row counting, vector search, and complete storage management (upload, download, list, move, copy, delete files and buckets).', - docsLink: 'https://docs.sim.ai/integrations/supabase', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#1C1C1C', - icon: SupabaseIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/table.display.ts b/apps/sim/blocks/blocks/table.display.ts new file mode 100644 index 00000000000..463c44682a4 --- /dev/null +++ b/apps/sim/blocks/blocks/table.display.ts @@ -0,0 +1,14 @@ +import { TableIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const TableBlockDisplay = { + type: 'table', + name: 'Table', + description: 'User-defined data tables', + category: 'blocks', + bgColor: '#10B981', + icon: TableIcon, + longDescription: + 'Create and manage custom data tables. Store, query, and manipulate structured data within workflows.', + docsLink: 'https://docs.simstudio.ai/tools/table', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/table.ts b/apps/sim/blocks/blocks/table.ts index 281bcd077e7..a37cb1d9f2d 100644 --- a/apps/sim/blocks/blocks/table.ts +++ b/apps/sim/blocks/blocks/table.ts @@ -1,7 +1,7 @@ import { toError } from '@sim/utils/errors' -import { TableIcon } from '@/components/icons' import { TABLE_LIMITS } from '@/lib/table/constants' import { filterRulesToFilter, sortRulesToSort } from '@/lib/table/query-builder/converters' +import { TableBlockDisplay } from '@/blocks/blocks/table.display' import type { BlockConfig } from '@/blocks/types' import type { TableQueryResponse } from '@/tools/table/types' import { getTrigger } from '@/triggers' @@ -178,15 +178,7 @@ const paramTransformers: Record ParsedPara } export const TableBlock: BlockConfig = { - type: 'table', - name: 'Table', - description: 'User-defined data tables', - longDescription: - 'Create and manage custom data tables. Store, query, and manipulate structured data within workflows.', - docsLink: 'https://docs.simstudio.ai/tools/table', - category: 'blocks', - bgColor: '#10B981', - icon: TableIcon, + ...TableBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/tailscale.display.ts b/apps/sim/blocks/blocks/tailscale.display.ts new file mode 100644 index 00000000000..87a4246559a --- /dev/null +++ b/apps/sim/blocks/blocks/tailscale.display.ts @@ -0,0 +1,16 @@ +import { TailscaleIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TailscaleBlockDisplay = { + type: 'tailscale', + name: 'Tailscale', + description: 'Manage devices and network settings in your Tailscale tailnet', + category: 'tools', + bgColor: '#2E2D2D', + icon: TailscaleIcon, + longDescription: + 'Interact with the Tailscale API to manage devices, DNS, ACLs, auth keys, users, and routes across your tailnet.', + docsLink: 'https://docs.sim.ai/integrations/tailscale', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/tailscale.ts b/apps/sim/blocks/blocks/tailscale.ts index 690bb0a772e..e4219617a01 100644 --- a/apps/sim/blocks/blocks/tailscale.ts +++ b/apps/sim/blocks/blocks/tailscale.ts @@ -1,18 +1,10 @@ import { TailscaleIcon } from '@/components/icons' +import { TailscaleBlockDisplay } from '@/blocks/blocks/tailscale.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const TailscaleBlock: BlockConfig = { - type: 'tailscale', - name: 'Tailscale', - description: 'Manage devices and network settings in your Tailscale tailnet', - longDescription: - 'Interact with the Tailscale API to manage devices, DNS, ACLs, auth keys, users, and routes across your tailnet.', - docsLink: 'https://docs.sim.ai/integrations/tailscale', - category: 'tools', - integrationType: IntegrationType.Security, - bgColor: '#2E2D2D', - icon: TailscaleIcon, + ...TailscaleBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/tavily.display.ts b/apps/sim/blocks/blocks/tavily.display.ts new file mode 100644 index 00000000000..f52e700a63c --- /dev/null +++ b/apps/sim/blocks/blocks/tavily.display.ts @@ -0,0 +1,16 @@ +import { TavilyIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TavilyBlockDisplay = { + type: 'tavily', + name: 'Tavily', + description: 'Search and extract information', + category: 'tools', + bgColor: '#FFFFFF', + icon: TavilyIcon, + longDescription: + 'Integrate Tavily into the workflow. Can search the web and extract content from specific URLs. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/tavily', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/tavily.ts b/apps/sim/blocks/blocks/tavily.ts index b2dd31a9960..9f1fdd1643f 100644 --- a/apps/sim/blocks/blocks/tavily.ts +++ b/apps/sim/blocks/blocks/tavily.ts @@ -1,20 +1,12 @@ import { TavilyIcon } from '@/components/icons' +import { TavilyBlockDisplay } from '@/blocks/blocks/tavily.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { TavilyResponse } from '@/tools/tavily/types' export const TavilyBlock: BlockConfig = { - type: 'tavily', - name: 'Tavily', - description: 'Search and extract information', + ...TavilyBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Tavily into the workflow. Can search the web and extract content from specific URLs. Requires API Key.', - category: 'tools', - integrationType: IntegrationType.Search, - docsLink: 'https://docs.sim.ai/integrations/tavily', - bgColor: '#FFFFFF', - icon: TavilyIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/telegram.display.ts b/apps/sim/blocks/blocks/telegram.display.ts new file mode 100644 index 00000000000..1e39a59fcfc --- /dev/null +++ b/apps/sim/blocks/blocks/telegram.display.ts @@ -0,0 +1,17 @@ +import { TelegramIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TelegramBlockDisplay = { + type: 'telegram', + name: 'Telegram', + description: 'Interact with Telegram', + category: 'tools', + bgColor: '#FFFFFF', + icon: TelegramIcon, + longDescription: + 'Integrate Telegram into the workflow. Can send and delete messages. Can be used in trigger mode to trigger a workflow when a message is sent to a chat.', + docsLink: 'https://docs.sim.ai/integrations/telegram', + integrationType: IntegrationType.Communication, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/telegram.ts b/apps/sim/blocks/blocks/telegram.ts index 6236a93ffe9..64853f38b45 100644 --- a/apps/sim/blocks/blocks/telegram.ts +++ b/apps/sim/blocks/blocks/telegram.ts @@ -1,23 +1,14 @@ import { TelegramIcon } from '@/components/icons' +import { TelegramBlockDisplay } from '@/blocks/blocks/telegram.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { TelegramResponse } from '@/tools/telegram/types' import { getTrigger } from '@/triggers' export const TelegramBlock: BlockConfig = { - type: 'telegram', - name: 'Telegram', - description: 'Interact with Telegram', + ...TelegramBlockDisplay, authMode: AuthMode.BotToken, - longDescription: - 'Integrate Telegram into the workflow. Can send and delete messages. Can be used in trigger mode to trigger a workflow when a message is sent to a chat.', - docsLink: 'https://docs.sim.ai/integrations/telegram', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#FFFFFF', - icon: TelegramIcon, - triggerAllowed: true, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/temporal.display.ts b/apps/sim/blocks/blocks/temporal.display.ts new file mode 100644 index 00000000000..8450942c28f --- /dev/null +++ b/apps/sim/blocks/blocks/temporal.display.ts @@ -0,0 +1,16 @@ +import { TemporalIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TemporalBlockDisplay = { + type: 'temporal', + name: 'Temporal', + description: 'Start, signal, query, and manage Temporal workflow executions', + category: 'tools', + bgColor: '#141414', + icon: TemporalIcon, + longDescription: + "Connect to a Temporal cluster over the server's HTTP API to start workflow executions, send signals, run queries against workflow state, describe and list executions, fetch event histories, and cancel or terminate running workflows. API key only required for servers with authentication enabled.", + docsLink: 'https://docs.sim.ai/integrations/temporal', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/temporal.ts b/apps/sim/blocks/blocks/temporal.ts index d55bb22d95c..36d6cca14f8 100644 --- a/apps/sim/blocks/blocks/temporal.ts +++ b/apps/sim/blocks/blocks/temporal.ts @@ -1,6 +1,6 @@ import { TemporalIcon } from '@/components/icons' +import { TemporalBlockDisplay } from '@/blocks/blocks/temporal.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { TemporalResponse } from '@/tools/temporal/types' /** Coerces a subBlock value to a finite number, returning undefined for empty or non-numeric input. */ @@ -64,17 +64,7 @@ Examples: Return ONLY valid JSON - no explanations, no extra text.` export const TemporalBlock: BlockConfig = { - type: 'temporal', - name: 'Temporal', - description: 'Start, signal, query, and manage Temporal workflow executions', - longDescription: - "Connect to a Temporal cluster over the server's HTTP API to start workflow executions, send signals, run queries against workflow state, describe and list executions, fetch event histories, and cancel or terminate running workflows. API key only required for servers with authentication enabled.", - docsLink: 'https://docs.sim.ai/integrations/temporal', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#141414', - icon: TemporalIcon, - + ...TemporalBlockDisplay, subBlocks: [ // ── Operation selector ───────────────────────────────────────────────────── { diff --git a/apps/sim/blocks/blocks/textract.display.ts b/apps/sim/blocks/blocks/textract.display.ts new file mode 100644 index 00000000000..8af130386e7 --- /dev/null +++ b/apps/sim/blocks/blocks/textract.display.ts @@ -0,0 +1,24 @@ +import { TextractIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TextractBlockDisplay = { + type: 'textract', + name: 'AWS Textract', + description: 'Extract text, tables, and forms from documents', + category: 'tools', + bgColor: 'linear-gradient(135deg, #055F4E 0%, #56C0A7 100%)', + icon: TextractIcon, + iconColor: '#56C0A7', + longDescription: `Integrate AWS Textract into your workflow to extract text, tables, forms, and key-value pairs from documents. Single-page mode supports JPEG, PNG, and single-page PDF. Multi-page mode supports multi-page PDF and TIFF.`, + docsLink: 'https://docs.sim.ai/integrations/textract', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const TextractV2BlockDisplay = { + ...TextractBlockDisplay, + type: 'textract_v2', + name: 'AWS Textract', + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/textract.ts b/apps/sim/blocks/blocks/textract.ts index 9a6baa033b8..a43ae73f7a3 100644 --- a/apps/sim/blocks/blocks/textract.ts +++ b/apps/sim/blocks/blocks/textract.ts @@ -1,27 +1,12 @@ import { TextractIcon } from '@/components/icons' -import { - AuthMode, - type BlockConfig, - type BlockMeta, - IntegrationType, - type SubBlockType, -} from '@/blocks/types' +import { TextractBlockDisplay, TextractV2BlockDisplay } from '@/blocks/blocks/textract.display' +import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { TextractParserOutput } from '@/tools/textract/types' export const TextractBlock: BlockConfig = { - type: 'textract', - name: 'AWS Textract', - description: 'Extract text, tables, and forms from documents', - hideFromToolbar: true, + ...TextractBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: `Integrate AWS Textract into your workflow to extract text, tables, forms, and key-value pairs from documents. Single-page mode supports JPEG, PNG, and single-page PDF. Multi-page mode supports multi-page PDF and TIFF.`, - docsLink: 'https://docs.sim.ai/integrations/textract', - category: 'tools', - integrationType: IntegrationType.AI, - bgColor: 'linear-gradient(135deg, #055F4E 0%, #56C0A7 100%)', - iconColor: '#56C0A7', - icon: TextractIcon, subBlocks: [ { id: 'processingMode', @@ -228,9 +213,7 @@ const textractV2SubBlocks = (TextractBlock.subBlocks || []).flatMap((subBlock) = export const TextractV2Block: BlockConfig = { ...TextractBlock, - type: 'textract_v2', - name: 'AWS Textract', - hideFromToolbar: false, + ...TextractV2BlockDisplay, subBlocks: textractV2SubBlocks, tools: { access: ['textract_parser_v2'], diff --git a/apps/sim/blocks/blocks/thinking.display.ts b/apps/sim/blocks/blocks/thinking.display.ts new file mode 100644 index 00000000000..cae82cc7e4c --- /dev/null +++ b/apps/sim/blocks/blocks/thinking.display.ts @@ -0,0 +1,15 @@ +import { BrainIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const ThinkingBlockDisplay = { + type: 'thinking', + name: 'Thinking', + description: 'Forces model to outline its thought process.', + category: 'blocks', + bgColor: '#181C1E', + icon: BrainIcon, + longDescription: + 'Adds a step where the model explicitly outlines its thought process before proceeding. This can improve reasoning quality by encouraging step-by-step analysis.', + docsLink: 'https://docs.sim.ai/integrations/thinking', + hideFromToolbar: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/thinking.ts b/apps/sim/blocks/blocks/thinking.ts index 15cb485d511..dc3a54d8c52 100644 --- a/apps/sim/blocks/blocks/thinking.ts +++ b/apps/sim/blocks/blocks/thinking.ts @@ -1,19 +1,9 @@ -import { BrainIcon } from '@/components/icons' +import { ThinkingBlockDisplay } from '@/blocks/blocks/thinking.display' import type { BlockConfig } from '@/blocks/types' import type { ThinkingToolResponse } from '@/tools/thinking/types' export const ThinkingBlock: BlockConfig = { - type: 'thinking', - name: 'Thinking', - description: 'Forces model to outline its thought process.', - longDescription: - 'Adds a step where the model explicitly outlines its thought process before proceeding. This can improve reasoning quality by encouraging step-by-step analysis.', - docsLink: 'https://docs.sim.ai/integrations/thinking', - category: 'blocks', - bgColor: '#181C1E', - icon: BrainIcon, - hideFromToolbar: true, - + ...ThinkingBlockDisplay, subBlocks: [ { id: 'thought', diff --git a/apps/sim/blocks/blocks/thrive.display.ts b/apps/sim/blocks/blocks/thrive.display.ts new file mode 100644 index 00000000000..1412919a27f --- /dev/null +++ b/apps/sim/blocks/blocks/thrive.display.ts @@ -0,0 +1,16 @@ +import { ThriveIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ThriveBlockDisplay = { + type: 'thrive', + name: 'Thrive', + description: 'Manage users, audiences, learning and CPD on Thrive', + category: 'tools', + bgColor: '#FFFFFF', + icon: ThriveIcon, + longDescription: + 'Integrate Thrive Learning into the workflow. Manage user lifecycle, audiences and their members and managers, content assignments and enrolments, learning completions, content and activity records, CPD, tags, and skills.', + docsLink: 'https://docs.sim.ai/tools/thrive', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/thrive.ts b/apps/sim/blocks/blocks/thrive.ts index 3f0062e3621..5591e499be6 100644 --- a/apps/sim/blocks/blocks/thrive.ts +++ b/apps/sim/blocks/blocks/thrive.ts @@ -1,5 +1,6 @@ import { ThriveIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ThriveBlockDisplay } from '@/blocks/blocks/thrive.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' const PAGINATED_OPS = [ 'search_users', @@ -67,16 +68,7 @@ const USER_ID_REQUIRED_OPS = [ const USER_ID_OPS = [...USER_ID_REQUIRED_OPS, 'list_completions'] export const ThriveBlock: BlockConfig = { - type: 'thrive', - name: 'Thrive', - description: 'Manage users, audiences, learning and CPD on Thrive', - longDescription: - 'Integrate Thrive Learning into the workflow. Manage user lifecycle, audiences and their members and managers, content assignments and enrolments, learning completions, content and activity records, CPD, tags, and skills.', - docsLink: 'https://docs.sim.ai/tools/thrive', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#FFFFFF', - icon: ThriveIcon, + ...ThriveBlockDisplay, authMode: AuthMode.ApiKey, subBlocks: [ diff --git a/apps/sim/blocks/blocks/tinybird.display.ts b/apps/sim/blocks/blocks/tinybird.display.ts new file mode 100644 index 00000000000..7da09a6c371 --- /dev/null +++ b/apps/sim/blocks/blocks/tinybird.display.ts @@ -0,0 +1,16 @@ +import { TinybirdIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TinybirdBlockDisplay = { + type: 'tinybird', + name: 'Tinybird', + description: 'Send events, query data, and manage Data Sources with Tinybird', + category: 'tools', + bgColor: '#2EF598', + icon: TinybirdIcon, + longDescription: + 'Interact with Tinybird: stream JSON or NDJSON events with the Events API, run SQL with the Query API, call published Pipe API Endpoints by name with dynamic parameters, and manage Data Sources by appending from a URL, truncating, or deleting rows by condition.', + docsLink: 'https://docs.sim.ai/integrations/tinybird', + integrationType: IntegrationType.Analytics, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/tinybird.ts b/apps/sim/blocks/blocks/tinybird.ts index aefd038863d..58308c9f174 100644 --- a/apps/sim/blocks/blocks/tinybird.ts +++ b/apps/sim/blocks/blocks/tinybird.ts @@ -1,20 +1,12 @@ import { TinybirdIcon } from '@/components/icons' +import { TinybirdBlockDisplay } from '@/blocks/blocks/tinybird.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { TinybirdResponse } from '@/tools/tinybird/types' export const TinybirdBlock: BlockConfig = { - type: 'tinybird', - name: 'Tinybird', - description: 'Send events, query data, and manage Data Sources with Tinybird', + ...TinybirdBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Interact with Tinybird: stream JSON or NDJSON events with the Events API, run SQL with the Query API, call published Pipe API Endpoints by name with dynamic parameters, and manage Data Sources by appending from a URL, truncating, or deleting rows by condition.', - docsLink: 'https://docs.sim.ai/integrations/tinybird', - category: 'tools', - integrationType: IntegrationType.Analytics, - bgColor: '#2EF598', - icon: TinybirdIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/translate.display.ts b/apps/sim/blocks/blocks/translate.display.ts new file mode 100644 index 00000000000..b6107f749fd --- /dev/null +++ b/apps/sim/blocks/blocks/translate.display.ts @@ -0,0 +1,15 @@ +import { TranslateIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TranslateBlockDisplay = { + type: 'translate', + name: 'Translate', + description: 'Translate text to any language', + category: 'blocks', + bgColor: '#FF4B4B', + icon: TranslateIcon, + longDescription: 'Integrate Translate into the workflow. Can translate text to any language.', + docsLink: 'https://docs.sim.ai/integrations/translate', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/translate.ts b/apps/sim/blocks/blocks/translate.ts index 950a4803431..6adb412c626 100644 --- a/apps/sim/blocks/blocks/translate.ts +++ b/apps/sim/blocks/blocks/translate.ts @@ -1,5 +1,5 @@ -import { TranslateIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' +import { TranslateBlockDisplay } from '@/blocks/blocks/translate.display' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { getModelOptions, getProviderCredentialSubBlocks, @@ -10,16 +10,8 @@ const getTranslationPrompt = (targetLanguage: string) => `Translate the following text into ${targetLanguage || 'English'}. Output ONLY the translated text with no additional commentary, explanations, or notes.` export const TranslateBlock: BlockConfig = { - type: 'translate', - name: 'Translate', - description: 'Translate text to any language', + ...TranslateBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Translate into the workflow. Can translate text to any language.', - docsLink: 'https://docs.sim.ai/integrations/translate', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#FF4B4B', - icon: TranslateIcon, subBlocks: [ { id: 'context', diff --git a/apps/sim/blocks/blocks/trello.display.ts b/apps/sim/blocks/blocks/trello.display.ts new file mode 100644 index 00000000000..a0d8bb9c589 --- /dev/null +++ b/apps/sim/blocks/blocks/trello.display.ts @@ -0,0 +1,16 @@ +import { TrelloIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TrelloBlockDisplay = { + type: 'trello', + name: 'Trello', + description: 'Manage Trello lists, cards, and activity', + category: 'tools', + bgColor: '#0052CC', + icon: TrelloIcon, + longDescription: + 'Integrate with Trello to list board lists, list cards, create cards, update cards, review activity, and add comments.', + docsLink: 'https://docs.sim.ai/integrations/trello', + integrationType: IntegrationType.Productivity, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/trello.ts b/apps/sim/blocks/blocks/trello.ts index 9cb459895e4..317e2ca24ee 100644 --- a/apps/sim/blocks/blocks/trello.ts +++ b/apps/sim/blocks/blocks/trello.ts @@ -1,7 +1,8 @@ import { TrelloIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { TrelloBlockDisplay } from '@/blocks/blocks/trello.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, parseOptionalNumberInput } from '@/blocks/utils' import type { TrelloResponse } from '@/tools/trello' @@ -53,17 +54,8 @@ function parseStringArray(value: unknown): string[] | undefined { * the normal OAuth block UX while relying on the custom Trello auth routes. */ export const TrelloBlock: BlockConfig = { - type: 'trello', - name: 'Trello', - description: 'Manage Trello lists, cards, and activity', + ...TrelloBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with Trello to list board lists, list cards, create cards, update cards, review activity, and add comments.', - docsLink: 'https://docs.sim.ai/integrations/trello', - category: 'tools', - integrationType: IntegrationType.Productivity, - bgColor: '#0052CC', - icon: TrelloIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/trigger_dev.display.ts b/apps/sim/blocks/blocks/trigger_dev.display.ts new file mode 100644 index 00000000000..59e2e505382 --- /dev/null +++ b/apps/sim/blocks/blocks/trigger_dev.display.ts @@ -0,0 +1,16 @@ +import { TriggerDevIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TriggerDevBlockDisplay = { + type: 'trigger_dev', + name: 'Trigger.dev', + description: 'Trigger tasks and manage runs and schedules', + category: 'tools', + bgColor: '#000000', + icon: TriggerDevIcon, + longDescription: + 'Integrate Trigger.dev into the workflow. Trigger and batch trigger background tasks, retrieve and control runs (cancel, replay, reschedule, tags, metadata, events, traces), manage cron schedules, environment variables, queues, deployments, and waitpoint tokens, and query run data with TRQL.', + docsLink: 'https://docs.sim.ai/integrations/trigger_dev', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/trigger_dev.ts b/apps/sim/blocks/blocks/trigger_dev.ts index a48af95c08d..d4c06ccd437 100644 --- a/apps/sim/blocks/blocks/trigger_dev.ts +++ b/apps/sim/blocks/blocks/trigger_dev.ts @@ -1,6 +1,7 @@ import { TriggerDevIcon } from '@/components/icons' +import { TriggerDevBlockDisplay } from '@/blocks/blocks/trigger_dev.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { TriggerDevResponse } from '@/tools/trigger_dev/types' const TASK_IDENTIFIER_OPERATIONS = ['trigger_dev_trigger_task', 'trigger_dev_batch_trigger_task'] @@ -73,17 +74,8 @@ const PAGE_BEFORE_OPERATIONS = ['trigger_dev_list_runs', 'trigger_dev_list_waitp const NUMBERED_PAGE_OPERATIONS = ['trigger_dev_list_schedules', 'trigger_dev_list_queues'] export const TriggerDevBlock: BlockConfig = { - type: 'trigger_dev', - name: 'Trigger.dev', - description: 'Trigger tasks and manage runs and schedules', + ...TriggerDevBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Trigger.dev into the workflow. Trigger and batch trigger background tasks, retrieve and control runs (cancel, replay, reschedule, tags, metadata, events, traces), manage cron schedules, environment variables, queues, deployments, and waitpoint tokens, and query run data with TRQL.', - docsLink: 'https://docs.sim.ai/integrations/trigger_dev', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#000000', - icon: TriggerDevIcon, subBlocks: [ { diff --git a/apps/sim/blocks/blocks/tts.display.ts b/apps/sim/blocks/blocks/tts.display.ts new file mode 100644 index 00000000000..35883a2f85d --- /dev/null +++ b/apps/sim/blocks/blocks/tts.display.ts @@ -0,0 +1,16 @@ +import { TTSIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TtsBlockDisplay = { + type: 'tts', + name: 'Text-to-Speech', + description: 'Convert text to speech using AI voices', + category: 'blocks', + bgColor: '#181C1E', + icon: TTSIcon, + longDescription: + 'Generate natural-sounding speech from text using state-of-the-art AI voices from OpenAI, Deepgram, ElevenLabs, Cartesia, Google Cloud, Azure, and PlayHT. Supports multiple voices, languages, and audio formats.', + docsLink: 'https://docs.sim.ai/integrations/tts', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/tts.ts b/apps/sim/blocks/blocks/tts.ts index af13c5709b8..2c6326a6b51 100644 --- a/apps/sim/blocks/blocks/tts.ts +++ b/apps/sim/blocks/blocks/tts.ts @@ -1,19 +1,10 @@ -import { TTSIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' +import { TtsBlockDisplay } from '@/blocks/blocks/tts.display' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { TtsBlockResponse } from '@/tools/tts/types' export const TtsBlock: BlockConfig = { - type: 'tts', - name: 'Text-to-Speech', - description: 'Convert text to speech using AI voices', + ...TtsBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Generate natural-sounding speech from text using state-of-the-art AI voices from OpenAI, Deepgram, ElevenLabs, Cartesia, Google Cloud, Azure, and PlayHT. Supports multiple voices, languages, and audio formats.', - docsLink: 'https://docs.sim.ai/integrations/tts', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: TTSIcon, subBlocks: [ // Provider selection diff --git a/apps/sim/blocks/blocks/twilio.display.ts b/apps/sim/blocks/blocks/twilio.display.ts new file mode 100644 index 00000000000..e992e5facc7 --- /dev/null +++ b/apps/sim/blocks/blocks/twilio.display.ts @@ -0,0 +1,16 @@ +import { TwilioIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TwilioSMSBlockDisplay = { + type: 'twilio_sms', + name: 'Twilio SMS', + description: 'Send SMS messages', + category: 'tools', + bgColor: '#F22F46', + icon: TwilioIcon, + iconColor: '#F22F46', + longDescription: 'Integrate Twilio into the workflow. Can send SMS messages.', + docsLink: 'https://docs.sim.ai/integrations/twilio_sms', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/twilio.ts b/apps/sim/blocks/blocks/twilio.ts index d3ccc595eed..aa978c77f21 100644 --- a/apps/sim/blocks/blocks/twilio.ts +++ b/apps/sim/blocks/blocks/twilio.ts @@ -1,20 +1,12 @@ import { TwilioIcon } from '@/components/icons' +import { TwilioSMSBlockDisplay } from '@/blocks/blocks/twilio.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { TwilioSMSBlockOutput } from '@/tools/twilio/types' export const TwilioSMSBlock: BlockConfig = { - type: 'twilio_sms', - name: 'Twilio SMS', - description: 'Send SMS messages', - authMode: AuthMode.ApiKey, - longDescription: 'Integrate Twilio into the workflow. Can send SMS messages.', - category: 'tools', - integrationType: IntegrationType.Communication, - docsLink: 'https://docs.sim.ai/integrations/twilio_sms', - bgColor: '#F22F46', // Twilio brand color - iconColor: '#F22F46', - icon: TwilioIcon, + ...TwilioSMSBlockDisplay, + authMode: AuthMode.ApiKey, // Twilio brand color subBlocks: [ { id: 'phoneNumbers', diff --git a/apps/sim/blocks/blocks/twilio_voice.display.ts b/apps/sim/blocks/blocks/twilio_voice.display.ts new file mode 100644 index 00000000000..4341e3625fc --- /dev/null +++ b/apps/sim/blocks/blocks/twilio_voice.display.ts @@ -0,0 +1,18 @@ +import { TwilioIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TwilioVoiceBlockDisplay = { + type: 'twilio_voice', + name: 'Twilio Voice', + description: 'Make and manage phone calls', + category: 'tools', + bgColor: '#F22F46', + icon: TwilioIcon, + iconColor: '#F22F46', + longDescription: + 'Integrate Twilio Voice into the workflow. Make outbound calls and retrieve call recordings.', + docsLink: 'https://docs.sim.ai/integrations/twilio_voice', + integrationType: IntegrationType.Communication, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/twilio_voice.ts b/apps/sim/blocks/blocks/twilio_voice.ts index bdf485c4d62..cf00963719c 100644 --- a/apps/sim/blocks/blocks/twilio_voice.ts +++ b/apps/sim/blocks/blocks/twilio_voice.ts @@ -1,23 +1,13 @@ import { TwilioIcon } from '@/components/icons' +import { TwilioVoiceBlockDisplay } from '@/blocks/blocks/twilio_voice.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' export const TwilioVoiceBlock: BlockConfig = { - type: 'twilio_voice', - name: 'Twilio Voice', - description: 'Make and manage phone calls', - authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Twilio Voice into the workflow. Make outbound calls and retrieve call recordings.', - category: 'tools', - integrationType: IntegrationType.Communication, - docsLink: 'https://docs.sim.ai/integrations/twilio_voice', - bgColor: '#F22F46', // Twilio brand color - iconColor: '#F22F46', - icon: TwilioIcon, - triggerAllowed: true, + ...TwilioVoiceBlockDisplay, + authMode: AuthMode.ApiKey, // Twilio brand color subBlocks: [ ...getTrigger('twilio_voice_webhook').subBlocks, { diff --git a/apps/sim/blocks/blocks/typeform.display.ts b/apps/sim/blocks/blocks/typeform.display.ts new file mode 100644 index 00000000000..c323fd18e4b --- /dev/null +++ b/apps/sim/blocks/blocks/typeform.display.ts @@ -0,0 +1,16 @@ +import { TypeformIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const TypeformBlockDisplay = { + type: 'typeform', + name: 'Typeform', + description: 'Interact with Typeform', + category: 'tools', + bgColor: '#262627', + icon: TypeformIcon, + longDescription: + 'Integrate Typeform into the workflow. Can retrieve responses, download files, and get form insights. Can be used in trigger mode to trigger a workflow when a form is submitted. Requires API Key.', + docsLink: 'https://docs.sim.ai/integrations/typeform', + integrationType: IntegrationType.Documents, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/typeform.ts b/apps/sim/blocks/blocks/typeform.ts index feb79b3584a..08ef0acaf44 100644 --- a/apps/sim/blocks/blocks/typeform.ts +++ b/apps/sim/blocks/blocks/typeform.ts @@ -1,21 +1,13 @@ import { TypeformIcon } from '@/components/icons' +import { TypeformBlockDisplay } from '@/blocks/blocks/typeform.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { TypeformResponse } from '@/tools/typeform/types' import { getTrigger } from '@/triggers' export const TypeformBlock: BlockConfig = { - type: 'typeform', - name: 'Typeform', - description: 'Interact with Typeform', - authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Typeform into the workflow. Can retrieve responses, download files, and get form insights. Can be used in trigger mode to trigger a workflow when a form is submitted. Requires API Key.', - docsLink: 'https://docs.sim.ai/integrations/typeform', - category: 'tools', - integrationType: IntegrationType.Documents, - bgColor: '#262627', // Typeform brand color - icon: TypeformIcon, + ...TypeformBlockDisplay, + authMode: AuthMode.ApiKey, // Typeform brand color subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/upstash.display.ts b/apps/sim/blocks/blocks/upstash.display.ts new file mode 100644 index 00000000000..97a7dbe37c6 --- /dev/null +++ b/apps/sim/blocks/blocks/upstash.display.ts @@ -0,0 +1,16 @@ +import { UpstashIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const UpstashBlockDisplay = { + type: 'upstash', + name: 'Upstash', + description: 'Serverless Redis with Upstash', + category: 'tools', + bgColor: '#181C1E', + icon: UpstashIcon, + longDescription: + 'Connect to Upstash Redis to perform key-value, hash, list, and utility operations via the REST API.', + docsLink: 'https://docs.sim.ai/integrations/upstash', + integrationType: IntegrationType.Databases, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/upstash.ts b/apps/sim/blocks/blocks/upstash.ts index 58ae0dfe19f..a9b3c58ad1d 100644 --- a/apps/sim/blocks/blocks/upstash.ts +++ b/apps/sim/blocks/blocks/upstash.ts @@ -1,6 +1,7 @@ import { UpstashIcon } from '@/components/icons' +import { UpstashBlockDisplay } from '@/blocks/blocks/upstash.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { UpstashRedisCommandResponse, UpstashRedisDeleteResponse, @@ -39,17 +40,8 @@ type UpstashResponse = | UpstashRedisSetnxResponse export const UpstashBlock: BlockConfig = { - type: 'upstash', - name: 'Upstash', - description: 'Serverless Redis with Upstash', - longDescription: - 'Connect to Upstash Redis to perform key-value, hash, list, and utility operations via the REST API.', - docsLink: 'https://docs.sim.ai/integrations/upstash', - category: 'tools', - integrationType: IntegrationType.Databases, - bgColor: '#181C1E', + ...UpstashBlockDisplay, authMode: AuthMode.ApiKey, - icon: UpstashIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/vanta.display.ts b/apps/sim/blocks/blocks/vanta.display.ts new file mode 100644 index 00000000000..01bb8a45dbd --- /dev/null +++ b/apps/sim/blocks/blocks/vanta.display.ts @@ -0,0 +1,16 @@ +import { VantaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const VantaBlockDisplay = { + type: 'vanta', + name: 'Vanta', + description: 'Query compliance status and manage evidence in Vanta', + category: 'tools', + bgColor: '#F8F4F3', + icon: VantaIcon, + longDescription: + 'Integrate Vanta into the workflow. Monitor compliance frameworks, controls, and automated tests; find failing test entities; manage evidence documents including file upload, download, and submission; and track people, policies, vendors, monitored computers, vulnerabilities, and risk scenarios. Requires Vanta OAuth client credentials.', + docsLink: 'https://docs.sim.ai/integrations/vanta', + integrationType: IntegrationType.Security, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/vanta.ts b/apps/sim/blocks/blocks/vanta.ts index 92ba649b251..65dd81fa53b 100644 --- a/apps/sim/blocks/blocks/vanta.ts +++ b/apps/sim/blocks/blocks/vanta.ts @@ -1,6 +1,7 @@ import { VantaIcon } from '@/components/icons' +import { VantaBlockDisplay } from '@/blocks/blocks/vanta.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ToolResponse } from '@/tools/types' @@ -54,17 +55,8 @@ function optionalString(value: unknown): string | undefined { } export const VantaBlock: BlockConfig = { - type: 'vanta', - name: 'Vanta', - description: 'Query compliance status and manage evidence in Vanta', + ...VantaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Vanta into the workflow. Monitor compliance frameworks, controls, and automated tests; find failing test entities; manage evidence documents including file upload, download, and submission; and track people, policies, vendors, monitored computers, vulnerabilities, and risk scenarios. Requires Vanta OAuth client credentials.', - category: 'tools', - integrationType: IntegrationType.Security, - docsLink: 'https://docs.sim.ai/integrations/vanta', - bgColor: '#F8F4F3', - icon: VantaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/variables.display.ts b/apps/sim/blocks/blocks/variables.display.ts new file mode 100644 index 00000000000..b4b565975e4 --- /dev/null +++ b/apps/sim/blocks/blocks/variables.display.ts @@ -0,0 +1,14 @@ +import { VariableIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const VariablesBlockDisplay = { + type: 'variables', + name: 'Variables', + description: 'Set workflow-scoped variables', + category: 'blocks', + bgColor: '#8B5CF6', + icon: VariableIcon, + longDescription: + 'Set workflow-scoped variables that can be accessed throughout the workflow using syntax. All Variables blocks share the same namespace, so later blocks can update previously set variables.', + docsLink: 'https://docs.sim.ai/workflows/blocks/variables', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/variables.ts b/apps/sim/blocks/blocks/variables.ts index 1feddfc8937..a73ae82f375 100644 --- a/apps/sim/blocks/blocks/variables.ts +++ b/apps/sim/blocks/blocks/variables.ts @@ -1,13 +1,8 @@ -import { VariableIcon } from '@/components/icons' +import { VariablesBlockDisplay } from '@/blocks/blocks/variables.display' import type { BlockConfig } from '@/blocks/types' export const VariablesBlock: BlockConfig = { - type: 'variables', - name: 'Variables', - description: 'Set workflow-scoped variables', - longDescription: - 'Set workflow-scoped variables that can be accessed throughout the workflow using syntax. All Variables blocks share the same namespace, so later blocks can update previously set variables.', - bgColor: '#8B5CF6', + ...VariablesBlockDisplay, bestPractices: ` - Variables are workflow-scoped and persist throughout execution (but not between executions) - Reference variables using syntax in any block @@ -15,9 +10,6 @@ export const VariablesBlock: BlockConfig = { - Any Variables block can update existing variables by setting the same variable name - Variables do not appear as block outputs - they're accessed via the prefix `, - icon: VariableIcon, - category: 'blocks', - docsLink: 'https://docs.sim.ai/workflows/blocks/variables', subBlocks: [ { id: 'variables', diff --git a/apps/sim/blocks/blocks/vercel.display.ts b/apps/sim/blocks/blocks/vercel.display.ts new file mode 100644 index 00000000000..b90bfa81735 --- /dev/null +++ b/apps/sim/blocks/blocks/vercel.display.ts @@ -0,0 +1,16 @@ +import { VercelIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const VercelBlockDisplay = { + type: 'vercel', + name: 'Vercel', + description: 'Manage Vercel deployments, projects, and infrastructure', + category: 'tools', + bgColor: '#171717', + icon: VercelIcon, + longDescription: + 'Integrate with Vercel to manage deployments, projects, domains, DNS records, environment variables, aliases, edge configs, teams, and more.', + docsLink: 'https://docs.sim.ai/integrations/vercel', + integrationType: IntegrationType.DevOps, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/vercel.ts b/apps/sim/blocks/blocks/vercel.ts index 65e0513c63b..0db5554132a 100644 --- a/apps/sim/blocks/blocks/vercel.ts +++ b/apps/sim/blocks/blocks/vercel.ts @@ -1,19 +1,11 @@ import { VercelIcon } from '@/components/icons' +import { VercelBlockDisplay } from '@/blocks/blocks/vercel.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' export const VercelBlock: BlockConfig = { - type: 'vercel', - name: 'Vercel', - description: 'Manage Vercel deployments, projects, and infrastructure', - longDescription: - 'Integrate with Vercel to manage deployments, projects, domains, DNS records, environment variables, aliases, edge configs, teams, and more.', - docsLink: 'https://docs.sim.ai/integrations/vercel', - category: 'tools', - integrationType: IntegrationType.DevOps, - bgColor: '#171717', - icon: VercelIcon, + ...VercelBlockDisplay, authMode: AuthMode.ApiKey, triggers: { enabled: true, diff --git a/apps/sim/blocks/blocks/video_generator.display.ts b/apps/sim/blocks/blocks/video_generator.display.ts new file mode 100644 index 00000000000..e5a64380fc8 --- /dev/null +++ b/apps/sim/blocks/blocks/video_generator.display.ts @@ -0,0 +1,39 @@ +import { VideoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const VideoGeneratorBlockDisplay = { + type: 'video_generator', + name: 'Video Generator (Legacy)', + description: 'Generate videos from text using AI', + category: 'blocks', + bgColor: '#181C1E', + icon: VideoIcon, + longDescription: + 'Generate high-quality videos from text prompts using leading AI providers. Supports multiple models, aspect ratios, resolutions, and provider-specific features like world consistency, camera controls, and audio generation.', + docsLink: 'https://docs.sim.ai/integrations/video-generator', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const VideoGeneratorV2BlockDisplay = { + ...VideoGeneratorBlockDisplay, + type: 'video_generator_v2', + name: 'Video Generator', + hideFromToolbar: true, +} satisfies BlockDisplay + +export const VideoGeneratorV3BlockDisplay = { + ...VideoGeneratorV2BlockDisplay, + type: 'video_generator_v3', + name: 'Video Generator', + description: 'Generate videos from text using AI', + category: 'blocks', + bgColor: '#181C1E', + icon: VideoIcon, + longDescription: + 'Generate high-quality videos from text prompts using leading AI providers. Supports Runway, Google Veo, Luma, MiniMax, and Fal.ai multi-model generation with provider-specific durations, aspect ratios, resolutions, prompt optimization, and native audio controls.', + docsLink: 'https://docs.sim.ai/integrations/video_generator', + integrationType: IntegrationType.AI, + hideFromToolbar: false, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/video_generator.ts b/apps/sim/blocks/blocks/video_generator.ts index 496738dc0d8..dab77b56d2e 100644 --- a/apps/sim/blocks/blocks/video_generator.ts +++ b/apps/sim/blocks/blocks/video_generator.ts @@ -1,5 +1,9 @@ -import { VideoIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, IntegrationType, type SubBlockConfig } from '@/blocks/types' +import { + VideoGeneratorBlockDisplay, + VideoGeneratorV2BlockDisplay, + VideoGeneratorV3BlockDisplay, +} from '@/blocks/blocks/video_generator.display' +import { AuthMode, type BlockConfig, type SubBlockConfig } from '@/blocks/types' import { normalizeFileInput, parseOptionalBooleanInput } from '@/blocks/utils' import type { VideoBlockResponse } from '@/tools/video/types' @@ -71,18 +75,8 @@ const withFalAIModelOptions = ( }) export const VideoGeneratorBlock: BlockConfig = { - type: 'video_generator', - name: 'Video Generator (Legacy)', - description: 'Generate videos from text using AI', - hideFromToolbar: true, + ...VideoGeneratorBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Generate high-quality videos from text prompts using leading AI providers. Supports multiple models, aspect ratios, resolutions, and provider-specific features like world consistency, camera controls, and audio generation.', - docsLink: 'https://docs.sim.ai/integrations/video-generator', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: VideoIcon, subBlocks: [ // Provider selection @@ -889,9 +883,7 @@ export const VideoGeneratorBlock: BlockConfig = { export const VideoGeneratorV2Block: BlockConfig = { ...VideoGeneratorBlock, - type: 'video_generator_v2', - name: 'Video Generator', - hideFromToolbar: true, + ...VideoGeneratorV2BlockDisplay, subBlocks: [ { id: 'provider', @@ -1649,16 +1641,6 @@ export const VideoGeneratorV2Block: BlockConfig = { export const VideoGeneratorV3Block: BlockConfig = { ...VideoGeneratorV2Block, - type: 'video_generator_v3', - name: 'Video Generator', - description: 'Generate videos from text using AI', - longDescription: - 'Generate high-quality videos from text prompts using leading AI providers. Supports Runway, Google Veo, Luma, MiniMax, and Fal.ai multi-model generation with provider-specific durations, aspect ratios, resolutions, prompt optimization, and native audio controls.', - docsLink: 'https://docs.sim.ai/integrations/video_generator', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#181C1E', - icon: VideoIcon, - hideFromToolbar: false, + ...VideoGeneratorV3BlockDisplay, subBlocks: withFalAIModelOptions(VideoGeneratorV2Block.subBlocks, FALAI_LATEST_MODEL_OPTIONS), } diff --git a/apps/sim/blocks/blocks/vision.display.ts b/apps/sim/blocks/blocks/vision.display.ts new file mode 100644 index 00000000000..1dccf181df5 --- /dev/null +++ b/apps/sim/blocks/blocks/vision.display.ts @@ -0,0 +1,24 @@ +import { EyeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const VisionBlockDisplay = { + type: 'vision', + name: 'Vision (Legacy)', + description: 'Analyze images with vision models', + category: 'blocks', + bgColor: '#4D5FFF', + icon: EyeIcon, + longDescription: 'Integrate Vision into the workflow. Can analyze images with vision models.', + docsLink: 'https://docs.sim.ai/integrations/vision', + integrationType: IntegrationType.AI, + hideFromToolbar: true, +} satisfies BlockDisplay + +export const VisionV2BlockDisplay = { + ...VisionBlockDisplay, + type: 'vision_v2', + name: 'Vision', + description: 'Analyze images with vision models', + hideFromToolbar: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/vision.ts b/apps/sim/blocks/blocks/vision.ts index 16e3b3aaa39..7c5f8f85eb2 100644 --- a/apps/sim/blocks/blocks/vision.ts +++ b/apps/sim/blocks/blocks/vision.ts @@ -1,6 +1,6 @@ -import { EyeIcon } from '@/components/icons' +import { VisionBlockDisplay, VisionV2BlockDisplay } from '@/blocks/blocks/vision.display' import type { BlockConfig } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { VisionResponse } from '@/tools/vision/types' @@ -22,17 +22,8 @@ const VISION_MODEL_OPTIONS = [ ] export const VisionBlock: BlockConfig = { - type: 'vision', - name: 'Vision (Legacy)', - description: 'Analyze images with vision models', - hideFromToolbar: true, + ...VisionBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate Vision into the workflow. Can analyze images with vision models.', - docsLink: 'https://docs.sim.ai/integrations/vision', - category: 'blocks', - integrationType: IntegrationType.AI, - bgColor: '#4D5FFF', - icon: EyeIcon, subBlocks: [ // Image file upload (basic mode) { @@ -105,10 +96,7 @@ export const VisionBlock: BlockConfig = { export const VisionV2Block: BlockConfig = { ...VisionBlock, - type: 'vision_v2', - name: 'Vision', - description: 'Analyze images with vision models', - hideFromToolbar: true, + ...VisionV2BlockDisplay, tools: { access: ['vision_tool_v2'], config: { diff --git a/apps/sim/blocks/blocks/wait.display.ts b/apps/sim/blocks/blocks/wait.display.ts new file mode 100644 index 00000000000..67d82aab99f --- /dev/null +++ b/apps/sim/blocks/blocks/wait.display.ts @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +import { createElement } from 'react' +import { PauseCircle } from 'lucide-react' +import type { BlockDisplay } from '@/blocks/manifest' + +const WaitIcon = (props: SVGProps) => createElement(PauseCircle, props) + +export const WaitBlockDisplay = { + type: 'wait', + name: 'Wait', + description: 'Pause workflow execution for a time interval', + category: 'blocks', + bgColor: '#F59E0B', + icon: WaitIcon, + longDescription: + 'Pauses workflow execution for a specified time interval. By default the wait runs in-process for up to 5 minutes. Enable Async to pause the run on disk and resume automatically for waits up to 30 days.', + docsLink: 'https://docs.sim.ai/workflows/blocks/wait', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/wait.ts b/apps/sim/blocks/blocks/wait.ts index a3f6f56bf35..b65156ce87c 100644 --- a/apps/sim/blocks/blocks/wait.ts +++ b/apps/sim/blocks/blocks/wait.ts @@ -1,26 +1,19 @@ import type { SVGProps } from 'react' import { createElement } from 'react' import { PauseCircle } from 'lucide-react' +import { WaitBlockDisplay } from '@/blocks/blocks/wait.display' import type { BlockConfig } from '@/blocks/types' const WaitIcon = (props: SVGProps) => createElement(PauseCircle, props) export const WaitBlock: BlockConfig = { - type: 'wait', - name: 'Wait', - description: 'Pause workflow execution for a time interval', - longDescription: - 'Pauses workflow execution for a specified time interval. By default the wait runs in-process for up to 5 minutes. Enable Async to pause the run on disk and resume automatically for waits up to 30 days.', + ...WaitBlockDisplay, bestPractices: ` - Configure the wait amount and unit - Default mode runs in-process and caps at 5 minutes - Enable Async for longer waits (up to 30 days); seconds are not available in this mode - Enter a positive number for the wait amount `, - category: 'blocks', - bgColor: '#F59E0B', - icon: WaitIcon, - docsLink: 'https://docs.sim.ai/workflows/blocks/wait', subBlocks: [ { id: 'timeValue', diff --git a/apps/sim/blocks/blocks/wealthbox.display.ts b/apps/sim/blocks/blocks/wealthbox.display.ts new file mode 100644 index 00000000000..89e7161c949 --- /dev/null +++ b/apps/sim/blocks/blocks/wealthbox.display.ts @@ -0,0 +1,16 @@ +import { WealthboxIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WealthboxBlockDisplay = { + type: 'wealthbox', + name: 'Wealthbox', + description: 'Interact with Wealthbox', + category: 'tools', + bgColor: '#FFFFFF', + icon: WealthboxIcon, + longDescription: + 'Integrate Wealthbox into the workflow. Can read and write notes, read and write contacts, and read and write tasks.', + docsLink: 'https://docs.sim.ai/integrations/wealthbox', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/wealthbox.ts b/apps/sim/blocks/blocks/wealthbox.ts index 1107f3c8e86..6fb814e593c 100644 --- a/apps/sim/blocks/blocks/wealthbox.ts +++ b/apps/sim/blocks/blocks/wealthbox.ts @@ -1,21 +1,13 @@ import { WealthboxIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { WealthboxBlockDisplay } from '@/blocks/blocks/wealthbox.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { WealthboxResponse } from '@/tools/wealthbox/types' export const WealthboxBlock: BlockConfig = { - type: 'wealthbox', - name: 'Wealthbox', - description: 'Interact with Wealthbox', + ...WealthboxBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Wealthbox into the workflow. Can read and write notes, read and write contacts, and read and write tasks.', - docsLink: 'https://docs.sim.ai/integrations/wealthbox', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: WealthboxIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/webflow.display.ts b/apps/sim/blocks/blocks/webflow.display.ts new file mode 100644 index 00000000000..817cbd950b5 --- /dev/null +++ b/apps/sim/blocks/blocks/webflow.display.ts @@ -0,0 +1,17 @@ +import { WebflowIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WebflowBlockDisplay = { + type: 'webflow', + name: 'Webflow', + description: 'Manage Webflow CMS collections', + category: 'tools', + bgColor: '#FFFFFF', + icon: WebflowIcon, + longDescription: + 'Integrates Webflow CMS into the workflow. Can create, get, list, update, or delete items in Webflow CMS collections. Manage your Webflow content programmatically. Can be used in trigger mode to trigger workflows when collection items change or forms are submitted.', + docsLink: 'https://docs.sim.ai/integrations/webflow', + integrationType: IntegrationType.Marketing, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/webflow.ts b/apps/sim/blocks/blocks/webflow.ts index b079f0071a6..872b5623ed1 100644 --- a/apps/sim/blocks/blocks/webflow.ts +++ b/apps/sim/blocks/blocks/webflow.ts @@ -1,23 +1,14 @@ import { WebflowIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { WebflowBlockDisplay } from '@/blocks/blocks/webflow.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { WebflowResponse } from '@/tools/webflow/types' import { getTrigger } from '@/triggers' export const WebflowBlock: BlockConfig = { - type: 'webflow', - name: 'Webflow', - description: 'Manage Webflow CMS collections', + ...WebflowBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrates Webflow CMS into the workflow. Can create, get, list, update, or delete items in Webflow CMS collections. Manage your Webflow content programmatically. Can be used in trigger mode to trigger workflows when collection items change or forms are submitted.', - docsLink: 'https://docs.sim.ai/integrations/webflow', - category: 'tools', - integrationType: IntegrationType.Marketing, - triggerAllowed: true, - bgColor: '#FFFFFF', - icon: WebflowIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/webhook_request.display.ts b/apps/sim/blocks/blocks/webhook_request.display.ts new file mode 100644 index 00000000000..e13aea63162 --- /dev/null +++ b/apps/sim/blocks/blocks/webhook_request.display.ts @@ -0,0 +1,14 @@ +import { WebhookIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const WebhookRequestBlockDisplay = { + type: 'webhook_request', + name: 'Outgoing Webhook', + description: 'Send a webhook request', + category: 'blocks', + bgColor: '#10B981', + icon: WebhookIcon, + longDescription: + 'Send an HTTP POST request to a webhook URL with automatic webhook headers. Optionally sign the payload with HMAC-SHA256 for secure webhook delivery.', + docsLink: 'https://docs.sim.ai/workflows/blocks/webhook', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/webhook_request.ts b/apps/sim/blocks/blocks/webhook_request.ts index b34e78413d4..c5022e76352 100644 --- a/apps/sim/blocks/blocks/webhook_request.ts +++ b/apps/sim/blocks/blocks/webhook_request.ts @@ -1,17 +1,9 @@ -import { WebhookIcon } from '@/components/icons' +import { WebhookRequestBlockDisplay } from '@/blocks/blocks/webhook_request.display' import type { BlockConfig } from '@/blocks/types' import type { RequestResponse } from '@/tools/http/types' export const WebhookRequestBlock: BlockConfig = { - type: 'webhook_request', - name: 'Outgoing Webhook', - description: 'Send a webhook request', - longDescription: - 'Send an HTTP POST request to a webhook URL with automatic webhook headers. Optionally sign the payload with HMAC-SHA256 for secure webhook delivery.', - docsLink: 'https://docs.sim.ai/workflows/blocks/webhook', - category: 'blocks', - bgColor: '#10B981', - icon: WebhookIcon, + ...WebhookRequestBlockDisplay, subBlocks: [ { id: 'url', diff --git a/apps/sim/blocks/blocks/whatsapp.display.ts b/apps/sim/blocks/blocks/whatsapp.display.ts new file mode 100644 index 00000000000..3697e69cff9 --- /dev/null +++ b/apps/sim/blocks/blocks/whatsapp.display.ts @@ -0,0 +1,17 @@ +import { WhatsAppIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WhatsAppBlockDisplay = { + type: 'whatsapp', + name: 'WhatsApp', + description: 'Send WhatsApp messages', + category: 'tools', + bgColor: '#25D366', + icon: WhatsAppIcon, + iconColor: '#25D366', + longDescription: 'Integrate WhatsApp into the workflow. Can send messages.', + docsLink: 'https://docs.sim.ai/integrations/whatsapp', + integrationType: IntegrationType.Communication, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/whatsapp.ts b/apps/sim/blocks/blocks/whatsapp.ts index 1cf9601a22d..dbbece26f50 100644 --- a/apps/sim/blocks/blocks/whatsapp.ts +++ b/apps/sim/blocks/blocks/whatsapp.ts @@ -1,22 +1,13 @@ import { WhatsAppIcon } from '@/components/icons' +import { WhatsAppBlockDisplay } from '@/blocks/blocks/whatsapp.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { WhatsAppResponse } from '@/tools/whatsapp/types' import { getTrigger } from '@/triggers' export const WhatsAppBlock: BlockConfig = { - type: 'whatsapp', - name: 'WhatsApp', - description: 'Send WhatsApp messages', + ...WhatsAppBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: 'Integrate WhatsApp into the workflow. Can send messages.', - docsLink: 'https://docs.sim.ai/integrations/whatsapp', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#25D366', - iconColor: '#25D366', - icon: WhatsAppIcon, - triggerAllowed: true, subBlocks: [ { id: 'phoneNumber', diff --git a/apps/sim/blocks/blocks/wikipedia.display.ts b/apps/sim/blocks/blocks/wikipedia.display.ts new file mode 100644 index 00000000000..6e1c2e49083 --- /dev/null +++ b/apps/sim/blocks/blocks/wikipedia.display.ts @@ -0,0 +1,16 @@ +import { WikipediaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WikipediaBlockDisplay = { + type: 'wikipedia', + name: 'Wikipedia', + description: 'Search and retrieve content from Wikipedia', + category: 'tools', + bgColor: '#000000', + icon: WikipediaIcon, + longDescription: + 'Integrate Wikipedia into the workflow. Can get page summary, search pages, get page content, and get random page.', + docsLink: 'https://docs.sim.ai/integrations/wikipedia', + integrationType: IntegrationType.Search, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/wikipedia.ts b/apps/sim/blocks/blocks/wikipedia.ts index a2d375cda72..ce6ec461e70 100644 --- a/apps/sim/blocks/blocks/wikipedia.ts +++ b/apps/sim/blocks/blocks/wikipedia.ts @@ -1,19 +1,10 @@ import { WikipediaIcon } from '@/components/icons' +import { WikipediaBlockDisplay } from '@/blocks/blocks/wikipedia.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' import type { WikipediaResponse } from '@/tools/wikipedia/types' export const WikipediaBlock: BlockConfig = { - type: 'wikipedia', - name: 'Wikipedia', - description: 'Search and retrieve content from Wikipedia', - longDescription: - 'Integrate Wikipedia into the workflow. Can get page summary, search pages, get page content, and get random page.', - docsLink: 'https://docs.sim.ai/integrations/wikipedia', - category: 'tools', - integrationType: IntegrationType.Search, - bgColor: '#000000', - icon: WikipediaIcon, + ...WikipediaBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/wiza.display.ts b/apps/sim/blocks/blocks/wiza.display.ts new file mode 100644 index 00000000000..0b76e686993 --- /dev/null +++ b/apps/sim/blocks/blocks/wiza.display.ts @@ -0,0 +1,17 @@ +import { WizaIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WizaBlockDisplay = { + type: 'wiza', + name: 'Wiza', + description: 'Find, enrich, and verify B2B contact data with Wiza', + category: 'tools', + bgColor: '#9284BC', + icon: WizaIcon, + iconColor: '#9284BC', + longDescription: + 'Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.', + docsLink: 'https://docs.sim.ai/integrations/wiza', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/wiza.ts b/apps/sim/blocks/blocks/wiza.ts index 7df60ae7a3e..d835cea2eab 100644 --- a/apps/sim/blocks/blocks/wiza.ts +++ b/apps/sim/blocks/blocks/wiza.ts @@ -1,21 +1,12 @@ import { WizaIcon } from '@/components/icons' +import { WizaBlockDisplay } from '@/blocks/blocks/wiza.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { WizaResponse } from '@/tools/wiza/types' export const WizaBlock: BlockConfig = { - type: 'wiza', - name: 'Wiza', - description: 'Find, enrich, and verify B2B contact data with Wiza', + ...WizaBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.', - docsLink: 'https://docs.sim.ai/integrations/wiza', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#9284BC', - iconColor: '#9284BC', - icon: WizaIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/wordpress.display.ts b/apps/sim/blocks/blocks/wordpress.display.ts new file mode 100644 index 00000000000..1634283be35 --- /dev/null +++ b/apps/sim/blocks/blocks/wordpress.display.ts @@ -0,0 +1,17 @@ +import { WordpressIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WordPressBlockDisplay = { + type: 'wordpress', + name: 'WordPress', + description: 'Manage WordPress content', + category: 'tools', + bgColor: '#21759B', + icon: WordpressIcon, + iconColor: '#21759B', + longDescription: + 'Integrate with WordPress to create, update, and manage posts, pages, media, comments, categories, tags, and users. Supports WordPress.com sites via OAuth and self-hosted WordPress sites using Application Passwords authentication.', + docsLink: 'https://docs.sim.ai/integrations/wordpress', + integrationType: IntegrationType.Marketing, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/wordpress.ts b/apps/sim/blocks/blocks/wordpress.ts index b451b6a1a41..25d6974f8bd 100644 --- a/apps/sim/blocks/blocks/wordpress.ts +++ b/apps/sim/blocks/blocks/wordpress.ts @@ -1,23 +1,14 @@ import { WordpressIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { WordPressBlockDisplay } from '@/blocks/blocks/wordpress.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { WordPressResponse } from '@/tools/wordpress/types' export const WordPressBlock: BlockConfig = { - type: 'wordpress', - name: 'WordPress', - description: 'Manage WordPress content', + ...WordPressBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate with WordPress to create, update, and manage posts, pages, media, comments, categories, tags, and users. Supports WordPress.com sites via OAuth and self-hosted WordPress sites using Application Passwords authentication.', - docsLink: 'https://docs.sim.ai/integrations/wordpress', - category: 'tools', - integrationType: IntegrationType.Marketing, - bgColor: '#21759B', - iconColor: '#21759B', - icon: WordpressIcon, subBlocks: [ // Operation Selection { diff --git a/apps/sim/blocks/blocks/workday.display.ts b/apps/sim/blocks/blocks/workday.display.ts new file mode 100644 index 00000000000..fa11b19f0c3 --- /dev/null +++ b/apps/sim/blocks/blocks/workday.display.ts @@ -0,0 +1,16 @@ +import { WorkdayIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const WorkdayBlockDisplay = { + type: 'workday', + name: 'Workday', + description: 'Manage workers, hiring, onboarding, and HR operations in Workday', + category: 'tools', + bgColor: '#F5F0EB', + icon: WorkdayIcon, + longDescription: + 'Integrate Workday HRIS into your workflow. Create pre-hires, hire employees, manage worker profiles, assign onboarding plans, handle job changes, retrieve compensation data, and process terminations.', + docsLink: 'https://docs.sim.ai/integrations/workday', + integrationType: IntegrationType.HR, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/workday.ts b/apps/sim/blocks/blocks/workday.ts index d7c7189cfd5..d50bab9c76f 100644 --- a/apps/sim/blocks/blocks/workday.ts +++ b/apps/sim/blocks/blocks/workday.ts @@ -1,18 +1,9 @@ import { WorkdayIcon } from '@/components/icons' +import { WorkdayBlockDisplay } from '@/blocks/blocks/workday.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { IntegrationType } from '@/blocks/types' export const WorkdayBlock: BlockConfig = { - type: 'workday', - name: 'Workday', - description: 'Manage workers, hiring, onboarding, and HR operations in Workday', - longDescription: - 'Integrate Workday HRIS into your workflow. Create pre-hires, hire employees, manage worker profiles, assign onboarding plans, handle job changes, retrieve compensation data, and process terminations.', - docsLink: 'https://docs.sim.ai/integrations/workday', - category: 'tools', - integrationType: IntegrationType.HR, - bgColor: '#F5F0EB', - icon: WorkdayIcon, + ...WorkdayBlockDisplay, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/workflow.display.ts b/apps/sim/blocks/blocks/workflow.display.ts new file mode 100644 index 00000000000..53974eb485a --- /dev/null +++ b/apps/sim/blocks/blocks/workflow.display.ts @@ -0,0 +1,13 @@ +import { WorkflowIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const WorkflowBlockDisplay = { + type: 'workflow', + name: 'Workflow', + description: + 'This is a core workflow block. Execute another workflow as a block in your workflow. Enter the input variable to pass to the child workflow.', + category: 'blocks', + bgColor: '#6366F1', + icon: WorkflowIcon, + hideFromToolbar: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/workflow.ts b/apps/sim/blocks/blocks/workflow.ts index 667b6614ea4..90166140cec 100644 --- a/apps/sim/blocks/blocks/workflow.ts +++ b/apps/sim/blocks/blocks/workflow.ts @@ -1,14 +1,8 @@ -import { WorkflowIcon } from '@/components/icons' +import { WorkflowBlockDisplay } from '@/blocks/blocks/workflow.display' import type { BlockConfig } from '@/blocks/types' export const WorkflowBlock: BlockConfig = { - type: 'workflow', - name: 'Workflow', - description: - 'This is a core workflow block. Execute another workflow as a block in your workflow. Enter the input variable to pass to the child workflow.', - category: 'blocks', - bgColor: '#6366F1', - icon: WorkflowIcon, + ...WorkflowBlockDisplay, subBlocks: [ { id: 'workflowId', @@ -63,5 +57,4 @@ export const WorkflowBlock: BlockConfig = { hiddenFromDisplay: true, }, }, - hideFromToolbar: true, } diff --git a/apps/sim/blocks/blocks/workflow_input.display.ts b/apps/sim/blocks/blocks/workflow_input.display.ts new file mode 100644 index 00000000000..91a0aeef868 --- /dev/null +++ b/apps/sim/blocks/blocks/workflow_input.display.ts @@ -0,0 +1,13 @@ +import { WorkflowIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' + +export const WorkflowInputBlockDisplay = { + type: 'workflow_input', + name: 'Workflow', + description: 'Execute another workflow and map variables to its Start trigger schema.', + category: 'blocks', + bgColor: '#6366F1', + icon: WorkflowIcon, + longDescription: `Execute another child workflow and map variables to its Start trigger schema. Helps with modularizing workflows.`, + docsLink: 'https://docs.sim.ai/workflows/blocks/workflow', +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/workflow_input.ts b/apps/sim/blocks/blocks/workflow_input.ts index 87dd81e2d22..fe7e7c78b49 100644 --- a/apps/sim/blocks/blocks/workflow_input.ts +++ b/apps/sim/blocks/blocks/workflow_input.ts @@ -1,19 +1,12 @@ -import { WorkflowIcon } from '@/components/icons' +import { WorkflowInputBlockDisplay } from '@/blocks/blocks/workflow_input.display' import type { BlockConfig } from '@/blocks/types' export const WorkflowInputBlock: BlockConfig = { - type: 'workflow_input', - name: 'Workflow', - description: 'Execute another workflow and map variables to its Start trigger schema.', - longDescription: `Execute another child workflow and map variables to its Start trigger schema. Helps with modularizing workflows.`, + ...WorkflowInputBlockDisplay, bestPractices: ` - Usually clarify/check if the user has tagged a workflow to use as the child workflow. Understand the child workflow to determine the logical position of this block in the workflow. - Remember, that the start point of the child workflow is the Start block. `, - category: 'blocks', - docsLink: 'https://docs.sim.ai/workflows/blocks/workflow', - bgColor: '#6366F1', - icon: WorkflowIcon, subBlocks: [ { id: 'workflowId', diff --git a/apps/sim/blocks/blocks/x.display.ts b/apps/sim/blocks/blocks/x.display.ts new file mode 100644 index 00000000000..fa13be628ba --- /dev/null +++ b/apps/sim/blocks/blocks/x.display.ts @@ -0,0 +1,16 @@ +import { xIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const XBlockDisplay = { + type: 'x', + name: 'X', + description: 'Interact with X', + category: 'tools', + bgColor: '#000000', + icon: xIcon, + longDescription: + 'Integrate X into the workflow. Search tweets, manage bookmarks, follow/block/mute users, like and retweet, view trends, and more.', + docsLink: 'https://docs.sim.ai/integrations/x', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/x.ts b/apps/sim/blocks/blocks/x.ts index 4161838cc00..e1d17db7d49 100644 --- a/apps/sim/blocks/blocks/x.ts +++ b/apps/sim/blocks/blocks/x.ts @@ -1,20 +1,12 @@ import { xIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { XBlockDisplay } from '@/blocks/blocks/x.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' export const XBlock: BlockConfig = { - type: 'x', - name: 'X', - description: 'Interact with X', + ...XBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate X into the workflow. Search tweets, manage bookmarks, follow/block/mute users, like and retweet, view trends, and more.', - docsLink: 'https://docs.sim.ai/integrations/x', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#000000', - icon: xIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/youtube.display.ts b/apps/sim/blocks/blocks/youtube.display.ts new file mode 100644 index 00000000000..3d4e7fc7619 --- /dev/null +++ b/apps/sim/blocks/blocks/youtube.display.ts @@ -0,0 +1,16 @@ +import { YouTubeIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const YouTubeBlockDisplay = { + type: 'youtube', + name: 'YouTube', + description: 'Interact with YouTube videos, channels, and playlists', + category: 'tools', + bgColor: '#FF0000', + icon: YouTubeIcon, + longDescription: + 'Integrate YouTube into the workflow. Can search for videos, get trending videos, get video details, get video categories, get channel information, get all videos from a channel, get channel playlists, get playlist items, and get video comments.', + docsLink: 'https://docs.sim.ai/integrations/youtube', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/youtube.ts b/apps/sim/blocks/blocks/youtube.ts index 0fde73b4fe6..9b727ed01f4 100644 --- a/apps/sim/blocks/blocks/youtube.ts +++ b/apps/sim/blocks/blocks/youtube.ts @@ -1,20 +1,12 @@ import { ElevenLabsIcon, YouTubeIcon } from '@/components/icons' +import { YouTubeBlockDisplay } from '@/blocks/blocks/youtube.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { YouTubeResponse } from '@/tools/youtube/types' export const YouTubeBlock: BlockConfig = { - type: 'youtube', - name: 'YouTube', - description: 'Interact with YouTube videos, channels, and playlists', + ...YouTubeBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate YouTube into the workflow. Can search for videos, get trending videos, get video details, get video categories, get channel information, get all videos from a channel, get channel playlists, get playlist items, and get video comments.', - docsLink: 'https://docs.sim.ai/integrations/youtube', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#FF0000', - icon: YouTubeIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/zendesk.display.ts b/apps/sim/blocks/blocks/zendesk.display.ts new file mode 100644 index 00000000000..afd411c747f --- /dev/null +++ b/apps/sim/blocks/blocks/zendesk.display.ts @@ -0,0 +1,17 @@ +import { ZendeskIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ZendeskBlockDisplay = { + type: 'zendesk', + name: 'Zendesk', + description: 'Manage support tickets, users, and organizations in Zendesk', + category: 'tools', + bgColor: '#03363D', + icon: ZendeskIcon, + longDescription: + 'Integrate Zendesk into the workflow. Can get tickets, get ticket, create ticket, create tickets bulk, update ticket, update tickets bulk, delete ticket, merge tickets, get users, get user, get current user, search users, create user, create users bulk, update user, update users bulk, delete user, get organizations, get organization, autocomplete organizations, create organization, create organizations bulk, update organization, delete organization, search, search count.', + docsLink: 'https://docs.sim.ai/integrations/zendesk', + integrationType: IntegrationType.Support, + triggerAllowed: true, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/zendesk.ts b/apps/sim/blocks/blocks/zendesk.ts index 9d51552cf82..374914b9e96 100644 --- a/apps/sim/blocks/blocks/zendesk.ts +++ b/apps/sim/blocks/blocks/zendesk.ts @@ -1,21 +1,12 @@ import { ZendeskIcon } from '@/components/icons' +import { ZendeskBlockDisplay } from '@/blocks/blocks/zendesk.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' export const ZendeskBlock: BlockConfig = { - type: 'zendesk', - name: 'Zendesk', - description: 'Manage support tickets, users, and organizations in Zendesk', - triggerAllowed: true, - longDescription: - 'Integrate Zendesk into the workflow. Can get tickets, get ticket, create ticket, create tickets bulk, update ticket, update tickets bulk, delete ticket, merge tickets, get users, get user, get current user, search users, create user, create users bulk, update user, update users bulk, delete user, get organizations, get organization, autocomplete organizations, create organization, create organizations bulk, update organization, delete organization, search, search count.', - docsLink: 'https://docs.sim.ai/integrations/zendesk', + ...ZendeskBlockDisplay, authMode: AuthMode.ApiKey, - category: 'tools', - integrationType: IntegrationType.Support, - bgColor: '#03363D', - icon: ZendeskIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/zep.display.ts b/apps/sim/blocks/blocks/zep.display.ts new file mode 100644 index 00000000000..9f7a01a6fe9 --- /dev/null +++ b/apps/sim/blocks/blocks/zep.display.ts @@ -0,0 +1,16 @@ +import { ZepIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ZepBlockDisplay = { + type: 'zep', + name: 'Zep', + description: 'Long-term memory for AI agents', + category: 'tools', + bgColor: '#E8E8E8', + icon: ZepIcon, + longDescription: + 'Integrate Zep for long-term memory management. Create threads, add messages, retrieve context with AI-powered summaries and facts extraction.', + docsLink: 'https://docs.sim.ai/integrations/zep', + integrationType: IntegrationType.AI, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/zep.ts b/apps/sim/blocks/blocks/zep.ts index b38de76016d..0376852d56a 100644 --- a/apps/sim/blocks/blocks/zep.ts +++ b/apps/sim/blocks/blocks/zep.ts @@ -1,19 +1,11 @@ import { ZepIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ZepBlockDisplay } from '@/blocks/blocks/zep.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ZepResponse } from '@/tools/zep/types' export const ZepBlock: BlockConfig = { - type: 'zep', - name: 'Zep', - description: 'Long-term memory for AI agents', + ...ZepBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate Zep for long-term memory management. Create threads, add messages, retrieve context with AI-powered summaries and facts extraction.', - bgColor: '#E8E8E8', - icon: ZepIcon, - category: 'tools', - integrationType: IntegrationType.AI, - docsLink: 'https://docs.sim.ai/integrations/zep', subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/zerobounce.display.ts b/apps/sim/blocks/blocks/zerobounce.display.ts new file mode 100644 index 00000000000..db0378f6c05 --- /dev/null +++ b/apps/sim/blocks/blocks/zerobounce.display.ts @@ -0,0 +1,16 @@ +import { ZeroBounceIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ZeroBounceBlockDisplay = { + type: 'zerobounce', + name: 'ZeroBounce', + description: 'Validate email deliverability and check account credits', + category: 'tools', + bgColor: '#FFFFFF', + icon: ZeroBounceIcon, + longDescription: + 'Integrate ZeroBounce to validate email deliverability in real time — detect invalid, catch-all, spamtrap, abuse, and do-not-mail addresses — and check your remaining validation credits.', + docsLink: 'https://docs.sim.ai/integrations/zerobounce', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/zerobounce.ts b/apps/sim/blocks/blocks/zerobounce.ts index cc6f98a9e3f..edef766c224 100644 --- a/apps/sim/blocks/blocks/zerobounce.ts +++ b/apps/sim/blocks/blocks/zerobounce.ts @@ -1,19 +1,10 @@ -import { ZeroBounceIcon } from '@/components/icons' -import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' +import { ZeroBounceBlockDisplay } from '@/blocks/blocks/zerobounce.display' +import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' import type { ZeroBounceResponse } from '@/tools/zerobounce/types' export const ZeroBounceBlock: BlockConfig = { - type: 'zerobounce', - name: 'ZeroBounce', - description: 'Validate email deliverability and check account credits', + ...ZeroBounceBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrate ZeroBounce to validate email deliverability in real time — detect invalid, catch-all, spamtrap, abuse, and do-not-mail addresses — and check your remaining validation credits.', - docsLink: 'https://docs.sim.ai/integrations/zerobounce', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#FFFFFF', - icon: ZeroBounceIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/blocks/zoom.display.ts b/apps/sim/blocks/blocks/zoom.display.ts new file mode 100644 index 00000000000..05624364a07 --- /dev/null +++ b/apps/sim/blocks/blocks/zoom.display.ts @@ -0,0 +1,17 @@ +import { ZoomIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ZoomBlockDisplay = { + type: 'zoom', + name: 'Zoom', + description: 'Create and manage Zoom meetings and recordings', + category: 'tools', + bgColor: '#2D8CFF', + icon: ZoomIcon, + iconColor: '#2D8CFF', + longDescription: + 'Integrate Zoom into workflows. Create, list, update, and delete Zoom meetings. Get meeting details, invitations, recordings, and participants. Manage cloud recordings programmatically.', + docsLink: 'https://docs.sim.ai/integrations/zoom', + integrationType: IntegrationType.Communication, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/zoom.ts b/apps/sim/blocks/blocks/zoom.ts index 95216e98f72..e408496b774 100644 --- a/apps/sim/blocks/blocks/zoom.ts +++ b/apps/sim/blocks/blocks/zoom.ts @@ -1,23 +1,14 @@ import { ZoomIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' +import { ZoomBlockDisplay } from '@/blocks/blocks/zoom.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ZoomResponse } from '@/tools/zoom/types' import { getTrigger } from '@/triggers' export const ZoomBlock: BlockConfig = { - type: 'zoom', - name: 'Zoom', - description: 'Create and manage Zoom meetings and recordings', + ...ZoomBlockDisplay, authMode: AuthMode.OAuth, - longDescription: - 'Integrate Zoom into workflows. Create, list, update, and delete Zoom meetings. Get meeting details, invitations, recordings, and participants. Manage cloud recordings programmatically.', - docsLink: 'https://docs.sim.ai/integrations/zoom', - category: 'tools', - integrationType: IntegrationType.Communication, - bgColor: '#2D8CFF', - iconColor: '#2D8CFF', - icon: ZoomIcon, triggers: { enabled: true, available: [ diff --git a/apps/sim/blocks/blocks/zoominfo.display.ts b/apps/sim/blocks/blocks/zoominfo.display.ts new file mode 100644 index 00000000000..cb67b3e8bea --- /dev/null +++ b/apps/sim/blocks/blocks/zoominfo.display.ts @@ -0,0 +1,16 @@ +import { ZoomInfoIcon } from '@/components/icons' +import type { BlockDisplay } from '@/blocks/manifest' +import { IntegrationType } from '@/blocks/types' + +export const ZoomInfoBlockDisplay = { + type: 'zoominfo', + name: 'ZoomInfo', + description: 'Search and enrich B2B company and contact data with ZoomInfo.', + category: 'tools', + bgColor: '#EA1B15', + icon: ZoomInfoIcon, + longDescription: + 'Integrates ZoomInfo into the workflow. Search companies and contacts, enrich firmographic and contact data, find intent signals, and pull news — all using the ZoomInfo GTM API.', + docsLink: 'https://docs.sim.ai/integrations/zoominfo', + integrationType: IntegrationType.Sales, +} satisfies BlockDisplay diff --git a/apps/sim/blocks/blocks/zoominfo.ts b/apps/sim/blocks/blocks/zoominfo.ts index ced43e92033..7d6e756297d 100644 --- a/apps/sim/blocks/blocks/zoominfo.ts +++ b/apps/sim/blocks/blocks/zoominfo.ts @@ -1,20 +1,12 @@ import { ZoomInfoIcon } from '@/components/icons' +import { ZoomInfoBlockDisplay } from '@/blocks/blocks/zoominfo.display' import type { BlockConfig, BlockMeta } from '@/blocks/types' -import { AuthMode, IntegrationType } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' import type { ZoomInfoResponse } from '@/tools/zoominfo/types' export const ZoomInfoBlock: BlockConfig = { - type: 'zoominfo', - name: 'ZoomInfo', - description: 'Search and enrich B2B company and contact data with ZoomInfo.', + ...ZoomInfoBlockDisplay, authMode: AuthMode.ApiKey, - longDescription: - 'Integrates ZoomInfo into the workflow. Search companies and contacts, enrich firmographic and contact data, find intent signals, and pull news — all using the ZoomInfo GTM API.', - docsLink: 'https://docs.sim.ai/integrations/zoominfo', - category: 'tools', - integrationType: IntegrationType.Sales, - bgColor: '#EA1B15', - icon: ZoomInfoIcon, subBlocks: [ { id: 'operation', diff --git a/apps/sim/blocks/icon-color.ts b/apps/sim/blocks/icon-color.ts index 08dccd5f214..138d79fbd35 100644 --- a/apps/sim/blocks/icon-color.ts +++ b/apps/sim/blocks/icon-color.ts @@ -1,5 +1,5 @@ import type { ComponentType, CSSProperties } from 'react' -import { getAllBlocks } from '@/blocks/registry' +import { getAllBlockDisplay } from '@/blocks/manifest' /** A brand icon component that accepts standard styling props. */ export type StyleableIcon = ComponentType<{ className?: string; style?: CSSProperties }> @@ -16,7 +16,7 @@ let iconColorByComponent: Map | null = null function getIconColorMap(): Map { if (iconColorByComponent) return iconColorByComponent const map = new Map() - for (const block of getAllBlocks()) { + for (const block of getAllBlockDisplay()) { if (block.iconColor) map.set(block.icon, block.iconColor) } iconColorByComponent = map diff --git a/apps/sim/blocks/integration-matcher.ts b/apps/sim/blocks/integration-matcher.ts index 148d5cc6a3d..4390068fd11 100644 --- a/apps/sim/blocks/integration-matcher.ts +++ b/apps/sim/blocks/integration-matcher.ts @@ -1,5 +1,5 @@ import { LandingPromptStorage } from '@/lib/core/utils/browser-storage' -import { getCanonicalBlocksByCategory } from '@/blocks/registry' +import { getCanonicalBlockDisplayByCategory } from '@/blocks/manifest' import type { BlockIcon } from '@/blocks/types' /** @@ -50,7 +50,7 @@ function buildMatcher(): IntegrationMatcher { const byName = new Map() const names: string[] = [] - for (const block of getCanonicalBlocksByCategory('tools')) { + for (const block of getCanonicalBlockDisplayByCategory('tools')) { if (!block.name || block.name.trim().length < 2) continue const displayName = normalizeDisplayName(block.name) const key = displayName.toLowerCase() diff --git a/apps/sim/blocks/manifest-data.ts b/apps/sim/blocks/manifest-data.ts new file mode 100644 index 00000000000..790d6382c70 --- /dev/null +++ b/apps/sim/blocks/manifest-data.ts @@ -0,0 +1,4338 @@ +// @generated by scripts/generate-block-manifest-data.ts — do not edit by hand. +// Source of truth is each blocks/blocks/.display.ts. Run `bun run blocks:manifest-data`. +import { A2ABlockDisplay } from '@/blocks/blocks/a2a.display' +import { AgentBlockDisplay } from '@/blocks/blocks/agent.display' +import { AgentMailBlockDisplay } from '@/blocks/blocks/agentmail.display' +import { AgentPhoneBlockDisplay } from '@/blocks/blocks/agentphone.display' +import { AgiloftBlockDisplay } from '@/blocks/blocks/agiloft.display' +import { AhrefsBlockDisplay } from '@/blocks/blocks/ahrefs.display' +import { AirtableBlockDisplay } from '@/blocks/blocks/airtable.display' +import { AirweaveBlockDisplay } from '@/blocks/blocks/airweave.display' +import { AlgoliaBlockDisplay } from '@/blocks/blocks/algolia.display' +import { AmplitudeBlockDisplay } from '@/blocks/blocks/amplitude.display' +import { ApiBlockDisplay } from '@/blocks/blocks/api.display' +import { ApiTriggerBlockDisplay } from '@/blocks/blocks/api_trigger.display' +import { ApifyBlockDisplay } from '@/blocks/blocks/apify.display' +import { ApolloBlockDisplay } from '@/blocks/blocks/apollo.display' +import { AppConfigBlockDisplay } from '@/blocks/blocks/appconfig.display' +import { ArxivBlockDisplay } from '@/blocks/blocks/arxiv.display' +import { AsanaBlockDisplay } from '@/blocks/blocks/asana.display' +import { AshbyBlockDisplay } from '@/blocks/blocks/ashby.display' +import { AthenaBlockDisplay } from '@/blocks/blocks/athena.display' +import { AttioBlockDisplay } from '@/blocks/blocks/attio.display' +import { AzureDevOpsBlockDisplay } from '@/blocks/blocks/azure_devops.display' +import { BoxBlockDisplay } from '@/blocks/blocks/box.display' +import { BrandfetchBlockDisplay } from '@/blocks/blocks/brandfetch.display' +import { BrexBlockDisplay } from '@/blocks/blocks/brex.display' +import { BrightDataBlockDisplay } from '@/blocks/blocks/brightdata.display' +import { BrowserUseBlockDisplay } from '@/blocks/blocks/browser_use.display' +import { CalComBlockDisplay } from '@/blocks/blocks/calcom.display' +import { CalendlyBlockDisplay } from '@/blocks/blocks/calendly.display' +import { ChatTriggerBlockDisplay } from '@/blocks/blocks/chat_trigger.display' +import { CirclebackBlockDisplay } from '@/blocks/blocks/circleback.display' +import { ClayBlockDisplay } from '@/blocks/blocks/clay.display' +import { ClerkBlockDisplay } from '@/blocks/blocks/clerk.display' +import { ClickHouseBlockDisplay } from '@/blocks/blocks/clickhouse.display' +import { CloudflareBlockDisplay } from '@/blocks/blocks/cloudflare.display' +import { CloudFormationBlockDisplay } from '@/blocks/blocks/cloudformation.display' +import { CloudWatchBlockDisplay } from '@/blocks/blocks/cloudwatch.display' +import { CodePipelineBlockDisplay } from '@/blocks/blocks/codepipeline.display' +import { ConditionBlockDisplay } from '@/blocks/blocks/condition.display' +import { + ConfluenceBlockDisplay, + ConfluenceV2BlockDisplay, +} from '@/blocks/blocks/confluence.display' +import { ContextDevBlockDisplay } from '@/blocks/blocks/context_dev.display' +import { ConvexBlockDisplay } from '@/blocks/blocks/convex.display' +import { CredentialBlockDisplay } from '@/blocks/blocks/credential.display' +import { CrowdStrikeBlockDisplay } from '@/blocks/blocks/crowdstrike.display' +import { CursorBlockDisplay, CursorV2BlockDisplay } from '@/blocks/blocks/cursor.display' +import { DagsterBlockDisplay } from '@/blocks/blocks/dagster.display' +import { DatabricksBlockDisplay } from '@/blocks/blocks/databricks.display' +import { DatadogBlockDisplay } from '@/blocks/blocks/datadog.display' +import { DatagmaBlockDisplay } from '@/blocks/blocks/datagma.display' +import { DaytonaBlockDisplay } from '@/blocks/blocks/daytona.display' +import { DeploymentsBlockDisplay } from '@/blocks/blocks/deployments.display' +import { DevinBlockDisplay } from '@/blocks/blocks/devin.display' +import { DiscordBlockDisplay } from '@/blocks/blocks/discord.display' +import { DocuSignBlockDisplay } from '@/blocks/blocks/docusign.display' +import { DropboxBlockDisplay } from '@/blocks/blocks/dropbox.display' +import { DropcontactBlockDisplay } from '@/blocks/blocks/dropcontact.display' +import { DSPyBlockDisplay } from '@/blocks/blocks/dspy.display' +import { DubBlockDisplay } from '@/blocks/blocks/dub.display' +import { DuckDuckGoBlockDisplay } from '@/blocks/blocks/duckduckgo.display' +import { DynamoDBBlockDisplay } from '@/blocks/blocks/dynamodb.display' +import { ElasticsearchBlockDisplay } from '@/blocks/blocks/elasticsearch.display' +import { ElevenLabsBlockDisplay } from '@/blocks/blocks/elevenlabs.display' +import { EmailBisonBlockDisplay } from '@/blocks/blocks/emailbison.display' +import { EnrichBlockDisplay } from '@/blocks/blocks/enrich.display' +import { EnrichmentBlockDisplay } from '@/blocks/blocks/enrichment.display' +import { EnrowBlockDisplay } from '@/blocks/blocks/enrow.display' +import { EvaluatorBlockDisplay } from '@/blocks/blocks/evaluator.display' +import { EvernoteBlockDisplay } from '@/blocks/blocks/evernote.display' +import { ExaBlockDisplay } from '@/blocks/blocks/exa.display' +import { ExtendBlockDisplay, ExtendV2BlockDisplay } from '@/blocks/blocks/extend.display' +import { FathomBlockDisplay } from '@/blocks/blocks/fathom.display' +import { + FileBlockDisplay, + FileV2BlockDisplay, + FileV3BlockDisplay, + FileV4BlockDisplay, + FileV5BlockDisplay, +} from '@/blocks/blocks/file.display' +import { FindymailBlockDisplay } from '@/blocks/blocks/findymail.display' +import { FirecrawlBlockDisplay } from '@/blocks/blocks/firecrawl.display' +import { FirefliesBlockDisplay, FirefliesV2BlockDisplay } from '@/blocks/blocks/fireflies.display' +import { FunctionBlockDisplay } from '@/blocks/blocks/function.display' +import { GammaBlockDisplay } from '@/blocks/blocks/gamma.display' +import { GenericWebhookBlockDisplay } from '@/blocks/blocks/generic_webhook.display' +import { GitHubBlockDisplay, GitHubV2BlockDisplay } from '@/blocks/blocks/github.display' +import { GitLabBlockDisplay } from '@/blocks/blocks/gitlab.display' +import { GmailBlockDisplay, GmailV2BlockDisplay } from '@/blocks/blocks/gmail.display' +import { GongBlockDisplay } from '@/blocks/blocks/gong.display' +import { GoogleSearchBlockDisplay } from '@/blocks/blocks/google.display' +import { GoogleAdsBlockDisplay } from '@/blocks/blocks/google_ads.display' +import { GoogleBigQueryBlockDisplay } from '@/blocks/blocks/google_bigquery.display' +import { GoogleBooksBlockDisplay } from '@/blocks/blocks/google_books.display' +import { + GoogleCalendarBlockDisplay, + GoogleCalendarV2BlockDisplay, +} from '@/blocks/blocks/google_calendar.display' +import { GoogleContactsBlockDisplay } from '@/blocks/blocks/google_contacts.display' +import { GoogleDocsBlockDisplay } from '@/blocks/blocks/google_docs.display' +import { GoogleDriveBlockDisplay } from '@/blocks/blocks/google_drive.display' +import { GoogleFormsBlockDisplay } from '@/blocks/blocks/google_forms.display' +import { GoogleGroupsBlockDisplay } from '@/blocks/blocks/google_groups.display' +import { GoogleMapsBlockDisplay } from '@/blocks/blocks/google_maps.display' +import { GoogleMeetBlockDisplay } from '@/blocks/blocks/google_meet.display' +import { GooglePagespeedBlockDisplay } from '@/blocks/blocks/google_pagespeed.display' +import { + GoogleSheetsBlockDisplay, + GoogleSheetsV2BlockDisplay, +} from '@/blocks/blocks/google_sheets.display' +import { + GoogleSlidesBlockDisplay, + GoogleSlidesV2BlockDisplay, +} from '@/blocks/blocks/google_slides.display' +import { GoogleTasksBlockDisplay } from '@/blocks/blocks/google_tasks.display' +import { GoogleTranslateBlockDisplay } from '@/blocks/blocks/google_translate.display' +import { GoogleVaultBlockDisplay } from '@/blocks/blocks/google_vault.display' +import { GrafanaBlockDisplay } from '@/blocks/blocks/grafana.display' +import { GrainBlockDisplay } from '@/blocks/blocks/grain.display' +import { GranolaBlockDisplay } from '@/blocks/blocks/granola.display' +import { GreenhouseBlockDisplay } from '@/blocks/blocks/greenhouse.display' +import { GreptileBlockDisplay } from '@/blocks/blocks/greptile.display' +import { GuardrailsBlockDisplay } from '@/blocks/blocks/guardrails.display' +import { HexBlockDisplay } from '@/blocks/blocks/hex.display' +import { HubSpotBlockDisplay } from '@/blocks/blocks/hubspot.display' +import { HuggingFaceBlockDisplay } from '@/blocks/blocks/huggingface.display' +import { HumanInTheLoopBlockDisplay } from '@/blocks/blocks/human_in_the_loop.display' +import { HunterBlockDisplay } from '@/blocks/blocks/hunter.display' +import { IAMBlockDisplay } from '@/blocks/blocks/iam.display' +import { IcypeasBlockDisplay } from '@/blocks/blocks/icypeas.display' +import { IdentityCenterBlockDisplay } from '@/blocks/blocks/identity_center.display' +import { + ImageGeneratorBlockDisplay, + ImageGeneratorV2BlockDisplay, +} from '@/blocks/blocks/image_generator.display' +import { ImapBlockDisplay } from '@/blocks/blocks/imap.display' +import { IncidentioBlockDisplay } from '@/blocks/blocks/incidentio.display' +import { InfisicalBlockDisplay } from '@/blocks/blocks/infisical.display' +import { InputTriggerBlockDisplay } from '@/blocks/blocks/input_trigger.display' +import { InstantlyBlockDisplay } from '@/blocks/blocks/instantly.display' +import { IntercomBlockDisplay, IntercomV2BlockDisplay } from '@/blocks/blocks/intercom.display' +import { JinaBlockDisplay } from '@/blocks/blocks/jina.display' +import { JiraBlockDisplay } from '@/blocks/blocks/jira.display' +import { JiraServiceManagementBlockDisplay } from '@/blocks/blocks/jira_service_management.display' +import { KalshiBlockDisplay, KalshiV2BlockDisplay } from '@/blocks/blocks/kalshi.display' +import { KetchBlockDisplay } from '@/blocks/blocks/ketch.display' +import { KnowledgeBlockDisplay } from '@/blocks/blocks/knowledge.display' +import { LangsmithBlockDisplay } from '@/blocks/blocks/langsmith.display' +import { LatexBlockDisplay } from '@/blocks/blocks/latex.display' +import { LaunchDarklyBlockDisplay } from '@/blocks/blocks/launchdarkly.display' +import { LeadMagicBlockDisplay } from '@/blocks/blocks/leadmagic.display' +import { LemlistBlockDisplay } from '@/blocks/blocks/lemlist.display' +import { LinearBlockDisplay, LinearV2BlockDisplay } from '@/blocks/blocks/linear.display' +import { LinkedInBlockDisplay } from '@/blocks/blocks/linkedin.display' +import { LinkupBlockDisplay } from '@/blocks/blocks/linkup.display' +import { LinqBlockDisplay } from '@/blocks/blocks/linq.display' +import { LogsBlockDisplay, LogsV2BlockDisplay } from '@/blocks/blocks/logs.display' +import { LoopsBlockDisplay } from '@/blocks/blocks/loops.display' +import { LumaBlockDisplay } from '@/blocks/blocks/luma.display' +import { MailchimpBlockDisplay } from '@/blocks/blocks/mailchimp.display' +import { MailgunBlockDisplay } from '@/blocks/blocks/mailgun.display' +import { ManualTriggerBlockDisplay } from '@/blocks/blocks/manual_trigger.display' +import { McpBlockDisplay } from '@/blocks/blocks/mcp.display' +import { Mem0BlockDisplay } from '@/blocks/blocks/mem0.display' +import { MemoryBlockDisplay } from '@/blocks/blocks/memory.display' +import { MicrosoftAdBlockDisplay } from '@/blocks/blocks/microsoft_ad.display' +import { MicrosoftDataverseBlockDisplay } from '@/blocks/blocks/microsoft_dataverse.display' +import { + MicrosoftExcelBlockDisplay, + MicrosoftExcelV2BlockDisplay, +} from '@/blocks/blocks/microsoft_excel.display' +import { MicrosoftPlannerBlockDisplay } from '@/blocks/blocks/microsoft_planner.display' +import { MicrosoftTeamsBlockDisplay } from '@/blocks/blocks/microsoft_teams.display' +import { MillionVerifierBlockDisplay } from '@/blocks/blocks/millionverifier.display' +import { + MistralParseBlockDisplay, + MistralParseV2BlockDisplay, + MistralParseV3BlockDisplay, +} from '@/blocks/blocks/mistral_parse.display' +import { MondayBlockDisplay } from '@/blocks/blocks/monday.display' +import { MongoDBBlockDisplay } from '@/blocks/blocks/mongodb.display' +import { MothershipBlockDisplay } from '@/blocks/blocks/mothership.display' +import { MySQLBlockDisplay } from '@/blocks/blocks/mysql.display' +import { Neo4jBlockDisplay } from '@/blocks/blocks/neo4j.display' +import { NeverBounceBlockDisplay } from '@/blocks/blocks/neverbounce.display' +import { NewRelicBlockDisplay } from '@/blocks/blocks/new_relic.display' +import { NoteBlockDisplay } from '@/blocks/blocks/note.display' +import { NotionBlockDisplay, NotionV2BlockDisplay } from '@/blocks/blocks/notion.display' +import { ObsidianBlockDisplay } from '@/blocks/blocks/obsidian.display' +import { OktaBlockDisplay } from '@/blocks/blocks/okta.display' +import { OneDriveBlockDisplay } from '@/blocks/blocks/onedrive.display' +import { OnePasswordBlockDisplay } from '@/blocks/blocks/onepassword.display' +import { OpenAIBlockDisplay } from '@/blocks/blocks/openai.display' +import { OutlookBlockDisplay } from '@/blocks/blocks/outlook.display' +import { PagerDutyBlockDisplay } from '@/blocks/blocks/pagerduty.display' +import { ParallelBlockDisplay } from '@/blocks/blocks/parallel.display' +import { PeopleDataLabsBlockDisplay } from '@/blocks/blocks/peopledatalabs.display' +import { PerplexityBlockDisplay } from '@/blocks/blocks/perplexity.display' +import { PersonaBlockDisplay } from '@/blocks/blocks/persona.display' +import { PiBlockDisplay } from '@/blocks/blocks/pi.display' +import { PineconeBlockDisplay } from '@/blocks/blocks/pinecone.display' +import { PipedriveBlockDisplay } from '@/blocks/blocks/pipedrive.display' +import { PolymarketBlockDisplay } from '@/blocks/blocks/polymarket.display' +import { PostgreSQLBlockDisplay } from '@/blocks/blocks/postgresql.display' +import { PostHogBlockDisplay } from '@/blocks/blocks/posthog.display' +import { ProfoundBlockDisplay } from '@/blocks/blocks/profound.display' +import { ProspeoBlockDisplay } from '@/blocks/blocks/prospeo.display' +import { PulseBlockDisplay, PulseV2BlockDisplay } from '@/blocks/blocks/pulse.display' +import { QdrantBlockDisplay } from '@/blocks/blocks/qdrant.display' +import { QuartrBlockDisplay } from '@/blocks/blocks/quartr.display' +import { QuiverBlockDisplay } from '@/blocks/blocks/quiver.display' +import { RailwayBlockDisplay } from '@/blocks/blocks/railway.display' +import { RB2BBlockDisplay } from '@/blocks/blocks/rb2b.display' +import { RDSBlockDisplay } from '@/blocks/blocks/rds.display' +import { RedditBlockDisplay } from '@/blocks/blocks/reddit.display' +import { RedisBlockDisplay } from '@/blocks/blocks/redis.display' +import { ReductoBlockDisplay, ReductoV2BlockDisplay } from '@/blocks/blocks/reducto.display' +import { ResendBlockDisplay } from '@/blocks/blocks/resend.display' +import { ResponseBlockDisplay } from '@/blocks/blocks/response.display' +import { RevenueCatBlockDisplay } from '@/blocks/blocks/revenuecat.display' +import { RipplingBlockDisplay } from '@/blocks/blocks/rippling.display' +import { RootlyBlockDisplay } from '@/blocks/blocks/rootly.display' +import { RouterBlockDisplay, RouterV2BlockDisplay } from '@/blocks/blocks/router.display' +import { RssBlockDisplay } from '@/blocks/blocks/rss.display' +import { S3BlockDisplay } from '@/blocks/blocks/s3.display' +import { SalesforceBlockDisplay } from '@/blocks/blocks/salesforce.display' +import { SapConcurBlockDisplay } from '@/blocks/blocks/sap_concur.display' +import { SapS4HanaBlockDisplay } from '@/blocks/blocks/sap_s4hana.display' +import { ScheduleBlockDisplay } from '@/blocks/blocks/schedule.display' +import { SearchBlockDisplay } from '@/blocks/blocks/search.display' +import { SecretsManagerBlockDisplay } from '@/blocks/blocks/secrets_manager.display' +import { SendblueBlockDisplay } from '@/blocks/blocks/sendblue.display' +import { SendGridBlockDisplay } from '@/blocks/blocks/sendgrid.display' +import { SentryBlockDisplay } from '@/blocks/blocks/sentry.display' +import { SerperBlockDisplay } from '@/blocks/blocks/serper.display' +import { ServiceNowBlockDisplay } from '@/blocks/blocks/servicenow.display' +import { SESBlockDisplay } from '@/blocks/blocks/ses.display' +import { SftpBlockDisplay } from '@/blocks/blocks/sftp.display' +import { + SharepointBlockDisplay, + SharepointV2BlockDisplay, +} from '@/blocks/blocks/sharepoint.display' +import { ShopifyBlockDisplay } from '@/blocks/blocks/shopify.display' +import { SimWorkspaceEventBlockDisplay } from '@/blocks/blocks/sim_workspace_event.display' +import { SimilarwebBlockDisplay } from '@/blocks/blocks/similarweb.display' +import { SixtyfourBlockDisplay } from '@/blocks/blocks/sixtyfour.display' +import { SlackBlockDisplay } from '@/blocks/blocks/slack.display' +import { SmtpBlockDisplay } from '@/blocks/blocks/smtp.display' +import { SportmonksBlockDisplay } from '@/blocks/blocks/sportmonks.display' +import { SpotifyBlockDisplay } from '@/blocks/blocks/spotify.display' +import { SQSBlockDisplay } from '@/blocks/blocks/sqs.display' +import { SquareBlockDisplay } from '@/blocks/blocks/square.display' +import { SSHBlockDisplay } from '@/blocks/blocks/ssh.display' +import { StagehandBlockDisplay } from '@/blocks/blocks/stagehand.display' +import { StartTriggerBlockDisplay } from '@/blocks/blocks/start_trigger.display' +import { StarterBlockDisplay } from '@/blocks/blocks/starter.display' +import { StripeBlockDisplay } from '@/blocks/blocks/stripe.display' +import { STSBlockDisplay } from '@/blocks/blocks/sts.display' +import { SttBlockDisplay, SttV2BlockDisplay } from '@/blocks/blocks/stt.display' +import { SupabaseBlockDisplay } from '@/blocks/blocks/supabase.display' +import { TableBlockDisplay } from '@/blocks/blocks/table.display' +import { TailscaleBlockDisplay } from '@/blocks/blocks/tailscale.display' +import { TavilyBlockDisplay } from '@/blocks/blocks/tavily.display' +import { TelegramBlockDisplay } from '@/blocks/blocks/telegram.display' +import { TemporalBlockDisplay } from '@/blocks/blocks/temporal.display' +import { TextractBlockDisplay, TextractV2BlockDisplay } from '@/blocks/blocks/textract.display' +import { ThinkingBlockDisplay } from '@/blocks/blocks/thinking.display' +import { ThriveBlockDisplay } from '@/blocks/blocks/thrive.display' +import { TinybirdBlockDisplay } from '@/blocks/blocks/tinybird.display' +import { TranslateBlockDisplay } from '@/blocks/blocks/translate.display' +import { TrelloBlockDisplay } from '@/blocks/blocks/trello.display' +import { TriggerDevBlockDisplay } from '@/blocks/blocks/trigger_dev.display' +import { TtsBlockDisplay } from '@/blocks/blocks/tts.display' +import { TwilioSMSBlockDisplay } from '@/blocks/blocks/twilio.display' +import { TwilioVoiceBlockDisplay } from '@/blocks/blocks/twilio_voice.display' +import { TypeformBlockDisplay } from '@/blocks/blocks/typeform.display' +import { UpstashBlockDisplay } from '@/blocks/blocks/upstash.display' +import { VantaBlockDisplay } from '@/blocks/blocks/vanta.display' +import { VariablesBlockDisplay } from '@/blocks/blocks/variables.display' +import { VercelBlockDisplay } from '@/blocks/blocks/vercel.display' +import { + VideoGeneratorBlockDisplay, + VideoGeneratorV2BlockDisplay, + VideoGeneratorV3BlockDisplay, +} from '@/blocks/blocks/video_generator.display' +import { VisionBlockDisplay, VisionV2BlockDisplay } from '@/blocks/blocks/vision.display' +import { WaitBlockDisplay } from '@/blocks/blocks/wait.display' +import { WealthboxBlockDisplay } from '@/blocks/blocks/wealthbox.display' +import { WebflowBlockDisplay } from '@/blocks/blocks/webflow.display' +import { WebhookRequestBlockDisplay } from '@/blocks/blocks/webhook_request.display' +import { WhatsAppBlockDisplay } from '@/blocks/blocks/whatsapp.display' +import { WikipediaBlockDisplay } from '@/blocks/blocks/wikipedia.display' +import { WizaBlockDisplay } from '@/blocks/blocks/wiza.display' +import { WordPressBlockDisplay } from '@/blocks/blocks/wordpress.display' +import { WorkdayBlockDisplay } from '@/blocks/blocks/workday.display' +import { WorkflowBlockDisplay } from '@/blocks/blocks/workflow.display' +import { WorkflowInputBlockDisplay } from '@/blocks/blocks/workflow_input.display' +import { XBlockDisplay } from '@/blocks/blocks/x.display' +import { YouTubeBlockDisplay } from '@/blocks/blocks/youtube.display' +import { ZendeskBlockDisplay } from '@/blocks/blocks/zendesk.display' +import { ZepBlockDisplay } from '@/blocks/blocks/zep.display' +import { ZeroBounceBlockDisplay } from '@/blocks/blocks/zerobounce.display' +import { ZoomBlockDisplay } from '@/blocks/blocks/zoom.display' +import { ZoomInfoBlockDisplay } from '@/blocks/blocks/zoominfo.display' +import type { BlockDisplay } from '@/blocks/manifest' +import type { BlockMeta } from '@/blocks/types' + +/** Light display slice for every registered block, keyed by registry type. */ +export const BLOCK_DISPLAY: Record = { + a2a: A2ABlockDisplay, + agent: AgentBlockDisplay, + agentmail: AgentMailBlockDisplay, + agentphone: AgentPhoneBlockDisplay, + agiloft: AgiloftBlockDisplay, + ahrefs: AhrefsBlockDisplay, + airtable: AirtableBlockDisplay, + airweave: AirweaveBlockDisplay, + algolia: AlgoliaBlockDisplay, + amplitude: AmplitudeBlockDisplay, + api: ApiBlockDisplay, + api_trigger: ApiTriggerBlockDisplay, + apify: ApifyBlockDisplay, + apollo: ApolloBlockDisplay, + appconfig: AppConfigBlockDisplay, + arxiv: ArxivBlockDisplay, + asana: AsanaBlockDisplay, + ashby: AshbyBlockDisplay, + athena: AthenaBlockDisplay, + attio: AttioBlockDisplay, + azure_devops: AzureDevOpsBlockDisplay, + box: BoxBlockDisplay, + brandfetch: BrandfetchBlockDisplay, + brex: BrexBlockDisplay, + brightdata: BrightDataBlockDisplay, + browser_use: BrowserUseBlockDisplay, + calcom: CalComBlockDisplay, + calendly: CalendlyBlockDisplay, + chat_trigger: ChatTriggerBlockDisplay, + circleback: CirclebackBlockDisplay, + clay: ClayBlockDisplay, + clerk: ClerkBlockDisplay, + clickhouse: ClickHouseBlockDisplay, + cloudflare: CloudflareBlockDisplay, + cloudformation: CloudFormationBlockDisplay, + cloudwatch: CloudWatchBlockDisplay, + codepipeline: CodePipelineBlockDisplay, + condition: ConditionBlockDisplay, + confluence: ConfluenceBlockDisplay, + confluence_v2: ConfluenceV2BlockDisplay, + context_dev: ContextDevBlockDisplay, + convex: ConvexBlockDisplay, + credential: CredentialBlockDisplay, + crowdstrike: CrowdStrikeBlockDisplay, + cursor: CursorBlockDisplay, + cursor_v2: CursorV2BlockDisplay, + dagster: DagsterBlockDisplay, + databricks: DatabricksBlockDisplay, + datadog: DatadogBlockDisplay, + datagma: DatagmaBlockDisplay, + daytona: DaytonaBlockDisplay, + deployments: DeploymentsBlockDisplay, + devin: DevinBlockDisplay, + discord: DiscordBlockDisplay, + docusign: DocuSignBlockDisplay, + dropbox: DropboxBlockDisplay, + dropcontact: DropcontactBlockDisplay, + dspy: DSPyBlockDisplay, + dub: DubBlockDisplay, + duckduckgo: DuckDuckGoBlockDisplay, + dynamodb: DynamoDBBlockDisplay, + elasticsearch: ElasticsearchBlockDisplay, + elevenlabs: ElevenLabsBlockDisplay, + emailbison: EmailBisonBlockDisplay, + enrich: EnrichBlockDisplay, + enrichment: EnrichmentBlockDisplay, + enrow: EnrowBlockDisplay, + evaluator: EvaluatorBlockDisplay, + evernote: EvernoteBlockDisplay, + exa: ExaBlockDisplay, + extend: ExtendBlockDisplay, + extend_v2: ExtendV2BlockDisplay, + fathom: FathomBlockDisplay, + file: FileBlockDisplay, + file_v2: FileV2BlockDisplay, + file_v3: FileV3BlockDisplay, + file_v4: FileV4BlockDisplay, + file_v5: FileV5BlockDisplay, + findymail: FindymailBlockDisplay, + firecrawl: FirecrawlBlockDisplay, + fireflies: FirefliesBlockDisplay, + fireflies_v2: FirefliesV2BlockDisplay, + function: FunctionBlockDisplay, + gamma: GammaBlockDisplay, + generic_webhook: GenericWebhookBlockDisplay, + github: GitHubBlockDisplay, + github_v2: GitHubV2BlockDisplay, + gitlab: GitLabBlockDisplay, + gmail: GmailBlockDisplay, + gmail_v2: GmailV2BlockDisplay, + gong: GongBlockDisplay, + google_ads: GoogleAdsBlockDisplay, + google_bigquery: GoogleBigQueryBlockDisplay, + google_books: GoogleBooksBlockDisplay, + google_calendar: GoogleCalendarBlockDisplay, + google_calendar_v2: GoogleCalendarV2BlockDisplay, + google_contacts: GoogleContactsBlockDisplay, + google_docs: GoogleDocsBlockDisplay, + google_drive: GoogleDriveBlockDisplay, + google_forms: GoogleFormsBlockDisplay, + google_groups: GoogleGroupsBlockDisplay, + google_maps: GoogleMapsBlockDisplay, + google_meet: GoogleMeetBlockDisplay, + google_pagespeed: GooglePagespeedBlockDisplay, + google_search: GoogleSearchBlockDisplay, + google_sheets: GoogleSheetsBlockDisplay, + google_sheets_v2: GoogleSheetsV2BlockDisplay, + google_slides: GoogleSlidesBlockDisplay, + google_slides_v2: GoogleSlidesV2BlockDisplay, + google_tasks: GoogleTasksBlockDisplay, + google_translate: GoogleTranslateBlockDisplay, + google_vault: GoogleVaultBlockDisplay, + grafana: GrafanaBlockDisplay, + grain: GrainBlockDisplay, + granola: GranolaBlockDisplay, + greenhouse: GreenhouseBlockDisplay, + greptile: GreptileBlockDisplay, + guardrails: GuardrailsBlockDisplay, + hex: HexBlockDisplay, + hubspot: HubSpotBlockDisplay, + huggingface: HuggingFaceBlockDisplay, + human_in_the_loop: HumanInTheLoopBlockDisplay, + hunter: HunterBlockDisplay, + iam: IAMBlockDisplay, + icypeas: IcypeasBlockDisplay, + identity_center: IdentityCenterBlockDisplay, + image_generator: ImageGeneratorBlockDisplay, + image_generator_v2: ImageGeneratorV2BlockDisplay, + imap: ImapBlockDisplay, + incidentio: IncidentioBlockDisplay, + infisical: InfisicalBlockDisplay, + input_trigger: InputTriggerBlockDisplay, + instantly: InstantlyBlockDisplay, + intercom: IntercomBlockDisplay, + intercom_v2: IntercomV2BlockDisplay, + jina: JinaBlockDisplay, + jira: JiraBlockDisplay, + jira_service_management: JiraServiceManagementBlockDisplay, + kalshi: KalshiBlockDisplay, + kalshi_v2: KalshiV2BlockDisplay, + ketch: KetchBlockDisplay, + knowledge: KnowledgeBlockDisplay, + langsmith: LangsmithBlockDisplay, + latex: LatexBlockDisplay, + launchdarkly: LaunchDarklyBlockDisplay, + leadmagic: LeadMagicBlockDisplay, + lemlist: LemlistBlockDisplay, + linear: LinearBlockDisplay, + linear_v2: LinearV2BlockDisplay, + linkedin: LinkedInBlockDisplay, + linkup: LinkupBlockDisplay, + linq: LinqBlockDisplay, + logs: LogsBlockDisplay, + logs_v2: LogsV2BlockDisplay, + loops: LoopsBlockDisplay, + luma: LumaBlockDisplay, + mailchimp: MailchimpBlockDisplay, + mailgun: MailgunBlockDisplay, + manual_trigger: ManualTriggerBlockDisplay, + mcp: McpBlockDisplay, + mem0: Mem0BlockDisplay, + memory: MemoryBlockDisplay, + microsoft_ad: MicrosoftAdBlockDisplay, + microsoft_dataverse: MicrosoftDataverseBlockDisplay, + microsoft_excel: MicrosoftExcelBlockDisplay, + microsoft_excel_v2: MicrosoftExcelV2BlockDisplay, + microsoft_planner: MicrosoftPlannerBlockDisplay, + microsoft_teams: MicrosoftTeamsBlockDisplay, + millionverifier: MillionVerifierBlockDisplay, + mistral_parse: MistralParseBlockDisplay, + mistral_parse_v2: MistralParseV2BlockDisplay, + mistral_parse_v3: MistralParseV3BlockDisplay, + monday: MondayBlockDisplay, + mongodb: MongoDBBlockDisplay, + mothership: MothershipBlockDisplay, + mysql: MySQLBlockDisplay, + neo4j: Neo4jBlockDisplay, + neverbounce: NeverBounceBlockDisplay, + new_relic: NewRelicBlockDisplay, + note: NoteBlockDisplay, + notion: NotionBlockDisplay, + notion_v2: NotionV2BlockDisplay, + obsidian: ObsidianBlockDisplay, + okta: OktaBlockDisplay, + onedrive: OneDriveBlockDisplay, + onepassword: OnePasswordBlockDisplay, + openai: OpenAIBlockDisplay, + outlook: OutlookBlockDisplay, + pagerduty: PagerDutyBlockDisplay, + parallel_ai: ParallelBlockDisplay, + peopledatalabs: PeopleDataLabsBlockDisplay, + perplexity: PerplexityBlockDisplay, + persona: PersonaBlockDisplay, + pi: PiBlockDisplay, + pinecone: PineconeBlockDisplay, + pipedrive: PipedriveBlockDisplay, + polymarket: PolymarketBlockDisplay, + postgresql: PostgreSQLBlockDisplay, + posthog: PostHogBlockDisplay, + profound: ProfoundBlockDisplay, + prospeo: ProspeoBlockDisplay, + pulse: PulseBlockDisplay, + pulse_v2: PulseV2BlockDisplay, + qdrant: QdrantBlockDisplay, + quartr: QuartrBlockDisplay, + quiver: QuiverBlockDisplay, + railway: RailwayBlockDisplay, + rb2b: RB2BBlockDisplay, + rds: RDSBlockDisplay, + reddit: RedditBlockDisplay, + redis: RedisBlockDisplay, + reducto: ReductoBlockDisplay, + reducto_v2: ReductoV2BlockDisplay, + resend: ResendBlockDisplay, + response: ResponseBlockDisplay, + revenuecat: RevenueCatBlockDisplay, + rippling: RipplingBlockDisplay, + rootly: RootlyBlockDisplay, + router: RouterBlockDisplay, + router_v2: RouterV2BlockDisplay, + rss: RssBlockDisplay, + s3: S3BlockDisplay, + salesforce: SalesforceBlockDisplay, + sap_concur: SapConcurBlockDisplay, + sap_s4hana: SapS4HanaBlockDisplay, + schedule: ScheduleBlockDisplay, + search: SearchBlockDisplay, + secrets_manager: SecretsManagerBlockDisplay, + sendblue: SendblueBlockDisplay, + sendgrid: SendGridBlockDisplay, + sentry: SentryBlockDisplay, + serper: SerperBlockDisplay, + servicenow: ServiceNowBlockDisplay, + ses: SESBlockDisplay, + sftp: SftpBlockDisplay, + sharepoint: SharepointBlockDisplay, + sharepoint_v2: SharepointV2BlockDisplay, + shopify: ShopifyBlockDisplay, + sim_workspace_event: SimWorkspaceEventBlockDisplay, + similarweb: SimilarwebBlockDisplay, + sixtyfour: SixtyfourBlockDisplay, + slack: SlackBlockDisplay, + smtp: SmtpBlockDisplay, + sportmonks: SportmonksBlockDisplay, + spotify: SpotifyBlockDisplay, + sqs: SQSBlockDisplay, + square: SquareBlockDisplay, + ssh: SSHBlockDisplay, + stagehand: StagehandBlockDisplay, + start_trigger: StartTriggerBlockDisplay, + starter: StarterBlockDisplay, + stripe: StripeBlockDisplay, + sts: STSBlockDisplay, + stt: SttBlockDisplay, + stt_v2: SttV2BlockDisplay, + supabase: SupabaseBlockDisplay, + table: TableBlockDisplay, + tailscale: TailscaleBlockDisplay, + tavily: TavilyBlockDisplay, + telegram: TelegramBlockDisplay, + temporal: TemporalBlockDisplay, + textract: TextractBlockDisplay, + textract_v2: TextractV2BlockDisplay, + thinking: ThinkingBlockDisplay, + thrive: ThriveBlockDisplay, + tinybird: TinybirdBlockDisplay, + translate: TranslateBlockDisplay, + trello: TrelloBlockDisplay, + trigger_dev: TriggerDevBlockDisplay, + tts: TtsBlockDisplay, + twilio_sms: TwilioSMSBlockDisplay, + twilio_voice: TwilioVoiceBlockDisplay, + typeform: TypeformBlockDisplay, + upstash: UpstashBlockDisplay, + vanta: VantaBlockDisplay, + variables: VariablesBlockDisplay, + vercel: VercelBlockDisplay, + video_generator: VideoGeneratorBlockDisplay, + video_generator_v2: VideoGeneratorV2BlockDisplay, + video_generator_v3: VideoGeneratorV3BlockDisplay, + vision: VisionBlockDisplay, + vision_v2: VisionV2BlockDisplay, + wait: WaitBlockDisplay, + wealthbox: WealthboxBlockDisplay, + webflow: WebflowBlockDisplay, + webhook_request: WebhookRequestBlockDisplay, + whatsapp: WhatsAppBlockDisplay, + wikipedia: WikipediaBlockDisplay, + wiza: WizaBlockDisplay, + wordpress: WordPressBlockDisplay, + workday: WorkdayBlockDisplay, + workflow: WorkflowBlockDisplay, + workflow_input: WorkflowInputBlockDisplay, + x: XBlockDisplay, + youtube: YouTubeBlockDisplay, + zendesk: ZendeskBlockDisplay, + zep: ZepBlockDisplay, + zerobounce: ZeroBounceBlockDisplay, + zoom: ZoomBlockDisplay, + zoominfo: ZoomInfoBlockDisplay, +} + +/** Tool id → owning block type, for tool-name → icon/color resolution. */ +export const TOOL_TO_BLOCK: Record = { + a2a_cancel_task: 'a2a', + a2a_delete_push_notification: 'a2a', + a2a_get_agent_card: 'a2a', + a2a_get_push_notification: 'a2a', + a2a_get_task: 'a2a', + a2a_resubscribe: 'a2a', + a2a_send_message: 'a2a', + a2a_set_push_notification: 'a2a', + agentmail_create_draft: 'agentmail', + agentmail_create_inbox: 'agentmail', + agentmail_delete_draft: 'agentmail', + agentmail_delete_inbox: 'agentmail', + agentmail_delete_thread: 'agentmail', + agentmail_forward_message: 'agentmail', + agentmail_get_draft: 'agentmail', + agentmail_get_inbox: 'agentmail', + agentmail_get_message: 'agentmail', + agentmail_get_thread: 'agentmail', + agentmail_list_drafts: 'agentmail', + agentmail_list_inboxes: 'agentmail', + agentmail_list_messages: 'agentmail', + agentmail_list_threads: 'agentmail', + agentmail_reply_message: 'agentmail', + agentmail_send_draft: 'agentmail', + agentmail_send_message: 'agentmail', + agentmail_update_draft: 'agentmail', + agentmail_update_inbox: 'agentmail', + agentmail_update_message: 'agentmail', + agentmail_update_thread: 'agentmail', + agentphone_create_call: 'agentphone', + agentphone_create_contact: 'agentphone', + agentphone_create_number: 'agentphone', + agentphone_delete_contact: 'agentphone', + agentphone_get_call: 'agentphone', + agentphone_get_call_transcript: 'agentphone', + agentphone_get_contact: 'agentphone', + agentphone_get_conversation: 'agentphone', + agentphone_get_conversation_messages: 'agentphone', + agentphone_get_number_messages: 'agentphone', + agentphone_get_usage: 'agentphone', + agentphone_get_usage_daily: 'agentphone', + agentphone_get_usage_monthly: 'agentphone', + agentphone_list_calls: 'agentphone', + agentphone_list_contacts: 'agentphone', + agentphone_list_conversations: 'agentphone', + agentphone_list_numbers: 'agentphone', + agentphone_react_to_message: 'agentphone', + agentphone_release_number: 'agentphone', + agentphone_send_message: 'agentphone', + agentphone_update_contact: 'agentphone', + agentphone_update_conversation: 'agentphone', + agiloft_attach_file: 'agiloft', + agiloft_attachment_info: 'agiloft', + agiloft_create_record: 'agiloft', + agiloft_delete_record: 'agiloft', + agiloft_get_choice_line_id: 'agiloft', + agiloft_lock_record: 'agiloft', + agiloft_read_record: 'agiloft', + agiloft_remove_attachment: 'agiloft', + agiloft_retrieve_attachment: 'agiloft', + agiloft_saved_search: 'agiloft', + agiloft_search_records: 'agiloft', + agiloft_select_records: 'agiloft', + agiloft_update_record: 'agiloft', + ahrefs_backlinks: 'ahrefs', + ahrefs_backlinks_stats: 'ahrefs', + ahrefs_broken_backlinks: 'ahrefs', + ahrefs_domain_rating: 'ahrefs', + ahrefs_keyword_overview: 'ahrefs', + ahrefs_organic_keywords: 'ahrefs', + ahrefs_referring_domains: 'ahrefs', + ahrefs_top_pages: 'ahrefs', + airtable_create_records: 'airtable', + airtable_get_base_schema: 'airtable', + airtable_get_record: 'airtable', + airtable_list_bases: 'airtable', + airtable_list_records: 'airtable', + airtable_list_tables: 'airtable', + airtable_update_multiple_records: 'airtable', + airtable_update_record: 'airtable', + airweave_search: 'airweave', + algolia_add_record: 'algolia', + algolia_batch_operations: 'algolia', + algolia_browse_records: 'algolia', + algolia_clear_records: 'algolia', + algolia_copy_move_index: 'algolia', + algolia_delete_by_filter: 'algolia', + algolia_delete_index: 'algolia', + algolia_delete_record: 'algolia', + algolia_get_record: 'algolia', + algolia_get_records: 'algolia', + algolia_get_settings: 'algolia', + algolia_list_indices: 'algolia', + algolia_partial_update_record: 'algolia', + algolia_search: 'algolia', + algolia_update_settings: 'algolia', + amplitude_event_segmentation: 'amplitude', + amplitude_get_active_users: 'amplitude', + amplitude_get_revenue: 'amplitude', + amplitude_group_identify: 'amplitude', + amplitude_identify_user: 'amplitude', + amplitude_list_events: 'amplitude', + amplitude_realtime_active_users: 'amplitude', + amplitude_send_event: 'amplitude', + amplitude_user_activity: 'amplitude', + amplitude_user_profile: 'amplitude', + amplitude_user_search: 'amplitude', + anthropic_chat: 'router_v2', + apify_get_dataset_items: 'apify', + apify_get_run: 'apify', + apify_run_actor_async: 'apify', + apify_run_actor_sync: 'apify', + apify_run_task: 'apify', + apollo_account_bulk_create: 'apollo', + apollo_account_bulk_update: 'apollo', + apollo_account_create: 'apollo', + apollo_account_search: 'apollo', + apollo_account_update: 'apollo', + apollo_contact_bulk_create: 'apollo', + apollo_contact_bulk_update: 'apollo', + apollo_contact_create: 'apollo', + apollo_contact_search: 'apollo', + apollo_contact_update: 'apollo', + apollo_email_accounts: 'apollo', + apollo_opportunity_create: 'apollo', + apollo_opportunity_get: 'apollo', + apollo_opportunity_search: 'apollo', + apollo_opportunity_update: 'apollo', + apollo_organization_bulk_enrich: 'apollo', + apollo_organization_enrich: 'apollo', + apollo_organization_search: 'apollo', + apollo_people_bulk_enrich: 'apollo', + apollo_people_enrich: 'apollo', + apollo_people_search: 'apollo', + apollo_sequence_add_contacts: 'apollo', + apollo_sequence_search: 'apollo', + apollo_task_create: 'apollo', + apollo_task_search: 'apollo', + appconfig_create_application: 'appconfig', + appconfig_create_configuration_profile: 'appconfig', + appconfig_create_environment: 'appconfig', + appconfig_create_hosted_configuration_version: 'appconfig', + appconfig_delete_application: 'appconfig', + appconfig_delete_configuration_profile: 'appconfig', + appconfig_delete_environment: 'appconfig', + appconfig_delete_hosted_configuration_version: 'appconfig', + appconfig_get_application: 'appconfig', + appconfig_get_configuration: 'appconfig', + appconfig_get_configuration_profile: 'appconfig', + appconfig_get_deployment: 'appconfig', + appconfig_get_environment: 'appconfig', + appconfig_get_hosted_configuration_version: 'appconfig', + appconfig_list_applications: 'appconfig', + appconfig_list_configuration_profiles: 'appconfig', + appconfig_list_deployment_strategies: 'appconfig', + appconfig_list_deployments: 'appconfig', + appconfig_list_environments: 'appconfig', + appconfig_list_hosted_configuration_versions: 'appconfig', + appconfig_start_deployment: 'appconfig', + appconfig_stop_deployment: 'appconfig', + appconfig_update_application: 'appconfig', + appconfig_update_configuration_profile: 'appconfig', + appconfig_update_environment: 'appconfig', + arxiv_get_author_papers: 'arxiv', + arxiv_get_paper: 'arxiv', + arxiv_search: 'arxiv', + asana_add_comment: 'asana', + asana_create_task: 'asana', + asana_get_projects: 'asana', + asana_get_task: 'asana', + asana_search_tasks: 'asana', + asana_update_task: 'asana', + ashby_add_candidate_tag: 'ashby', + ashby_change_application_stage: 'ashby', + ashby_create_application: 'ashby', + ashby_create_candidate: 'ashby', + ashby_create_note: 'ashby', + ashby_get_application: 'ashby', + ashby_get_candidate: 'ashby', + ashby_get_job: 'ashby', + ashby_get_job_posting: 'ashby', + ashby_get_offer: 'ashby', + ashby_list_applications: 'ashby', + ashby_list_archive_reasons: 'ashby', + ashby_list_candidate_tags: 'ashby', + ashby_list_candidates: 'ashby', + ashby_list_custom_fields: 'ashby', + ashby_list_departments: 'ashby', + ashby_list_interviews: 'ashby', + ashby_list_job_postings: 'ashby', + ashby_list_jobs: 'ashby', + ashby_list_locations: 'ashby', + ashby_list_notes: 'ashby', + ashby_list_offers: 'ashby', + ashby_list_openings: 'ashby', + ashby_list_sources: 'ashby', + ashby_list_users: 'ashby', + ashby_remove_candidate_tag: 'ashby', + ashby_search_candidates: 'ashby', + ashby_update_candidate: 'ashby', + athena_create_named_query: 'athena', + athena_get_named_query: 'athena', + athena_get_query_execution: 'athena', + athena_get_query_results: 'athena', + athena_list_named_queries: 'athena', + athena_list_query_executions: 'athena', + athena_start_query: 'athena', + athena_stop_query: 'athena', + attio_assert_record: 'attio', + attio_create_comment: 'attio', + attio_create_list: 'attio', + attio_create_list_entry: 'attio', + attio_create_note: 'attio', + attio_create_object: 'attio', + attio_create_record: 'attio', + attio_create_task: 'attio', + attio_create_webhook: 'attio', + attio_delete_comment: 'attio', + attio_delete_list_entry: 'attio', + attio_delete_note: 'attio', + attio_delete_record: 'attio', + attio_delete_task: 'attio', + attio_delete_webhook: 'attio', + attio_get_comment: 'attio', + attio_get_list: 'attio', + attio_get_list_entry: 'attio', + attio_get_member: 'attio', + attio_get_note: 'attio', + attio_get_object: 'attio', + attio_get_record: 'attio', + attio_get_task: 'attio', + attio_get_thread: 'attio', + attio_get_webhook: 'attio', + attio_list_lists: 'attio', + attio_list_members: 'attio', + attio_list_notes: 'attio', + attio_list_objects: 'attio', + attio_list_records: 'attio', + attio_list_tasks: 'attio', + attio_list_threads: 'attio', + attio_list_webhooks: 'attio', + attio_query_list_entries: 'attio', + attio_search_records: 'attio', + attio_update_list: 'attio', + attio_update_list_entry: 'attio', + attio_update_object: 'attio', + attio_update_record: 'attio', + attio_update_task: 'attio', + attio_update_webhook: 'attio', + azure_devops_add_comment: 'azure_devops', + azure_devops_create_work_item: 'azure_devops', + azure_devops_get_build_log: 'azure_devops', + azure_devops_get_build_timeline: 'azure_devops', + azure_devops_get_comments: 'azure_devops', + azure_devops_get_pipeline: 'azure_devops', + azure_devops_get_pipeline_run: 'azure_devops', + azure_devops_get_work_item: 'azure_devops', + azure_devops_get_work_items_batch: 'azure_devops', + azure_devops_get_work_items_between_builds: 'azure_devops', + azure_devops_list_build_logs: 'azure_devops', + azure_devops_list_builds: 'azure_devops', + azure_devops_list_pipeline_runs: 'azure_devops', + azure_devops_list_pipelines: 'azure_devops', + azure_devops_query_work_items: 'azure_devops', + azure_devops_update_work_item: 'azure_devops', + box_copy_file: 'box', + box_create_folder: 'box', + box_delete_file: 'box', + box_delete_folder: 'box', + box_download_file: 'box', + box_get_file_info: 'box', + box_list_folder_items: 'box', + box_search: 'box', + box_sign_cancel_request: 'box', + box_sign_create_request: 'box', + box_sign_get_request: 'box', + box_sign_list_requests: 'box', + box_sign_resend_request: 'box', + box_update_file: 'box', + box_upload_file: 'box', + brandfetch_get_brand: 'brandfetch', + brandfetch_search: 'brandfetch', + brex_get_budget: 'brex', + brex_get_cash_account: 'brex', + brex_get_company: 'brex', + brex_get_current_user: 'brex', + brex_get_expense: 'brex', + brex_get_spend_limit: 'brex', + brex_get_transfer: 'brex', + brex_get_user: 'brex', + brex_get_vendor: 'brex', + brex_list_budgets: 'brex', + brex_list_card_accounts: 'brex', + brex_list_card_statements: 'brex', + brex_list_card_transactions: 'brex', + brex_list_cards: 'brex', + brex_list_cash_accounts: 'brex', + brex_list_cash_statements: 'brex', + brex_list_cash_transactions: 'brex', + brex_list_departments: 'brex', + brex_list_expenses: 'brex', + brex_list_locations: 'brex', + brex_list_spend_limits: 'brex', + brex_list_titles: 'brex', + brex_list_transfers: 'brex', + brex_list_users: 'brex', + brex_list_vendors: 'brex', + brex_match_receipt: 'brex', + brex_update_expense: 'brex', + brex_upload_receipt: 'brex', + brightdata_cancel_snapshot: 'brightdata', + brightdata_discover: 'brightdata', + brightdata_download_snapshot: 'brightdata', + brightdata_scrape_dataset: 'brightdata', + brightdata_scrape_url: 'brightdata', + brightdata_serp_search: 'brightdata', + brightdata_snapshot_status: 'brightdata', + brightdata_sync_scrape: 'brightdata', + browser_use_run_task: 'browser_use', + calcom_cancel_booking: 'calcom', + calcom_confirm_booking: 'calcom', + calcom_create_booking: 'calcom', + calcom_create_event_type: 'calcom', + calcom_create_schedule: 'calcom', + calcom_decline_booking: 'calcom', + calcom_delete_event_type: 'calcom', + calcom_delete_schedule: 'calcom', + calcom_get_booking: 'calcom', + calcom_get_default_schedule: 'calcom', + calcom_get_event_type: 'calcom', + calcom_get_schedule: 'calcom', + calcom_get_slots: 'calcom', + calcom_list_bookings: 'calcom', + calcom_list_event_types: 'calcom', + calcom_list_schedules: 'calcom', + calcom_reschedule_booking: 'calcom', + calcom_update_event_type: 'calcom', + calcom_update_schedule: 'calcom', + calendly_cancel_event: 'calendly', + calendly_get_current_user: 'calendly', + calendly_get_event_type: 'calendly', + calendly_get_scheduled_event: 'calendly', + calendly_list_event_invitees: 'calendly', + calendly_list_event_types: 'calendly', + calendly_list_scheduled_events: 'calendly', + clay_populate: 'clay', + clerk_create_organization: 'clerk', + clerk_create_user: 'clerk', + clerk_delete_user: 'clerk', + clerk_get_organization: 'clerk', + clerk_get_session: 'clerk', + clerk_get_user: 'clerk', + clerk_list_organizations: 'clerk', + clerk_list_sessions: 'clerk', + clerk_list_users: 'clerk', + clerk_revoke_session: 'clerk', + clerk_update_user: 'clerk', + clickhouse_count_rows: 'clickhouse', + clickhouse_create_database: 'clickhouse', + clickhouse_create_table: 'clickhouse', + clickhouse_delete: 'clickhouse', + clickhouse_describe_table: 'clickhouse', + clickhouse_drop_database: 'clickhouse', + clickhouse_drop_partition: 'clickhouse', + clickhouse_drop_table: 'clickhouse', + clickhouse_execute: 'clickhouse', + clickhouse_insert: 'clickhouse', + clickhouse_insert_rows: 'clickhouse', + clickhouse_introspect: 'clickhouse', + clickhouse_kill_query: 'clickhouse', + clickhouse_list_clusters: 'clickhouse', + clickhouse_list_databases: 'clickhouse', + clickhouse_list_mutations: 'clickhouse', + clickhouse_list_partitions: 'clickhouse', + clickhouse_list_running_queries: 'clickhouse', + clickhouse_list_tables: 'clickhouse', + clickhouse_optimize_table: 'clickhouse', + clickhouse_query: 'clickhouse', + clickhouse_rename_table: 'clickhouse', + clickhouse_show_create_table: 'clickhouse', + clickhouse_table_stats: 'clickhouse', + clickhouse_truncate_table: 'clickhouse', + clickhouse_update: 'clickhouse', + cloudflare_create_dns_record: 'cloudflare', + cloudflare_create_zone: 'cloudflare', + cloudflare_delete_dns_record: 'cloudflare', + cloudflare_delete_zone: 'cloudflare', + cloudflare_dns_analytics: 'cloudflare', + cloudflare_get_zone: 'cloudflare', + cloudflare_get_zone_settings: 'cloudflare', + cloudflare_list_certificates: 'cloudflare', + cloudflare_list_dns_records: 'cloudflare', + cloudflare_list_zones: 'cloudflare', + cloudflare_purge_cache: 'cloudflare', + cloudflare_update_dns_record: 'cloudflare', + cloudflare_update_zone_setting: 'cloudflare', + cloudformation_describe_stack_drift_detection_status: 'cloudformation', + cloudformation_describe_stack_events: 'cloudformation', + cloudformation_describe_stacks: 'cloudformation', + cloudformation_detect_stack_drift: 'cloudformation', + cloudformation_get_template: 'cloudformation', + cloudformation_list_stack_resources: 'cloudformation', + cloudformation_validate_template: 'cloudformation', + cloudwatch_describe_alarms: 'cloudwatch', + cloudwatch_describe_log_groups: 'cloudwatch', + cloudwatch_describe_log_streams: 'cloudwatch', + cloudwatch_get_log_events: 'cloudwatch', + cloudwatch_get_metric_statistics: 'cloudwatch', + cloudwatch_list_metrics: 'cloudwatch', + cloudwatch_mute_alarm: 'cloudwatch', + cloudwatch_put_metric_data: 'cloudwatch', + cloudwatch_query_logs: 'cloudwatch', + cloudwatch_unmute_alarm: 'cloudwatch', + codepipeline_get_pipeline_execution: 'codepipeline', + codepipeline_get_pipeline_state: 'codepipeline', + codepipeline_list_pipeline_executions: 'codepipeline', + codepipeline_list_pipelines: 'codepipeline', + codepipeline_put_approval_result: 'codepipeline', + codepipeline_retry_stage_execution: 'codepipeline', + codepipeline_start_execution: 'codepipeline', + codepipeline_stop_execution: 'codepipeline', + confluence_add_label: 'confluence_v2', + confluence_create_blogpost: 'confluence_v2', + confluence_create_comment: 'confluence_v2', + confluence_create_page: 'confluence_v2', + confluence_create_page_property: 'confluence_v2', + confluence_create_space: 'confluence_v2', + confluence_create_space_property: 'confluence_v2', + confluence_delete_attachment: 'confluence_v2', + confluence_delete_blogpost: 'confluence_v2', + confluence_delete_comment: 'confluence_v2', + confluence_delete_label: 'confluence_v2', + confluence_delete_page: 'confluence_v2', + confluence_delete_page_property: 'confluence_v2', + confluence_delete_space: 'confluence_v2', + confluence_delete_space_property: 'confluence_v2', + confluence_get_blogpost: 'confluence_v2', + confluence_get_page_ancestors: 'confluence_v2', + confluence_get_page_children: 'confluence_v2', + confluence_get_page_descendants: 'confluence_v2', + confluence_get_page_version: 'confluence_v2', + confluence_get_pages_by_label: 'confluence_v2', + confluence_get_space: 'confluence_v2', + confluence_get_task: 'confluence_v2', + confluence_get_user: 'confluence_v2', + confluence_list_attachments: 'confluence_v2', + confluence_list_blogposts: 'confluence_v2', + confluence_list_blogposts_in_space: 'confluence_v2', + confluence_list_comments: 'confluence_v2', + confluence_list_labels: 'confluence_v2', + confluence_list_page_properties: 'confluence_v2', + confluence_list_page_versions: 'confluence_v2', + confluence_list_pages_in_space: 'confluence_v2', + confluence_list_space_labels: 'confluence_v2', + confluence_list_space_permissions: 'confluence_v2', + confluence_list_space_properties: 'confluence_v2', + confluence_list_spaces: 'confluence_v2', + confluence_list_tasks: 'confluence_v2', + confluence_retrieve: 'confluence_v2', + confluence_search: 'confluence_v2', + confluence_search_in_space: 'confluence_v2', + confluence_update: 'confluence_v2', + confluence_update_blogpost: 'confluence_v2', + confluence_update_comment: 'confluence_v2', + confluence_update_space: 'confluence_v2', + confluence_update_task: 'confluence_v2', + confluence_upload_attachment: 'confluence_v2', + context_dev_classify_naics: 'context_dev', + context_dev_classify_sic: 'context_dev', + context_dev_crawl: 'context_dev', + context_dev_extract: 'context_dev', + context_dev_extract_product: 'context_dev', + context_dev_extract_products: 'context_dev', + context_dev_get_brand: 'context_dev', + context_dev_get_brand_by_email: 'context_dev', + context_dev_get_brand_by_name: 'context_dev', + context_dev_get_brand_by_ticker: 'context_dev', + context_dev_get_brand_simplified: 'context_dev', + context_dev_identify_transaction: 'context_dev', + context_dev_map: 'context_dev', + context_dev_prefetch_by_email: 'context_dev', + context_dev_prefetch_domain: 'context_dev', + context_dev_scrape_fonts: 'context_dev', + context_dev_scrape_html: 'context_dev', + context_dev_scrape_images: 'context_dev', + context_dev_scrape_markdown: 'context_dev', + context_dev_scrape_styleguide: 'context_dev', + context_dev_screenshot: 'context_dev', + context_dev_search: 'context_dev', + convex_action: 'convex', + convex_document_deltas: 'convex', + convex_list_documents: 'convex', + convex_list_tables: 'convex', + convex_mutation: 'convex', + convex_query: 'convex', + convex_run_function: 'convex', + crowdstrike_get_sensor_aggregates: 'crowdstrike', + crowdstrike_get_sensor_details: 'crowdstrike', + crowdstrike_query_sensors: 'crowdstrike', + cursor_add_followup: 'cursor', + cursor_add_followup_v2: 'cursor_v2', + cursor_delete_agent: 'cursor', + cursor_delete_agent_v2: 'cursor_v2', + cursor_download_artifact: 'cursor', + cursor_download_artifact_v2: 'cursor_v2', + cursor_get_agent: 'cursor', + cursor_get_agent_v2: 'cursor_v2', + cursor_get_api_key_info: 'cursor', + cursor_get_api_key_info_v2: 'cursor_v2', + cursor_get_conversation: 'cursor', + cursor_get_conversation_v2: 'cursor_v2', + cursor_launch_agent: 'cursor', + cursor_launch_agent_v2: 'cursor_v2', + cursor_list_agents: 'cursor', + cursor_list_agents_v2: 'cursor_v2', + cursor_list_artifacts: 'cursor', + cursor_list_artifacts_v2: 'cursor_v2', + cursor_list_models: 'cursor', + cursor_list_models_v2: 'cursor_v2', + cursor_list_repositories: 'cursor', + cursor_list_repositories_v2: 'cursor_v2', + cursor_stop_agent: 'cursor', + cursor_stop_agent_v2: 'cursor_v2', + dagster_delete_run: 'dagster', + dagster_get_asset: 'dagster', + dagster_get_run: 'dagster', + dagster_get_run_logs: 'dagster', + dagster_launch_run: 'dagster', + dagster_list_assets: 'dagster', + dagster_list_jobs: 'dagster', + dagster_list_runs: 'dagster', + dagster_list_schedules: 'dagster', + dagster_list_sensors: 'dagster', + dagster_materialize_assets: 'dagster', + dagster_reexecute_run: 'dagster', + dagster_report_asset_materialization: 'dagster', + dagster_start_schedule: 'dagster', + dagster_start_sensor: 'dagster', + dagster_stop_schedule: 'dagster', + dagster_stop_sensor: 'dagster', + dagster_terminate_run: 'dagster', + dagster_wipe_asset: 'dagster', + databricks_cancel_run: 'databricks', + databricks_execute_sql: 'databricks', + databricks_get_cluster: 'databricks', + databricks_get_job: 'databricks', + databricks_get_run: 'databricks', + databricks_get_run_output: 'databricks', + databricks_get_statement: 'databricks', + databricks_list_clusters: 'databricks', + databricks_list_jobs: 'databricks', + databricks_list_runs: 'databricks', + databricks_list_warehouses: 'databricks', + databricks_run_job: 'databricks', + datadog_cancel_downtime: 'datadog', + datadog_create_downtime: 'datadog', + datadog_create_event: 'datadog', + datadog_create_monitor: 'datadog', + datadog_get_monitor: 'datadog', + datadog_list_downtimes: 'datadog', + datadog_list_monitors: 'datadog', + datadog_mute_monitor: 'datadog', + datadog_query_logs: 'datadog', + datadog_query_timeseries: 'datadog', + datadog_send_logs: 'datadog', + datadog_submit_metrics: 'datadog', + datagma_enrich_company: 'datagma', + datagma_enrich_person: 'datagma', + datagma_find_email: 'datagma', + datagma_find_phone: 'datagma', + datagma_get_credits: 'datagma', + daytona_create_sandbox: 'daytona', + daytona_delete_sandbox: 'daytona', + daytona_download_file: 'daytona', + daytona_execute_command: 'daytona', + daytona_get_sandbox: 'daytona', + daytona_git_clone: 'daytona', + daytona_list_files: 'daytona', + daytona_list_sandboxes: 'daytona', + daytona_run_code: 'daytona', + daytona_start_sandbox: 'daytona', + daytona_stop_sandbox: 'daytona', + daytona_upload_file: 'daytona', + deepseek_chat: 'router_v2', + deepseek_reasoner: 'router_v2', + deployments_deploy: 'deployments', + deployments_get_version: 'deployments', + deployments_list_versions: 'deployments', + deployments_promote: 'deployments', + deployments_undeploy: 'deployments', + devin_append_session_tags: 'devin', + devin_archive_session: 'devin', + devin_create_session: 'devin', + devin_get_session: 'devin', + devin_get_session_tags: 'devin', + devin_list_session_attachments: 'devin', + devin_list_session_messages: 'devin', + devin_list_sessions: 'devin', + devin_replace_session_tags: 'devin', + devin_send_message: 'devin', + devin_terminate_session: 'devin', + discord_add_reaction: 'discord', + discord_archive_thread: 'discord', + discord_assign_role: 'discord', + discord_ban_member: 'discord', + discord_create_channel: 'discord', + discord_create_invite: 'discord', + discord_create_role: 'discord', + discord_create_thread: 'discord', + discord_create_webhook: 'discord', + discord_delete_channel: 'discord', + discord_delete_invite: 'discord', + discord_delete_message: 'discord', + discord_delete_role: 'discord', + discord_delete_webhook: 'discord', + discord_edit_message: 'discord', + discord_execute_webhook: 'discord', + discord_get_channel: 'discord', + discord_get_invite: 'discord', + discord_get_member: 'discord', + discord_get_messages: 'discord', + discord_get_server: 'discord', + discord_get_user: 'discord', + discord_get_webhook: 'discord', + discord_join_thread: 'discord', + discord_kick_member: 'discord', + discord_leave_thread: 'discord', + discord_pin_message: 'discord', + discord_remove_reaction: 'discord', + discord_remove_role: 'discord', + discord_send_message: 'discord', + discord_unban_member: 'discord', + discord_unpin_message: 'discord', + discord_update_channel: 'discord', + discord_update_member: 'discord', + discord_update_role: 'discord', + docusign_create_from_template: 'docusign', + docusign_download_document: 'docusign', + docusign_get_envelope: 'docusign', + docusign_list_envelopes: 'docusign', + docusign_list_recipients: 'docusign', + docusign_list_templates: 'docusign', + docusign_send_envelope: 'docusign', + docusign_void_envelope: 'docusign', + dropbox_copy: 'dropbox', + dropbox_create_folder: 'dropbox', + dropbox_create_shared_link: 'dropbox', + dropbox_delete: 'dropbox', + dropbox_download: 'dropbox', + dropbox_get_metadata: 'dropbox', + dropbox_list_folder: 'dropbox', + dropbox_move: 'dropbox', + dropbox_search: 'dropbox', + dropbox_upload: 'dropbox', + dropcontact_enrich_contact: 'dropcontact', + dspy_chain_of_thought: 'dspy', + dspy_predict: 'dspy', + dspy_react: 'dspy', + dub_bulk_create_links: 'dub', + dub_bulk_delete_links: 'dub', + dub_bulk_update_links: 'dub', + dub_create_link: 'dub', + dub_delete_link: 'dub', + dub_get_analytics: 'dub', + dub_get_events: 'dub', + dub_get_link: 'dub', + dub_get_links_count: 'dub', + dub_get_qr_code: 'dub', + dub_list_links: 'dub', + dub_update_link: 'dub', + dub_upsert_link: 'dub', + duckduckgo_search: 'duckduckgo', + dynamodb_delete: 'dynamodb', + dynamodb_get: 'dynamodb', + dynamodb_introspect: 'dynamodb', + dynamodb_put: 'dynamodb', + dynamodb_query: 'dynamodb', + dynamodb_scan: 'dynamodb', + dynamodb_update: 'dynamodb', + elasticsearch_bulk: 'elasticsearch', + elasticsearch_cluster_health: 'elasticsearch', + elasticsearch_cluster_stats: 'elasticsearch', + elasticsearch_count: 'elasticsearch', + elasticsearch_create_index: 'elasticsearch', + elasticsearch_delete_document: 'elasticsearch', + elasticsearch_delete_index: 'elasticsearch', + elasticsearch_get_document: 'elasticsearch', + elasticsearch_get_index: 'elasticsearch', + elasticsearch_index_document: 'elasticsearch', + elasticsearch_list_indices: 'elasticsearch', + elasticsearch_search: 'elasticsearch', + elasticsearch_update_document: 'elasticsearch', + elevenlabs_tts: 'elevenlabs', + emailbison_attach_leads_to_campaign: 'emailbison', + emailbison_attach_tags_to_leads: 'emailbison', + emailbison_create_campaign: 'emailbison', + emailbison_create_lead: 'emailbison', + emailbison_create_tag: 'emailbison', + emailbison_get_lead: 'emailbison', + emailbison_list_campaigns: 'emailbison', + emailbison_list_leads: 'emailbison', + emailbison_list_replies: 'emailbison', + emailbison_list_tags: 'emailbison', + emailbison_update_campaign: 'emailbison', + emailbison_update_campaign_status: 'emailbison', + emailbison_update_lead: 'emailbison', + enrich_check_credits: 'enrich', + enrich_company_funding: 'enrich', + enrich_company_lookup: 'enrich', + enrich_company_revenue: 'enrich', + enrich_disposable_email_check: 'enrich', + enrich_email_to_ip: 'enrich', + enrich_email_to_person_lite: 'enrich', + enrich_email_to_phone: 'enrich', + enrich_email_to_profile: 'enrich', + enrich_find_email: 'enrich', + enrich_get_post_details: 'enrich', + enrich_ip_to_company: 'enrich', + enrich_linkedin_profile: 'enrich', + enrich_linkedin_to_personal_email: 'enrich', + enrich_linkedin_to_work_email: 'enrich', + enrich_phone_finder: 'enrich', + enrich_reverse_hash_lookup: 'enrich', + enrich_sales_pointer_people: 'enrich', + enrich_search_company: 'enrich', + enrich_search_company_activities: 'enrich', + enrich_search_company_employees: 'enrich', + enrich_search_jobs: 'enrich', + enrich_search_logo: 'enrich', + enrich_search_people: 'enrich', + enrich_search_people_activities: 'enrich', + enrich_search_post_comments: 'enrich', + enrich_search_post_comments_by_url: 'enrich', + enrich_search_post_reactions: 'enrich', + enrich_search_post_reactions_by_url: 'enrich', + enrich_search_posts: 'enrich', + enrich_search_similar_companies: 'enrich', + enrich_verify_email: 'enrich', + enrichment_run: 'enrichment', + enrow_find_email: 'enrow', + enrow_verify_email: 'enrow', + evernote_copy_note: 'evernote', + evernote_create_note: 'evernote', + evernote_create_notebook: 'evernote', + evernote_create_tag: 'evernote', + evernote_delete_note: 'evernote', + evernote_get_note: 'evernote', + evernote_get_notebook: 'evernote', + evernote_list_notebooks: 'evernote', + evernote_list_tags: 'evernote', + evernote_search_notes: 'evernote', + evernote_update_note: 'evernote', + exa_answer: 'exa', + exa_find_similar_links: 'exa', + exa_get_contents: 'exa', + exa_research: 'exa', + exa_search: 'exa', + extend_parser: 'extend', + extend_parser_v2: 'extend_v2', + fathom_get_summary: 'fathom', + fathom_get_transcript: 'fathom', + fathom_list_meetings: 'fathom', + fathom_list_team_members: 'fathom', + fathom_list_teams: 'fathom', + file_append: 'file_v5', + file_compress: 'file_v5', + file_decompress: 'file_v5', + file_fetch: 'file_v5', + file_get: 'file_v3', + file_get_content: 'file_v5', + file_manage_sharing: 'file_v5', + file_parser: 'file', + file_parser_v2: 'file_v2', + file_parser_v3: 'file_v3', + file_read: 'file_v5', + file_write: 'file_v5', + findymail_find_email_from_linkedin: 'findymail', + findymail_find_email_from_name: 'findymail', + findymail_find_emails_by_domain: 'findymail', + findymail_find_employees: 'findymail', + findymail_find_phone: 'findymail', + findymail_get_company: 'findymail', + findymail_get_credits: 'findymail', + findymail_lookup_technologies: 'findymail', + findymail_reverse_email_lookup: 'findymail', + findymail_search_technologies: 'findymail', + findymail_verify_email: 'findymail', + firecrawl_agent: 'firecrawl', + firecrawl_crawl: 'firecrawl', + firecrawl_extract: 'firecrawl', + firecrawl_map: 'firecrawl', + firecrawl_parse: 'firecrawl', + firecrawl_scrape: 'firecrawl', + firecrawl_search: 'firecrawl', + fireflies_add_to_live_meeting: 'fireflies_v2', + fireflies_create_bite: 'fireflies_v2', + fireflies_delete_transcript: 'fireflies_v2', + fireflies_get_transcript: 'fireflies_v2', + fireflies_get_user: 'fireflies_v2', + fireflies_list_bites: 'fireflies_v2', + fireflies_list_contacts: 'fireflies_v2', + fireflies_list_transcripts: 'fireflies_v2', + fireflies_list_users: 'fireflies_v2', + fireflies_upload_audio: 'fireflies_v2', + function_execute: 'function', + gamma_check_status: 'gamma', + gamma_generate: 'gamma', + gamma_generate_from_template: 'gamma', + gamma_list_folders: 'gamma', + gamma_list_themes: 'gamma', + github_add_assignees: 'github', + github_add_assignees_v2: 'github_v2', + github_add_labels: 'github', + github_add_labels_v2: 'github_v2', + github_cancel_workflow_run: 'github', + github_cancel_workflow_run_v2: 'github_v2', + github_check_star: 'github', + github_check_star_v2: 'github_v2', + github_close_issue: 'github', + github_close_issue_v2: 'github_v2', + github_close_pr: 'github', + github_close_pr_v2: 'github_v2', + github_comment: 'github', + github_comment_v2: 'github_v2', + github_compare_commits: 'github', + github_compare_commits_v2: 'github_v2', + github_create_branch: 'github', + github_create_branch_v2: 'github_v2', + github_create_comment_reaction: 'github', + github_create_comment_reaction_v2: 'github_v2', + github_create_file: 'github', + github_create_file_v2: 'github_v2', + github_create_gist: 'github', + github_create_gist_v2: 'github_v2', + github_create_issue: 'github', + github_create_issue_reaction: 'github', + github_create_issue_reaction_v2: 'github_v2', + github_create_issue_v2: 'github_v2', + github_create_milestone: 'github', + github_create_milestone_v2: 'github_v2', + github_create_pr: 'github', + github_create_pr_v2: 'github_v2', + github_create_project: 'github', + github_create_project_v2: 'github_v2', + github_create_release: 'github', + github_create_release_v2: 'github_v2', + github_delete_branch: 'github', + github_delete_branch_v2: 'github_v2', + github_delete_comment: 'github', + github_delete_comment_reaction: 'github', + github_delete_comment_reaction_v2: 'github_v2', + github_delete_comment_v2: 'github_v2', + github_delete_file: 'github', + github_delete_file_v2: 'github_v2', + github_delete_gist: 'github', + github_delete_gist_v2: 'github_v2', + github_delete_issue_reaction: 'github', + github_delete_issue_reaction_v2: 'github_v2', + github_delete_milestone: 'github', + github_delete_milestone_v2: 'github_v2', + github_delete_project: 'github', + github_delete_project_v2: 'github_v2', + github_delete_release: 'github', + github_delete_release_v2: 'github_v2', + github_fork_gist: 'github', + github_fork_gist_v2: 'github_v2', + github_fork_repo: 'github', + github_fork_repo_v2: 'github_v2', + github_get_branch: 'github', + github_get_branch_protection: 'github', + github_get_branch_protection_v2: 'github_v2', + github_get_branch_v2: 'github_v2', + github_get_commit: 'github', + github_get_commit_v2: 'github_v2', + github_get_file_content: 'github', + github_get_file_content_v2: 'github_v2', + github_get_gist: 'github', + github_get_gist_v2: 'github_v2', + github_get_issue: 'github', + github_get_issue_v2: 'github_v2', + github_get_milestone: 'github', + github_get_milestone_v2: 'github_v2', + github_get_pr_files: 'github', + github_get_pr_files_v2: 'github_v2', + github_get_project: 'github', + github_get_project_v2: 'github_v2', + github_get_release: 'github', + github_get_release_v2: 'github_v2', + github_get_tree: 'github', + github_get_tree_v2: 'github_v2', + github_get_workflow: 'github', + github_get_workflow_run: 'github', + github_get_workflow_run_v2: 'github_v2', + github_get_workflow_v2: 'github_v2', + github_issue_comment: 'github', + github_issue_comment_v2: 'github_v2', + github_latest_commit: 'github', + github_latest_commit_v2: 'github_v2', + github_list_branches: 'github', + github_list_branches_v2: 'github_v2', + github_list_commits: 'github', + github_list_commits_v2: 'github_v2', + github_list_forks: 'github', + github_list_forks_v2: 'github_v2', + github_list_gists: 'github', + github_list_gists_v2: 'github_v2', + github_list_issue_comments: 'github', + github_list_issue_comments_v2: 'github_v2', + github_list_issues: 'github', + github_list_issues_v2: 'github_v2', + github_list_milestones: 'github', + github_list_milestones_v2: 'github_v2', + github_list_pr_comments: 'github', + github_list_pr_comments_v2: 'github_v2', + github_list_projects: 'github', + github_list_projects_v2: 'github_v2', + github_list_prs: 'github', + github_list_prs_v2: 'github_v2', + github_list_releases: 'github', + github_list_releases_v2: 'github_v2', + github_list_stargazers: 'github', + github_list_stargazers_v2: 'github_v2', + github_list_workflow_runs: 'github', + github_list_workflow_runs_v2: 'github_v2', + github_list_workflows: 'github', + github_list_workflows_v2: 'github_v2', + github_merge_pr: 'github', + github_merge_pr_v2: 'github_v2', + github_pr: 'github', + github_pr_v2: 'github_v2', + github_remove_label: 'github', + github_remove_label_v2: 'github_v2', + github_repo_info: 'github', + github_repo_info_v2: 'github_v2', + github_request_reviewers: 'github', + github_request_reviewers_v2: 'github_v2', + github_rerun_workflow: 'github', + github_rerun_workflow_v2: 'github_v2', + github_search_code: 'github', + github_search_code_v2: 'github_v2', + github_search_commits: 'github', + github_search_commits_v2: 'github_v2', + github_search_issues: 'github', + github_search_issues_v2: 'github_v2', + github_search_repos: 'github', + github_search_repos_v2: 'github_v2', + github_search_users: 'github', + github_search_users_v2: 'github_v2', + github_star_gist: 'github', + github_star_gist_v2: 'github_v2', + github_star_repo: 'github', + github_star_repo_v2: 'github_v2', + github_trigger_workflow: 'github', + github_trigger_workflow_v2: 'github_v2', + github_unstar_gist: 'github', + github_unstar_gist_v2: 'github_v2', + github_unstar_repo: 'github', + github_unstar_repo_v2: 'github_v2', + github_update_branch_protection: 'github', + github_update_branch_protection_v2: 'github_v2', + github_update_comment: 'github', + github_update_comment_v2: 'github_v2', + github_update_file: 'github', + github_update_file_v2: 'github_v2', + github_update_gist: 'github', + github_update_gist_v2: 'github_v2', + github_update_issue: 'github', + github_update_issue_v2: 'github_v2', + github_update_milestone: 'github', + github_update_milestone_v2: 'github_v2', + github_update_pr: 'github', + github_update_pr_v2: 'github_v2', + github_update_project: 'github', + github_update_project_v2: 'github_v2', + github_update_release: 'github', + github_update_release_v2: 'github_v2', + gitlab_approve_merge_request: 'gitlab', + gitlab_cancel_pipeline: 'gitlab', + gitlab_create_branch: 'gitlab', + gitlab_create_file: 'gitlab', + gitlab_create_issue: 'gitlab', + gitlab_create_issue_note: 'gitlab', + gitlab_create_merge_request: 'gitlab', + gitlab_create_merge_request_note: 'gitlab', + gitlab_create_pipeline: 'gitlab', + gitlab_delete_issue: 'gitlab', + gitlab_get_file: 'gitlab', + gitlab_get_issue: 'gitlab', + gitlab_get_job_log: 'gitlab', + gitlab_get_merge_request: 'gitlab', + gitlab_get_merge_request_changes: 'gitlab', + gitlab_get_pipeline: 'gitlab', + gitlab_get_project: 'gitlab', + gitlab_list_branches: 'gitlab', + gitlab_list_commits: 'gitlab', + gitlab_list_issues: 'gitlab', + gitlab_list_merge_requests: 'gitlab', + gitlab_list_pipeline_jobs: 'gitlab', + gitlab_list_pipelines: 'gitlab', + gitlab_list_projects: 'gitlab', + gitlab_list_repository_tree: 'gitlab', + gitlab_merge_merge_request: 'gitlab', + gitlab_play_job: 'gitlab', + gitlab_retry_pipeline: 'gitlab', + gitlab_update_file: 'gitlab', + gitlab_update_issue: 'gitlab', + gitlab_update_merge_request: 'gitlab', + gmail_add_label: 'gmail', + gmail_add_label_v2: 'gmail_v2', + gmail_archive: 'gmail', + gmail_archive_v2: 'gmail_v2', + gmail_delete: 'gmail', + gmail_delete_v2: 'gmail_v2', + gmail_draft: 'gmail', + gmail_draft_v2: 'gmail_v2', + gmail_edit_draft_v2: 'gmail_v2', + gmail_mark_read: 'gmail', + gmail_mark_read_v2: 'gmail_v2', + gmail_mark_unread: 'gmail', + gmail_mark_unread_v2: 'gmail_v2', + gmail_move: 'gmail', + gmail_move_v2: 'gmail_v2', + gmail_read: 'gmail', + gmail_read_v2: 'gmail_v2', + gmail_remove_label: 'gmail', + gmail_remove_label_v2: 'gmail_v2', + gmail_search: 'gmail', + gmail_search_v2: 'gmail_v2', + gmail_send: 'gmail', + gmail_send_v2: 'gmail_v2', + gmail_unarchive: 'gmail', + gmail_unarchive_v2: 'gmail_v2', + gong_aggregate_activity: 'gong', + gong_aggregate_by_period: 'gong', + gong_answered_scorecards: 'gong', + gong_create_call: 'gong', + gong_day_by_day_activity: 'gong', + gong_get_call: 'gong', + gong_get_call_transcript: 'gong', + gong_get_coaching: 'gong', + gong_get_extensive_calls: 'gong', + gong_get_folder_content: 'gong', + gong_get_user: 'gong', + gong_interaction_stats: 'gong', + gong_list_calls: 'gong', + gong_list_flows: 'gong', + gong_list_library_folders: 'gong', + gong_list_scorecards: 'gong', + gong_list_trackers: 'gong', + gong_list_users: 'gong', + gong_list_workspaces: 'gong', + gong_lookup_email: 'gong', + gong_lookup_phone: 'gong', + google_ads_ad_performance: 'google_ads', + google_ads_campaign_performance: 'google_ads', + google_ads_list_ad_groups: 'google_ads', + google_ads_list_campaigns: 'google_ads', + google_ads_list_customers: 'google_ads', + google_ads_search: 'google_ads', + google_bigquery_get_table: 'google_bigquery', + google_bigquery_insert_rows: 'google_bigquery', + google_bigquery_list_datasets: 'google_bigquery', + google_bigquery_list_tables: 'google_bigquery', + google_bigquery_query: 'google_bigquery', + google_books_volume_details: 'google_books', + google_books_volume_search: 'google_books', + google_calendar_create: 'google_calendar', + google_calendar_create_calendar: 'google_calendar', + google_calendar_create_calendar_v2: 'google_calendar_v2', + google_calendar_create_v2: 'google_calendar_v2', + google_calendar_delete: 'google_calendar', + google_calendar_delete_v2: 'google_calendar_v2', + google_calendar_freebusy: 'google_calendar', + google_calendar_freebusy_v2: 'google_calendar_v2', + google_calendar_get: 'google_calendar', + google_calendar_get_v2: 'google_calendar_v2', + google_calendar_instances: 'google_calendar', + google_calendar_instances_v2: 'google_calendar_v2', + google_calendar_invite: 'google_calendar', + google_calendar_invite_v2: 'google_calendar_v2', + google_calendar_list: 'google_calendar', + google_calendar_list_acl: 'google_calendar', + google_calendar_list_acl_v2: 'google_calendar_v2', + google_calendar_list_calendars: 'google_calendar', + google_calendar_list_calendars_v2: 'google_calendar_v2', + google_calendar_list_v2: 'google_calendar_v2', + google_calendar_move: 'google_calendar', + google_calendar_move_v2: 'google_calendar_v2', + google_calendar_quick_add: 'google_calendar', + google_calendar_quick_add_v2: 'google_calendar_v2', + google_calendar_share_calendar: 'google_calendar', + google_calendar_share_calendar_v2: 'google_calendar_v2', + google_calendar_unshare_calendar: 'google_calendar', + google_calendar_unshare_calendar_v2: 'google_calendar_v2', + google_calendar_update: 'google_calendar', + google_calendar_update_v2: 'google_calendar_v2', + google_chat: 'router_v2', + google_contacts_create: 'google_contacts', + google_contacts_delete: 'google_contacts', + google_contacts_get: 'google_contacts', + google_contacts_list: 'google_contacts', + google_contacts_search: 'google_contacts', + google_contacts_update: 'google_contacts', + google_docs_create: 'google_docs', + google_docs_read: 'google_docs', + google_docs_write: 'google_docs', + google_drive_copy: 'google_drive', + google_drive_create_folder: 'google_drive', + google_drive_delete: 'google_drive', + google_drive_download: 'google_drive', + google_drive_get_about: 'google_drive', + google_drive_get_content: 'google_drive', + google_drive_get_file: 'google_drive', + google_drive_list: 'google_drive', + google_drive_list_permissions: 'google_drive', + google_drive_move: 'google_drive', + google_drive_search: 'google_drive', + google_drive_share: 'google_drive', + google_drive_trash: 'google_drive', + google_drive_unshare: 'google_drive', + google_drive_untrash: 'google_drive', + google_drive_update: 'google_drive', + google_drive_upload: 'google_drive', + google_forms_batch_update: 'google_forms', + google_forms_create_form: 'google_forms', + google_forms_create_watch: 'google_forms', + google_forms_delete_watch: 'google_forms', + google_forms_get_form: 'google_forms', + google_forms_get_responses: 'google_forms', + google_forms_list_watches: 'google_forms', + google_forms_renew_watch: 'google_forms', + google_forms_set_publish_settings: 'google_forms', + google_groups_add_alias: 'google_groups', + google_groups_add_member: 'google_groups', + google_groups_create_group: 'google_groups', + google_groups_delete_group: 'google_groups', + google_groups_get_group: 'google_groups', + google_groups_get_member: 'google_groups', + google_groups_get_settings: 'google_groups', + google_groups_has_member: 'google_groups', + google_groups_list_aliases: 'google_groups', + google_groups_list_groups: 'google_groups', + google_groups_list_members: 'google_groups', + google_groups_remove_alias: 'google_groups', + google_groups_remove_member: 'google_groups', + google_groups_update_group: 'google_groups', + google_groups_update_member: 'google_groups', + google_groups_update_settings: 'google_groups', + google_maps_air_quality: 'google_maps', + google_maps_directions: 'google_maps', + google_maps_distance_matrix: 'google_maps', + google_maps_elevation: 'google_maps', + google_maps_geocode: 'google_maps', + google_maps_geolocate: 'google_maps', + google_maps_place_details: 'google_maps', + google_maps_places_search: 'google_maps', + google_maps_pollen: 'google_maps', + google_maps_reverse_geocode: 'google_maps', + google_maps_snap_to_roads: 'google_maps', + google_maps_solar: 'google_maps', + google_maps_speed_limits: 'google_maps', + google_maps_timezone: 'google_maps', + google_maps_validate_address: 'google_maps', + google_meet_create_space: 'google_meet', + google_meet_end_conference: 'google_meet', + google_meet_get_conference_record: 'google_meet', + google_meet_get_space: 'google_meet', + google_meet_list_conference_records: 'google_meet', + google_meet_list_participants: 'google_meet', + google_pagespeed_analyze: 'google_pagespeed', + google_search: 'google_search', + google_sheets_append: 'google_sheets', + google_sheets_append_v2: 'google_sheets_v2', + google_sheets_batch_clear_v2: 'google_sheets_v2', + google_sheets_batch_get_v2: 'google_sheets_v2', + google_sheets_batch_update_v2: 'google_sheets_v2', + google_sheets_clear_v2: 'google_sheets_v2', + google_sheets_copy_sheet_v2: 'google_sheets_v2', + google_sheets_create_spreadsheet_v2: 'google_sheets_v2', + google_sheets_delete_rows_v2: 'google_sheets_v2', + google_sheets_delete_sheet_v2: 'google_sheets_v2', + google_sheets_delete_spreadsheet_v2: 'google_sheets_v2', + google_sheets_get_spreadsheet_v2: 'google_sheets_v2', + google_sheets_read: 'google_sheets', + google_sheets_read_v2: 'google_sheets_v2', + google_sheets_update: 'google_sheets', + google_sheets_update_v2: 'google_sheets_v2', + google_sheets_write: 'google_sheets', + google_sheets_write_v2: 'google_sheets_v2', + google_slides_add_image: 'google_slides_v2', + google_slides_add_slide: 'google_slides_v2', + google_slides_batch_update: 'google_slides_v2', + google_slides_copy_presentation: 'google_slides_v2', + google_slides_create: 'google_slides_v2', + google_slides_create_line: 'google_slides_v2', + google_slides_create_paragraph_bullets: 'google_slides_v2', + google_slides_create_shape: 'google_slides_v2', + google_slides_create_sheets_chart: 'google_slides_v2', + google_slides_create_table: 'google_slides_v2', + google_slides_create_video: 'google_slides_v2', + google_slides_delete_object: 'google_slides_v2', + google_slides_delete_paragraph_bullets: 'google_slides_v2', + google_slides_delete_table_column: 'google_slides_v2', + google_slides_delete_table_row: 'google_slides_v2', + google_slides_delete_text: 'google_slides_v2', + google_slides_duplicate_object: 'google_slides_v2', + google_slides_export_presentation: 'google_slides_v2', + google_slides_get_page: 'google_slides_v2', + google_slides_get_thumbnail: 'google_slides_v2', + google_slides_group_objects: 'google_slides_v2', + google_slides_insert_table_columns: 'google_slides_v2', + google_slides_insert_table_rows: 'google_slides_v2', + google_slides_insert_text: 'google_slides_v2', + google_slides_merge_table_cells: 'google_slides_v2', + google_slides_read: 'google_slides_v2', + google_slides_refresh_sheets_chart: 'google_slides_v2', + google_slides_replace_all_shapes_with_image: 'google_slides_v2', + google_slides_replace_all_shapes_with_sheets_chart: 'google_slides_v2', + google_slides_replace_all_text: 'google_slides_v2', + google_slides_replace_image: 'google_slides_v2', + google_slides_reroute_line: 'google_slides_v2', + google_slides_ungroup_objects: 'google_slides_v2', + google_slides_unmerge_table_cells: 'google_slides_v2', + google_slides_update_image_properties: 'google_slides_v2', + google_slides_update_line_category: 'google_slides_v2', + google_slides_update_line_properties: 'google_slides_v2', + google_slides_update_page_element_alt_text: 'google_slides_v2', + google_slides_update_page_element_transform: 'google_slides_v2', + google_slides_update_page_elements_z_order: 'google_slides_v2', + google_slides_update_page_properties: 'google_slides_v2', + google_slides_update_paragraph_style: 'google_slides_v2', + google_slides_update_shape_properties: 'google_slides_v2', + google_slides_update_slide_properties: 'google_slides_v2', + google_slides_update_slides_position: 'google_slides_v2', + google_slides_update_table_border_properties: 'google_slides_v2', + google_slides_update_table_cell_properties: 'google_slides_v2', + google_slides_update_table_column_properties: 'google_slides_v2', + google_slides_update_table_row_properties: 'google_slides_v2', + google_slides_update_text_style: 'google_slides_v2', + google_slides_update_video_properties: 'google_slides_v2', + google_slides_write: 'google_slides_v2', + google_tasks_create: 'google_tasks', + google_tasks_delete: 'google_tasks', + google_tasks_get: 'google_tasks', + google_tasks_list: 'google_tasks', + google_tasks_list_task_lists: 'google_tasks', + google_tasks_update: 'google_tasks', + google_translate_detect: 'google_translate', + google_translate_text: 'google_translate', + google_vault_create_matters: 'google_vault', + google_vault_create_matters_export: 'google_vault', + google_vault_create_matters_holds: 'google_vault', + google_vault_download_export_file: 'google_vault', + google_vault_list_matters: 'google_vault', + google_vault_list_matters_export: 'google_vault', + google_vault_list_matters_holds: 'google_vault', + grafana_check_data_source_health: 'grafana', + grafana_create_alert_rule: 'grafana', + grafana_create_annotation: 'grafana', + grafana_create_contact_point: 'grafana', + grafana_create_dashboard: 'grafana', + grafana_create_folder: 'grafana', + grafana_delete_alert_rule: 'grafana', + grafana_delete_annotation: 'grafana', + grafana_delete_dashboard: 'grafana', + grafana_delete_folder: 'grafana', + grafana_get_alert_rule: 'grafana', + grafana_get_dashboard: 'grafana', + grafana_get_data_source: 'grafana', + grafana_get_folder: 'grafana', + grafana_get_health: 'grafana', + grafana_list_alert_rules: 'grafana', + grafana_list_annotations: 'grafana', + grafana_list_contact_points: 'grafana', + grafana_list_dashboards: 'grafana', + grafana_list_data_sources: 'grafana', + grafana_list_folders: 'grafana', + grafana_update_alert_rule: 'grafana', + grafana_update_annotation: 'grafana', + grafana_update_dashboard: 'grafana', + grafana_update_folder: 'grafana', + grain_create_hook: 'grain', + grain_delete_hook: 'grain', + grain_get_recording: 'grain', + grain_get_transcript: 'grain', + grain_list_hooks: 'grain', + grain_list_meeting_types: 'grain', + grain_list_recordings: 'grain', + grain_list_teams: 'grain', + grain_list_views: 'grain', + granola_get_note: 'granola', + granola_list_folders: 'granola', + granola_list_notes: 'granola', + greenhouse_get_application: 'greenhouse', + greenhouse_get_candidate: 'greenhouse', + greenhouse_get_job: 'greenhouse', + greenhouse_get_user: 'greenhouse', + greenhouse_list_applications: 'greenhouse', + greenhouse_list_candidates: 'greenhouse', + greenhouse_list_departments: 'greenhouse', + greenhouse_list_job_stages: 'greenhouse', + greenhouse_list_jobs: 'greenhouse', + greenhouse_list_offices: 'greenhouse', + greenhouse_list_users: 'greenhouse', + greptile_index_repo: 'greptile', + greptile_query: 'greptile', + greptile_status: 'greptile', + guardrails_validate: 'guardrails', + hex_cancel_run: 'hex', + hex_create_collection: 'hex', + hex_get_collection: 'hex', + hex_get_data_connection: 'hex', + hex_get_group: 'hex', + hex_get_project: 'hex', + hex_get_project_runs: 'hex', + hex_get_queried_tables: 'hex', + hex_get_run_status: 'hex', + hex_list_collections: 'hex', + hex_list_data_connections: 'hex', + hex_list_groups: 'hex', + hex_list_projects: 'hex', + hex_list_users: 'hex', + hex_run_project: 'hex', + hex_update_project: 'hex', + http_request: 'api', + hubspot_create_appointment: 'hubspot', + hubspot_create_association: 'hubspot', + hubspot_create_company: 'hubspot', + hubspot_create_contact: 'hubspot', + hubspot_create_deal: 'hubspot', + hubspot_create_email: 'hubspot', + hubspot_create_line_item: 'hubspot', + hubspot_create_list: 'hubspot', + hubspot_create_note: 'hubspot', + hubspot_create_ticket: 'hubspot', + hubspot_get_appointment: 'hubspot', + hubspot_get_cart: 'hubspot', + hubspot_get_company: 'hubspot', + hubspot_get_contact: 'hubspot', + hubspot_get_deal: 'hubspot', + hubspot_get_email: 'hubspot', + hubspot_get_line_item: 'hubspot', + hubspot_get_list: 'hubspot', + hubspot_get_marketing_event: 'hubspot', + hubspot_get_note: 'hubspot', + hubspot_get_properties: 'hubspot', + hubspot_get_quote: 'hubspot', + hubspot_get_ticket: 'hubspot', + hubspot_get_users: 'hubspot', + hubspot_list_appointments: 'hubspot', + hubspot_list_associations: 'hubspot', + hubspot_list_carts: 'hubspot', + hubspot_list_companies: 'hubspot', + hubspot_list_contacts: 'hubspot', + hubspot_list_deals: 'hubspot', + hubspot_list_emails: 'hubspot', + hubspot_list_line_items: 'hubspot', + hubspot_list_lists: 'hubspot', + hubspot_list_marketing_events: 'hubspot', + hubspot_list_notes: 'hubspot', + hubspot_list_owners: 'hubspot', + hubspot_list_quotes: 'hubspot', + hubspot_list_tickets: 'hubspot', + hubspot_search_companies: 'hubspot', + hubspot_search_contacts: 'hubspot', + hubspot_search_deals: 'hubspot', + hubspot_search_emails: 'hubspot', + hubspot_search_notes: 'hubspot', + hubspot_search_tickets: 'hubspot', + hubspot_update_appointment: 'hubspot', + hubspot_update_company: 'hubspot', + hubspot_update_contact: 'hubspot', + hubspot_update_deal: 'hubspot', + hubspot_update_line_item: 'hubspot', + hubspot_update_ticket: 'hubspot', + huggingface_chat: 'huggingface', + hunter_companies_find: 'hunter', + hunter_discover: 'hunter', + hunter_domain_search: 'hunter', + hunter_email_count: 'hunter', + hunter_email_finder: 'hunter', + hunter_email_verifier: 'hunter', + iam_add_user_to_group: 'iam', + iam_attach_role_policy: 'iam', + iam_attach_user_policy: 'iam', + iam_create_access_key: 'iam', + iam_create_role: 'iam', + iam_create_user: 'iam', + iam_delete_access_key: 'iam', + iam_delete_role: 'iam', + iam_delete_user: 'iam', + iam_detach_role_policy: 'iam', + iam_detach_user_policy: 'iam', + iam_get_role: 'iam', + iam_get_user: 'iam', + iam_list_attached_role_policies: 'iam', + iam_list_attached_user_policies: 'iam', + iam_list_groups: 'iam', + iam_list_policies: 'iam', + iam_list_roles: 'iam', + iam_list_users: 'iam', + iam_remove_user_from_group: 'iam', + iam_simulate_principal_policy: 'iam', + icypeas_find_email: 'icypeas', + icypeas_verify_email: 'icypeas', + identity_center_check_assignment_deletion_status: 'identity_center', + identity_center_check_assignment_status: 'identity_center', + identity_center_create_account_assignment: 'identity_center', + identity_center_delete_account_assignment: 'identity_center', + identity_center_describe_account: 'identity_center', + identity_center_get_group: 'identity_center', + identity_center_get_user: 'identity_center', + identity_center_list_account_assignments: 'identity_center', + identity_center_list_accounts: 'identity_center', + identity_center_list_groups: 'identity_center', + identity_center_list_instances: 'identity_center', + identity_center_list_permission_sets: 'identity_center', + image_generate: 'image_generator_v2', + incidentio_actions_list: 'incidentio', + incidentio_actions_show: 'incidentio', + incidentio_custom_fields_create: 'incidentio', + incidentio_custom_fields_delete: 'incidentio', + incidentio_custom_fields_list: 'incidentio', + incidentio_custom_fields_show: 'incidentio', + incidentio_custom_fields_update: 'incidentio', + incidentio_escalation_paths_create: 'incidentio', + incidentio_escalation_paths_delete: 'incidentio', + incidentio_escalation_paths_list: 'incidentio', + incidentio_escalation_paths_show: 'incidentio', + incidentio_escalation_paths_update: 'incidentio', + incidentio_escalations_create: 'incidentio', + incidentio_escalations_list: 'incidentio', + incidentio_escalations_show: 'incidentio', + incidentio_follow_ups_list: 'incidentio', + incidentio_follow_ups_show: 'incidentio', + incidentio_incident_roles_create: 'incidentio', + incidentio_incident_roles_delete: 'incidentio', + incidentio_incident_roles_list: 'incidentio', + incidentio_incident_roles_show: 'incidentio', + incidentio_incident_roles_update: 'incidentio', + incidentio_incident_statuses_list: 'incidentio', + incidentio_incident_timestamps_list: 'incidentio', + incidentio_incident_timestamps_show: 'incidentio', + incidentio_incident_types_list: 'incidentio', + incidentio_incident_updates_list: 'incidentio', + incidentio_incidents_create: 'incidentio', + incidentio_incidents_list: 'incidentio', + incidentio_incidents_show: 'incidentio', + incidentio_incidents_update: 'incidentio', + incidentio_schedule_entries_list: 'incidentio', + incidentio_schedule_overrides_create: 'incidentio', + incidentio_schedules_create: 'incidentio', + incidentio_schedules_delete: 'incidentio', + incidentio_schedules_list: 'incidentio', + incidentio_schedules_show: 'incidentio', + incidentio_schedules_update: 'incidentio', + incidentio_severities_list: 'incidentio', + incidentio_users_list: 'incidentio', + incidentio_users_show: 'incidentio', + incidentio_workflows_create: 'incidentio', + incidentio_workflows_delete: 'incidentio', + incidentio_workflows_list: 'incidentio', + incidentio_workflows_show: 'incidentio', + incidentio_workflows_update: 'incidentio', + infisical_create_secret: 'infisical', + infisical_delete_secret: 'infisical', + infisical_get_secret: 'infisical', + infisical_list_secrets: 'infisical', + infisical_update_secret: 'infisical', + instantly_activate_campaign: 'instantly', + instantly_create_campaign: 'instantly', + instantly_create_lead: 'instantly', + instantly_create_lead_list: 'instantly', + instantly_delete_leads: 'instantly', + instantly_get_lead: 'instantly', + instantly_list_campaigns: 'instantly', + instantly_list_emails: 'instantly', + instantly_list_lead_lists: 'instantly', + instantly_list_leads: 'instantly', + instantly_patch_campaign: 'instantly', + instantly_reply_to_email: 'instantly', + instantly_update_lead_interest_status: 'instantly', + intercom_assign_conversation_v2: 'intercom_v2', + intercom_attach_contact_to_company_v2: 'intercom_v2', + intercom_close_conversation_v2: 'intercom_v2', + intercom_create_company: 'intercom', + intercom_create_company_v2: 'intercom_v2', + intercom_create_contact: 'intercom', + intercom_create_contact_v2: 'intercom_v2', + intercom_create_event_v2: 'intercom_v2', + intercom_create_message: 'intercom', + intercom_create_message_v2: 'intercom_v2', + intercom_create_note_v2: 'intercom_v2', + intercom_create_tag_v2: 'intercom_v2', + intercom_create_ticket: 'intercom', + intercom_create_ticket_v2: 'intercom_v2', + intercom_delete_contact: 'intercom', + intercom_delete_contact_v2: 'intercom_v2', + intercom_detach_contact_from_company_v2: 'intercom_v2', + intercom_get_company: 'intercom', + intercom_get_company_v2: 'intercom_v2', + intercom_get_contact: 'intercom', + intercom_get_contact_v2: 'intercom_v2', + intercom_get_conversation: 'intercom', + intercom_get_conversation_v2: 'intercom_v2', + intercom_get_ticket: 'intercom', + intercom_get_ticket_v2: 'intercom_v2', + intercom_list_admins_v2: 'intercom_v2', + intercom_list_companies: 'intercom', + intercom_list_companies_v2: 'intercom_v2', + intercom_list_contacts: 'intercom', + intercom_list_contacts_v2: 'intercom_v2', + intercom_list_conversations: 'intercom', + intercom_list_conversations_v2: 'intercom_v2', + intercom_list_tags_v2: 'intercom_v2', + intercom_open_conversation_v2: 'intercom_v2', + intercom_reply_conversation: 'intercom', + intercom_reply_conversation_v2: 'intercom_v2', + intercom_search_contacts: 'intercom', + intercom_search_contacts_v2: 'intercom_v2', + intercom_search_conversations: 'intercom', + intercom_search_conversations_v2: 'intercom_v2', + intercom_snooze_conversation_v2: 'intercom_v2', + intercom_tag_contact_v2: 'intercom_v2', + intercom_tag_conversation_v2: 'intercom_v2', + intercom_untag_contact_v2: 'intercom_v2', + intercom_update_contact: 'intercom', + intercom_update_contact_v2: 'intercom_v2', + intercom_update_ticket_v2: 'intercom_v2', + jina_read_url: 'jina', + jina_search: 'jina', + jira_add_attachment: 'jira', + jira_add_comment: 'jira', + jira_add_watcher: 'jira', + jira_add_worklog: 'jira', + jira_assign_issue: 'jira', + jira_bulk_read: 'jira', + jira_create_issue_link: 'jira', + jira_delete_attachment: 'jira', + jira_delete_comment: 'jira', + jira_delete_issue: 'jira', + jira_delete_issue_link: 'jira', + jira_delete_worklog: 'jira', + jira_get_attachments: 'jira', + jira_get_comments: 'jira', + jira_get_users: 'jira', + jira_get_worklogs: 'jira', + jira_remove_watcher: 'jira', + jira_retrieve: 'jira', + jira_search_issues: 'jira', + jira_search_users: 'jira', + jira_transition_issue: 'jira', + jira_update: 'jira', + jira_update_comment: 'jira', + jira_update_worklog: 'jira', + jira_write: 'jira', + jsm_add_comment: 'jira_service_management', + jsm_add_customer: 'jira_service_management', + jsm_add_organization: 'jira_service_management', + jsm_add_participants: 'jira_service_management', + jsm_answer_approval: 'jira_service_management', + jsm_attach_form: 'jira_service_management', + jsm_copy_forms: 'jira_service_management', + jsm_create_object: 'jira_service_management', + jsm_create_organization: 'jira_service_management', + jsm_create_request: 'jira_service_management', + jsm_delete_form: 'jira_service_management', + jsm_delete_object: 'jira_service_management', + jsm_externalise_form: 'jira_service_management', + jsm_get_approvals: 'jira_service_management', + jsm_get_comments: 'jira_service_management', + jsm_get_customers: 'jira_service_management', + jsm_get_form: 'jira_service_management', + jsm_get_form_answers: 'jira_service_management', + jsm_get_form_structure: 'jira_service_management', + jsm_get_form_templates: 'jira_service_management', + jsm_get_issue_forms: 'jira_service_management', + jsm_get_object: 'jira_service_management', + jsm_get_object_schema: 'jira_service_management', + jsm_get_object_type_attributes: 'jira_service_management', + jsm_get_organizations: 'jira_service_management', + jsm_get_participants: 'jira_service_management', + jsm_get_queues: 'jira_service_management', + jsm_get_request: 'jira_service_management', + jsm_get_request_type_fields: 'jira_service_management', + jsm_get_request_types: 'jira_service_management', + jsm_get_requests: 'jira_service_management', + jsm_get_service_desks: 'jira_service_management', + jsm_get_sla: 'jira_service_management', + jsm_get_transitions: 'jira_service_management', + jsm_internalise_form: 'jira_service_management', + jsm_list_object_schemas: 'jira_service_management', + jsm_list_object_types: 'jira_service_management', + jsm_reopen_form: 'jira_service_management', + jsm_save_form_answers: 'jira_service_management', + jsm_search_objects_aql: 'jira_service_management', + jsm_submit_form: 'jira_service_management', + jsm_transition_request: 'jira_service_management', + jsm_update_object: 'jira_service_management', + kalshi_amend_order: 'kalshi', + kalshi_amend_order_v2: 'kalshi_v2', + kalshi_cancel_order: 'kalshi', + kalshi_cancel_order_v2: 'kalshi_v2', + kalshi_create_order: 'kalshi', + kalshi_create_order_v2: 'kalshi_v2', + kalshi_get_balance: 'kalshi', + kalshi_get_balance_v2: 'kalshi_v2', + kalshi_get_candlesticks: 'kalshi', + kalshi_get_candlesticks_v2: 'kalshi_v2', + kalshi_get_event: 'kalshi', + kalshi_get_event_candlesticks: 'kalshi', + kalshi_get_event_candlesticks_v2: 'kalshi_v2', + kalshi_get_event_v2: 'kalshi_v2', + kalshi_get_events: 'kalshi', + kalshi_get_events_v2: 'kalshi_v2', + kalshi_get_exchange_announcements: 'kalshi', + kalshi_get_exchange_announcements_v2: 'kalshi_v2', + kalshi_get_exchange_schedule: 'kalshi', + kalshi_get_exchange_schedule_v2: 'kalshi_v2', + kalshi_get_exchange_status: 'kalshi', + kalshi_get_exchange_status_v2: 'kalshi_v2', + kalshi_get_fills: 'kalshi', + kalshi_get_fills_v2: 'kalshi_v2', + kalshi_get_market: 'kalshi', + kalshi_get_market_v2: 'kalshi_v2', + kalshi_get_markets: 'kalshi', + kalshi_get_markets_v2: 'kalshi_v2', + kalshi_get_order: 'kalshi', + kalshi_get_order_v2: 'kalshi_v2', + kalshi_get_orderbook: 'kalshi', + kalshi_get_orderbook_v2: 'kalshi_v2', + kalshi_get_orders: 'kalshi', + kalshi_get_orders_v2: 'kalshi_v2', + kalshi_get_positions: 'kalshi', + kalshi_get_positions_v2: 'kalshi_v2', + kalshi_get_series_by_ticker: 'kalshi', + kalshi_get_series_by_ticker_v2: 'kalshi_v2', + kalshi_get_series_list: 'kalshi', + kalshi_get_series_list_v2: 'kalshi_v2', + kalshi_get_settlements: 'kalshi', + kalshi_get_settlements_v2: 'kalshi_v2', + kalshi_get_trades: 'kalshi', + kalshi_get_trades_v2: 'kalshi_v2', + ketch_get_consent: 'ketch', + ketch_get_subscriptions: 'ketch', + ketch_invoke_right: 'ketch', + ketch_set_consent: 'ketch', + ketch_set_subscriptions: 'ketch', + knowledge_create_document: 'knowledge', + knowledge_delete_chunk: 'knowledge', + knowledge_delete_document: 'knowledge', + knowledge_get_connector: 'knowledge', + knowledge_get_document: 'knowledge', + knowledge_list_chunks: 'knowledge', + knowledge_list_connectors: 'knowledge', + knowledge_list_documents: 'knowledge', + knowledge_list_tags: 'knowledge', + knowledge_search: 'knowledge', + knowledge_trigger_sync: 'knowledge', + knowledge_update_chunk: 'knowledge', + knowledge_upload_chunk: 'knowledge', + knowledge_upsert_document: 'knowledge', + langsmith_create_run: 'langsmith', + langsmith_create_runs_batch: 'langsmith', + latex_compile: 'latex', + latex_get_package: 'latex', + latex_list_fonts: 'latex', + latex_search_packages: 'latex', + launchdarkly_create_flag: 'launchdarkly', + launchdarkly_delete_flag: 'launchdarkly', + launchdarkly_get_audit_log: 'launchdarkly', + launchdarkly_get_flag: 'launchdarkly', + launchdarkly_get_flag_status: 'launchdarkly', + launchdarkly_list_environments: 'launchdarkly', + launchdarkly_list_flags: 'launchdarkly', + launchdarkly_list_members: 'launchdarkly', + launchdarkly_list_projects: 'launchdarkly', + launchdarkly_list_segments: 'launchdarkly', + launchdarkly_toggle_flag: 'launchdarkly', + launchdarkly_update_flag: 'launchdarkly', + leadmagic_company_search: 'leadmagic', + leadmagic_email_to_profile: 'leadmagic', + leadmagic_find_email: 'leadmagic', + leadmagic_find_mobile: 'leadmagic', + leadmagic_get_credits: 'leadmagic', + leadmagic_profile_search: 'leadmagic', + leadmagic_profile_to_email: 'leadmagic', + leadmagic_role_finder: 'leadmagic', + leadmagic_validate_email: 'leadmagic', + lemlist_get_activities: 'lemlist', + lemlist_get_lead: 'lemlist', + lemlist_send_email: 'lemlist', + linear_add_label_to_issue: 'linear_v2', + linear_add_label_to_project: 'linear_v2', + linear_archive_issue: 'linear_v2', + linear_archive_label: 'linear_v2', + linear_archive_project: 'linear_v2', + linear_create_attachment: 'linear_v2', + linear_create_comment: 'linear_v2', + linear_create_customer: 'linear_v2', + linear_create_customer_request: 'linear_v2', + linear_create_customer_status: 'linear_v2', + linear_create_customer_tier: 'linear_v2', + linear_create_cycle: 'linear_v2', + linear_create_favorite: 'linear_v2', + linear_create_issue: 'linear_v2', + linear_create_issue_relation: 'linear_v2', + linear_create_label: 'linear_v2', + linear_create_project: 'linear_v2', + linear_create_project_label: 'linear_v2', + linear_create_project_milestone: 'linear_v2', + linear_create_project_status: 'linear_v2', + linear_create_project_update: 'linear_v2', + linear_create_workflow_state: 'linear_v2', + linear_delete_attachment: 'linear_v2', + linear_delete_comment: 'linear_v2', + linear_delete_customer: 'linear_v2', + linear_delete_customer_status: 'linear_v2', + linear_delete_customer_tier: 'linear_v2', + linear_delete_issue: 'linear_v2', + linear_delete_issue_relation: 'linear_v2', + linear_delete_project: 'linear_v2', + linear_delete_project_label: 'linear_v2', + linear_delete_project_milestone: 'linear_v2', + linear_delete_project_status: 'linear_v2', + linear_get_active_cycle: 'linear_v2', + linear_get_customer: 'linear_v2', + linear_get_cycle: 'linear_v2', + linear_get_issue: 'linear_v2', + linear_get_project: 'linear_v2', + linear_get_viewer: 'linear_v2', + linear_list_attachments: 'linear_v2', + linear_list_comments: 'linear_v2', + linear_list_customer_requests: 'linear_v2', + linear_list_customer_statuses: 'linear_v2', + linear_list_customer_tiers: 'linear_v2', + linear_list_customers: 'linear_v2', + linear_list_cycles: 'linear_v2', + linear_list_favorites: 'linear_v2', + linear_list_issue_relations: 'linear_v2', + linear_list_labels: 'linear_v2', + linear_list_notifications: 'linear_v2', + linear_list_project_labels: 'linear_v2', + linear_list_project_milestones: 'linear_v2', + linear_list_project_statuses: 'linear_v2', + linear_list_project_updates: 'linear_v2', + linear_list_projects: 'linear_v2', + linear_list_teams: 'linear_v2', + linear_list_users: 'linear_v2', + linear_list_workflow_states: 'linear_v2', + linear_merge_customers: 'linear_v2', + linear_read_issues: 'linear_v2', + linear_remove_label_from_issue: 'linear_v2', + linear_remove_label_from_project: 'linear_v2', + linear_search_issues: 'linear_v2', + linear_unarchive_issue: 'linear_v2', + linear_update_attachment: 'linear_v2', + linear_update_comment: 'linear_v2', + linear_update_customer: 'linear_v2', + linear_update_customer_request: 'linear_v2', + linear_update_customer_status: 'linear_v2', + linear_update_customer_tier: 'linear_v2', + linear_update_issue: 'linear_v2', + linear_update_label: 'linear_v2', + linear_update_notification: 'linear_v2', + linear_update_project: 'linear_v2', + linear_update_project_label: 'linear_v2', + linear_update_project_milestone: 'linear_v2', + linear_update_project_status: 'linear_v2', + linear_update_workflow_state: 'linear_v2', + linkedin_get_profile: 'linkedin', + linkedin_share_post: 'linkedin', + linkup_search: 'linkup', + linq_add_participant: 'linq', + linq_check_imessage: 'linq', + linq_check_rcs: 'linq', + linq_create_attachment: 'linq', + linq_create_chat: 'linq', + linq_create_contact_card: 'linq', + linq_create_webhook_subscription: 'linq', + linq_delete_attachment: 'linq', + linq_delete_message: 'linq', + linq_delete_webhook_subscription: 'linq', + linq_edit_message: 'linq', + linq_get_attachment: 'linq', + linq_get_chat: 'linq', + linq_get_contact_card: 'linq', + linq_get_message: 'linq', + linq_get_webhook_subscription: 'linq', + linq_leave_chat: 'linq', + linq_list_chats: 'linq', + linq_list_messages: 'linq', + linq_list_phone_numbers: 'linq', + linq_list_thread: 'linq', + linq_list_webhook_events: 'linq', + linq_list_webhook_subscriptions: 'linq', + linq_mark_chat_read: 'linq', + linq_react_to_message: 'linq', + linq_remove_participant: 'linq', + linq_send_message: 'linq', + linq_send_voice_memo: 'linq', + linq_share_contact_card: 'linq', + linq_start_typing: 'linq', + linq_stop_typing: 'linq', + linq_update_chat: 'linq', + linq_update_contact_card: 'linq', + linq_update_webhook_subscription: 'linq', + llm_chat: 'translate', + logs_get: 'logs', + logs_get_execution: 'logs', + logs_get_run_details: 'logs_v2', + logs_query: 'logs', + logs_query_runs: 'logs_v2', + loops_create_contact: 'loops', + loops_create_contact_property: 'loops', + loops_delete_contact: 'loops', + loops_find_contact: 'loops', + loops_list_contact_properties: 'loops', + loops_list_mailing_lists: 'loops', + loops_list_transactional_emails: 'loops', + loops_send_event: 'loops', + loops_send_transactional_email: 'loops', + loops_update_contact: 'loops', + luma_add_guests: 'luma', + luma_cancel_event: 'luma', + luma_create_event: 'luma', + luma_get_event: 'luma', + luma_get_guest: 'luma', + luma_get_guests: 'luma', + luma_list_events: 'luma', + luma_lookup_event: 'luma', + luma_send_invites: 'luma', + luma_update_event: 'luma', + luma_update_guest_status: 'luma', + mailchimp_add_member: 'mailchimp', + mailchimp_add_member_tags: 'mailchimp', + mailchimp_add_or_update_member: 'mailchimp', + mailchimp_add_segment_member: 'mailchimp', + mailchimp_add_subscriber_to_automation: 'mailchimp', + mailchimp_archive_member: 'mailchimp', + mailchimp_create_audience: 'mailchimp', + mailchimp_create_batch_operation: 'mailchimp', + mailchimp_create_campaign: 'mailchimp', + mailchimp_create_interest: 'mailchimp', + mailchimp_create_interest_category: 'mailchimp', + mailchimp_create_landing_page: 'mailchimp', + mailchimp_create_merge_field: 'mailchimp', + mailchimp_create_segment: 'mailchimp', + mailchimp_create_template: 'mailchimp', + mailchimp_delete_audience: 'mailchimp', + mailchimp_delete_batch_operation: 'mailchimp', + mailchimp_delete_campaign: 'mailchimp', + mailchimp_delete_interest: 'mailchimp', + mailchimp_delete_interest_category: 'mailchimp', + mailchimp_delete_landing_page: 'mailchimp', + mailchimp_delete_member: 'mailchimp', + mailchimp_delete_merge_field: 'mailchimp', + mailchimp_delete_segment: 'mailchimp', + mailchimp_delete_template: 'mailchimp', + mailchimp_get_audience: 'mailchimp', + mailchimp_get_audiences: 'mailchimp', + mailchimp_get_automation: 'mailchimp', + mailchimp_get_automations: 'mailchimp', + mailchimp_get_batch_operation: 'mailchimp', + mailchimp_get_batch_operations: 'mailchimp', + mailchimp_get_campaign: 'mailchimp', + mailchimp_get_campaign_content: 'mailchimp', + mailchimp_get_campaign_report: 'mailchimp', + mailchimp_get_campaign_reports: 'mailchimp', + mailchimp_get_campaigns: 'mailchimp', + mailchimp_get_interest: 'mailchimp', + mailchimp_get_interest_categories: 'mailchimp', + mailchimp_get_interest_category: 'mailchimp', + mailchimp_get_interests: 'mailchimp', + mailchimp_get_landing_page: 'mailchimp', + mailchimp_get_landing_pages: 'mailchimp', + mailchimp_get_member: 'mailchimp', + mailchimp_get_member_tags: 'mailchimp', + mailchimp_get_members: 'mailchimp', + mailchimp_get_merge_field: 'mailchimp', + mailchimp_get_merge_fields: 'mailchimp', + mailchimp_get_segment: 'mailchimp', + mailchimp_get_segment_members: 'mailchimp', + mailchimp_get_segments: 'mailchimp', + mailchimp_get_template: 'mailchimp', + mailchimp_get_templates: 'mailchimp', + mailchimp_pause_automation: 'mailchimp', + mailchimp_publish_landing_page: 'mailchimp', + mailchimp_remove_member_tags: 'mailchimp', + mailchimp_remove_segment_member: 'mailchimp', + mailchimp_replicate_campaign: 'mailchimp', + mailchimp_schedule_campaign: 'mailchimp', + mailchimp_send_campaign: 'mailchimp', + mailchimp_set_campaign_content: 'mailchimp', + mailchimp_start_automation: 'mailchimp', + mailchimp_unarchive_member: 'mailchimp', + mailchimp_unpublish_landing_page: 'mailchimp', + mailchimp_unschedule_campaign: 'mailchimp', + mailchimp_update_audience: 'mailchimp', + mailchimp_update_campaign: 'mailchimp', + mailchimp_update_interest: 'mailchimp', + mailchimp_update_interest_category: 'mailchimp', + mailchimp_update_landing_page: 'mailchimp', + mailchimp_update_member: 'mailchimp', + mailchimp_update_merge_field: 'mailchimp', + mailchimp_update_segment: 'mailchimp', + mailchimp_update_template: 'mailchimp', + mailgun_add_list_member: 'mailgun', + mailgun_create_mailing_list: 'mailgun', + mailgun_get_domain: 'mailgun', + mailgun_get_mailing_list: 'mailgun', + mailgun_get_message: 'mailgun', + mailgun_list_domains: 'mailgun', + mailgun_list_messages: 'mailgun', + mailgun_send_message: 'mailgun', + mem0_add_memories: 'mem0', + mem0_get_memories: 'mem0', + mem0_search_memories: 'mem0', + memory_add: 'memory', + memory_delete: 'memory', + memory_get: 'memory', + memory_get_all: 'memory', + microsoft_ad_add_group_member: 'microsoft_ad', + microsoft_ad_create_group: 'microsoft_ad', + microsoft_ad_create_user: 'microsoft_ad', + microsoft_ad_delete_group: 'microsoft_ad', + microsoft_ad_delete_user: 'microsoft_ad', + microsoft_ad_get_group: 'microsoft_ad', + microsoft_ad_get_user: 'microsoft_ad', + microsoft_ad_list_group_members: 'microsoft_ad', + microsoft_ad_list_groups: 'microsoft_ad', + microsoft_ad_list_users: 'microsoft_ad', + microsoft_ad_remove_group_member: 'microsoft_ad', + microsoft_ad_update_group: 'microsoft_ad', + microsoft_ad_update_user: 'microsoft_ad', + microsoft_dataverse_associate: 'microsoft_dataverse', + microsoft_dataverse_create_multiple: 'microsoft_dataverse', + microsoft_dataverse_create_record: 'microsoft_dataverse', + microsoft_dataverse_delete_record: 'microsoft_dataverse', + microsoft_dataverse_disassociate: 'microsoft_dataverse', + microsoft_dataverse_download_file: 'microsoft_dataverse', + microsoft_dataverse_execute_action: 'microsoft_dataverse', + microsoft_dataverse_execute_function: 'microsoft_dataverse', + microsoft_dataverse_fetchxml_query: 'microsoft_dataverse', + microsoft_dataverse_get_record: 'microsoft_dataverse', + microsoft_dataverse_list_records: 'microsoft_dataverse', + microsoft_dataverse_search: 'microsoft_dataverse', + microsoft_dataverse_update_multiple: 'microsoft_dataverse', + microsoft_dataverse_update_record: 'microsoft_dataverse', + microsoft_dataverse_upload_file: 'microsoft_dataverse', + microsoft_dataverse_upsert_record: 'microsoft_dataverse', + microsoft_dataverse_whoami: 'microsoft_dataverse', + microsoft_excel_read: 'microsoft_excel', + microsoft_excel_read_v2: 'microsoft_excel_v2', + microsoft_excel_table_add: 'microsoft_excel', + microsoft_excel_worksheet_add: 'microsoft_excel', + microsoft_excel_write: 'microsoft_excel', + microsoft_excel_write_v2: 'microsoft_excel_v2', + microsoft_planner_create_bucket: 'microsoft_planner', + microsoft_planner_create_task: 'microsoft_planner', + microsoft_planner_delete_bucket: 'microsoft_planner', + microsoft_planner_delete_task: 'microsoft_planner', + microsoft_planner_get_task_details: 'microsoft_planner', + microsoft_planner_list_buckets: 'microsoft_planner', + microsoft_planner_list_plans: 'microsoft_planner', + microsoft_planner_read_bucket: 'microsoft_planner', + microsoft_planner_read_plan: 'microsoft_planner', + microsoft_planner_read_task: 'microsoft_planner', + microsoft_planner_update_bucket: 'microsoft_planner', + microsoft_planner_update_task: 'microsoft_planner', + microsoft_planner_update_task_details: 'microsoft_planner', + microsoft_teams_delete_channel_message: 'microsoft_teams', + microsoft_teams_delete_chat_message: 'microsoft_teams', + microsoft_teams_get_message: 'microsoft_teams', + microsoft_teams_list_channel_members: 'microsoft_teams', + microsoft_teams_list_team_members: 'microsoft_teams', + microsoft_teams_read_channel: 'microsoft_teams', + microsoft_teams_read_chat: 'microsoft_teams', + microsoft_teams_reply_to_message: 'microsoft_teams', + microsoft_teams_set_reaction: 'microsoft_teams', + microsoft_teams_unset_reaction: 'microsoft_teams', + microsoft_teams_update_channel_message: 'microsoft_teams', + microsoft_teams_update_chat_message: 'microsoft_teams', + microsoft_teams_write_channel: 'microsoft_teams', + microsoft_teams_write_chat: 'microsoft_teams', + millionverifier_get_credits: 'millionverifier', + millionverifier_verify_email: 'millionverifier', + mistral_parser: 'mistral_parse', + mistral_parser_v2: 'mistral_parse_v2', + mistral_parser_v3: 'mistral_parse_v3', + monday_archive_item: 'monday', + monday_create_group: 'monday', + monday_create_item: 'monday', + monday_create_subitem: 'monday', + monday_create_update: 'monday', + monday_delete_item: 'monday', + monday_get_board: 'monday', + monday_get_item: 'monday', + monday_get_items: 'monday', + monday_list_boards: 'monday', + monday_move_item_to_group: 'monday', + monday_search_items: 'monday', + monday_update_item: 'monday', + mongodb_delete: 'mongodb', + mongodb_execute: 'mongodb', + mongodb_insert: 'mongodb', + mongodb_introspect: 'mongodb', + mongodb_query: 'mongodb', + mongodb_update: 'mongodb', + mysql_delete: 'mysql', + mysql_execute: 'mysql', + mysql_insert: 'mysql', + mysql_introspect: 'mysql', + mysql_query: 'mysql', + mysql_update: 'mysql', + neo4j_create: 'neo4j', + neo4j_delete: 'neo4j', + neo4j_execute: 'neo4j', + neo4j_introspect: 'neo4j', + neo4j_merge: 'neo4j', + neo4j_query: 'neo4j', + neo4j_update: 'neo4j', + neverbounce_get_credits: 'neverbounce', + neverbounce_verify_email: 'neverbounce', + new_relic_create_deployment_event: 'new_relic', + new_relic_get_entity: 'new_relic', + new_relic_nrql_query: 'new_relic', + new_relic_search_entities: 'new_relic', + notion_add_database_row_v2: 'notion_v2', + notion_create_database: 'notion', + notion_create_database_v2: 'notion_v2', + notion_create_page: 'notion', + notion_create_page_v2: 'notion_v2', + notion_query_database: 'notion', + notion_query_database_v2: 'notion_v2', + notion_read: 'notion', + notion_read_database: 'notion', + notion_read_database_v2: 'notion_v2', + notion_read_v2: 'notion_v2', + notion_search: 'notion', + notion_search_v2: 'notion_v2', + notion_update_page_v2: 'notion_v2', + notion_write: 'notion', + notion_write_v2: 'notion_v2', + obsidian_append_active: 'obsidian', + obsidian_append_note: 'obsidian', + obsidian_append_periodic_note: 'obsidian', + obsidian_create_note: 'obsidian', + obsidian_delete_note: 'obsidian', + obsidian_execute_command: 'obsidian', + obsidian_get_active: 'obsidian', + obsidian_get_note: 'obsidian', + obsidian_get_periodic_note: 'obsidian', + obsidian_list_commands: 'obsidian', + obsidian_list_files: 'obsidian', + obsidian_open_file: 'obsidian', + obsidian_patch_active: 'obsidian', + obsidian_patch_note: 'obsidian', + obsidian_search: 'obsidian', + okta_activate_user: 'okta', + okta_add_user_to_group: 'okta', + okta_create_group: 'okta', + okta_create_user: 'okta', + okta_deactivate_user: 'okta', + okta_delete_group: 'okta', + okta_delete_user: 'okta', + okta_get_group: 'okta', + okta_get_user: 'okta', + okta_list_group_members: 'okta', + okta_list_groups: 'okta', + okta_list_users: 'okta', + okta_remove_user_from_group: 'okta', + okta_reset_password: 'okta', + okta_suspend_user: 'okta', + okta_unsuspend_user: 'okta', + okta_update_group: 'okta', + okta_update_user: 'okta', + onedrive_create_folder: 'onedrive', + onedrive_delete: 'onedrive', + onedrive_download: 'onedrive', + onedrive_list: 'onedrive', + onedrive_upload: 'onedrive', + onepassword_create_item: 'onepassword', + onepassword_delete_item: 'onepassword', + onepassword_get_item: 'onepassword', + onepassword_get_vault: 'onepassword', + onepassword_list_items: 'onepassword', + onepassword_list_vaults: 'onepassword', + onepassword_replace_item: 'onepassword', + onepassword_resolve_secret: 'onepassword', + onepassword_update_item: 'onepassword', + openai_chat: 'router_v2', + openai_embeddings: 'openai', + openai_image: 'image_generator', + outlook_copy: 'outlook', + outlook_delete: 'outlook', + outlook_draft: 'outlook', + outlook_forward: 'outlook', + outlook_mark_read: 'outlook', + outlook_mark_unread: 'outlook', + outlook_move: 'outlook', + outlook_read: 'outlook', + outlook_send: 'outlook', + pagerduty_add_note: 'pagerduty', + pagerduty_create_incident: 'pagerduty', + pagerduty_list_incidents: 'pagerduty', + pagerduty_list_oncalls: 'pagerduty', + pagerduty_list_services: 'pagerduty', + pagerduty_update_incident: 'pagerduty', + parallel_deep_research: 'parallel_ai', + parallel_extract: 'parallel_ai', + parallel_search: 'parallel_ai', + pdl_autocomplete: 'peopledatalabs', + pdl_bulk_company_enrich: 'peopledatalabs', + pdl_bulk_person_enrich: 'peopledatalabs', + pdl_clean_company: 'peopledatalabs', + pdl_clean_location: 'peopledatalabs', + pdl_clean_school: 'peopledatalabs', + pdl_company_enrich: 'peopledatalabs', + pdl_company_search: 'peopledatalabs', + pdl_person_enrich: 'peopledatalabs', + pdl_person_identify: 'peopledatalabs', + pdl_person_search: 'peopledatalabs', + perplexity_chat: 'perplexity', + perplexity_search: 'perplexity', + persona_approve_inquiry: 'persona', + persona_create_account: 'persona', + persona_create_inquiry: 'persona', + persona_create_report: 'persona', + persona_decline_inquiry: 'persona', + persona_expire_inquiry: 'persona', + persona_generate_inquiry_link: 'persona', + persona_get_account: 'persona', + persona_get_case: 'persona', + persona_get_document: 'persona', + persona_get_inquiry: 'persona', + persona_get_report: 'persona', + persona_get_verification: 'persona', + persona_import_accounts: 'persona', + persona_list_accounts: 'persona', + persona_list_cases: 'persona', + persona_list_inquiries: 'persona', + persona_list_inquiry_templates: 'persona', + persona_list_reports: 'persona', + persona_mark_inquiry_for_review: 'persona', + persona_print_inquiry_pdf: 'persona', + persona_redact_account: 'persona', + persona_redact_inquiry: 'persona', + persona_resume_inquiry: 'persona', + persona_update_account: 'persona', + persona_update_inquiry: 'persona', + pinecone_fetch: 'pinecone', + pinecone_generate_embeddings: 'pinecone', + pinecone_search_text: 'pinecone', + pinecone_search_vector: 'pinecone', + pinecone_upsert_text: 'pinecone', + pipedrive_create_activity: 'pipedrive', + pipedrive_create_deal: 'pipedrive', + pipedrive_create_lead: 'pipedrive', + pipedrive_create_project: 'pipedrive', + pipedrive_delete_lead: 'pipedrive', + pipedrive_get_activities: 'pipedrive', + pipedrive_get_all_deals: 'pipedrive', + pipedrive_get_deal: 'pipedrive', + pipedrive_get_files: 'pipedrive', + pipedrive_get_leads: 'pipedrive', + pipedrive_get_mail_messages: 'pipedrive', + pipedrive_get_mail_thread: 'pipedrive', + pipedrive_get_pipeline_deals: 'pipedrive', + pipedrive_get_pipelines: 'pipedrive', + pipedrive_get_projects: 'pipedrive', + pipedrive_update_activity: 'pipedrive', + pipedrive_update_deal: 'pipedrive', + pipedrive_update_lead: 'pipedrive', + polymarket_get_activity: 'polymarket', + polymarket_get_event: 'polymarket', + polymarket_get_events: 'polymarket', + polymarket_get_holders: 'polymarket', + polymarket_get_last_trade_price: 'polymarket', + polymarket_get_leaderboard: 'polymarket', + polymarket_get_market: 'polymarket', + polymarket_get_markets: 'polymarket', + polymarket_get_midpoint: 'polymarket', + polymarket_get_orderbook: 'polymarket', + polymarket_get_positions: 'polymarket', + polymarket_get_price: 'polymarket', + polymarket_get_price_history: 'polymarket', + polymarket_get_series: 'polymarket', + polymarket_get_series_by_id: 'polymarket', + polymarket_get_spread: 'polymarket', + polymarket_get_tags: 'polymarket', + polymarket_get_tick_size: 'polymarket', + polymarket_get_trades: 'polymarket', + polymarket_search: 'polymarket', + postgresql_delete: 'postgresql', + postgresql_execute: 'postgresql', + postgresql_insert: 'postgresql', + postgresql_introspect: 'postgresql', + postgresql_query: 'postgresql', + postgresql_update: 'postgresql', + posthog_batch_events: 'posthog', + posthog_capture_event: 'posthog', + posthog_create_annotation: 'posthog', + posthog_create_cohort: 'posthog', + posthog_create_experiment: 'posthog', + posthog_create_feature_flag: 'posthog', + posthog_create_insight: 'posthog', + posthog_create_survey: 'posthog', + posthog_delete_feature_flag: 'posthog', + posthog_delete_person: 'posthog', + posthog_evaluate_flags: 'posthog', + posthog_get_cohort: 'posthog', + posthog_get_dashboard: 'posthog', + posthog_get_event_definition: 'posthog', + posthog_get_experiment: 'posthog', + posthog_get_feature_flag: 'posthog', + posthog_get_insight: 'posthog', + posthog_get_organization: 'posthog', + posthog_get_person: 'posthog', + posthog_get_project: 'posthog', + posthog_get_property_definition: 'posthog', + posthog_get_session_recording: 'posthog', + posthog_get_survey: 'posthog', + posthog_list_actions: 'posthog', + posthog_list_annotations: 'posthog', + posthog_list_cohorts: 'posthog', + posthog_list_dashboards: 'posthog', + posthog_list_event_definitions: 'posthog', + posthog_list_experiments: 'posthog', + posthog_list_feature_flags: 'posthog', + posthog_list_insights: 'posthog', + posthog_list_organizations: 'posthog', + posthog_list_persons: 'posthog', + posthog_list_projects: 'posthog', + posthog_list_property_definitions: 'posthog', + posthog_list_recording_playlists: 'posthog', + posthog_list_session_recordings: 'posthog', + posthog_list_surveys: 'posthog', + posthog_query: 'posthog', + posthog_update_event_definition: 'posthog', + posthog_update_feature_flag: 'posthog', + posthog_update_property_definition: 'posthog', + posthog_update_survey: 'posthog', + profound_bot_logs: 'profound', + profound_bots_report: 'profound', + profound_category_assets: 'profound', + profound_category_personas: 'profound', + profound_category_prompts: 'profound', + profound_category_tags: 'profound', + profound_category_topics: 'profound', + profound_citation_prompts: 'profound', + profound_citations_report: 'profound', + profound_list_assets: 'profound', + profound_list_categories: 'profound', + profound_list_domains: 'profound', + profound_list_models: 'profound', + profound_list_optimizations: 'profound', + profound_list_personas: 'profound', + profound_list_regions: 'profound', + profound_optimization_analysis: 'profound', + profound_prompt_answers: 'profound', + profound_prompt_volume: 'profound', + profound_query_fanouts: 'profound', + profound_raw_logs: 'profound', + profound_referrals_report: 'profound', + profound_sentiment_report: 'profound', + profound_visibility_report: 'profound', + prospeo_account_information: 'prospeo', + prospeo_bulk_enrich_company: 'prospeo', + prospeo_bulk_enrich_person: 'prospeo', + prospeo_enrich_company: 'prospeo', + prospeo_enrich_person: 'prospeo', + prospeo_search_company: 'prospeo', + prospeo_search_person: 'prospeo', + prospeo_search_suggestions: 'prospeo', + pulse_parser: 'pulse', + pulse_parser_v2: 'pulse_v2', + qdrant_fetch_points: 'qdrant', + qdrant_search_vector: 'qdrant', + qdrant_upsert_points: 'qdrant', + quartr_get_audio: 'quartr', + quartr_get_company: 'quartr', + quartr_get_event: 'quartr', + quartr_get_event_summary: 'quartr', + quartr_get_report: 'quartr', + quartr_get_slide_deck: 'quartr', + quartr_get_transcript: 'quartr', + quartr_list_audio: 'quartr', + quartr_list_companies: 'quartr', + quartr_list_document_types: 'quartr', + quartr_list_documents: 'quartr', + quartr_list_event_types: 'quartr', + quartr_list_events: 'quartr', + quartr_list_live_events: 'quartr', + quartr_list_reports: 'quartr', + quartr_list_slide_decks: 'quartr', + quartr_list_transcripts: 'quartr', + quiver_image_to_svg: 'quiver', + quiver_list_models: 'quiver', + quiver_text_to_svg: 'quiver', + railway_create_environment: 'railway', + railway_create_project: 'railway', + railway_create_service: 'railway', + railway_delete_environment: 'railway', + railway_delete_project: 'railway', + railway_delete_service: 'railway', + railway_delete_variable: 'railway', + railway_deploy_service: 'railway', + railway_get_deployment: 'railway', + railway_get_deployment_logs: 'railway', + railway_get_project: 'railway', + railway_list_deployments: 'railway', + railway_list_project_members: 'railway', + railway_list_projects: 'railway', + railway_list_variables: 'railway', + railway_restart_deployment: 'railway', + railway_rollback_deployment: 'railway', + railway_transfer_project: 'railway', + railway_update_project: 'railway', + railway_upsert_variable: 'railway', + rb2b_credit_check: 'rb2b', + rb2b_email_to_activity: 'rb2b', + rb2b_hem_to_best_linkedin: 'rb2b', + rb2b_hem_to_business_profile: 'rb2b', + rb2b_hem_to_linkedin: 'rb2b', + rb2b_hem_to_maid: 'rb2b', + rb2b_ip_to_company: 'rb2b', + rb2b_ip_to_hem: 'rb2b', + rb2b_ip_to_maid: 'rb2b', + rb2b_linkedin_slug_search: 'rb2b', + rb2b_linkedin_to_best_personal_email: 'rb2b', + rb2b_linkedin_to_business_profile: 'rb2b', + rb2b_linkedin_to_hashed_emails: 'rb2b', + rb2b_linkedin_to_mobile_phone: 'rb2b', + rb2b_linkedin_to_personal_email: 'rb2b', + rds_delete: 'rds', + rds_execute: 'rds', + rds_insert: 'rds', + rds_introspect: 'rds', + rds_query: 'rds', + rds_update: 'rds', + reddit_delete: 'reddit', + reddit_edit: 'reddit', + reddit_get_comments: 'reddit', + reddit_get_controversial: 'reddit', + reddit_get_info: 'reddit', + reddit_get_me: 'reddit', + reddit_get_messages: 'reddit', + reddit_get_posts: 'reddit', + reddit_get_saved: 'reddit', + reddit_get_subreddit_info: 'reddit', + reddit_get_subreddit_rules: 'reddit', + reddit_get_user: 'reddit', + reddit_get_user_comments: 'reddit', + reddit_get_user_posts: 'reddit', + reddit_hide: 'reddit', + reddit_list_my_subreddits: 'reddit', + reddit_lock: 'reddit', + reddit_mark_all_read: 'reddit', + reddit_mark_read: 'reddit', + reddit_marknsfw: 'reddit', + reddit_mod_approve: 'reddit', + reddit_mod_distinguish: 'reddit', + reddit_mod_remove: 'reddit', + reddit_mod_sticky: 'reddit', + reddit_reply: 'reddit', + reddit_report: 'reddit', + reddit_save: 'reddit', + reddit_search: 'reddit', + reddit_search_subreddits: 'reddit', + reddit_send_message: 'reddit', + reddit_submit_post: 'reddit', + reddit_subscribe: 'reddit', + reddit_unhide: 'reddit', + reddit_unlock: 'reddit', + reddit_unmarknsfw: 'reddit', + reddit_unsave: 'reddit', + reddit_vote: 'reddit', + redis_command: 'redis', + redis_delete: 'redis', + redis_exists: 'redis', + redis_expire: 'redis', + redis_get: 'redis', + redis_hdel: 'redis', + redis_hget: 'redis', + redis_hgetall: 'redis', + redis_hset: 'redis', + redis_incr: 'redis', + redis_incrby: 'redis', + redis_keys: 'redis', + redis_llen: 'redis', + redis_lpop: 'redis', + redis_lpush: 'redis', + redis_lrange: 'redis', + redis_persist: 'redis', + redis_rpop: 'redis', + redis_rpush: 'redis', + redis_set: 'redis', + redis_setnx: 'redis', + redis_ttl: 'redis', + reducto_parser: 'reducto', + reducto_parser_v2: 'reducto_v2', + resend_create_contact: 'resend', + resend_delete_contact: 'resend', + resend_get_contact: 'resend', + resend_get_email: 'resend', + resend_list_contacts: 'resend', + resend_list_domains: 'resend', + resend_send: 'resend', + resend_update_contact: 'resend', + revenuecat_create_purchase: 'revenuecat', + revenuecat_defer_google_subscription: 'revenuecat', + revenuecat_delete_customer: 'revenuecat', + revenuecat_get_customer: 'revenuecat', + revenuecat_grant_entitlement: 'revenuecat', + revenuecat_list_offerings: 'revenuecat', + revenuecat_refund_google_subscription: 'revenuecat', + revenuecat_revoke_entitlement: 'revenuecat', + revenuecat_revoke_google_subscription: 'revenuecat', + revenuecat_update_subscriber_attributes: 'revenuecat', + rippling_bulk_create_custom_object_records: 'rippling', + rippling_bulk_delete_custom_object_records: 'rippling', + rippling_bulk_update_custom_object_records: 'rippling', + rippling_create_business_partner: 'rippling', + rippling_create_business_partner_group: 'rippling', + rippling_create_custom_app: 'rippling', + rippling_create_custom_object: 'rippling', + rippling_create_custom_object_field: 'rippling', + rippling_create_custom_object_record: 'rippling', + rippling_create_custom_page: 'rippling', + rippling_create_custom_setting: 'rippling', + rippling_create_department: 'rippling', + rippling_create_draft_hires: 'rippling', + rippling_create_object_category: 'rippling', + rippling_create_title: 'rippling', + rippling_create_work_location: 'rippling', + rippling_delete_business_partner: 'rippling', + rippling_delete_business_partner_group: 'rippling', + rippling_delete_custom_app: 'rippling', + rippling_delete_custom_object: 'rippling', + rippling_delete_custom_object_field: 'rippling', + rippling_delete_custom_object_record: 'rippling', + rippling_delete_custom_page: 'rippling', + rippling_delete_custom_setting: 'rippling', + rippling_delete_object_category: 'rippling', + rippling_delete_title: 'rippling', + rippling_delete_work_location: 'rippling', + rippling_get_business_partner: 'rippling', + rippling_get_business_partner_group: 'rippling', + rippling_get_current_user: 'rippling', + rippling_get_custom_app: 'rippling', + rippling_get_custom_object: 'rippling', + rippling_get_custom_object_field: 'rippling', + rippling_get_custom_object_record: 'rippling', + rippling_get_custom_object_record_by_external_id: 'rippling', + rippling_get_custom_page: 'rippling', + rippling_get_custom_setting: 'rippling', + rippling_get_department: 'rippling', + rippling_get_employment_type: 'rippling', + rippling_get_job_function: 'rippling', + rippling_get_object_category: 'rippling', + rippling_get_report_run: 'rippling', + rippling_get_supergroup: 'rippling', + rippling_get_team: 'rippling', + rippling_get_title: 'rippling', + rippling_get_user: 'rippling', + rippling_get_work_location: 'rippling', + rippling_get_worker: 'rippling', + rippling_list_business_partner_groups: 'rippling', + rippling_list_business_partners: 'rippling', + rippling_list_companies: 'rippling', + rippling_list_custom_apps: 'rippling', + rippling_list_custom_fields: 'rippling', + rippling_list_custom_object_fields: 'rippling', + rippling_list_custom_object_records: 'rippling', + rippling_list_custom_objects: 'rippling', + rippling_list_custom_pages: 'rippling', + rippling_list_custom_settings: 'rippling', + rippling_list_departments: 'rippling', + rippling_list_employment_types: 'rippling', + rippling_list_entitlements: 'rippling', + rippling_list_job_functions: 'rippling', + rippling_list_object_categories: 'rippling', + rippling_list_supergroup_exclusion_members: 'rippling', + rippling_list_supergroup_inclusion_members: 'rippling', + rippling_list_supergroup_members: 'rippling', + rippling_list_supergroups: 'rippling', + rippling_list_teams: 'rippling', + rippling_list_titles: 'rippling', + rippling_list_users: 'rippling', + rippling_list_work_locations: 'rippling', + rippling_list_workers: 'rippling', + rippling_query_custom_object_records: 'rippling', + rippling_trigger_report_run: 'rippling', + rippling_update_custom_app: 'rippling', + rippling_update_custom_object: 'rippling', + rippling_update_custom_object_field: 'rippling', + rippling_update_custom_object_record: 'rippling', + rippling_update_custom_page: 'rippling', + rippling_update_custom_setting: 'rippling', + rippling_update_department: 'rippling', + rippling_update_object_category: 'rippling', + rippling_update_supergroup_exclusion_members: 'rippling', + rippling_update_supergroup_inclusion_members: 'rippling', + rippling_update_title: 'rippling', + rippling_update_work_location: 'rippling', + rootly_acknowledge_alert: 'rootly', + rootly_add_incident_event: 'rootly', + rootly_add_subscribers: 'rootly', + rootly_assign_incident_role: 'rootly', + rootly_create_action_item: 'rootly', + rootly_create_alert: 'rootly', + rootly_create_incident: 'rootly', + rootly_create_status_page_event: 'rootly', + rootly_delete_action_item: 'rootly', + rootly_delete_incident: 'rootly', + rootly_escalate_alert: 'rootly', + rootly_get_alert: 'rootly', + rootly_get_incident: 'rootly', + rootly_list_action_items: 'rootly', + rootly_list_alerts: 'rootly', + rootly_list_causes: 'rootly', + rootly_list_environments: 'rootly', + rootly_list_escalation_policies: 'rootly', + rootly_list_functionalities: 'rootly', + rootly_list_incident_events: 'rootly', + rootly_list_incident_roles: 'rootly', + rootly_list_incident_types: 'rootly', + rootly_list_incidents: 'rootly', + rootly_list_on_calls: 'rootly', + rootly_list_playbooks: 'rootly', + rootly_list_retrospectives: 'rootly', + rootly_list_schedules: 'rootly', + rootly_list_services: 'rootly', + rootly_list_severities: 'rootly', + rootly_list_teams: 'rootly', + rootly_list_users: 'rootly', + rootly_mitigate_incident: 'rootly', + rootly_remove_subscribers: 'rootly', + rootly_resolve_alert: 'rootly', + rootly_resolve_incident: 'rootly', + rootly_run_workflow: 'rootly', + rootly_snooze_alert: 'rootly', + rootly_unassign_incident_role: 'rootly', + rootly_update_action_item: 'rootly', + rootly_update_alert: 'rootly', + rootly_update_incident: 'rootly', + s3_copy_object: 's3', + s3_delete_object: 's3', + s3_get_object: 's3', + s3_list_objects: 's3', + s3_put_object: 's3', + salesforce_create_account: 'salesforce', + salesforce_create_case: 'salesforce', + salesforce_create_contact: 'salesforce', + salesforce_create_custom_field: 'salesforce', + salesforce_create_custom_object: 'salesforce', + salesforce_create_lead: 'salesforce', + salesforce_create_opportunity: 'salesforce', + salesforce_create_task: 'salesforce', + salesforce_delete_account: 'salesforce', + salesforce_delete_case: 'salesforce', + salesforce_delete_contact: 'salesforce', + salesforce_delete_custom_field: 'salesforce', + salesforce_delete_lead: 'salesforce', + salesforce_delete_opportunity: 'salesforce', + salesforce_delete_task: 'salesforce', + salesforce_describe_object: 'salesforce', + salesforce_get_accounts: 'salesforce', + salesforce_get_cases: 'salesforce', + salesforce_get_contacts: 'salesforce', + salesforce_get_dashboard: 'salesforce', + salesforce_get_leads: 'salesforce', + salesforce_get_opportunities: 'salesforce', + salesforce_get_report: 'salesforce', + salesforce_get_tasks: 'salesforce', + salesforce_list_dashboards: 'salesforce', + salesforce_list_objects: 'salesforce', + salesforce_list_report_types: 'salesforce', + salesforce_list_reports: 'salesforce', + salesforce_query: 'salesforce', + salesforce_query_more: 'salesforce', + salesforce_refresh_dashboard: 'salesforce', + salesforce_run_report: 'salesforce', + salesforce_tooling_query: 'salesforce', + salesforce_update_account: 'salesforce', + salesforce_update_case: 'salesforce', + salesforce_update_contact: 'salesforce', + salesforce_update_custom_field: 'salesforce', + salesforce_update_lead: 'salesforce', + salesforce_update_opportunity: 'salesforce', + salesforce_update_task: 'salesforce', + sap_concur_approve_expense_report: 'sap_concur', + sap_concur_associate_attendees: 'sap_concur', + sap_concur_create_cash_advance: 'sap_concur', + sap_concur_create_expected_expense: 'sap_concur', + sap_concur_create_expense_report: 'sap_concur', + sap_concur_create_list_item: 'sap_concur', + sap_concur_create_purchase_request: 'sap_concur', + sap_concur_create_quick_expense: 'sap_concur', + sap_concur_create_quick_expense_with_image: 'sap_concur', + sap_concur_create_report_comment: 'sap_concur', + sap_concur_create_travel_request: 'sap_concur', + sap_concur_create_user: 'sap_concur', + sap_concur_delete_expected_expense: 'sap_concur', + sap_concur_delete_expense: 'sap_concur', + sap_concur_delete_expense_report: 'sap_concur', + sap_concur_delete_list_item: 'sap_concur', + sap_concur_delete_travel_request: 'sap_concur', + sap_concur_delete_user: 'sap_concur', + sap_concur_get_allocation: 'sap_concur', + sap_concur_get_budget: 'sap_concur', + sap_concur_get_cash_advance: 'sap_concur', + sap_concur_get_expected_expense: 'sap_concur', + sap_concur_get_expense: 'sap_concur', + sap_concur_get_expense_report: 'sap_concur', + sap_concur_get_itemizations: 'sap_concur', + sap_concur_get_itinerary: 'sap_concur', + sap_concur_get_list: 'sap_concur', + sap_concur_get_list_item: 'sap_concur', + sap_concur_get_purchase_request: 'sap_concur', + sap_concur_get_receipt: 'sap_concur', + sap_concur_get_receipt_status: 'sap_concur', + sap_concur_get_request_cash_advance: 'sap_concur', + sap_concur_get_travel_profile: 'sap_concur', + sap_concur_get_travel_request: 'sap_concur', + sap_concur_get_user: 'sap_concur', + sap_concur_issue_cash_advance: 'sap_concur', + sap_concur_list_allocations: 'sap_concur', + sap_concur_list_attendee_associations: 'sap_concur', + sap_concur_list_budget_categories: 'sap_concur', + sap_concur_list_budgets: 'sap_concur', + sap_concur_list_exceptions: 'sap_concur', + sap_concur_list_expected_expenses: 'sap_concur', + sap_concur_list_expense_reports: 'sap_concur', + sap_concur_list_expenses: 'sap_concur', + sap_concur_list_itineraries: 'sap_concur', + sap_concur_list_list_items: 'sap_concur', + sap_concur_list_lists: 'sap_concur', + sap_concur_list_receipts: 'sap_concur', + sap_concur_list_report_comments: 'sap_concur', + sap_concur_list_reports_to_approve: 'sap_concur', + sap_concur_list_travel_profiles_summary: 'sap_concur', + sap_concur_list_travel_request_comments: 'sap_concur', + sap_concur_list_travel_requests: 'sap_concur', + sap_concur_list_users: 'sap_concur', + sap_concur_move_travel_request: 'sap_concur', + sap_concur_recall_expense_report: 'sap_concur', + sap_concur_remove_all_attendees: 'sap_concur', + sap_concur_search_locations: 'sap_concur', + sap_concur_search_users: 'sap_concur', + sap_concur_send_back_expense_report: 'sap_concur', + sap_concur_submit_expense_report: 'sap_concur', + sap_concur_update_allocation: 'sap_concur', + sap_concur_update_expected_expense: 'sap_concur', + sap_concur_update_expense: 'sap_concur', + sap_concur_update_expense_report: 'sap_concur', + sap_concur_update_list_item: 'sap_concur', + sap_concur_update_travel_request: 'sap_concur', + sap_concur_update_user: 'sap_concur', + sap_concur_upload_exchange_rates: 'sap_concur', + sap_concur_upload_receipt_image: 'sap_concur', + sap_s4hana_create_business_partner: 'sap_s4hana', + sap_s4hana_create_purchase_order: 'sap_s4hana', + sap_s4hana_create_purchase_requisition: 'sap_s4hana', + sap_s4hana_create_sales_order: 'sap_s4hana', + sap_s4hana_delete_sales_order: 'sap_s4hana', + sap_s4hana_get_billing_document: 'sap_s4hana', + sap_s4hana_get_business_partner: 'sap_s4hana', + sap_s4hana_get_customer: 'sap_s4hana', + sap_s4hana_get_inbound_delivery: 'sap_s4hana', + sap_s4hana_get_material_document: 'sap_s4hana', + sap_s4hana_get_outbound_delivery: 'sap_s4hana', + sap_s4hana_get_product: 'sap_s4hana', + sap_s4hana_get_purchase_order: 'sap_s4hana', + sap_s4hana_get_purchase_requisition: 'sap_s4hana', + sap_s4hana_get_sales_order: 'sap_s4hana', + sap_s4hana_get_supplier: 'sap_s4hana', + sap_s4hana_get_supplier_invoice: 'sap_s4hana', + sap_s4hana_list_billing_documents: 'sap_s4hana', + sap_s4hana_list_business_partners: 'sap_s4hana', + sap_s4hana_list_customers: 'sap_s4hana', + sap_s4hana_list_inbound_deliveries: 'sap_s4hana', + sap_s4hana_list_material_documents: 'sap_s4hana', + sap_s4hana_list_material_stock: 'sap_s4hana', + sap_s4hana_list_outbound_deliveries: 'sap_s4hana', + sap_s4hana_list_products: 'sap_s4hana', + sap_s4hana_list_purchase_orders: 'sap_s4hana', + sap_s4hana_list_purchase_requisitions: 'sap_s4hana', + sap_s4hana_list_sales_orders: 'sap_s4hana', + sap_s4hana_list_supplier_invoices: 'sap_s4hana', + sap_s4hana_list_suppliers: 'sap_s4hana', + sap_s4hana_odata_query: 'sap_s4hana', + sap_s4hana_update_business_partner: 'sap_s4hana', + sap_s4hana_update_customer: 'sap_s4hana', + sap_s4hana_update_product: 'sap_s4hana', + sap_s4hana_update_purchase_order: 'sap_s4hana', + sap_s4hana_update_purchase_requisition: 'sap_s4hana', + sap_s4hana_update_sales_order: 'sap_s4hana', + sap_s4hana_update_supplier: 'sap_s4hana', + search_tool: 'search', + secrets_manager_create_secret: 'secrets_manager', + secrets_manager_delete_secret: 'secrets_manager', + secrets_manager_get_secret: 'secrets_manager', + secrets_manager_list_secrets: 'secrets_manager', + secrets_manager_update_secret: 'secrets_manager', + sendblue_evaluate_service: 'sendblue', + sendblue_get_message: 'sendblue', + sendblue_send_group_message: 'sendblue', + sendblue_send_message: 'sendblue', + sendblue_send_typing_indicator: 'sendblue', + sendgrid_add_contact: 'sendgrid', + sendgrid_add_contacts_to_list: 'sendgrid', + sendgrid_create_list: 'sendgrid', + sendgrid_create_template: 'sendgrid', + sendgrid_create_template_version: 'sendgrid', + sendgrid_delete_contacts: 'sendgrid', + sendgrid_delete_list: 'sendgrid', + sendgrid_delete_template: 'sendgrid', + sendgrid_get_contact: 'sendgrid', + sendgrid_get_list: 'sendgrid', + sendgrid_get_template: 'sendgrid', + sendgrid_list_all_lists: 'sendgrid', + sendgrid_list_templates: 'sendgrid', + sendgrid_remove_contacts_from_list: 'sendgrid', + sendgrid_search_contacts: 'sendgrid', + sendgrid_send_mail: 'sendgrid', + sentry_events_get: 'sentry', + sentry_events_list: 'sentry', + sentry_issues_get: 'sentry', + sentry_issues_list: 'sentry', + sentry_issues_update: 'sentry', + sentry_projects_create: 'sentry', + sentry_projects_get: 'sentry', + sentry_projects_list: 'sentry', + sentry_projects_update: 'sentry', + sentry_releases_create: 'sentry', + sentry_releases_deploy: 'sentry', + sentry_releases_list: 'sentry', + sentry_teams_list: 'sentry', + serper_search: 'serper', + servicenow_aggregate: 'servicenow', + servicenow_create_record: 'servicenow', + servicenow_delete_record: 'servicenow', + servicenow_download_attachment: 'servicenow', + servicenow_list_attachments: 'servicenow', + servicenow_read_record: 'servicenow', + servicenow_update_record: 'servicenow', + servicenow_upload_attachment: 'servicenow', + ses_create_template: 'ses', + ses_delete_template: 'ses', + ses_get_account: 'ses', + ses_get_template: 'ses', + ses_list_identities: 'ses', + ses_list_templates: 'ses', + ses_send_bulk_email: 'ses', + ses_send_email: 'ses', + ses_send_templated_email: 'ses', + sftp_delete: 'sftp', + sftp_download: 'sftp', + sftp_list: 'sftp', + sftp_mkdir: 'sftp', + sftp_upload: 'sftp', + sharepoint_add_list_items: 'sharepoint_v2', + sharepoint_create_list: 'sharepoint_v2', + sharepoint_create_page: 'sharepoint_v2', + sharepoint_get_list: 'sharepoint_v2', + sharepoint_list_sites: 'sharepoint_v2', + sharepoint_read_page: 'sharepoint_v2', + sharepoint_update_list: 'sharepoint_v2', + sharepoint_upload_file: 'sharepoint_v2', + shopify_adjust_inventory: 'shopify', + shopify_cancel_order: 'shopify', + shopify_create_customer: 'shopify', + shopify_create_fulfillment: 'shopify', + shopify_create_product: 'shopify', + shopify_delete_customer: 'shopify', + shopify_delete_product: 'shopify', + shopify_get_collection: 'shopify', + shopify_get_customer: 'shopify', + shopify_get_inventory_level: 'shopify', + shopify_get_order: 'shopify', + shopify_get_product: 'shopify', + shopify_list_collections: 'shopify', + shopify_list_customers: 'shopify', + shopify_list_inventory_items: 'shopify', + shopify_list_locations: 'shopify', + shopify_list_orders: 'shopify', + shopify_list_products: 'shopify', + shopify_update_customer: 'shopify', + shopify_update_order: 'shopify', + shopify_update_product: 'shopify', + similarweb_bounce_rate: 'similarweb', + similarweb_pages_per_visit: 'similarweb', + similarweb_traffic_visits: 'similarweb', + similarweb_visit_duration: 'similarweb', + similarweb_website_overview: 'similarweb', + sixtyfour_enrich_company: 'sixtyfour', + sixtyfour_enrich_lead: 'sixtyfour', + sixtyfour_find_email: 'sixtyfour', + sixtyfour_find_phone: 'sixtyfour', + slack_add_reaction: 'slack', + slack_canvas: 'slack', + slack_create_channel_canvas: 'slack', + slack_create_conversation: 'slack', + slack_delete_canvas: 'slack', + slack_delete_message: 'slack', + slack_download: 'slack', + slack_edit_canvas: 'slack', + slack_ephemeral_message: 'slack', + slack_get_canvas: 'slack', + slack_get_channel_history: 'slack', + slack_get_channel_info: 'slack', + slack_get_message: 'slack', + slack_get_permalink: 'slack', + slack_get_thread: 'slack', + slack_get_thread_replies: 'slack', + slack_get_user: 'slack', + slack_get_user_presence: 'slack', + slack_invite_to_conversation: 'slack', + slack_list_canvases: 'slack', + slack_list_channels: 'slack', + slack_list_members: 'slack', + slack_list_users: 'slack', + slack_lookup_canvas_sections: 'slack', + slack_message: 'slack', + slack_message_reader: 'slack', + slack_open_view: 'slack', + slack_publish_view: 'slack', + slack_push_view: 'slack', + slack_remove_reaction: 'slack', + slack_set_status: 'slack', + slack_set_suggested_prompts: 'slack', + slack_set_title: 'slack', + slack_update_message: 'slack', + slack_update_view: 'slack', + smtp_send_mail: 'smtp', + sportmonks_core_get_cities: 'sportmonks', + sportmonks_core_get_city: 'sportmonks', + sportmonks_core_get_continent: 'sportmonks', + sportmonks_core_get_continents: 'sportmonks', + sportmonks_core_get_countries: 'sportmonks', + sportmonks_core_get_country: 'sportmonks', + sportmonks_core_get_entity_filters: 'sportmonks', + sportmonks_core_get_my_usage: 'sportmonks', + sportmonks_core_get_region: 'sportmonks', + sportmonks_core_get_regions: 'sportmonks', + sportmonks_core_get_timezones: 'sportmonks', + sportmonks_core_get_type: 'sportmonks', + sportmonks_core_get_type_by_entity: 'sportmonks', + sportmonks_core_get_types: 'sportmonks', + sportmonks_core_search_cities: 'sportmonks', + sportmonks_core_search_countries: 'sportmonks', + sportmonks_core_search_regions: 'sportmonks', + sportmonks_football_expected_by_player: 'sportmonks', + sportmonks_football_expected_by_team: 'sportmonks', + sportmonks_football_get_all_commentaries: 'sportmonks', + sportmonks_football_get_all_fixtures: 'sportmonks', + sportmonks_football_get_all_players: 'sportmonks', + sportmonks_football_get_all_rivals: 'sportmonks', + sportmonks_football_get_all_teams: 'sportmonks', + sportmonks_football_get_all_transfer_rumours: 'sportmonks', + sportmonks_football_get_all_transfers: 'sportmonks', + sportmonks_football_get_brackets_by_season: 'sportmonks', + sportmonks_football_get_coach: 'sportmonks', + sportmonks_football_get_coaches: 'sportmonks', + sportmonks_football_get_coaches_by_country: 'sportmonks', + sportmonks_football_get_commentaries_by_fixture: 'sportmonks', + sportmonks_football_get_current_leagues_by_team: 'sportmonks', + sportmonks_football_get_expected_lineups_by_player: 'sportmonks', + sportmonks_football_get_expected_lineups_by_team: 'sportmonks', + sportmonks_football_get_extended_team_squad: 'sportmonks', + sportmonks_football_get_fixture: 'sportmonks', + sportmonks_football_get_fixtures_by_date: 'sportmonks', + sportmonks_football_get_fixtures_by_date_range: 'sportmonks', + sportmonks_football_get_fixtures_by_date_range_for_team: 'sportmonks', + sportmonks_football_get_fixtures_by_ids: 'sportmonks', + sportmonks_football_get_grouped_standings_by_round: 'sportmonks', + sportmonks_football_get_head_to_head: 'sportmonks', + sportmonks_football_get_inplay_livescores: 'sportmonks', + sportmonks_football_get_latest_coaches: 'sportmonks', + sportmonks_football_get_latest_fixtures: 'sportmonks', + sportmonks_football_get_latest_livescores: 'sportmonks', + sportmonks_football_get_latest_players: 'sportmonks', + sportmonks_football_get_latest_totw: 'sportmonks', + sportmonks_football_get_latest_transfers: 'sportmonks', + sportmonks_football_get_league: 'sportmonks', + sportmonks_football_get_leagues: 'sportmonks', + sportmonks_football_get_leagues_by_country: 'sportmonks', + sportmonks_football_get_leagues_by_date: 'sportmonks', + sportmonks_football_get_leagues_by_team: 'sportmonks', + sportmonks_football_get_live_leagues: 'sportmonks', + sportmonks_football_get_live_probabilities: 'sportmonks', + sportmonks_football_get_live_probabilities_by_fixture: 'sportmonks', + sportmonks_football_get_live_standings_by_league: 'sportmonks', + sportmonks_football_get_livescores: 'sportmonks', + sportmonks_football_get_match_facts: 'sportmonks', + sportmonks_football_get_match_facts_by_date_range: 'sportmonks', + sportmonks_football_get_match_facts_by_fixture: 'sportmonks', + sportmonks_football_get_match_facts_by_league: 'sportmonks', + sportmonks_football_get_past_fixtures_by_tv_station: 'sportmonks', + sportmonks_football_get_player: 'sportmonks', + sportmonks_football_get_players_by_country: 'sportmonks', + sportmonks_football_get_postmatch_news: 'sportmonks', + sportmonks_football_get_postmatch_news_by_season: 'sportmonks', + sportmonks_football_get_predictability_by_league: 'sportmonks', + sportmonks_football_get_prematch_news: 'sportmonks', + sportmonks_football_get_prematch_news_by_season: 'sportmonks', + sportmonks_football_get_prematch_news_upcoming: 'sportmonks', + sportmonks_football_get_probabilities: 'sportmonks', + sportmonks_football_get_probabilities_by_fixture: 'sportmonks', + sportmonks_football_get_referee: 'sportmonks', + sportmonks_football_get_referees: 'sportmonks', + sportmonks_football_get_referees_by_country: 'sportmonks', + sportmonks_football_get_referees_by_season: 'sportmonks', + sportmonks_football_get_rivals_by_team: 'sportmonks', + sportmonks_football_get_round: 'sportmonks', + sportmonks_football_get_round_statistics: 'sportmonks', + sportmonks_football_get_rounds: 'sportmonks', + sportmonks_football_get_rounds_by_season: 'sportmonks', + sportmonks_football_get_schedules_by_season: 'sportmonks', + sportmonks_football_get_schedules_by_season_and_team: 'sportmonks', + sportmonks_football_get_schedules_by_team: 'sportmonks', + sportmonks_football_get_season: 'sportmonks', + sportmonks_football_get_seasons: 'sportmonks', + sportmonks_football_get_seasons_by_team: 'sportmonks', + sportmonks_football_get_stage: 'sportmonks', + sportmonks_football_get_stage_statistics: 'sportmonks', + sportmonks_football_get_stages: 'sportmonks', + sportmonks_football_get_stages_by_season: 'sportmonks', + sportmonks_football_get_standing_corrections_by_season: 'sportmonks', + sportmonks_football_get_standings: 'sportmonks', + sportmonks_football_get_standings_by_round: 'sportmonks', + sportmonks_football_get_standings_by_season: 'sportmonks', + sportmonks_football_get_state: 'sportmonks', + sportmonks_football_get_states: 'sportmonks', + sportmonks_football_get_team: 'sportmonks', + sportmonks_football_get_team_rankings: 'sportmonks', + sportmonks_football_get_team_rankings_by_date: 'sportmonks', + sportmonks_football_get_team_rankings_by_team: 'sportmonks', + sportmonks_football_get_team_squad: 'sportmonks', + sportmonks_football_get_team_squad_by_season: 'sportmonks', + sportmonks_football_get_teams_by_country: 'sportmonks', + sportmonks_football_get_teams_by_season: 'sportmonks', + sportmonks_football_get_topscorers_by_season: 'sportmonks', + sportmonks_football_get_topscorers_by_stage: 'sportmonks', + sportmonks_football_get_totw: 'sportmonks', + sportmonks_football_get_totw_by_round: 'sportmonks', + sportmonks_football_get_transfer: 'sportmonks', + sportmonks_football_get_transfer_rumour: 'sportmonks', + sportmonks_football_get_transfer_rumours_between_dates: 'sportmonks', + sportmonks_football_get_transfer_rumours_by_player: 'sportmonks', + sportmonks_football_get_transfer_rumours_by_team: 'sportmonks', + sportmonks_football_get_transfers_between_dates: 'sportmonks', + sportmonks_football_get_transfers_by_player: 'sportmonks', + sportmonks_football_get_transfers_by_team: 'sportmonks', + sportmonks_football_get_tv_station: 'sportmonks', + sportmonks_football_get_tv_stations: 'sportmonks', + sportmonks_football_get_tv_stations_by_fixture: 'sportmonks', + sportmonks_football_get_upcoming_fixtures_by_market: 'sportmonks', + sportmonks_football_get_upcoming_fixtures_by_tv_station: 'sportmonks', + sportmonks_football_get_value_bets: 'sportmonks', + sportmonks_football_get_value_bets_by_fixture: 'sportmonks', + sportmonks_football_get_venue: 'sportmonks', + sportmonks_football_get_venues: 'sportmonks', + sportmonks_football_get_venues_by_season: 'sportmonks', + sportmonks_football_search_coaches: 'sportmonks', + sportmonks_football_search_fixtures: 'sportmonks', + sportmonks_football_search_leagues: 'sportmonks', + sportmonks_football_search_players: 'sportmonks', + sportmonks_football_search_referees: 'sportmonks', + sportmonks_football_search_rounds: 'sportmonks', + sportmonks_football_search_seasons: 'sportmonks', + sportmonks_football_search_stages: 'sportmonks', + sportmonks_football_search_teams: 'sportmonks', + sportmonks_football_search_venues: 'sportmonks', + sportmonks_motorsport_get_all_fixtures: 'sportmonks', + sportmonks_motorsport_get_current_leagues_by_team: 'sportmonks', + sportmonks_motorsport_get_driver: 'sportmonks', + sportmonks_motorsport_get_driver_standings: 'sportmonks', + sportmonks_motorsport_get_driver_standings_by_season: 'sportmonks', + sportmonks_motorsport_get_drivers: 'sportmonks', + sportmonks_motorsport_get_drivers_by_country: 'sportmonks', + sportmonks_motorsport_get_drivers_by_season: 'sportmonks', + sportmonks_motorsport_get_fixture: 'sportmonks', + sportmonks_motorsport_get_fixtures_by_date: 'sportmonks', + sportmonks_motorsport_get_fixtures_by_date_range: 'sportmonks', + sportmonks_motorsport_get_fixtures_by_ids: 'sportmonks', + sportmonks_motorsport_get_laps_by_fixture: 'sportmonks', + sportmonks_motorsport_get_laps_by_fixture_and_driver: 'sportmonks', + sportmonks_motorsport_get_laps_by_fixture_and_lap: 'sportmonks', + sportmonks_motorsport_get_latest_laps_by_fixture: 'sportmonks', + sportmonks_motorsport_get_latest_pitstops_by_fixture: 'sportmonks', + sportmonks_motorsport_get_latest_stints_by_fixture: 'sportmonks', + sportmonks_motorsport_get_latest_updated_drivers: 'sportmonks', + sportmonks_motorsport_get_latest_updated_fixtures: 'sportmonks', + sportmonks_motorsport_get_league: 'sportmonks', + sportmonks_motorsport_get_leagues: 'sportmonks', + sportmonks_motorsport_get_leagues_by_country: 'sportmonks', + sportmonks_motorsport_get_leagues_by_date: 'sportmonks', + sportmonks_motorsport_get_leagues_by_live: 'sportmonks', + sportmonks_motorsport_get_leagues_by_team: 'sportmonks', + sportmonks_motorsport_get_livescores: 'sportmonks', + sportmonks_motorsport_get_pitstops_by_fixture: 'sportmonks', + sportmonks_motorsport_get_pitstops_by_fixture_and_driver: 'sportmonks', + sportmonks_motorsport_get_pitstops_by_fixture_and_lap: 'sportmonks', + sportmonks_motorsport_get_race_results_by_season_and_driver: 'sportmonks', + sportmonks_motorsport_get_race_results_by_season_and_team: 'sportmonks', + sportmonks_motorsport_get_schedules_by_season: 'sportmonks', + sportmonks_motorsport_get_season: 'sportmonks', + sportmonks_motorsport_get_seasons: 'sportmonks', + sportmonks_motorsport_get_stage: 'sportmonks', + sportmonks_motorsport_get_stages: 'sportmonks', + sportmonks_motorsport_get_stages_by_season: 'sportmonks', + sportmonks_motorsport_get_state: 'sportmonks', + sportmonks_motorsport_get_states: 'sportmonks', + sportmonks_motorsport_get_stints_by_fixture: 'sportmonks', + sportmonks_motorsport_get_stints_by_fixture_and_driver: 'sportmonks', + sportmonks_motorsport_get_stints_by_fixture_and_stint: 'sportmonks', + sportmonks_motorsport_get_team: 'sportmonks', + sportmonks_motorsport_get_team_standings: 'sportmonks', + sportmonks_motorsport_get_team_standings_by_season: 'sportmonks', + sportmonks_motorsport_get_teams: 'sportmonks', + sportmonks_motorsport_get_teams_by_country: 'sportmonks', + sportmonks_motorsport_get_teams_by_season: 'sportmonks', + sportmonks_motorsport_get_venue: 'sportmonks', + sportmonks_motorsport_get_venues: 'sportmonks', + sportmonks_motorsport_get_venues_by_season: 'sportmonks', + sportmonks_motorsport_search_drivers: 'sportmonks', + sportmonks_motorsport_search_leagues: 'sportmonks', + sportmonks_motorsport_search_stages: 'sportmonks', + sportmonks_motorsport_search_teams: 'sportmonks', + sportmonks_motorsport_search_venues: 'sportmonks', + sportmonks_odds_get_all_historical_odds: 'sportmonks', + sportmonks_odds_get_all_inplay_odds: 'sportmonks', + sportmonks_odds_get_all_pre_match_odds: 'sportmonks', + sportmonks_odds_get_all_premium_odds: 'sportmonks', + sportmonks_odds_get_bookmaker: 'sportmonks', + sportmonks_odds_get_bookmaker_event_ids_by_fixture: 'sportmonks', + sportmonks_odds_get_bookmakers: 'sportmonks', + sportmonks_odds_get_bookmakers_by_fixture: 'sportmonks', + sportmonks_odds_get_inplay_odds_by_fixture: 'sportmonks', + sportmonks_odds_get_inplay_odds_by_fixture_and_bookmaker: 'sportmonks', + sportmonks_odds_get_inplay_odds_by_fixture_and_market: 'sportmonks', + sportmonks_odds_get_last_updated_inplay_odds: 'sportmonks', + sportmonks_odds_get_last_updated_pre_match_odds: 'sportmonks', + sportmonks_odds_get_market: 'sportmonks', + sportmonks_odds_get_markets: 'sportmonks', + sportmonks_odds_get_pre_match_odds_by_fixture: 'sportmonks', + sportmonks_odds_get_pre_match_odds_by_fixture_and_bookmaker: 'sportmonks', + sportmonks_odds_get_pre_match_odds_by_fixture_and_market: 'sportmonks', + sportmonks_odds_get_premium_odds_by_fixture: 'sportmonks', + sportmonks_odds_get_premium_odds_by_fixture_and_bookmaker: 'sportmonks', + sportmonks_odds_get_premium_odds_by_fixture_and_market: 'sportmonks', + sportmonks_odds_get_updated_historical_odds_between: 'sportmonks', + sportmonks_odds_get_updated_premium_odds_between: 'sportmonks', + sportmonks_odds_search_bookmakers: 'sportmonks', + sportmonks_odds_search_markets: 'sportmonks', + spotify_add_playlist_cover: 'spotify', + spotify_add_to_queue: 'spotify', + spotify_add_tracks_to_playlist: 'spotify', + spotify_check_following: 'spotify', + spotify_check_playlist_followers: 'spotify', + spotify_check_saved_albums: 'spotify', + spotify_check_saved_audiobooks: 'spotify', + spotify_check_saved_episodes: 'spotify', + spotify_check_saved_shows: 'spotify', + spotify_check_saved_tracks: 'spotify', + spotify_create_playlist: 'spotify', + spotify_follow_artists: 'spotify', + spotify_follow_playlist: 'spotify', + spotify_get_album: 'spotify', + spotify_get_album_tracks: 'spotify', + spotify_get_albums: 'spotify', + spotify_get_artist: 'spotify', + spotify_get_artist_albums: 'spotify', + spotify_get_artist_top_tracks: 'spotify', + spotify_get_artists: 'spotify', + spotify_get_audiobook: 'spotify', + spotify_get_audiobook_chapters: 'spotify', + spotify_get_audiobooks: 'spotify', + spotify_get_categories: 'spotify', + spotify_get_current_user: 'spotify', + spotify_get_currently_playing: 'spotify', + spotify_get_devices: 'spotify', + spotify_get_episode: 'spotify', + spotify_get_episodes: 'spotify', + spotify_get_followed_artists: 'spotify', + spotify_get_markets: 'spotify', + spotify_get_new_releases: 'spotify', + spotify_get_playback_state: 'spotify', + spotify_get_playlist: 'spotify', + spotify_get_playlist_cover: 'spotify', + spotify_get_playlist_tracks: 'spotify', + spotify_get_queue: 'spotify', + spotify_get_recently_played: 'spotify', + spotify_get_saved_albums: 'spotify', + spotify_get_saved_audiobooks: 'spotify', + spotify_get_saved_episodes: 'spotify', + spotify_get_saved_shows: 'spotify', + spotify_get_saved_tracks: 'spotify', + spotify_get_show: 'spotify', + spotify_get_show_episodes: 'spotify', + spotify_get_shows: 'spotify', + spotify_get_top_artists: 'spotify', + spotify_get_top_tracks: 'spotify', + spotify_get_track: 'spotify', + spotify_get_tracks: 'spotify', + spotify_get_user_playlists: 'spotify', + spotify_get_user_profile: 'spotify', + spotify_pause: 'spotify', + spotify_play: 'spotify', + spotify_remove_saved_albums: 'spotify', + spotify_remove_saved_audiobooks: 'spotify', + spotify_remove_saved_episodes: 'spotify', + spotify_remove_saved_shows: 'spotify', + spotify_remove_saved_tracks: 'spotify', + spotify_remove_tracks_from_playlist: 'spotify', + spotify_reorder_playlist_items: 'spotify', + spotify_replace_playlist_items: 'spotify', + spotify_save_albums: 'spotify', + spotify_save_audiobooks: 'spotify', + spotify_save_episodes: 'spotify', + spotify_save_shows: 'spotify', + spotify_save_tracks: 'spotify', + spotify_search: 'spotify', + spotify_seek: 'spotify', + spotify_set_repeat: 'spotify', + spotify_set_shuffle: 'spotify', + spotify_set_volume: 'spotify', + spotify_skip_next: 'spotify', + spotify_skip_previous: 'spotify', + spotify_transfer_playback: 'spotify', + spotify_unfollow_artists: 'spotify', + spotify_unfollow_playlist: 'spotify', + spotify_update_playlist: 'spotify', + sqs_send: 'sqs', + square_batch_retrieve_inventory_counts: 'square', + square_cancel_invoice: 'square', + square_cancel_payment: 'square', + square_complete_payment: 'square', + square_create_catalog_image: 'square', + square_create_customer: 'square', + square_create_invoice: 'square', + square_create_order: 'square', + square_create_payment: 'square', + square_delete_catalog_object: 'square', + square_delete_customer: 'square', + square_delete_invoice: 'square', + square_get_catalog_object: 'square', + square_get_customer: 'square', + square_get_invoice: 'square', + square_get_location: 'square', + square_get_order: 'square', + square_get_payment: 'square', + square_get_refund: 'square', + square_list_catalog: 'square', + square_list_customers: 'square', + square_list_invoices: 'square', + square_list_locations: 'square', + square_list_payments: 'square', + square_list_refunds: 'square', + square_pay_order: 'square', + square_publish_invoice: 'square', + square_refund_payment: 'square', + square_search_catalog_objects: 'square', + square_search_customers: 'square', + square_search_invoices: 'square', + square_search_orders: 'square', + square_update_customer: 'square', + square_upsert_catalog_object: 'square', + ssh_check_command_exists: 'ssh', + ssh_check_file_exists: 'ssh', + ssh_create_directory: 'ssh', + ssh_delete_file: 'ssh', + ssh_download_file: 'ssh', + ssh_execute_command: 'ssh', + ssh_execute_script: 'ssh', + ssh_get_system_info: 'ssh', + ssh_list_directory: 'ssh', + ssh_move_rename: 'ssh', + ssh_read_file_content: 'ssh', + ssh_upload_file: 'ssh', + ssh_write_file_content: 'ssh', + stagehand_agent: 'stagehand', + stagehand_extract: 'stagehand', + stripe_cancel_payment_intent: 'stripe', + stripe_cancel_subscription: 'stripe', + stripe_capture_charge: 'stripe', + stripe_capture_payment_intent: 'stripe', + stripe_confirm_payment_intent: 'stripe', + stripe_create_charge: 'stripe', + stripe_create_customer: 'stripe', + stripe_create_invoice: 'stripe', + stripe_create_payment_intent: 'stripe', + stripe_create_price: 'stripe', + stripe_create_product: 'stripe', + stripe_create_subscription: 'stripe', + stripe_delete_customer: 'stripe', + stripe_delete_invoice: 'stripe', + stripe_delete_product: 'stripe', + stripe_finalize_invoice: 'stripe', + stripe_list_charges: 'stripe', + stripe_list_customers: 'stripe', + stripe_list_events: 'stripe', + stripe_list_invoices: 'stripe', + stripe_list_payment_intents: 'stripe', + stripe_list_prices: 'stripe', + stripe_list_products: 'stripe', + stripe_list_subscriptions: 'stripe', + stripe_pay_invoice: 'stripe', + stripe_resume_subscription: 'stripe', + stripe_retrieve_charge: 'stripe', + stripe_retrieve_customer: 'stripe', + stripe_retrieve_event: 'stripe', + stripe_retrieve_invoice: 'stripe', + stripe_retrieve_payment_intent: 'stripe', + stripe_retrieve_price: 'stripe', + stripe_retrieve_product: 'stripe', + stripe_retrieve_subscription: 'stripe', + stripe_search_charges: 'stripe', + stripe_search_customers: 'stripe', + stripe_search_invoices: 'stripe', + stripe_search_payment_intents: 'stripe', + stripe_search_prices: 'stripe', + stripe_search_products: 'stripe', + stripe_search_subscriptions: 'stripe', + stripe_send_invoice: 'stripe', + stripe_update_charge: 'stripe', + stripe_update_customer: 'stripe', + stripe_update_invoice: 'stripe', + stripe_update_payment_intent: 'stripe', + stripe_update_price: 'stripe', + stripe_update_product: 'stripe', + stripe_update_subscription: 'stripe', + stripe_void_invoice: 'stripe', + sts_assume_role: 'sts', + sts_get_access_key_info: 'sts', + sts_get_caller_identity: 'sts', + sts_get_session_token: 'sts', + stt_assemblyai: 'stt', + stt_assemblyai_v2: 'stt_v2', + stt_deepgram: 'stt', + stt_deepgram_v2: 'stt_v2', + stt_elevenlabs: 'stt', + stt_elevenlabs_v2: 'stt_v2', + stt_gemini: 'stt', + stt_gemini_v2: 'stt_v2', + stt_whisper: 'stt', + stt_whisper_v2: 'stt_v2', + supabase_count: 'supabase', + supabase_delete: 'supabase', + supabase_get_row: 'supabase', + supabase_insert: 'supabase', + supabase_introspect: 'supabase', + supabase_invoke_function: 'supabase', + supabase_query: 'supabase', + supabase_rpc: 'supabase', + supabase_storage_copy: 'supabase', + supabase_storage_create_bucket: 'supabase', + supabase_storage_create_signed_url: 'supabase', + supabase_storage_delete: 'supabase', + supabase_storage_delete_bucket: 'supabase', + supabase_storage_download: 'supabase', + supabase_storage_get_public_url: 'supabase', + supabase_storage_list: 'supabase', + supabase_storage_list_buckets: 'supabase', + supabase_storage_move: 'supabase', + supabase_storage_upload: 'supabase', + supabase_text_search: 'supabase', + supabase_update: 'supabase', + supabase_upsert: 'supabase', + supabase_vector_search: 'supabase', + table_batch_insert_rows: 'table', + table_delete_row: 'table', + table_delete_rows_by_filter: 'table', + table_get_row: 'table', + table_get_schema: 'table', + table_insert_row: 'table', + table_query_rows: 'table', + table_update_row: 'table', + table_update_rows_by_filter: 'table', + table_upsert_row: 'table', + tailscale_authorize_device: 'tailscale', + tailscale_create_auth_key: 'tailscale', + tailscale_delete_auth_key: 'tailscale', + tailscale_delete_device: 'tailscale', + tailscale_get_acl: 'tailscale', + tailscale_get_auth_key: 'tailscale', + tailscale_get_device: 'tailscale', + tailscale_get_device_routes: 'tailscale', + tailscale_get_dns_preferences: 'tailscale', + tailscale_get_dns_searchpaths: 'tailscale', + tailscale_list_auth_keys: 'tailscale', + tailscale_list_devices: 'tailscale', + tailscale_list_dns_nameservers: 'tailscale', + tailscale_list_users: 'tailscale', + tailscale_set_device_routes: 'tailscale', + tailscale_set_device_tags: 'tailscale', + tailscale_set_dns_nameservers: 'tailscale', + tailscale_set_dns_preferences: 'tailscale', + tailscale_set_dns_searchpaths: 'tailscale', + tailscale_update_device_key: 'tailscale', + tavily_crawl: 'tavily', + tavily_extract: 'tavily', + tavily_map: 'tavily', + tavily_search: 'tavily', + telegram_delete_message: 'telegram', + telegram_message: 'telegram', + telegram_send_animation: 'telegram', + telegram_send_audio: 'telegram', + telegram_send_document: 'telegram', + telegram_send_photo: 'telegram', + telegram_send_video: 'telegram', + temporal_cancel_workflow: 'temporal', + temporal_count_workflows: 'temporal', + temporal_create_schedule: 'temporal', + temporal_delete_schedule: 'temporal', + temporal_describe_schedule: 'temporal', + temporal_describe_task_queue: 'temporal', + temporal_describe_workflow: 'temporal', + temporal_get_workflow_history: 'temporal', + temporal_list_schedules: 'temporal', + temporal_list_workflows: 'temporal', + temporal_pause_schedule: 'temporal', + temporal_query_workflow: 'temporal', + temporal_reset_workflow: 'temporal', + temporal_signal_with_start: 'temporal', + temporal_signal_workflow: 'temporal', + temporal_start_workflow: 'temporal', + temporal_terminate_workflow: 'temporal', + temporal_trigger_schedule: 'temporal', + temporal_unpause_schedule: 'temporal', + temporal_update_workflow: 'temporal', + textract_parser: 'textract', + textract_parser_v2: 'textract_v2', + thinking_tool: 'thinking', + thrive_add_audience_managers: 'thrive', + thrive_add_audience_members: 'thrive', + thrive_add_user_tags: 'thrive', + thrive_create_assignment: 'thrive', + thrive_create_audience: 'thrive', + thrive_create_completion: 'thrive', + thrive_create_user: 'thrive', + thrive_delete_assignment: 'thrive', + thrive_delete_audience: 'thrive', + thrive_delete_user: 'thrive', + thrive_get_activity: 'thrive', + thrive_get_assignment: 'thrive', + thrive_get_audience: 'thrive', + thrive_get_completion: 'thrive', + thrive_get_content: 'thrive', + thrive_get_cpd_category: 'thrive', + thrive_get_cpd_entry: 'thrive', + thrive_get_cpd_requirement: 'thrive', + thrive_get_enrolment: 'thrive', + thrive_get_skill_levels: 'thrive', + thrive_get_tag: 'thrive', + thrive_get_user_by_id: 'thrive', + thrive_get_user_by_ref: 'thrive', + thrive_list_assignments: 'thrive', + thrive_list_audience_managers: 'thrive', + thrive_list_audience_members: 'thrive', + thrive_list_audiences: 'thrive', + thrive_list_completions: 'thrive', + thrive_list_enrolments: 'thrive', + thrive_list_tags: 'thrive', + thrive_query_activities: 'thrive', + thrive_query_content: 'thrive', + thrive_query_cpd_categories: 'thrive', + thrive_query_cpd_entries: 'thrive', + thrive_query_cpd_requirements: 'thrive', + thrive_query_cpd_user_summaries: 'thrive', + thrive_remove_audience_manager: 'thrive', + thrive_remove_audience_member: 'thrive', + thrive_remove_user_tags: 'thrive', + thrive_replace_audience_managers: 'thrive', + thrive_replace_audience_members: 'thrive', + thrive_search_users: 'thrive', + thrive_suspend_user: 'thrive', + thrive_update_assignment: 'thrive', + thrive_update_audience: 'thrive', + thrive_update_user: 'thrive', + thrive_update_user_skills: 'thrive', + tinybird_append_datasource: 'tinybird', + tinybird_delete_datasource_rows: 'tinybird', + tinybird_events: 'tinybird', + tinybird_query: 'tinybird', + tinybird_query_pipe: 'tinybird', + tinybird_truncate_datasource: 'tinybird', + trello_add_comment: 'trello', + trello_create_card: 'trello', + trello_get_actions: 'trello', + trello_list_cards: 'trello', + trello_list_lists: 'trello', + trello_update_card: 'trello', + trigger_dev_activate_schedule: 'trigger_dev', + trigger_dev_add_run_tags: 'trigger_dev', + trigger_dev_batch_trigger_task: 'trigger_dev', + trigger_dev_cancel_run: 'trigger_dev', + trigger_dev_complete_waitpoint_token: 'trigger_dev', + trigger_dev_create_env_var: 'trigger_dev', + trigger_dev_create_schedule: 'trigger_dev', + trigger_dev_create_waitpoint_token: 'trigger_dev', + trigger_dev_deactivate_schedule: 'trigger_dev', + trigger_dev_delete_env_var: 'trigger_dev', + trigger_dev_delete_schedule: 'trigger_dev', + trigger_dev_execute_query: 'trigger_dev', + trigger_dev_get_batch: 'trigger_dev', + trigger_dev_get_batch_results: 'trigger_dev', + trigger_dev_get_deployment: 'trigger_dev', + trigger_dev_get_env_var: 'trigger_dev', + trigger_dev_get_latest_deployment: 'trigger_dev', + trigger_dev_get_query_schema: 'trigger_dev', + trigger_dev_get_queue: 'trigger_dev', + trigger_dev_get_run: 'trigger_dev', + trigger_dev_get_run_events: 'trigger_dev', + trigger_dev_get_run_result: 'trigger_dev', + trigger_dev_get_run_trace: 'trigger_dev', + trigger_dev_get_schedule: 'trigger_dev', + trigger_dev_get_waitpoint_token: 'trigger_dev', + trigger_dev_import_env_vars: 'trigger_dev', + trigger_dev_list_deployments: 'trigger_dev', + trigger_dev_list_env_vars: 'trigger_dev', + trigger_dev_list_queues: 'trigger_dev', + trigger_dev_list_runs: 'trigger_dev', + trigger_dev_list_schedules: 'trigger_dev', + trigger_dev_list_timezones: 'trigger_dev', + trigger_dev_list_waitpoint_tokens: 'trigger_dev', + trigger_dev_override_queue_concurrency: 'trigger_dev', + trigger_dev_pause_queue: 'trigger_dev', + trigger_dev_promote_deployment: 'trigger_dev', + trigger_dev_replay_run: 'trigger_dev', + trigger_dev_reschedule_run: 'trigger_dev', + trigger_dev_reset_queue_concurrency: 'trigger_dev', + trigger_dev_resume_queue: 'trigger_dev', + trigger_dev_trigger_task: 'trigger_dev', + trigger_dev_update_env_var: 'trigger_dev', + trigger_dev_update_run_metadata: 'trigger_dev', + trigger_dev_update_schedule: 'trigger_dev', + tts_azure: 'tts', + tts_cartesia: 'tts', + tts_deepgram: 'tts', + tts_elevenlabs: 'tts', + tts_google: 'tts', + tts_openai: 'tts', + tts_playht: 'tts', + twilio_send_sms: 'twilio_sms', + twilio_voice_get_recording: 'twilio_voice', + twilio_voice_list_calls: 'twilio_voice', + twilio_voice_make_call: 'twilio_voice', + typeform_create_form: 'typeform', + typeform_delete_form: 'typeform', + typeform_files: 'typeform', + typeform_get_form: 'typeform', + typeform_insights: 'typeform', + typeform_list_forms: 'typeform', + typeform_responses: 'typeform', + typeform_update_form: 'typeform', + upstash_redis_command: 'upstash', + upstash_redis_delete: 'upstash', + upstash_redis_exists: 'upstash', + upstash_redis_expire: 'upstash', + upstash_redis_get: 'upstash', + upstash_redis_hget: 'upstash', + upstash_redis_hgetall: 'upstash', + upstash_redis_hset: 'upstash', + upstash_redis_incr: 'upstash', + upstash_redis_incrby: 'upstash', + upstash_redis_keys: 'upstash', + upstash_redis_lpush: 'upstash', + upstash_redis_lrange: 'upstash', + upstash_redis_set: 'upstash', + upstash_redis_setnx: 'upstash', + upstash_redis_ttl: 'upstash', + vanta_download_document_file: 'vanta', + vanta_get_control: 'vanta', + vanta_get_document: 'vanta', + vanta_get_framework: 'vanta', + vanta_get_person: 'vanta', + vanta_get_policy: 'vanta', + vanta_get_risk_scenario: 'vanta', + vanta_get_test: 'vanta', + vanta_get_vendor: 'vanta', + vanta_get_vulnerable_asset: 'vanta', + vanta_list_control_documents: 'vanta', + vanta_list_control_tests: 'vanta', + vanta_list_controls: 'vanta', + vanta_list_document_uploads: 'vanta', + vanta_list_documents: 'vanta', + vanta_list_framework_controls: 'vanta', + vanta_list_frameworks: 'vanta', + vanta_list_monitored_computers: 'vanta', + vanta_list_people: 'vanta', + vanta_list_policies: 'vanta', + vanta_list_risk_scenarios: 'vanta', + vanta_list_test_entities: 'vanta', + vanta_list_tests: 'vanta', + vanta_list_vendors: 'vanta', + vanta_list_vulnerabilities: 'vanta', + vanta_list_vulnerability_remediations: 'vanta', + vanta_list_vulnerable_assets: 'vanta', + vanta_submit_document: 'vanta', + vanta_upload_document_file: 'vanta', + vercel_add_domain: 'vercel', + vercel_add_project_domain: 'vercel', + vercel_cancel_deployment: 'vercel', + vercel_create_alias: 'vercel', + vercel_create_check: 'vercel', + vercel_create_deployment: 'vercel', + vercel_create_dns_record: 'vercel', + vercel_create_edge_config: 'vercel', + vercel_create_env_var: 'vercel', + vercel_create_project: 'vercel', + vercel_create_webhook: 'vercel', + vercel_delete_alias: 'vercel', + vercel_delete_deployment: 'vercel', + vercel_delete_dns_record: 'vercel', + vercel_delete_domain: 'vercel', + vercel_delete_edge_config: 'vercel', + vercel_delete_env_var: 'vercel', + vercel_delete_project: 'vercel', + vercel_delete_webhook: 'vercel', + vercel_get_alias: 'vercel', + vercel_get_check: 'vercel', + vercel_get_deployment: 'vercel', + vercel_get_deployment_events: 'vercel', + vercel_get_domain: 'vercel', + vercel_get_domain_config: 'vercel', + vercel_get_edge_config: 'vercel', + vercel_get_edge_config_items: 'vercel', + vercel_get_env_vars: 'vercel', + vercel_get_project: 'vercel', + vercel_get_team: 'vercel', + vercel_get_user: 'vercel', + vercel_get_webhook: 'vercel', + vercel_list_aliases: 'vercel', + vercel_list_checks: 'vercel', + vercel_list_deployment_files: 'vercel', + vercel_list_deployments: 'vercel', + vercel_list_dns_records: 'vercel', + vercel_list_domains: 'vercel', + vercel_list_edge_configs: 'vercel', + vercel_list_project_domains: 'vercel', + vercel_list_projects: 'vercel', + vercel_list_team_members: 'vercel', + vercel_list_teams: 'vercel', + vercel_list_webhooks: 'vercel', + vercel_pause_project: 'vercel', + vercel_promote_deployment: 'vercel', + vercel_remove_project_domain: 'vercel', + vercel_rerequest_check: 'vercel', + vercel_unpause_project: 'vercel', + vercel_update_check: 'vercel', + vercel_update_dns_record: 'vercel', + vercel_update_edge_config_items: 'vercel', + vercel_update_env_var: 'vercel', + vercel_update_project: 'vercel', + vercel_update_project_domain: 'vercel', + vercel_verify_project_domain: 'vercel', + video_falai: 'video_generator_v3', + video_luma: 'video_generator_v3', + video_minimax: 'video_generator_v3', + video_runway: 'video_generator_v3', + video_veo: 'video_generator_v3', + vision_tool: 'vision', + vision_tool_v2: 'vision_v2', + wealthbox_read_contact: 'wealthbox', + wealthbox_read_note: 'wealthbox', + wealthbox_read_task: 'wealthbox', + wealthbox_write_contact: 'wealthbox', + wealthbox_write_note: 'wealthbox', + wealthbox_write_task: 'wealthbox', + webflow_create_item: 'webflow', + webflow_delete_item: 'webflow', + webflow_get_item: 'webflow', + webflow_list_items: 'webflow', + webflow_update_item: 'webflow', + webhook_request: 'webhook_request', + whatsapp_send_message: 'whatsapp', + wikipedia_content: 'wikipedia', + wikipedia_random: 'wikipedia', + wikipedia_search: 'wikipedia', + wikipedia_summary: 'wikipedia', + wiza_company_enrichment: 'wiza', + wiza_get_credits: 'wiza', + wiza_individual_reveal: 'wiza', + wiza_prospect_search: 'wiza', + wordpress_create_category: 'wordpress', + wordpress_create_comment: 'wordpress', + wordpress_create_page: 'wordpress', + wordpress_create_post: 'wordpress', + wordpress_create_tag: 'wordpress', + wordpress_delete_comment: 'wordpress', + wordpress_delete_media: 'wordpress', + wordpress_delete_page: 'wordpress', + wordpress_delete_post: 'wordpress', + wordpress_get_current_user: 'wordpress', + wordpress_get_media: 'wordpress', + wordpress_get_page: 'wordpress', + wordpress_get_post: 'wordpress', + wordpress_get_user: 'wordpress', + wordpress_list_categories: 'wordpress', + wordpress_list_comments: 'wordpress', + wordpress_list_media: 'wordpress', + wordpress_list_pages: 'wordpress', + wordpress_list_posts: 'wordpress', + wordpress_list_tags: 'wordpress', + wordpress_list_users: 'wordpress', + wordpress_search_content: 'wordpress', + wordpress_update_comment: 'wordpress', + wordpress_update_page: 'wordpress', + wordpress_update_post: 'wordpress', + wordpress_upload_media: 'wordpress', + workday_assign_onboarding: 'workday', + workday_change_job: 'workday', + workday_create_prehire: 'workday', + workday_get_compensation: 'workday', + workday_get_organizations: 'workday', + workday_get_worker: 'workday', + workday_hire_employee: 'workday', + workday_list_workers: 'workday', + workday_terminate_worker: 'workday', + workday_update_worker: 'workday', + workflow_executor: 'workflow_input', + x_create_bookmark: 'x', + x_create_tweet: 'x', + x_delete_bookmark: 'x', + x_delete_tweet: 'x', + x_get_blocking: 'x', + x_get_bookmarks: 'x', + x_get_followers: 'x', + x_get_following: 'x', + x_get_liked_tweets: 'x', + x_get_liking_users: 'x', + x_get_me: 'x', + x_get_personalized_trends: 'x', + x_get_quote_tweets: 'x', + x_get_retweeted_by: 'x', + x_get_trends_by_woeid: 'x', + x_get_tweets_by_ids: 'x', + x_get_usage: 'x', + x_get_user_mentions: 'x', + x_get_user_timeline: 'x', + x_get_user_tweets: 'x', + x_hide_reply: 'x', + x_manage_block: 'x', + x_manage_follow: 'x', + x_manage_like: 'x', + x_manage_mute: 'x', + x_manage_retweet: 'x', + x_search_tweets: 'x', + x_search_users: 'x', + xai_chat: 'router_v2', + youtube_channel_info: 'youtube', + youtube_channel_playlists: 'youtube', + youtube_channel_videos: 'youtube', + youtube_comments: 'youtube', + youtube_playlist_items: 'youtube', + youtube_search: 'youtube', + youtube_trending: 'youtube', + youtube_video_categories: 'youtube', + youtube_video_details: 'youtube', + zendesk_autocomplete_organizations: 'zendesk', + zendesk_create_organization: 'zendesk', + zendesk_create_organizations_bulk: 'zendesk', + zendesk_create_ticket: 'zendesk', + zendesk_create_tickets_bulk: 'zendesk', + zendesk_create_user: 'zendesk', + zendesk_create_users_bulk: 'zendesk', + zendesk_delete_organization: 'zendesk', + zendesk_delete_ticket: 'zendesk', + zendesk_delete_user: 'zendesk', + zendesk_get_current_user: 'zendesk', + zendesk_get_organization: 'zendesk', + zendesk_get_organizations: 'zendesk', + zendesk_get_ticket: 'zendesk', + zendesk_get_tickets: 'zendesk', + zendesk_get_user: 'zendesk', + zendesk_get_users: 'zendesk', + zendesk_merge_tickets: 'zendesk', + zendesk_search: 'zendesk', + zendesk_search_count: 'zendesk', + zendesk_search_users: 'zendesk', + zendesk_update_organization: 'zendesk', + zendesk_update_ticket: 'zendesk', + zendesk_update_tickets_bulk: 'zendesk', + zendesk_update_user: 'zendesk', + zendesk_update_users_bulk: 'zendesk', + zep_add_messages: 'zep', + zep_add_user: 'zep', + zep_create_thread: 'zep', + zep_delete_thread: 'zep', + zep_get_context: 'zep', + zep_get_messages: 'zep', + zep_get_threads: 'zep', + zep_get_user: 'zep', + zep_get_user_threads: 'zep', + zerobounce_get_credits: 'zerobounce', + zerobounce_verify_email: 'zerobounce', + zoom_create_meeting: 'zoom', + zoom_delete_meeting: 'zoom', + zoom_delete_recording: 'zoom', + zoom_get_meeting: 'zoom', + zoom_get_meeting_invitation: 'zoom', + zoom_get_meeting_recordings: 'zoom', + zoom_list_meetings: 'zoom', + zoom_list_past_participants: 'zoom', + zoom_list_recordings: 'zoom', + zoom_update_meeting: 'zoom', + zoominfo_enrich_companies: 'zoominfo', + zoominfo_enrich_contacts: 'zoominfo', + zoominfo_search_companies: 'zoominfo', + zoominfo_search_contacts: 'zoominfo', + zoominfo_search_intent: 'zoominfo', + zoominfo_search_news: 'zoominfo', +} + +/** + * Catalog meta (tags/templates/skills). Empty until each block's {Service}BlockMeta + * moves into its .display.ts (Phase 1b); catalog accessors fall back to @/blocks/registry. + */ +export const BLOCK_CATALOG: Record = {} diff --git a/apps/sim/blocks/manifest.ts b/apps/sim/blocks/manifest.ts new file mode 100644 index 00000000000..05ced1367ae --- /dev/null +++ b/apps/sim/blocks/manifest.ts @@ -0,0 +1,149 @@ +import { stripVersionSuffix } from '@sim/utils/string' +import { BLOCK_CATALOG, BLOCK_DISPLAY, TOOL_TO_BLOCK } from '@/blocks/manifest-data' +import type { + BlockCategory, + BlockConfig, + BlockMeta, + BlockTemplate, + SuggestedSkill, +} from '@/blocks/types' + +/** + * Lightweight presentation slice of a block — every field is a value the + * palette/catalog/log surfaces render, with none of the heavy execution data + * (`subBlocks`/`tools.config`/`inputs`/`outputs`). It is the spreadable subset + * of {@link BlockConfig}, so a block's `display.ts` is the single source of + * truth that its full config re-exports. + */ +export type BlockDisplay = Pick< + BlockConfig, + 'type' | 'name' | 'description' | 'category' | 'bgColor' | 'icon' +> & + Partial< + Pick< + BlockConfig, + | 'iconColor' + | 'longDescription' + | 'docsLink' + | 'integrationType' + | 'hideFromToolbar' + | 'triggerAllowed' + > + > + +/** + * A template scoped to a viewing block, enriched with `otherBlockTypes` — the + * integrations to render alongside the viewer in the icon cluster. + */ +export interface ScopedBlockTemplate extends BlockTemplate { + /** Block types (base form) to render alongside the viewing block. */ + otherBlockTypes: readonly string[] +} + +/** Dashes become underscores (some external sources use either form). */ +function normalizeType(type: string): string { + return type.replace(/-/g, '_') +} + +/** Get the display slice for a single block type. */ +export function getBlockDisplay(type: string): BlockDisplay | undefined { + return BLOCK_DISPLAY[type] ?? BLOCK_DISPLAY[normalizeType(type)] +} + +/** All block display slices. */ +export function getAllBlockDisplay(): BlockDisplay[] { + return Object.values(BLOCK_DISPLAY) +} + +/** + * The canonical (latest-version, toolbar-visible) display slices for a category + * — the manifest equivalent of `registry.ts:getCanonicalBlocksByCategory`. + * Superseded versions set `hideFromToolbar`, so they are excluded. + */ +export function getCanonicalBlockDisplayByCategory(category: BlockCategory): BlockDisplay[] { + return Object.values(BLOCK_DISPLAY).filter( + (block) => block.category === category && !block.hideFromToolbar + ) +} + +/** Resolve the block that owns a given tool id, for icon/color rendering. */ +export function getBlockDisplayByToolName(toolName: string): BlockDisplay | undefined { + const type = TOOL_TO_BLOCK[toolName] + return type ? getBlockDisplay(type) : undefined +} + +/** + * The canonical (highest-version) display slice for a base type — the manifest + * equivalent of `registry.ts:getLatestBlock`. Resolves versioned variants + * (`gmail_v2`): callers pass `gmail` and get the latest version's display. + */ +export function getLatestBlockDisplay(baseType: string): BlockDisplay | undefined { + const normalized = normalizeType(baseType) + const versionPattern = new RegExp(`^${normalized}_v(\\d+)$`) + let latestKey: string | undefined + let latestVersion = -1 + for (const key of Object.keys(BLOCK_DISPLAY)) { + const match = key.match(versionPattern) + if (!match) continue + const version = Number.parseInt(match[1]!, 10) + if (version > latestVersion) { + latestVersion = version + latestKey = key + } + } + return latestKey ? BLOCK_DISPLAY[latestKey] : BLOCK_DISPLAY[normalized] +} + +/** + * Get the catalog meta for a block type, resolving through the version suffix + * the same way {@link getTemplatesForBlock} does. Metas are keyed under the base + * type (e.g. `confluence`, not `confluence_v2`). + */ +export function getBlockCatalog(type: string): BlockMeta | undefined { + const normalized = normalizeType(type) + return ( + BLOCK_CATALOG[type] ?? + BLOCK_CATALOG[normalized] ?? + BLOCK_CATALOG[stripVersionSuffix(normalized)] + ) +} + +/** + * All templates whose owner block is `type` or which list `type` in their + * `alsoIntegrations`. Each returned template carries `otherBlockTypes` — the + * non-viewing integrations (owner + other alsoIntegrations) for icon cluster + * rendering. Mirrors the resolution in `registry.ts:getTemplatesForBlock`. + */ +export function getTemplatesForBlock(type: string): ScopedBlockTemplate[] { + const base = stripVersionSuffix(type) + const collected: ScopedBlockTemplate[] = [] + for (const [ownerType, meta] of Object.entries(BLOCK_CATALOG)) { + if (!meta.templates) continue + const ownerBase = stripVersionSuffix(ownerType) + const isOwnerMatch = ownerBase === base + for (const template of meta.templates) { + const isAlsoMatch = + template.alsoIntegrations?.includes(base) || template.alsoIntegrations?.includes(type) + if (!isOwnerMatch && !isAlsoMatch) continue + const others: string[] = [] + if (!isOwnerMatch) others.push(ownerBase) + for (const also of template.alsoIntegrations ?? []) { + const alsoBase = stripVersionSuffix(also) + if (alsoBase !== base && !others.includes(alsoBase)) others.push(alsoBase) + } + collected.push({ ...template, otherBlockTypes: others }) + } + } + return collected +} + +/** + * Popular, ready-to-add skills for a block type. Curated skills live on the base + * integration's meta; a versioned catalog type falls back to the stripped base. + */ +export function getSuggestedSkillsForBlock(type: string): readonly SuggestedSkill[] { + const direct = getBlockCatalog(type)?.skills + if (direct && direct.length > 0) return direct + const base = stripVersionSuffix(normalizeType(type)) + return BLOCK_CATALOG[base]?.skills ?? [] +} diff --git a/apps/sim/lib/logs/get-trigger-options.ts b/apps/sim/lib/logs/get-trigger-options.ts index 2240d2d0f2a..f3c4fff688b 100644 --- a/apps/sim/lib/logs/get-trigger-options.ts +++ b/apps/sim/lib/logs/get-trigger-options.ts @@ -1,4 +1,4 @@ -import { getLatestBlock } from '@/blocks/registry' +import { getLatestBlockDisplay } from '@/blocks/manifest' import { getAllTriggers } from '@/triggers' export interface TriggerOption { @@ -51,7 +51,7 @@ export function getTriggerOptions(): TriggerOption[] { continue } - const block = getLatestBlock(provider) + const block = getLatestBlockDisplay(provider) providerMap.set(provider, { value: provider, diff --git a/apps/sim/lib/permission-groups/block-access.ts b/apps/sim/lib/permission-groups/block-access.ts index 884f952665a..c53329ba16c 100644 --- a/apps/sim/lib/permission-groups/block-access.ts +++ b/apps/sim/lib/permission-groups/block-access.ts @@ -1,4 +1,4 @@ -import { getBlock } from '@/blocks/registry' +import { getBlockDisplay } from '@/blocks/manifest' /** * Block types that bypass permission-group access control entirely. @@ -18,5 +18,5 @@ import { getBlock } from '@/blocks/registry' */ export function isBlockTypeAccessControlExempt(blockType: string): boolean { if (blockType === 'start_trigger') return true - return getBlock(blockType)?.hideFromToolbar === true + return getBlockDisplay(blockType)?.hideFromToolbar === true } diff --git a/apps/sim/package.json b/apps/sim/package.json index bbef179755d..12f11042d65 100644 --- a/apps/sim/package.json +++ b/apps/sim/package.json @@ -24,6 +24,7 @@ "test:watch": "vitest", "test:coverage": "vitest run --coverage", "email:dev": "email dev --dir components/emails", + "blocks:manifest-data": "bun run scripts/generate-block-manifest-data.ts", "type-check": "NODE_OPTIONS='--max-old-space-size=8192' tsc --noEmit", "lint": "biome check --write --unsafe .", "lint:check": "biome check .", diff --git a/apps/sim/scripts/codemod-block-display.ts b/apps/sim/scripts/codemod-block-display.ts new file mode 100644 index 00000000000..4dbc61a0cf7 --- /dev/null +++ b/apps/sim/scripts/codemod-block-display.ts @@ -0,0 +1,213 @@ +// @ts-nocheck — one-time codemod run via a scratch `bun add ts-morph` (ts-morph is intentionally +// not a project dependency). Splits each blocks/blocks/.ts into a .display.ts + spread. +import { readdirSync } from 'node:fs' +import path from 'node:path' +import { Node, type ObjectLiteralExpression, Project } from 'ts-morph' + +const APP = process.cwd() +const BLOCK_DIR = path.join(APP, 'blocks/blocks') +const DISPLAY_KEYS = [ + 'type', + 'name', + 'description', + 'category', + 'bgColor', + 'icon', + 'iconColor', + 'longDescription', + 'docsLink', + 'integrationType', + 'hideFromToolbar', + 'triggerAllowed', +] + +const onlyArg = process.argv[2] // optional single-file test + +const project = new Project({ + tsConfigFilePath: path.join(APP, 'tsconfig.json'), + skipAddingFilesFromTsConfig: true, +}) + +function isBlockConfigConst(init: Node | undefined): init is ObjectLiteralExpression { + if (!init || !Node.isObjectLiteralExpression(init)) return false + const hasType = init.getProperty('type') + const hasHeavy = init.getProperty('subBlocks') || init.getProperty('tools') + return Boolean(hasType && hasHeavy) +} + +/** Collect identifier names referenced in a node (for import resolution). */ +function referencedIdents(node: Node): Set { + const out = new Set() + node.forEachDescendant((d) => { + if (Node.isIdentifier(d)) out.add(d.getText()) + }) + return out +} + +interface DisplayBlock { + constName: string + obj: ObjectLiteralExpression + props: { name: string; text: string }[] // full property text (e.g. "icon: SlackIcon") + baseConst?: string // same-file block const this variant spreads (inherits display from) +} + +const results: { file: string; status: string; note?: string }[] = [] + +const files = readdirSync(BLOCK_DIR) + .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && !f.endsWith('.display.ts')) + .filter((f) => (onlyArg ? f === onlyArg : true)) + +for (const file of files) { + const base = file.replace(/\.ts$/, '') + const sf = project.addSourceFileAtPath(path.join(BLOCK_DIR, file)) + try { + const blocks: DisplayBlock[] = [] + for (const vs of sf.getVariableStatements()) { + if (!vs.isExported()) continue + for (const decl of vs.getDeclarations()) { + const init = decl.getInitializer() + if (!isBlockConfigConst(init)) continue + const props: { name: string; text: string }[] = [] + for (const key of DISPLAY_KEYS) { + const p = init.getProperty(key) + if (p && Node.isPropertyAssignment(p)) props.push({ name: key, text: p.getText() }) + } + if (props.length === 0) continue + blocks.push({ constName: decl.getName(), obj: init, props }) + } + } + if (blocks.length === 0) { + results.push({ file, status: 'skip', note: 'no BlockConfig const' }) + project.removeSourceFile(sf) + continue + } + + // Detect base-block spreads (variant blocks inherit display from a same-file base) + const blockConstNames = new Set(blocks.map((b) => b.constName)) + for (const b of blocks) { + for (const prop of b.obj.getProperties()) { + if (Node.isSpreadAssignment(prop)) { + const expr = prop.getExpression().getText() + if (blockConstNames.has(expr) && expr !== b.constName) { + b.baseConst = expr + break + } + } + } + } + + // Gather identifiers used across all extracted props (icon + IntegrationType) + const usedIdents = new Set() + for (const b of blocks) + for (const p of b.props) { + const pa = b.obj.getProperty(p.name) + if (pa) for (const id of referencedIdents(pa)) usedIdents.add(id) + } + + // Resolve each used identifier to an import or a local declaration + const importByModule = new Map>() // module -> named imports + const localDecls: string[] = [] // full text of local const decls to copy + const localDeclImportIdents = new Set() + for (const id of usedIdents) { + const imp = sf + .getImportDeclarations() + .find((d) => + d.getNamedImports().some((n) => (n.getAliasNode()?.getText() ?? n.getName()) === id) + ) + if (imp) { + const mod = imp.getModuleSpecifierValue() + if (!importByModule.has(mod)) importByModule.set(mod, new Set()) + importByModule.get(mod)!.add(id) + continue + } + // local var decl (e.g. trigger icon const) + const localVar = sf + .getVariableStatements() + .find((vs) => vs.getDeclarations().some((d) => d.getName() === id)) + if (localVar) { + localDecls.push(localVar.getText().replace(/^export\s+/, '')) + for (const ld of referencedIdents(localVar)) localDeclImportIdents.add(ld) + } + } + // imports needed by copied local decls (createElement, lucide bases, SVGProps type) + for (const id of localDeclImportIdents) { + const imp = sf + .getImportDeclarations() + .find((d) => + d.getNamedImports().some((n) => (n.getAliasNode()?.getText() ?? n.getName()) === id) + ) + if (imp) { + const mod = imp.getModuleSpecifierValue() + if (!importByModule.has(mod)) importByModule.set(mod, new Set()) + importByModule.get(mod)!.add(id) + } + } + // SVGProps is a type import in trigger files + if (localDecls.some((d) => d.includes('SVGProps'))) { + if (!importByModule.has('react')) importByModule.set('react', new Set()) + } + + // Build .display.ts + const usesIntegrationType = usedIdents.has('IntegrationType') + const lines: string[] = [] + // react type import for SVGProps (trigger icons) — emit as a separate type import + const needsSvgProps = localDecls.some((d) => d.includes('SVGProps')) + if (needsSvgProps) lines.push("import type { SVGProps } from 'react'") + // value imports grouped by module (sorted) + for (const [mod, names] of [...importByModule].sort(([a], [b]) => a.localeCompare(b))) { + const filtered = [...names].filter((n) => n !== 'SVGProps' && n !== 'IntegrationType') + if (filtered.length === 0) continue + lines.push(`import { ${filtered.sort().join(', ')} } from '${mod}'`) + } + lines.push("import type { BlockDisplay } from '@/blocks/manifest'") + if (usesIntegrationType) lines.push("import { IntegrationType } from '@/blocks/types'") + lines.push('') + for (const d of localDecls) lines.push(d, '') + for (const b of blocks) { + lines.push( + `export const ${b.constName}Display = {`, + ...(b.baseConst ? [` ...${b.baseConst}Display,`] : []), + ...b.props.map((p) => ` ${p.text},`), + `} satisfies BlockDisplay`, + '' + ) + } + const displayPath = path.join(BLOCK_DIR, `${base}.display.ts`) + project.createSourceFile(displayPath, lines.join('\n'), { overwrite: true }) + + // Rewrite block.ts: remove extracted props, add the Display spread (after the + // base-block spread for variants, so the variant's display overrides win; else at 0) + for (const b of blocks) { + for (const p of b.props) { + const pa = b.obj.getProperty(p.name) + pa?.remove() + } + let insertIdx = 0 + if (b.baseConst) { + const after = b.obj + .getProperties() + .findIndex( + (p) => Node.isSpreadAssignment(p) && p.getExpression().getText() === b.baseConst + ) + if (after >= 0) insertIdx = after + 1 + } + b.obj.insertSpreadAssignment(insertIdx, { expression: `${b.constName}Display` }) + } + sf.insertImportDeclaration(0, { + namedImports: blocks.map((b) => `${b.constName}Display`), + moduleSpecifier: `@/blocks/blocks/${base}.display`, + }) + + results.push({ file, status: 'ok', note: `${blocks.length} block(s)` }) + } catch (e) { + results.push({ file, status: 'ERROR', note: String(e).slice(0, 120) }) + } +} + +project.saveSync() + +const ok = results.filter((r) => r.status === 'ok') +const err = results.filter((r) => r.status === 'ERROR') +const skip = results.filter((r) => r.status === 'skip') +console.log(`ok=${ok.length} skip=${skip.length} err=${err.length}`) +for (const r of [...err, ...skip]) console.log(` ${r.status} ${r.file} — ${r.note}`) diff --git a/apps/sim/scripts/generate-block-manifest-data.ts b/apps/sim/scripts/generate-block-manifest-data.ts new file mode 100644 index 00000000000..8b521df8178 --- /dev/null +++ b/apps/sim/scripts/generate-block-manifest-data.ts @@ -0,0 +1,83 @@ +/** + * Generates `apps/sim/blocks/manifest-data.ts` — the registry-free aggregation + * index over the per-block `.display.ts` files (the source of truth). Run + * after adding/renaming a block: `bun run scripts/generate-block-manifest-data.ts`. + * CI re-runs it and fails if `git diff` is non-empty. + * + * `BLOCK_DISPLAY`/`TOOL_TO_BLOCK` are populated; `BLOCK_CATALOG` is intentionally + * empty until the per-block `{Service}BlockMeta` is moved into `.display.ts` + * (Phase 1b) — the catalog accessors (`getBlockCatalog`, `getTemplatesForBlock`) + * stay on `@/blocks/registry` until then. + */ +import { readdirSync, readFileSync, writeFileSync } from 'node:fs' +import path from 'node:path' +import { getAllBlockTypes, getBlock } from '@/blocks/registry' + +const APP = process.cwd() +const BLOCK_DIR = path.join(APP, 'blocks/blocks') +const OUT = path.join(APP, 'blocks/manifest-data.ts') + +interface DisplayEntry { + constName: string + type: string + base: string +} + +const entries: DisplayEntry[] = [] +for (const file of readdirSync(BLOCK_DIR).filter((f) => f.endsWith('.display.ts'))) { + const base = file.replace(/\.display\.ts$/, '') + const src = readFileSync(path.join(BLOCK_DIR, file), 'utf8') + const re = /export const (\w+) = \{([\s\S]*?)\n\} satisfies BlockDisplay/g + let m: RegExpExecArray | null + while ((m = re.exec(src))) { + const constName = m[1] + const typeMatch = m[2].match(/^\s*type:\s*'([^']+)'/m) + if (!typeMatch) throw new Error(`No type field in ${file} const ${constName}`) + entries.push({ constName, type: typeMatch[1], base }) + } +} +entries.sort((a, b) => a.type.localeCompare(b.type)) + +// TOOL_TO_BLOCK from the registry (offline; the generated map is plain data) +const toolToBlock: Record = {} +for (const type of getAllBlockTypes()) { + const cfg = getBlock(type) + for (const tool of cfg?.tools?.access ?? []) toolToBlock[tool] = type +} + +const imports = entries + .map((e) => `import { ${e.constName} } from '@/blocks/blocks/${e.base}.display'`) + .join('\n') +const displayMap = entries.map((e) => ` ${JSON.stringify(e.type)}: ${e.constName},`).join('\n') +const toolMap = Object.keys(toolToBlock) + .sort() + .map((t) => ` ${JSON.stringify(t)}: ${JSON.stringify(toolToBlock[t])},`) + .join('\n') + +const body = `// @generated by scripts/generate-block-manifest-data.ts — do not edit by hand. +// Source of truth is each blocks/blocks/.display.ts. Run \`bun run blocks:manifest-data\`. +${imports} +import type { BlockDisplay } from '@/blocks/manifest' +import type { BlockMeta } from '@/blocks/types' + +/** Light display slice for every registered block, keyed by registry type. */ +export const BLOCK_DISPLAY: Record = { +${displayMap} +} + +/** Tool id → owning block type, for tool-name → icon/color resolution. */ +export const TOOL_TO_BLOCK: Record = { +${toolMap} +} + +/** + * Catalog meta (tags/templates/skills). Empty until each block's {Service}BlockMeta + * moves into its .display.ts (Phase 1b); catalog accessors fall back to @/blocks/registry. + */ +export const BLOCK_CATALOG: Record = {} +` + +writeFileSync(OUT, body) +console.log( + `Wrote blocks/manifest-data.ts — ${entries.length} display entries, ${Object.keys(toolToBlock).length} tool mappings.` +) From 6352c938b04d07ba69e7828cf248726695016128 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 27 Jun 2026 01:13:52 -0700 Subject: [PATCH 2/4] perf(blocks): move {Service}BlockMeta into .display.ts + populate BLOCK_CATALOG (Phase 1b) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves all 221 `{Service}BlockMeta` consts from blocks/blocks/.ts into the sibling .display.ts (carrying the template-icon imports they reference), so the light manifest can aggregate catalog data without importing heavy block configs. - scripts/codemod-block-meta.ts: ts-morph codemod for the move (idempotent; skips files whose meta is already gone) - generate-block-manifest-data.ts: aggregates the metas into BLOCK_CATALOG (231 entries), keyed by each meta's sibling display `type` — exact parity with the old BLOCK_META_REGISTRY (231 keys, zero diff); generator is idempotent - registry.ts: drop the `{XBlock, XBlockMeta}` meta imports and the inline BLOCK_META_REGISTRY; the catalog accessors now read BLOCK_CATALOG - manifest.ts: add getAllBlockMeta + getBlockMeta - migrate catalog consumers (integration detail page, landing slug page, lib/integrations re-export, suggested-actions via that re-export) to @/blocks/manifest type-check 0 errors; check-block-registry passes; BLOCK_CATALOG parity 231=231. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../integrations/(shell)/[slug]/page.tsx | 2 +- .../[block]/integration-block-detail.tsx | 2 +- apps/sim/blocks/blocks/agentmail.display.ts | 97 ++- apps/sim/blocks/blocks/agentmail.ts | 98 +-- apps/sim/blocks/blocks/agentphone.display.ts | 100 ++- apps/sim/blocks/blocks/agentphone.ts | 101 +-- apps/sim/blocks/blocks/agiloft.display.ts | 100 ++- apps/sim/blocks/blocks/agiloft.ts | 101 +-- apps/sim/blocks/blocks/ahrefs.display.ts | 100 ++- apps/sim/blocks/blocks/ahrefs.ts | 101 +-- apps/sim/blocks/blocks/airtable.display.ts | 114 ++- apps/sim/blocks/blocks/airtable.ts | 115 +-- apps/sim/blocks/blocks/airweave.display.ts | 90 +- apps/sim/blocks/blocks/airweave.ts | 91 +- apps/sim/blocks/blocks/algolia.display.ts | 97 ++- apps/sim/blocks/blocks/algolia.ts | 98 +-- apps/sim/blocks/blocks/amplitude.display.ts | 108 ++- apps/sim/blocks/blocks/amplitude.ts | 109 +-- apps/sim/blocks/blocks/apify.display.ts | 106 ++- apps/sim/blocks/blocks/apify.ts | 107 +-- apps/sim/blocks/blocks/apollo.display.ts | 112 ++- apps/sim/blocks/blocks/apollo.ts | 113 +-- apps/sim/blocks/blocks/appconfig.display.ts | 115 ++- apps/sim/blocks/blocks/appconfig.ts | 116 +-- apps/sim/blocks/blocks/arxiv.display.ts | 106 ++- apps/sim/blocks/blocks/arxiv.ts | 107 +-- apps/sim/blocks/blocks/asana.display.ts | 102 ++- apps/sim/blocks/blocks/asana.ts | 103 +-- apps/sim/blocks/blocks/ashby.display.ts | 100 ++- apps/sim/blocks/blocks/ashby.ts | 101 +-- apps/sim/blocks/blocks/athena.display.ts | 102 ++- apps/sim/blocks/blocks/athena.ts | 103 +-- apps/sim/blocks/blocks/attio.display.ts | 108 ++- apps/sim/blocks/blocks/attio.ts | 109 +-- .../sim/blocks/blocks/azure_devops.display.ts | 107 ++- apps/sim/blocks/blocks/azure_devops.ts | 108 +-- apps/sim/blocks/blocks/box.display.ts | 105 ++- apps/sim/blocks/blocks/box.ts | 106 +-- apps/sim/blocks/blocks/brandfetch.display.ts | 99 ++- apps/sim/blocks/blocks/brandfetch.ts | 100 +-- apps/sim/blocks/blocks/brex.display.ts | 124 ++- apps/sim/blocks/blocks/brex.ts | 125 +-- apps/sim/blocks/blocks/brightdata.display.ts | 105 ++- apps/sim/blocks/blocks/brightdata.ts | 106 +-- apps/sim/blocks/blocks/browser_use.display.ts | 99 ++- apps/sim/blocks/blocks/browser_use.ts | 100 +-- apps/sim/blocks/blocks/calcom.display.ts | 108 ++- apps/sim/blocks/blocks/calcom.ts | 109 +-- apps/sim/blocks/blocks/calendly.display.ts | 101 ++- apps/sim/blocks/blocks/calendly.ts | 102 +-- apps/sim/blocks/blocks/circleback.display.ts | 39 +- apps/sim/blocks/blocks/circleback.ts | 40 +- apps/sim/blocks/blocks/clay.display.ts | 92 +- apps/sim/blocks/blocks/clay.ts | 93 +-- apps/sim/blocks/blocks/clerk.display.ts | 108 ++- apps/sim/blocks/blocks/clerk.ts | 109 +-- apps/sim/blocks/blocks/clickhouse.display.ts | 61 +- apps/sim/blocks/blocks/clickhouse.ts | 62 +- apps/sim/blocks/blocks/cloudflare.display.ts | 99 ++- apps/sim/blocks/blocks/cloudflare.ts | 100 +-- .../blocks/blocks/cloudformation.display.ts | 99 ++- apps/sim/blocks/blocks/cloudformation.ts | 100 +-- apps/sim/blocks/blocks/cloudwatch.display.ts | 101 ++- apps/sim/blocks/blocks/cloudwatch.ts | 102 +-- .../sim/blocks/blocks/codepipeline.display.ts | 108 ++- apps/sim/blocks/blocks/codepipeline.ts | 109 +-- apps/sim/blocks/blocks/confluence.display.ts | 111 ++- apps/sim/blocks/blocks/confluence.ts | 110 +-- apps/sim/blocks/blocks/context_dev.display.ts | 92 +- apps/sim/blocks/blocks/context_dev.ts | 93 +-- apps/sim/blocks/blocks/convex.display.ts | 101 ++- apps/sim/blocks/blocks/convex.ts | 102 +-- apps/sim/blocks/blocks/crowdstrike.display.ts | 91 +- apps/sim/blocks/blocks/crowdstrike.ts | 92 +- apps/sim/blocks/blocks/cursor.display.ts | 101 ++- apps/sim/blocks/blocks/cursor.ts | 102 +-- apps/sim/blocks/blocks/dagster.display.ts | 107 ++- apps/sim/blocks/blocks/dagster.ts | 108 +-- apps/sim/blocks/blocks/databricks.display.ts | 100 ++- apps/sim/blocks/blocks/databricks.ts | 101 +-- apps/sim/blocks/blocks/datadog.display.ts | 108 ++- apps/sim/blocks/blocks/datadog.ts | 109 +-- apps/sim/blocks/blocks/datagma.display.ts | 7 +- apps/sim/blocks/blocks/datagma.ts | 7 +- apps/sim/blocks/blocks/daytona.display.ts | 116 ++- apps/sim/blocks/blocks/daytona.ts | 117 +-- apps/sim/blocks/blocks/devin.display.ts | 100 ++- apps/sim/blocks/blocks/devin.ts | 101 +-- apps/sim/blocks/blocks/discord.display.ts | 106 ++- apps/sim/blocks/blocks/discord.ts | 107 +-- apps/sim/blocks/blocks/docusign.display.ts | 107 ++- apps/sim/blocks/blocks/docusign.ts | 108 +-- apps/sim/blocks/blocks/dropbox.display.ts | 104 ++- apps/sim/blocks/blocks/dropbox.ts | 105 +-- apps/sim/blocks/blocks/dropcontact.display.ts | 7 +- apps/sim/blocks/blocks/dropcontact.ts | 7 +- apps/sim/blocks/blocks/dspy.display.ts | 96 ++- apps/sim/blocks/blocks/dspy.ts | 97 +-- apps/sim/blocks/blocks/dub.display.ts | 106 ++- apps/sim/blocks/blocks/dub.ts | 107 +-- apps/sim/blocks/blocks/duckduckgo.display.ts | 98 ++- apps/sim/blocks/blocks/duckduckgo.ts | 99 +-- apps/sim/blocks/blocks/dynamodb.display.ts | 99 ++- apps/sim/blocks/blocks/dynamodb.ts | 100 +-- .../blocks/blocks/elasticsearch.display.ts | 104 ++- apps/sim/blocks/blocks/elasticsearch.ts | 105 +-- apps/sim/blocks/blocks/elevenlabs.display.ts | 98 ++- apps/sim/blocks/blocks/elevenlabs.ts | 99 +-- apps/sim/blocks/blocks/emailbison.display.ts | 106 ++- apps/sim/blocks/blocks/emailbison.ts | 107 +-- apps/sim/blocks/blocks/enrich.display.ts | 107 ++- apps/sim/blocks/blocks/enrich.ts | 108 +-- apps/sim/blocks/blocks/enrichment.display.ts | 105 ++- apps/sim/blocks/blocks/enrichment.ts | 106 +-- apps/sim/blocks/blocks/enrow.display.ts | 7 +- apps/sim/blocks/blocks/enrow.ts | 7 +- apps/sim/blocks/blocks/evernote.display.ts | 102 ++- apps/sim/blocks/blocks/evernote.ts | 103 +-- apps/sim/blocks/blocks/exa.display.ts | 101 ++- apps/sim/blocks/blocks/exa.ts | 102 +-- apps/sim/blocks/blocks/extend.display.ts | 99 ++- apps/sim/blocks/blocks/extend.ts | 100 +-- apps/sim/blocks/blocks/fathom.display.ts | 100 ++- apps/sim/blocks/blocks/fathom.ts | 101 +-- apps/sim/blocks/blocks/findymail.display.ts | 103 ++- apps/sim/blocks/blocks/findymail.ts | 104 +-- apps/sim/blocks/blocks/firecrawl.display.ts | 106 ++- apps/sim/blocks/blocks/firecrawl.ts | 107 +-- apps/sim/blocks/blocks/fireflies.display.ts | 106 ++- apps/sim/blocks/blocks/fireflies.ts | 107 +-- apps/sim/blocks/blocks/gamma.display.ts | 106 ++- apps/sim/blocks/blocks/gamma.ts | 107 +-- apps/sim/blocks/blocks/github.display.ts | 137 ++- apps/sim/blocks/blocks/github.ts | 136 +-- apps/sim/blocks/blocks/gitlab.display.ts | 99 ++- apps/sim/blocks/blocks/gitlab.ts | 100 +-- apps/sim/blocks/blocks/gmail.display.ts | 125 ++- apps/sim/blocks/blocks/gmail.ts | 124 +-- apps/sim/blocks/blocks/gong.display.ts | 99 ++- apps/sim/blocks/blocks/gong.ts | 100 +-- apps/sim/blocks/blocks/google.display.ts | 98 ++- apps/sim/blocks/blocks/google.ts | 99 +-- apps/sim/blocks/blocks/google_ads.display.ts | 99 ++- apps/sim/blocks/blocks/google_ads.ts | 100 +-- .../blocks/blocks/google_bigquery.display.ts | 100 ++- apps/sim/blocks/blocks/google_bigquery.ts | 101 +-- .../sim/blocks/blocks/google_books.display.ts | 97 ++- apps/sim/blocks/blocks/google_books.ts | 98 +-- .../blocks/blocks/google_calendar.display.ts | 113 ++- apps/sim/blocks/blocks/google_calendar.ts | 112 +-- .../blocks/blocks/google_contacts.display.ts | 100 ++- apps/sim/blocks/blocks/google_contacts.ts | 101 +-- apps/sim/blocks/blocks/google_docs.display.ts | 98 ++- apps/sim/blocks/blocks/google_docs.ts | 99 +-- .../sim/blocks/blocks/google_drive.display.ts | 107 ++- apps/sim/blocks/blocks/google_drive.ts | 108 +-- .../sim/blocks/blocks/google_forms.display.ts | 100 ++- apps/sim/blocks/blocks/google_forms.ts | 101 +-- .../blocks/blocks/google_groups.display.ts | 106 ++- apps/sim/blocks/blocks/google_groups.ts | 107 +-- apps/sim/blocks/blocks/google_maps.display.ts | 106 ++- apps/sim/blocks/blocks/google_maps.ts | 107 +-- apps/sim/blocks/blocks/google_meet.display.ts | 98 ++- apps/sim/blocks/blocks/google_meet.ts | 99 +-- .../blocks/blocks/google_pagespeed.display.ts | 99 ++- apps/sim/blocks/blocks/google_pagespeed.ts | 100 +-- .../blocks/blocks/google_sheets.display.ts | 123 ++- apps/sim/blocks/blocks/google_sheets.ts | 124 +-- .../blocks/blocks/google_slides.display.ts | 111 ++- apps/sim/blocks/blocks/google_slides.ts | 112 +-- .../sim/blocks/blocks/google_tasks.display.ts | 100 ++- apps/sim/blocks/blocks/google_tasks.ts | 101 +-- .../blocks/blocks/google_translate.display.ts | 100 ++- apps/sim/blocks/blocks/google_translate.ts | 101 +-- .../sim/blocks/blocks/google_vault.display.ts | 98 ++- apps/sim/blocks/blocks/google_vault.ts | 98 +-- apps/sim/blocks/blocks/grafana.display.ts | 112 ++- apps/sim/blocks/blocks/grafana.ts | 113 +-- apps/sim/blocks/blocks/grain.display.ts | 99 ++- apps/sim/blocks/blocks/grain.ts | 100 +-- apps/sim/blocks/blocks/granola.display.ts | 99 ++- apps/sim/blocks/blocks/granola.ts | 100 +-- apps/sim/blocks/blocks/greenhouse.display.ts | 101 ++- apps/sim/blocks/blocks/greenhouse.ts | 102 +-- apps/sim/blocks/blocks/greptile.display.ts | 65 +- apps/sim/blocks/blocks/greptile.ts | 64 +- apps/sim/blocks/blocks/hex.display.ts | 105 ++- apps/sim/blocks/blocks/hex.ts | 106 +-- apps/sim/blocks/blocks/hubspot.display.ts | 141 +++- apps/sim/blocks/blocks/hubspot.ts | 142 +--- apps/sim/blocks/blocks/huggingface.display.ts | 96 ++- apps/sim/blocks/blocks/huggingface.ts | 97 +-- apps/sim/blocks/blocks/hunter.display.ts | 98 ++- apps/sim/blocks/blocks/hunter.ts | 99 +-- apps/sim/blocks/blocks/iam.display.ts | 108 ++- apps/sim/blocks/blocks/iam.ts | 109 +-- apps/sim/blocks/blocks/icypeas.display.ts | 7 +- apps/sim/blocks/blocks/icypeas.ts | 7 +- .../blocks/blocks/identity_center.display.ts | 101 ++- apps/sim/blocks/blocks/identity_center.ts | 102 +-- apps/sim/blocks/blocks/imap.display.ts | 37 +- apps/sim/blocks/blocks/imap.ts | 38 +- apps/sim/blocks/blocks/incidentio.display.ts | 106 ++- apps/sim/blocks/blocks/incidentio.ts | 107 +-- apps/sim/blocks/blocks/infisical.display.ts | 100 ++- apps/sim/blocks/blocks/infisical.ts | 101 +-- apps/sim/blocks/blocks/instantly.display.ts | 105 ++- apps/sim/blocks/blocks/instantly.ts | 106 +-- apps/sim/blocks/blocks/intercom.display.ts | 113 ++- apps/sim/blocks/blocks/intercom.ts | 114 +-- apps/sim/blocks/blocks/jina.display.ts | 95 ++- apps/sim/blocks/blocks/jina.ts | 96 +-- apps/sim/blocks/blocks/jira.display.ts | 105 ++- apps/sim/blocks/blocks/jira.ts | 106 +-- .../blocks/jira_service_management.display.ts | 97 ++- .../blocks/blocks/jira_service_management.ts | 98 +-- apps/sim/blocks/blocks/kalshi.display.ts | 104 ++- apps/sim/blocks/blocks/kalshi.ts | 105 +-- apps/sim/blocks/blocks/ketch.display.ts | 101 ++- apps/sim/blocks/blocks/ketch.ts | 102 +-- apps/sim/blocks/blocks/langsmith.display.ts | 89 +- apps/sim/blocks/blocks/langsmith.ts | 90 +- apps/sim/blocks/blocks/latex.display.ts | 124 ++- apps/sim/blocks/blocks/latex.ts | 125 +-- .../sim/blocks/blocks/launchdarkly.display.ts | 113 ++- apps/sim/blocks/blocks/launchdarkly.ts | 114 +-- apps/sim/blocks/blocks/leadmagic.display.ts | 7 +- apps/sim/blocks/blocks/leadmagic.ts | 7 +- apps/sim/blocks/blocks/lemlist.display.ts | 100 ++- apps/sim/blocks/blocks/lemlist.ts | 101 +-- apps/sim/blocks/blocks/linear.display.ts | 111 ++- apps/sim/blocks/blocks/linear.ts | 110 +-- apps/sim/blocks/blocks/linkedin.display.ts | 95 ++- apps/sim/blocks/blocks/linkedin.ts | 96 +-- apps/sim/blocks/blocks/linkup.display.ts | 98 ++- apps/sim/blocks/blocks/linkup.ts | 99 +-- apps/sim/blocks/blocks/linq.display.ts | 59 +- apps/sim/blocks/blocks/linq.ts | 60 +- apps/sim/blocks/blocks/loops.display.ts | 102 ++- apps/sim/blocks/blocks/loops.ts | 103 +-- apps/sim/blocks/blocks/luma.display.ts | 121 ++- apps/sim/blocks/blocks/luma.ts | 122 +-- apps/sim/blocks/blocks/mailchimp.display.ts | 106 ++- apps/sim/blocks/blocks/mailchimp.ts | 107 +-- apps/sim/blocks/blocks/mailgun.display.ts | 104 ++- apps/sim/blocks/blocks/mailgun.ts | 105 +-- apps/sim/blocks/blocks/mem0.display.ts | 99 ++- apps/sim/blocks/blocks/mem0.ts | 100 +-- .../sim/blocks/blocks/microsoft_ad.display.ts | 99 ++- apps/sim/blocks/blocks/microsoft_ad.ts | 100 +-- .../blocks/microsoft_dataverse.display.ts | 103 ++- apps/sim/blocks/blocks/microsoft_dataverse.ts | 104 +-- .../blocks/blocks/microsoft_excel.display.ts | 112 ++- apps/sim/blocks/blocks/microsoft_excel.ts | 113 +-- .../blocks/microsoft_planner.display.ts | 102 ++- apps/sim/blocks/blocks/microsoft_planner.ts | 103 +-- .../blocks/blocks/microsoft_teams.display.ts | 104 ++- apps/sim/blocks/blocks/microsoft_teams.ts | 105 +-- .../blocks/blocks/millionverifier.display.ts | 7 +- apps/sim/blocks/blocks/millionverifier.ts | 7 +- .../blocks/blocks/mistral_parse.display.ts | 95 ++- apps/sim/blocks/blocks/mistral_parse.ts | 96 +-- apps/sim/blocks/blocks/monday.display.ts | 97 ++- apps/sim/blocks/blocks/monday.ts | 98 +-- apps/sim/blocks/blocks/mongodb.display.ts | 98 ++- apps/sim/blocks/blocks/mongodb.ts | 99 +-- apps/sim/blocks/blocks/neo4j.display.ts | 95 ++- apps/sim/blocks/blocks/neo4j.ts | 96 +-- apps/sim/blocks/blocks/neverbounce.display.ts | 7 +- apps/sim/blocks/blocks/neverbounce.ts | 7 +- apps/sim/blocks/blocks/new_relic.display.ts | 100 ++- apps/sim/blocks/blocks/new_relic.ts | 101 +-- apps/sim/blocks/blocks/notion.display.ts | 112 ++- apps/sim/blocks/blocks/notion.ts | 113 +-- apps/sim/blocks/blocks/obsidian.display.ts | 95 ++- apps/sim/blocks/blocks/obsidian.ts | 96 +-- apps/sim/blocks/blocks/okta.display.ts | 103 ++- apps/sim/blocks/blocks/okta.ts | 104 +-- apps/sim/blocks/blocks/onedrive.display.ts | 98 ++- apps/sim/blocks/blocks/onedrive.ts | 99 +-- apps/sim/blocks/blocks/onepassword.display.ts | 100 ++- apps/sim/blocks/blocks/onepassword.ts | 101 +-- apps/sim/blocks/blocks/openai.display.ts | 99 ++- apps/sim/blocks/blocks/openai.ts | 100 +-- apps/sim/blocks/blocks/outlook.display.ts | 111 ++- apps/sim/blocks/blocks/outlook.ts | 112 +-- apps/sim/blocks/blocks/pagerduty.display.ts | 107 ++- apps/sim/blocks/blocks/pagerduty.ts | 108 +-- apps/sim/blocks/blocks/parallel.display.ts | 105 ++- apps/sim/blocks/blocks/parallel.ts | 106 +-- .../blocks/blocks/peopledatalabs.display.ts | 108 ++- apps/sim/blocks/blocks/peopledatalabs.ts | 109 +-- apps/sim/blocks/blocks/perplexity.display.ts | 101 ++- apps/sim/blocks/blocks/perplexity.ts | 102 +-- apps/sim/blocks/blocks/persona.display.ts | 129 ++- apps/sim/blocks/blocks/persona.ts | 130 +-- apps/sim/blocks/blocks/pinecone.display.ts | 107 ++- apps/sim/blocks/blocks/pinecone.ts | 108 +-- apps/sim/blocks/blocks/pipedrive.display.ts | 108 ++- apps/sim/blocks/blocks/pipedrive.ts | 109 +-- apps/sim/blocks/blocks/polymarket.display.ts | 107 ++- apps/sim/blocks/blocks/polymarket.ts | 108 +-- apps/sim/blocks/blocks/posthog.display.ts | 112 ++- apps/sim/blocks/blocks/posthog.ts | 113 +-- apps/sim/blocks/blocks/profound.display.ts | 106 ++- apps/sim/blocks/blocks/profound.ts | 107 +-- apps/sim/blocks/blocks/prospeo.display.ts | 104 ++- apps/sim/blocks/blocks/prospeo.ts | 105 +-- apps/sim/blocks/blocks/pulse.display.ts | 95 ++- apps/sim/blocks/blocks/pulse.ts | 96 +-- apps/sim/blocks/blocks/qdrant.display.ts | 95 ++- apps/sim/blocks/blocks/qdrant.ts | 96 +-- apps/sim/blocks/blocks/quartr.display.ts | 112 ++- apps/sim/blocks/blocks/quartr.ts | 113 +-- apps/sim/blocks/blocks/quiver.display.ts | 56 +- apps/sim/blocks/blocks/quiver.ts | 57 +- apps/sim/blocks/blocks/railway.display.ts | 117 ++- apps/sim/blocks/blocks/railway.ts | 118 +-- apps/sim/blocks/blocks/rb2b.display.ts | 103 ++- apps/sim/blocks/blocks/rb2b.ts | 104 +-- apps/sim/blocks/blocks/rds.display.ts | 99 ++- apps/sim/blocks/blocks/rds.ts | 100 +-- apps/sim/blocks/blocks/reddit.display.ts | 127 ++- apps/sim/blocks/blocks/reddit.ts | 128 +-- apps/sim/blocks/blocks/redis.display.ts | 99 ++- apps/sim/blocks/blocks/redis.ts | 100 +-- apps/sim/blocks/blocks/reducto.display.ts | 96 ++- apps/sim/blocks/blocks/reducto.ts | 97 +-- apps/sim/blocks/blocks/resend.display.ts | 95 ++- apps/sim/blocks/blocks/resend.ts | 96 +-- apps/sim/blocks/blocks/revenuecat.display.ts | 104 ++- apps/sim/blocks/blocks/revenuecat.ts | 105 +-- apps/sim/blocks/blocks/rippling.display.ts | 110 ++- apps/sim/blocks/blocks/rippling.ts | 111 +-- apps/sim/blocks/blocks/rootly.display.ts | 112 ++- apps/sim/blocks/blocks/rootly.ts | 113 +-- apps/sim/blocks/blocks/rss.display.ts | 38 +- apps/sim/blocks/blocks/rss.ts | 39 +- apps/sim/blocks/blocks/s3.display.ts | 100 ++- apps/sim/blocks/blocks/s3.ts | 101 +-- apps/sim/blocks/blocks/salesforce.display.ts | 111 ++- apps/sim/blocks/blocks/salesforce.ts | 112 +-- apps/sim/blocks/blocks/sap_concur.display.ts | 105 ++- apps/sim/blocks/blocks/sap_concur.ts | 106 +-- apps/sim/blocks/blocks/sap_s4hana.display.ts | 105 ++- apps/sim/blocks/blocks/sap_s4hana.ts | 106 +-- .../blocks/blocks/secrets_manager.display.ts | 108 ++- apps/sim/blocks/blocks/secrets_manager.ts | 109 +-- apps/sim/blocks/blocks/sendblue.display.ts | 104 ++- apps/sim/blocks/blocks/sendblue.ts | 105 +-- apps/sim/blocks/blocks/sendgrid.display.ts | 106 ++- apps/sim/blocks/blocks/sendgrid.ts | 107 +-- apps/sim/blocks/blocks/sentry.display.ts | 110 ++- apps/sim/blocks/blocks/sentry.ts | 111 +-- apps/sim/blocks/blocks/serper.display.ts | 105 ++- apps/sim/blocks/blocks/serper.ts | 106 +-- apps/sim/blocks/blocks/servicenow.display.ts | 99 ++- apps/sim/blocks/blocks/servicenow.ts | 100 +-- apps/sim/blocks/blocks/ses.display.ts | 105 ++- apps/sim/blocks/blocks/ses.ts | 106 +-- apps/sim/blocks/blocks/sharepoint.display.ts | 106 ++- apps/sim/blocks/blocks/sharepoint.ts | 107 +-- apps/sim/blocks/blocks/shopify.display.ts | 111 ++- apps/sim/blocks/blocks/shopify.ts | 112 +-- apps/sim/blocks/blocks/similarweb.display.ts | 98 ++- apps/sim/blocks/blocks/similarweb.ts | 99 +-- apps/sim/blocks/blocks/sixtyfour.display.ts | 100 ++- apps/sim/blocks/blocks/sixtyfour.ts | 101 +-- apps/sim/blocks/blocks/slack.display.ts | 158 +++- apps/sim/blocks/blocks/slack.ts | 157 +--- apps/sim/blocks/blocks/sportmonks.display.ts | 138 ++- apps/sim/blocks/blocks/sportmonks.ts | 139 +--- apps/sim/blocks/blocks/spotify.display.ts | 76 +- apps/sim/blocks/blocks/spotify.ts | 77 +- apps/sim/blocks/blocks/sqs.display.ts | 89 +- apps/sim/blocks/blocks/sqs.ts | 90 +- apps/sim/blocks/blocks/square.display.ts | 103 ++- apps/sim/blocks/blocks/square.ts | 104 +-- apps/sim/blocks/blocks/stagehand.display.ts | 96 ++- apps/sim/blocks/blocks/stagehand.ts | 97 +-- apps/sim/blocks/blocks/stripe.display.ts | 109 ++- apps/sim/blocks/blocks/stripe.ts | 108 +-- apps/sim/blocks/blocks/sts.display.ts | 106 ++- apps/sim/blocks/blocks/sts.ts | 107 +-- apps/sim/blocks/blocks/supabase.display.ts | 113 ++- apps/sim/blocks/blocks/supabase.ts | 114 +-- apps/sim/blocks/blocks/tailscale.display.ts | 99 ++- apps/sim/blocks/blocks/tailscale.ts | 100 +-- apps/sim/blocks/blocks/tavily.display.ts | 104 ++- apps/sim/blocks/blocks/tavily.ts | 105 +-- apps/sim/blocks/blocks/telegram.display.ts | 97 ++- apps/sim/blocks/blocks/telegram.ts | 98 +-- apps/sim/blocks/blocks/temporal.display.ts | 104 ++- apps/sim/blocks/blocks/temporal.ts | 105 +-- apps/sim/blocks/blocks/textract.display.ts | 101 ++- apps/sim/blocks/blocks/textract.ts | 102 +-- apps/sim/blocks/blocks/thrive.display.ts | 86 +- apps/sim/blocks/blocks/thrive.ts | 87 +- apps/sim/blocks/blocks/tinybird.display.ts | 107 ++- apps/sim/blocks/blocks/tinybird.ts | 108 +-- apps/sim/blocks/blocks/trello.display.ts | 104 ++- apps/sim/blocks/blocks/trello.ts | 105 +-- apps/sim/blocks/blocks/trigger_dev.display.ts | 132 ++- apps/sim/blocks/blocks/trigger_dev.ts | 133 +-- apps/sim/blocks/blocks/twilio.display.ts | 97 ++- apps/sim/blocks/blocks/twilio.ts | 98 +-- .../sim/blocks/blocks/twilio_voice.display.ts | 103 ++- apps/sim/blocks/blocks/twilio_voice.ts | 104 +-- apps/sim/blocks/blocks/typeform.display.ts | 104 ++- apps/sim/blocks/blocks/typeform.ts | 105 +-- apps/sim/blocks/blocks/upstash.display.ts | 105 ++- apps/sim/blocks/blocks/upstash.ts | 106 +-- apps/sim/blocks/blocks/vanta.display.ts | 111 ++- apps/sim/blocks/blocks/vanta.ts | 112 +-- apps/sim/blocks/blocks/vercel.display.ts | 105 ++- apps/sim/blocks/blocks/vercel.ts | 106 +-- apps/sim/blocks/blocks/wealthbox.display.ts | 105 ++- apps/sim/blocks/blocks/wealthbox.ts | 106 +-- apps/sim/blocks/blocks/webflow.display.ts | 100 ++- apps/sim/blocks/blocks/webflow.ts | 101 +-- apps/sim/blocks/blocks/whatsapp.display.ts | 100 ++- apps/sim/blocks/blocks/whatsapp.ts | 101 +-- apps/sim/blocks/blocks/wikipedia.display.ts | 96 ++- apps/sim/blocks/blocks/wikipedia.ts | 97 +-- apps/sim/blocks/blocks/wiza.display.ts | 98 ++- apps/sim/blocks/blocks/wiza.ts | 99 +-- apps/sim/blocks/blocks/wordpress.display.ts | 104 ++- apps/sim/blocks/blocks/wordpress.ts | 105 +-- apps/sim/blocks/blocks/workday.display.ts | 105 ++- apps/sim/blocks/blocks/workday.ts | 106 +-- apps/sim/blocks/blocks/x.display.ts | 105 ++- apps/sim/blocks/blocks/x.ts | 106 +-- apps/sim/blocks/blocks/youtube.display.ts | 111 ++- apps/sim/blocks/blocks/youtube.ts | 110 +-- apps/sim/blocks/blocks/zendesk.display.ts | 106 ++- apps/sim/blocks/blocks/zendesk.ts | 107 +-- apps/sim/blocks/blocks/zep.display.ts | 98 ++- apps/sim/blocks/blocks/zep.ts | 99 +-- apps/sim/blocks/blocks/zerobounce.display.ts | 7 +- apps/sim/blocks/blocks/zerobounce.ts | 7 +- apps/sim/blocks/blocks/zoom.display.ts | 102 ++- apps/sim/blocks/blocks/zoom.ts | 103 +-- apps/sim/blocks/blocks/zoominfo.display.ts | 105 ++- apps/sim/blocks/blocks/zoominfo.ts | 106 +-- apps/sim/blocks/manifest-data.ts | 783 +++++++++++++----- apps/sim/blocks/manifest.ts | 8 + apps/sim/blocks/registry.ts | 752 +++++------------ apps/sim/lib/integrations/index.ts | 4 +- apps/sim/scripts/codemod-block-meta.ts | 113 +++ .../scripts/generate-block-manifest-data.ts | 54 +- 450 files changed, 22854 insertions(+), 22870 deletions(-) create mode 100644 apps/sim/scripts/codemod-block-meta.ts diff --git a/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx index 0b7c616dd80..e0ea9f9579b 100644 --- a/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx +++ b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx @@ -17,7 +17,7 @@ import { IntegrationCtaButton } from '@/app/(landing)/integrations/(shell)/[slug import { IntegrationFAQ } from '@/app/(landing)/integrations/(shell)/[slug]/components/integration-faq' import { TemplateCardButton } from '@/app/(landing)/integrations/(shell)/[slug]/components/template-card-button' import { IntegrationIcon } from '@/app/(landing)/integrations/components/integration-icon' -import { getTemplatesForBlock } from '@/blocks/registry' +import { getTemplatesForBlock } from '@/blocks/manifest' const allIntegrations = INTEGRATIONS const INTEGRATION_COUNT = allIntegrations.length diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail.tsx index 3a2d73cf79a..16c8ab4ca9d 100644 --- a/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail.tsx +++ b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail.tsx @@ -25,7 +25,7 @@ import { getSuggestedSkillsForBlock, getTemplatesForBlock, type ScopedBlockTemplate, -} from '@/blocks/registry' +} from '@/blocks/manifest' import { useWorkspaceCredentials } from '@/hooks/queries/credentials' import { useOAuthReturnRouter } from '@/hooks/use-oauth-return' diff --git a/apps/sim/blocks/blocks/agentmail.display.ts b/apps/sim/blocks/blocks/agentmail.display.ts index ff6e8483d4e..5bad1758f36 100644 --- a/apps/sim/blocks/blocks/agentmail.display.ts +++ b/apps/sim/blocks/blocks/agentmail.display.ts @@ -1,6 +1,6 @@ import { AgentMailIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AgentMailBlockDisplay = { type: 'agentmail', @@ -14,3 +14,98 @@ export const AgentMailBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/agentmail', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const AgentMailBlockMeta = { + tags: ['messaging', 'automation'], + url: 'https://agentmail.to', + templates: [ + { + icon: AgentMailIcon, + title: 'AgentMail inbox-per-customer', + prompt: + 'Build a workflow that creates a dedicated AgentMail inbox for every new customer account, configures the display name and labels, and writes the inbox address back to the customer record so all customer email is isolated and threaded.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'enterprise'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail support concierge', + prompt: + 'Create a knowledge base from product docs and past resolutions, then build a scheduled workflow that polls an AgentMail inbox for new threads, drafts a contextual reply with citations, and either sends it or saves it as a draft based on confidence.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'communication'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail draft assistant', + prompt: + 'Build a scheduled workflow that polls AgentMail threads, drafts a reply that matches my tone using my recent sent messages as reference, and updates the existing draft each time the thread receives a new message so the draft stays current.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'communication', 'automation'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail label organizer', + prompt: + 'Create a workflow that classifies new AgentMail messages by topic and customer tier, applies the matching thread labels, and moves threads with stale labels into archive labels on a weekly schedule.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'team'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail + Loops support touch-points', + prompt: + 'Create a scheduled workflow that polls AgentMail support threads and sends a Loops event for each customer milestone — first contact, resolved, escalated — so Loops can automate the right follow-up email based on real support outcomes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail outbound sequence sender', + prompt: + 'Build a workflow that reads a prospects table, creates a personalized AgentMail draft per contact using their enriched profile, sends the message from a dedicated inbox, and logs the thread ID back to the row so replies can be tracked.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'communication'], + }, + { + icon: AgentMailIcon, + title: 'AgentMail thread escalation router', + prompt: + 'Create a scheduled workflow that polls AgentMail inboxes for new messages, detects urgent or negative threads with an agent, forwards the full thread to the on-call address, and posts a Slack alert so nothing high-priority sits unanswered.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'triage-inbox-messages', + description: + 'Read new messages in an AgentMail inbox, classify them, and reply or escalate as needed.', + content: + '# Triage Inbox Messages\n\nProcess unread email in an AgentMail inbox and act on each thread.\n\n## Steps\n1. List recent messages in the inbox and identify which threads are unread or unanswered.\n2. Read each thread for context including prior replies.\n3. Classify intent (question, request, spam, follow-up needed) and urgency.\n4. Draft and send a reply on the thread for routine items, or escalate by flagging the ones needing a human.\n\n## Output\nA summary of threads handled: who, the classification, and the action taken (replied, escalated, ignored).', + }, + { + name: 'extract-verification-code', + description: + 'Read a verification or OTP email in an AgentMail inbox and extract the code or confirmation link.', + content: + '# Extract Verification Code\n\nPull a 2FA/OTP code or confirmation link from an email so an agent can complete a signup or login flow.\n\n## Steps\n1. Search the inbox for the most recent message from the expected sender or matching the subject.\n2. Read the message body and extract the verification code or the confirmation URL.\n3. Return only the code or link.\n\n## Output\nThe extracted code or link. If multiple recent matches exist, return the newest and note its timestamp.', + }, + { + name: 'send-and-track-outreach', + description: + 'Send an email from an AgentMail inbox and monitor the thread for a reply to continue the conversation.', + content: + '# Send and Track Outreach\n\nSend an outbound email and follow the resulting thread.\n\n## Steps\n1. Compose the message with a clear subject and body from the provided details.\n2. Send it from the AgentMail inbox to the recipient.\n3. Check the thread for a reply; when one arrives, read it and determine the next action.\n\n## Output\nConfirm the message was sent with the thread ID. When a reply arrives, summarize it and recommend the next step.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/agentmail.ts b/apps/sim/blocks/blocks/agentmail.ts index 8bad89671a3..330f238f78f 100644 --- a/apps/sim/blocks/blocks/agentmail.ts +++ b/apps/sim/blocks/blocks/agentmail.ts @@ -1,6 +1,5 @@ -import { AgentMailIcon } from '@/components/icons' import { AgentMailBlockDisplay } from '@/blocks/blocks/agentmail.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const AgentMailBlock: BlockConfig = { @@ -612,98 +611,3 @@ export const AgentMailBlock: BlockConfig = { updatedAt: { type: 'string', description: 'Last updated timestamp' }, }, } - -export const AgentMailBlockMeta = { - tags: ['messaging', 'automation'], - url: 'https://agentmail.to', - templates: [ - { - icon: AgentMailIcon, - title: 'AgentMail inbox-per-customer', - prompt: - 'Build a workflow that creates a dedicated AgentMail inbox for every new customer account, configures the display name and labels, and writes the inbox address back to the customer record so all customer email is isolated and threaded.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'enterprise'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail support concierge', - prompt: - 'Create a knowledge base from product docs and past resolutions, then build a scheduled workflow that polls an AgentMail inbox for new threads, drafts a contextual reply with citations, and either sends it or saves it as a draft based on confidence.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'communication'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail draft assistant', - prompt: - 'Build a scheduled workflow that polls AgentMail threads, drafts a reply that matches my tone using my recent sent messages as reference, and updates the existing draft each time the thread receives a new message so the draft stays current.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'communication', 'automation'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail label organizer', - prompt: - 'Create a workflow that classifies new AgentMail messages by topic and customer tier, applies the matching thread labels, and moves threads with stale labels into archive labels on a weekly schedule.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'team'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail + Loops support touch-points', - prompt: - 'Create a scheduled workflow that polls AgentMail support threads and sends a Loops event for each customer milestone — first contact, resolved, escalated — so Loops can automate the right follow-up email based on real support outcomes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail outbound sequence sender', - prompt: - 'Build a workflow that reads a prospects table, creates a personalized AgentMail draft per contact using their enriched profile, sends the message from a dedicated inbox, and logs the thread ID back to the row so replies can be tracked.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'communication'], - }, - { - icon: AgentMailIcon, - title: 'AgentMail thread escalation router', - prompt: - 'Create a scheduled workflow that polls AgentMail inboxes for new messages, detects urgent or negative threads with an agent, forwards the full thread to the on-call address, and posts a Slack alert so nothing high-priority sits unanswered.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'triage-inbox-messages', - description: - 'Read new messages in an AgentMail inbox, classify them, and reply or escalate as needed.', - content: - '# Triage Inbox Messages\n\nProcess unread email in an AgentMail inbox and act on each thread.\n\n## Steps\n1. List recent messages in the inbox and identify which threads are unread or unanswered.\n2. Read each thread for context including prior replies.\n3. Classify intent (question, request, spam, follow-up needed) and urgency.\n4. Draft and send a reply on the thread for routine items, or escalate by flagging the ones needing a human.\n\n## Output\nA summary of threads handled: who, the classification, and the action taken (replied, escalated, ignored).', - }, - { - name: 'extract-verification-code', - description: - 'Read a verification or OTP email in an AgentMail inbox and extract the code or confirmation link.', - content: - '# Extract Verification Code\n\nPull a 2FA/OTP code or confirmation link from an email so an agent can complete a signup or login flow.\n\n## Steps\n1. Search the inbox for the most recent message from the expected sender or matching the subject.\n2. Read the message body and extract the verification code or the confirmation URL.\n3. Return only the code or link.\n\n## Output\nThe extracted code or link. If multiple recent matches exist, return the newest and note its timestamp.', - }, - { - name: 'send-and-track-outreach', - description: - 'Send an email from an AgentMail inbox and monitor the thread for a reply to continue the conversation.', - content: - '# Send and Track Outreach\n\nSend an outbound email and follow the resulting thread.\n\n## Steps\n1. Compose the message with a clear subject and body from the provided details.\n2. Send it from the AgentMail inbox to the recipient.\n3. Check the thread for a reply; when one arrives, read it and determine the next action.\n\n## Output\nConfirm the message was sent with the thread ID. When a reply arrives, summarize it and recommend the next step.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/agentphone.display.ts b/apps/sim/blocks/blocks/agentphone.display.ts index bfff96bf60c..3a2ed1a9730 100644 --- a/apps/sim/blocks/blocks/agentphone.display.ts +++ b/apps/sim/blocks/blocks/agentphone.display.ts @@ -1,6 +1,6 @@ import { AgentPhoneIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AgentPhoneBlockDisplay = { type: 'agentphone', @@ -14,3 +14,101 @@ export const AgentPhoneBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/agentphone', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const AgentPhoneBlockMeta = { + tags: ['messaging', 'automation'], + url: 'https://agentphone.ai', + templates: [ + { + icon: AgentPhoneIcon, + title: 'AgentPhone SMS support line', + prompt: + 'Create a workflow that provisions an AgentPhone number, replies to inbound support texts with an agent that pulls answers from context, and logs each conversation to a support table.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone lead call + transcript scoring', + prompt: + 'Build a workflow that places an outbound AgentPhone call to a new inbound lead, retrieves the call transcript afterward, scores qualification with an agent, and writes the result into HubSpot.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['hubspot'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone post-call summary', + prompt: + 'Create a workflow that runs after every AgentPhone call, summarizes the transcript with action items, and updates the linked Salesforce or HubSpot record with next steps.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone appointment reminder', + prompt: + 'Build a workflow that reads upcoming Calendly bookings and sends an AgentPhone SMS reminder to each attendee, then texts a confirmation when they reply.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['calendly'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone NPS texter', + prompt: + 'Create a scheduled workflow that texts recent customers an NPS survey over AgentPhone, reads their SMS replies, and writes structured ratings to a feedback table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone collections reminder', + prompt: + 'Build a workflow that picks up Stripe overdue invoices, sends a polite AgentPhone SMS payment reminder with the amount due, and reads the customer reply to update the invoice record.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['stripe'], + }, + { + icon: AgentPhoneIcon, + title: 'AgentPhone call-to-ticket logger', + prompt: + 'Create a scheduled workflow that lists recent AgentPhone calls, pulls each transcript, and opens a Zendesk ticket summarizing the issue so no call goes untracked.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + alsoIntegrations: ['zendesk'], + }, + ], + skills: [ + { + name: 'send-sms-notification', + description: + 'Send an SMS or iMessage from an AgentPhone number to notify or remind a recipient.', + content: + '# Send SMS Notification\n\nSend a text message to a person from an AgentPhone number.\n\n## Steps\n1. Determine the sending number and the recipient phone number.\n2. Write a clear, concise message (reminder, alert, confirmation, or update).\n3. Send the SMS or iMessage.\n\n## Output\nConfirm the message was sent with the recipient number and a short preview of the text. Note any send failure.', + }, + { + name: 'place-outbound-call', + description: + 'Place a voice call from an AgentPhone number to deliver a message or run a short scripted interaction.', + content: + '# Place Outbound Call\n\nMake a voice call from an AgentPhone number for reminders, confirmations, or notifications.\n\n## Steps\n1. Determine the AgentPhone number to call from and the destination number.\n2. Prepare the spoken message or script to deliver.\n3. Place the call and deliver the message.\n\n## Output\nConfirm the call was placed with the destination number and the message delivered. Report call status or transcript if available.', + }, + { + name: 'provision-and-respond', + description: + 'Provision a phone number and handle inbound SMS by reading the message and sending an appropriate reply.', + content: + '# Provision and Respond\n\nSet up a phone number and respond to incoming texts.\n\n## Steps\n1. Provision a US or Canadian phone number if one is not already assigned.\n2. Read inbound SMS messages received on that number.\n3. For each message, determine intent and send a relevant reply.\n\n## Output\nReport the provisioned number, the inbound messages handled, and the replies sent.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/agentphone.ts b/apps/sim/blocks/blocks/agentphone.ts index 88241ef388f..114924a3db9 100644 --- a/apps/sim/blocks/blocks/agentphone.ts +++ b/apps/sim/blocks/blocks/agentphone.ts @@ -1,7 +1,6 @@ import { toError } from '@sim/utils/errors' -import { AgentPhoneIcon } from '@/components/icons' import { AgentPhoneBlockDisplay } from '@/blocks/blocks/agentphone.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' const CONVERSATION_OPS = [ @@ -741,101 +740,3 @@ export const AgentPhoneBlock: BlockConfig = { months: { type: 'number', description: 'Months returned for monthly usage' }, }, } - -export const AgentPhoneBlockMeta = { - tags: ['messaging', 'automation'], - url: 'https://agentphone.ai', - templates: [ - { - icon: AgentPhoneIcon, - title: 'AgentPhone SMS support line', - prompt: - 'Create a workflow that provisions an AgentPhone number, replies to inbound support texts with an agent that pulls answers from context, and logs each conversation to a support table.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone lead call + transcript scoring', - prompt: - 'Build a workflow that places an outbound AgentPhone call to a new inbound lead, retrieves the call transcript afterward, scores qualification with an agent, and writes the result into HubSpot.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['hubspot'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone post-call summary', - prompt: - 'Create a workflow that runs after every AgentPhone call, summarizes the transcript with action items, and updates the linked Salesforce or HubSpot record with next steps.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone appointment reminder', - prompt: - 'Build a workflow that reads upcoming Calendly bookings and sends an AgentPhone SMS reminder to each attendee, then texts a confirmation when they reply.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['calendly'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone NPS texter', - prompt: - 'Create a scheduled workflow that texts recent customers an NPS survey over AgentPhone, reads their SMS replies, and writes structured ratings to a feedback table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone collections reminder', - prompt: - 'Build a workflow that picks up Stripe overdue invoices, sends a polite AgentPhone SMS payment reminder with the amount due, and reads the customer reply to update the invoice record.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['stripe'], - }, - { - icon: AgentPhoneIcon, - title: 'AgentPhone call-to-ticket logger', - prompt: - 'Create a scheduled workflow that lists recent AgentPhone calls, pulls each transcript, and opens a Zendesk ticket summarizing the issue so no call goes untracked.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - alsoIntegrations: ['zendesk'], - }, - ], - skills: [ - { - name: 'send-sms-notification', - description: - 'Send an SMS or iMessage from an AgentPhone number to notify or remind a recipient.', - content: - '# Send SMS Notification\n\nSend a text message to a person from an AgentPhone number.\n\n## Steps\n1. Determine the sending number and the recipient phone number.\n2. Write a clear, concise message (reminder, alert, confirmation, or update).\n3. Send the SMS or iMessage.\n\n## Output\nConfirm the message was sent with the recipient number and a short preview of the text. Note any send failure.', - }, - { - name: 'place-outbound-call', - description: - 'Place a voice call from an AgentPhone number to deliver a message or run a short scripted interaction.', - content: - '# Place Outbound Call\n\nMake a voice call from an AgentPhone number for reminders, confirmations, or notifications.\n\n## Steps\n1. Determine the AgentPhone number to call from and the destination number.\n2. Prepare the spoken message or script to deliver.\n3. Place the call and deliver the message.\n\n## Output\nConfirm the call was placed with the destination number and the message delivered. Report call status or transcript if available.', - }, - { - name: 'provision-and-respond', - description: - 'Provision a phone number and handle inbound SMS by reading the message and sending an appropriate reply.', - content: - '# Provision and Respond\n\nSet up a phone number and respond to incoming texts.\n\n## Steps\n1. Provision a US or Canadian phone number if one is not already assigned.\n2. Read inbound SMS messages received on that number.\n3. For each message, determine intent and send a relevant reply.\n\n## Output\nReport the provisioned number, the inbound messages handled, and the replies sent.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/agiloft.display.ts b/apps/sim/blocks/blocks/agiloft.display.ts index a191f24221a..707fb231cc8 100644 --- a/apps/sim/blocks/blocks/agiloft.display.ts +++ b/apps/sim/blocks/blocks/agiloft.display.ts @@ -1,6 +1,6 @@ import { AgiloftIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AgiloftBlockDisplay = { type: 'agiloft', @@ -14,3 +14,101 @@ export const AgiloftBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/agiloft', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const AgiloftBlockMeta = { + tags: ['automation'], + url: 'https://www.agiloft.com', + templates: [ + { + icon: AgiloftIcon, + title: 'Agiloft contract launcher', + prompt: + 'Build a workflow that on a closed-won Salesforce opportunity creates an Agiloft contract record from the right template, fills key fields from the opportunity, and routes for legal review.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['legal', 'sales'], + alsoIntegrations: ['salesforce'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft clause analyzer', + prompt: + 'Create a workflow that pulls Agiloft contracts on a schedule, extracts key clauses, writes deviations from the standard template to a legal review table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'analysis'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft renewal tracker', + prompt: + 'Build a scheduled workflow that finds Agiloft contracts with renewals due in the next 90 days, creates a renewal-prep task in the CRM, and emails the account owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'legal'], + alsoIntegrations: ['salesforce', 'gmail'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft approval router', + prompt: + 'Create a scheduled workflow that searches Agiloft for contracts needing approval, posts a Microsoft Teams adaptive card to the approver, captures the decision, and updates Agiloft.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft compliance audit', + prompt: + 'Build a scheduled monthly workflow that audits Agiloft contracts against compliance requirements, flags missing clauses or expired terms, and writes a remediation backlog.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft DocuSign bridge', + prompt: + 'Create a scheduled workflow that searches Agiloft for contracts marked ready-to-sign, creates a DocuSign envelope from the template, sends it, and writes the envelope ID back to Agiloft.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'legal'], + alsoIntegrations: ['docusign'], + }, + { + icon: AgiloftIcon, + title: 'Agiloft + Linear ticket bridge', + prompt: + 'Build a scheduled workflow that searches Agiloft for contracts flagged for engineering review and creates a Linear ticket with the contract context and a link, keeping status synced both ways.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['legal', 'engineering'], + alsoIntegrations: ['linear'], + }, + ], + skills: [ + { + name: 'flag-expiring-contracts', + description: + 'Query Agiloft for contracts approaching their renewal or expiration date and report the ones at risk.', + content: + '# Flag Expiring Contracts\n\nFind contracts in Agiloft that are nearing expiration or auto-renewal so the team can act in time.\n\n## Steps\n1. Query the contract records for upcoming expiration or renewal dates within the target window.\n2. For each match, read key terms: counterparty, value, renewal type, and notice period.\n3. Identify contracts with auto-renewal clauses that need a decision before the notice deadline.\n\n## Output\nA list of at-risk contracts sorted by date, with counterparty, expiration date, renewal type, and recommended action.', + }, + { + name: 'create-contract-record', + description: + 'Create a new contract or related record in Agiloft from provided deal or request details.', + content: + '# Create Contract Record\n\nAdd a new contract record to Agiloft from intake details.\n\n## Steps\n1. Map the provided details to the contract record fields (counterparty, type, value, start/end dates, owner).\n2. Set status to the correct initial stage in the lifecycle.\n3. Create the record and capture its ID.\n\n## Output\nConfirm the record was created with its ID and key fields. Note any required fields that were missing.', + }, + { + name: 'summarize-contract-terms', + description: + 'Read a contract record in Agiloft and produce a plain-language summary of its key obligations and dates.', + content: + '# Summarize Contract Terms\n\nTurn an Agiloft contract record into a concise brief.\n\n## Steps\n1. Read the contract record and its key fields and attached terms.\n2. Identify obligations, payment terms, renewal/termination clauses, and critical dates.\n3. Note any unusual or high-risk terms.\n\n## Output\nA short brief: parties, term, value, key obligations, critical dates, and any risk flags. Keep it readable for non-lawyers.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/agiloft.ts b/apps/sim/blocks/blocks/agiloft.ts index 415ff60317a..b5535c7d110 100644 --- a/apps/sim/blocks/blocks/agiloft.ts +++ b/apps/sim/blocks/blocks/agiloft.ts @@ -1,6 +1,5 @@ -import { AgiloftIcon } from '@/components/icons' import { AgiloftBlockDisplay } from '@/blocks/blocks/agiloft.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' @@ -423,101 +422,3 @@ export const AgiloftBlock: BlockConfig = { }, }, } - -export const AgiloftBlockMeta = { - tags: ['automation'], - url: 'https://www.agiloft.com', - templates: [ - { - icon: AgiloftIcon, - title: 'Agiloft contract launcher', - prompt: - 'Build a workflow that on a closed-won Salesforce opportunity creates an Agiloft contract record from the right template, fills key fields from the opportunity, and routes for legal review.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['legal', 'sales'], - alsoIntegrations: ['salesforce'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft clause analyzer', - prompt: - 'Create a workflow that pulls Agiloft contracts on a schedule, extracts key clauses, writes deviations from the standard template to a legal review table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'analysis'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft renewal tracker', - prompt: - 'Build a scheduled workflow that finds Agiloft contracts with renewals due in the next 90 days, creates a renewal-prep task in the CRM, and emails the account owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'legal'], - alsoIntegrations: ['salesforce', 'gmail'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft approval router', - prompt: - 'Create a scheduled workflow that searches Agiloft for contracts needing approval, posts a Microsoft Teams adaptive card to the approver, captures the decision, and updates Agiloft.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft compliance audit', - prompt: - 'Build a scheduled monthly workflow that audits Agiloft contracts against compliance requirements, flags missing clauses or expired terms, and writes a remediation backlog.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft DocuSign bridge', - prompt: - 'Create a scheduled workflow that searches Agiloft for contracts marked ready-to-sign, creates a DocuSign envelope from the template, sends it, and writes the envelope ID back to Agiloft.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'legal'], - alsoIntegrations: ['docusign'], - }, - { - icon: AgiloftIcon, - title: 'Agiloft + Linear ticket bridge', - prompt: - 'Build a scheduled workflow that searches Agiloft for contracts flagged for engineering review and creates a Linear ticket with the contract context and a link, keeping status synced both ways.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['legal', 'engineering'], - alsoIntegrations: ['linear'], - }, - ], - skills: [ - { - name: 'flag-expiring-contracts', - description: - 'Query Agiloft for contracts approaching their renewal or expiration date and report the ones at risk.', - content: - '# Flag Expiring Contracts\n\nFind contracts in Agiloft that are nearing expiration or auto-renewal so the team can act in time.\n\n## Steps\n1. Query the contract records for upcoming expiration or renewal dates within the target window.\n2. For each match, read key terms: counterparty, value, renewal type, and notice period.\n3. Identify contracts with auto-renewal clauses that need a decision before the notice deadline.\n\n## Output\nA list of at-risk contracts sorted by date, with counterparty, expiration date, renewal type, and recommended action.', - }, - { - name: 'create-contract-record', - description: - 'Create a new contract or related record in Agiloft from provided deal or request details.', - content: - '# Create Contract Record\n\nAdd a new contract record to Agiloft from intake details.\n\n## Steps\n1. Map the provided details to the contract record fields (counterparty, type, value, start/end dates, owner).\n2. Set status to the correct initial stage in the lifecycle.\n3. Create the record and capture its ID.\n\n## Output\nConfirm the record was created with its ID and key fields. Note any required fields that were missing.', - }, - { - name: 'summarize-contract-terms', - description: - 'Read a contract record in Agiloft and produce a plain-language summary of its key obligations and dates.', - content: - '# Summarize Contract Terms\n\nTurn an Agiloft contract record into a concise brief.\n\n## Steps\n1. Read the contract record and its key fields and attached terms.\n2. Identify obligations, payment terms, renewal/termination clauses, and critical dates.\n3. Note any unusual or high-risk terms.\n\n## Output\nA short brief: parties, term, value, key obligations, critical dates, and any risk flags. Keep it readable for non-lawyers.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ahrefs.display.ts b/apps/sim/blocks/blocks/ahrefs.display.ts index 60e6ad4688c..c3db512cb86 100644 --- a/apps/sim/blocks/blocks/ahrefs.display.ts +++ b/apps/sim/blocks/blocks/ahrefs.display.ts @@ -1,6 +1,6 @@ import { AhrefsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AhrefsBlockDisplay = { type: 'ahrefs', @@ -14,3 +14,101 @@ export const AhrefsBlockDisplay = { docsLink: 'https://docs.ahrefs.com/docs/api/reference/introduction', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const AhrefsBlockMeta = { + tags: ['seo', 'marketing', 'data-analytics'], + url: 'https://ahrefs.com', + templates: [ + { + icon: AhrefsIcon, + title: 'Ahrefs keyword tracker', + prompt: + 'Create a scheduled weekly workflow that queries Ahrefs for ranking positions of my tracked keywords, logs the results into a tables-based SEO scorecard, and posts a Slack summary of gainers and losers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs competitor backlink monitor', + prompt: + 'Build a scheduled workflow that pulls new Ahrefs referring domains for my competitors weekly, flags high-authority links, and posts a Slack digest with the linking page and anchor text.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs content gap finder', + prompt: + 'Create a workflow that pulls Ahrefs organic keywords for both my domain and a competitor, has an agent diff the lists to find keywords the competitor ranks for that I do not, and writes a prioritized content brief table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs broken-link sweeper', + prompt: + 'Build a scheduled workflow that runs an Ahrefs broken-backlinks check weekly, writes broken referring pages to a remediation table, and proposes redirects for the SEO lead to approve.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs + Similarweb growth scoreboard', + prompt: + 'Build a scheduled monthly workflow that joins Ahrefs SEO data with Similarweb traffic intelligence, writes a growth scoreboard table, and emails leadership.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting'], + alsoIntegrations: ['similarweb', 'gmail'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs + Profound combined visibility', + prompt: + 'Create a scheduled weekly workflow that combines Ahrefs SEO rankings with Profound AI-visibility scores, writes a combined visibility report, and surfaces gaps to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['profound', 'slack'], + }, + { + icon: AhrefsIcon, + title: 'Ahrefs domain-health watchdog', + prompt: + 'Build a scheduled workflow that checks Ahrefs domain rating and backlink stats for my site daily, logs the values to a trend table, and posts a Slack alert when domain rating drops or a spike of lost referring domains is detected.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'analyze-competitor-backlinks', + description: + "Pull a competitor domain's backlink profile from Ahrefs and surface link-building opportunities.", + content: + "# Analyze Competitor Backlinks\n\nUse Ahrefs to study a competitor's backlinks and find outreach targets.\n\n## Steps\n1. Run a backlink/referring-domains report for the competitor URL or domain.\n2. Identify high-authority referring domains and the anchor texts they use.\n3. Compare against your own domain to find sites linking to them but not you.\n\n## Output\nA prioritized list of link opportunities: referring domain, authority, linked page, and why it is worth pursuing.", + }, + { + name: 'keyword-research-report', + description: + 'Research keywords in Ahrefs for a topic and report volume, difficulty, and ranking opportunities.', + content: + '# Keyword Research Report\n\nBuild a keyword opportunity report from Ahrefs data.\n\n## Steps\n1. Pull the organic keywords a competitor domain already ranks for to source candidate keywords for the topic.\n2. Run a keyword overview on the most relevant candidates to collect search volume and keyword difficulty.\n3. Highlight keywords with meaningful volume and lower difficulty as quick wins.\n\n## Output\nA table of keywords with volume and difficulty, grouped into quick wins vs long-term targets, with a short recommendation.', + }, + { + name: 'track-organic-rankings', + description: + "Pull a domain's organic keyword rankings from Ahrefs and report top movers and lost positions.", + content: + '# Track Organic Rankings\n\nReport how a domain is ranking in organic search using Ahrefs.\n\n## Steps\n1. Pull the organic keywords report for the target domain.\n2. Identify the top-ranking keywords and their positions.\n3. Compare against a prior snapshot if available to find gains and losses.\n\n## Output\nA summary of top organic keywords, notable position gains and drops, and pages that may need attention.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ahrefs.ts b/apps/sim/blocks/blocks/ahrefs.ts index 3d915478f0e..4118097bdc9 100644 --- a/apps/sim/blocks/blocks/ahrefs.ts +++ b/apps/sim/blocks/blocks/ahrefs.ts @@ -1,6 +1,5 @@ -import { AhrefsIcon } from '@/components/icons' import { AhrefsBlockDisplay } from '@/blocks/blocks/ahrefs.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AhrefsResponse } from '@/tools/ahrefs/types' @@ -564,101 +563,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n brokenBacklinks: { type: 'json', description: 'List of broken backlinks' }, }, } - -export const AhrefsBlockMeta = { - tags: ['seo', 'marketing', 'data-analytics'], - url: 'https://ahrefs.com', - templates: [ - { - icon: AhrefsIcon, - title: 'Ahrefs keyword tracker', - prompt: - 'Create a scheduled weekly workflow that queries Ahrefs for ranking positions of my tracked keywords, logs the results into a tables-based SEO scorecard, and posts a Slack summary of gainers and losers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs competitor backlink monitor', - prompt: - 'Build a scheduled workflow that pulls new Ahrefs referring domains for my competitors weekly, flags high-authority links, and posts a Slack digest with the linking page and anchor text.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs content gap finder', - prompt: - 'Create a workflow that pulls Ahrefs organic keywords for both my domain and a competitor, has an agent diff the lists to find keywords the competitor ranks for that I do not, and writes a prioritized content brief table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs broken-link sweeper', - prompt: - 'Build a scheduled workflow that runs an Ahrefs broken-backlinks check weekly, writes broken referring pages to a remediation table, and proposes redirects for the SEO lead to approve.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs + Similarweb growth scoreboard', - prompt: - 'Build a scheduled monthly workflow that joins Ahrefs SEO data with Similarweb traffic intelligence, writes a growth scoreboard table, and emails leadership.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting'], - alsoIntegrations: ['similarweb', 'gmail'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs + Profound combined visibility', - prompt: - 'Create a scheduled weekly workflow that combines Ahrefs SEO rankings with Profound AI-visibility scores, writes a combined visibility report, and surfaces gaps to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['profound', 'slack'], - }, - { - icon: AhrefsIcon, - title: 'Ahrefs domain-health watchdog', - prompt: - 'Build a scheduled workflow that checks Ahrefs domain rating and backlink stats for my site daily, logs the values to a trend table, and posts a Slack alert when domain rating drops or a spike of lost referring domains is detected.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'analyze-competitor-backlinks', - description: - "Pull a competitor domain's backlink profile from Ahrefs and surface link-building opportunities.", - content: - "# Analyze Competitor Backlinks\n\nUse Ahrefs to study a competitor's backlinks and find outreach targets.\n\n## Steps\n1. Run a backlink/referring-domains report for the competitor URL or domain.\n2. Identify high-authority referring domains and the anchor texts they use.\n3. Compare against your own domain to find sites linking to them but not you.\n\n## Output\nA prioritized list of link opportunities: referring domain, authority, linked page, and why it is worth pursuing.", - }, - { - name: 'keyword-research-report', - description: - 'Research keywords in Ahrefs for a topic and report volume, difficulty, and ranking opportunities.', - content: - '# Keyword Research Report\n\nBuild a keyword opportunity report from Ahrefs data.\n\n## Steps\n1. Pull the organic keywords a competitor domain already ranks for to source candidate keywords for the topic.\n2. Run a keyword overview on the most relevant candidates to collect search volume and keyword difficulty.\n3. Highlight keywords with meaningful volume and lower difficulty as quick wins.\n\n## Output\nA table of keywords with volume and difficulty, grouped into quick wins vs long-term targets, with a short recommendation.', - }, - { - name: 'track-organic-rankings', - description: - "Pull a domain's organic keyword rankings from Ahrefs and report top movers and lost positions.", - content: - '# Track Organic Rankings\n\nReport how a domain is ranking in organic search using Ahrefs.\n\n## Steps\n1. Pull the organic keywords report for the target domain.\n2. Identify the top-ranking keywords and their positions.\n3. Compare against a prior snapshot if available to find gains and losses.\n\n## Output\nA summary of top organic keywords, notable position gains and drops, and pages that may need attention.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/airtable.display.ts b/apps/sim/blocks/blocks/airtable.display.ts index f2941cdab61..80240688dfc 100644 --- a/apps/sim/blocks/blocks/airtable.display.ts +++ b/apps/sim/blocks/blocks/airtable.display.ts @@ -1,6 +1,6 @@ import { AirtableIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AirtableBlockDisplay = { type: 'airtable', @@ -14,3 +14,115 @@ export const AirtableBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/airtable', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const AirtableBlockMeta = { + tags: ['spreadsheet', 'automation'], + url: 'https://www.airtable.com', + templates: [ + { + icon: AirtableIcon, + title: 'Airtable data sync', + prompt: + 'Create a scheduled workflow that syncs records from my Airtable base into a Sim table every hour, keeping both in sync. Use an agent to detect changes, resolve conflicts, and flag any discrepancies for review in Slack.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['sync', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AirtableIcon, + title: 'Airtable two-way sync', + prompt: + 'Build a scheduled workflow that mirrors records between an Airtable base and a Sim table, detects conflicts, and pings Slack on records that need manual resolution.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sync', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AirtableIcon, + title: 'Airtable form-to-CRM', + prompt: + 'Create a workflow that watches Airtable form submissions, enriches each row with company data, and pushes qualifying leads into HubSpot with the right owner.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: AirtableIcon, + title: 'Airtable content calendar publisher', + prompt: + 'Build a workflow that reads an Airtable content calendar, publishes due posts to WordPress with proper formatting, and writes the live URL back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['wordpress'], + }, + { + icon: AirtableIcon, + title: 'Airtable approval workflow', + prompt: + 'Create a workflow that watches Airtable for new approval rows, posts a Slack message with quick-action buttons, captures the decision, and updates the row state.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AirtableIcon, + title: 'Airtable digest reporter', + prompt: + 'Build a scheduled weekly workflow that summarizes activity in a chosen Airtable base — new rows, status changes, completed items — and emails a digest to the project owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: AirtableIcon, + title: 'Airtable to data-warehouse sync', + prompt: + 'Create a scheduled workflow that exports an Airtable base to BigQuery nightly with schema mapping, partitions by ingestion date, and writes the run history to a control table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sync', 'enterprise'], + alsoIntegrations: ['google_bigquery'], + }, + + { + icon: AirtableIcon, + title: 'Trigger Gmail from Airtable records', + prompt: + 'Build a workflow that watches Airtable for new or updated records and sends a personalised Gmail message for each one, so outreach and follow-ups go out automatically.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'sync-records-to-table', + description: + 'Parse incoming emails, forms, or documents and create or update structured Airtable records.', + content: + '# Sync Records to Airtable\n\nTurn unstructured inbound data into clean Airtable records.\n\n## Steps\n1. Read the source content (email body, form payload, or document text).\n2. Extract the fields that map to the target table columns (name, email, company, amount, status, etc.).\n3. Search the table for an existing record matching a unique key (such as email or order ID).\n4. Update the existing record if found; otherwise create a new one.\n5. Set any derived fields (category, priority, owner) based on the content.\n\n## Output\nReport how many records were created vs updated and list the record IDs. Flag any rows skipped for missing required fields.', + }, + { + name: 'triage-and-route-records', + description: + 'Classify new Airtable records (leads, tickets, requests) and assign owner, priority, and due dates.', + content: + '# Triage and Route Records\n\nAutomatically qualify and route new Airtable records.\n\n## Steps\n1. List recently created records in the target table.\n2. For each record, read the free-text fields (notes, message, transcript) and classify intent, urgency, and category.\n3. Set the owner, priority, and status fields based on the classification.\n4. Compute and set a due date for time-sensitive items.\n\n## Output\nSummarize the records triaged grouped by owner and priority. Note any records that need human review.', + }, + { + name: 'generate-status-report', + description: + 'Query an Airtable table or view and produce a rolled-up status report of progress, blockers, and trends.', + content: + '# Generate Status Report\n\nBuild a concise report from an Airtable table or view.\n\n## Steps\n1. Read records from the specified table or filtered view.\n2. Group by the relevant dimension (project, status, owner, or stage).\n3. Count totals per group and identify overdue or stalled items.\n4. Highlight notable changes or anomalies in the data.\n\n## Output\nA short report: totals per group, items at risk, and 2-3 takeaways. Keep it scannable with bullet points.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/airtable.ts b/apps/sim/blocks/blocks/airtable.ts index fa7c2d14461..5b217e5ec17 100644 --- a/apps/sim/blocks/blocks/airtable.ts +++ b/apps/sim/blocks/blocks/airtable.ts @@ -1,7 +1,6 @@ -import { AirtableIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { AirtableBlockDisplay } from '@/blocks/blocks/airtable.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AirtableResponse } from '@/tools/airtable/types' import { getTrigger } from '@/triggers' @@ -337,115 +336,3 @@ Return ONLY the valid JSON object - no explanations, no markdown.`, available: ['airtable_webhook'], }, } - -export const AirtableBlockMeta = { - tags: ['spreadsheet', 'automation'], - url: 'https://www.airtable.com', - templates: [ - { - icon: AirtableIcon, - title: 'Airtable data sync', - prompt: - 'Create a scheduled workflow that syncs records from my Airtable base into a Sim table every hour, keeping both in sync. Use an agent to detect changes, resolve conflicts, and flag any discrepancies for review in Slack.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['sync', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AirtableIcon, - title: 'Airtable two-way sync', - prompt: - 'Build a scheduled workflow that mirrors records between an Airtable base and a Sim table, detects conflicts, and pings Slack on records that need manual resolution.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sync', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AirtableIcon, - title: 'Airtable form-to-CRM', - prompt: - 'Create a workflow that watches Airtable form submissions, enriches each row with company data, and pushes qualifying leads into HubSpot with the right owner.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: AirtableIcon, - title: 'Airtable content calendar publisher', - prompt: - 'Build a workflow that reads an Airtable content calendar, publishes due posts to WordPress with proper formatting, and writes the live URL back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['wordpress'], - }, - { - icon: AirtableIcon, - title: 'Airtable approval workflow', - prompt: - 'Create a workflow that watches Airtable for new approval rows, posts a Slack message with quick-action buttons, captures the decision, and updates the row state.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AirtableIcon, - title: 'Airtable digest reporter', - prompt: - 'Build a scheduled weekly workflow that summarizes activity in a chosen Airtable base — new rows, status changes, completed items — and emails a digest to the project owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: AirtableIcon, - title: 'Airtable to data-warehouse sync', - prompt: - 'Create a scheduled workflow that exports an Airtable base to BigQuery nightly with schema mapping, partitions by ingestion date, and writes the run history to a control table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sync', 'enterprise'], - alsoIntegrations: ['google_bigquery'], - }, - - { - icon: AirtableIcon, - title: 'Trigger Gmail from Airtable records', - prompt: - 'Build a workflow that watches Airtable for new or updated records and sends a personalised Gmail message for each one, so outreach and follow-ups go out automatically.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'sync-records-to-table', - description: - 'Parse incoming emails, forms, or documents and create or update structured Airtable records.', - content: - '# Sync Records to Airtable\n\nTurn unstructured inbound data into clean Airtable records.\n\n## Steps\n1. Read the source content (email body, form payload, or document text).\n2. Extract the fields that map to the target table columns (name, email, company, amount, status, etc.).\n3. Search the table for an existing record matching a unique key (such as email or order ID).\n4. Update the existing record if found; otherwise create a new one.\n5. Set any derived fields (category, priority, owner) based on the content.\n\n## Output\nReport how many records were created vs updated and list the record IDs. Flag any rows skipped for missing required fields.', - }, - { - name: 'triage-and-route-records', - description: - 'Classify new Airtable records (leads, tickets, requests) and assign owner, priority, and due dates.', - content: - '# Triage and Route Records\n\nAutomatically qualify and route new Airtable records.\n\n## Steps\n1. List recently created records in the target table.\n2. For each record, read the free-text fields (notes, message, transcript) and classify intent, urgency, and category.\n3. Set the owner, priority, and status fields based on the classification.\n4. Compute and set a due date for time-sensitive items.\n\n## Output\nSummarize the records triaged grouped by owner and priority. Note any records that need human review.', - }, - { - name: 'generate-status-report', - description: - 'Query an Airtable table or view and produce a rolled-up status report of progress, blockers, and trends.', - content: - '# Generate Status Report\n\nBuild a concise report from an Airtable table or view.\n\n## Steps\n1. Read records from the specified table or filtered view.\n2. Group by the relevant dimension (project, status, owner, or stage).\n3. Count totals per group and identify overdue or stalled items.\n4. Highlight notable changes or anomalies in the data.\n\n## Output\nA short report: totals per group, items at risk, and 2-3 takeaways. Keep it scannable with bullet points.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/airweave.display.ts b/apps/sim/blocks/blocks/airweave.display.ts index 48936bd0794..5e88c4777f5 100644 --- a/apps/sim/blocks/blocks/airweave.display.ts +++ b/apps/sim/blocks/blocks/airweave.display.ts @@ -1,6 +1,6 @@ import { AirweaveIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AirweaveBlockDisplay = { type: 'airweave', @@ -15,3 +15,91 @@ export const AirweaveBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/airweave', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const AirweaveBlockMeta = { + tags: ['vector-search', 'knowledge-base'], + url: 'https://airweave.ai', + templates: [ + { + icon: AirweaveIcon, + title: 'Airweave cross-source answerer', + prompt: + 'Build a workflow that takes a user question, searches across your Airweave-synced sources — Notion, Confluence, Drive — and returns an AI-generated answer with sourced citations.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'enterprise'], + }, + { + icon: AirweaveIcon, + title: 'Airweave + agent answer endpoint', + prompt: + 'Create an agent that searches an Airweave-managed retrieval layer, answers user questions with sourced citations, and deploys as a chat endpoint for internal teams.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'enterprise'], + }, + { + icon: AirweaveIcon, + title: 'Airweave daily knowledge digest', + prompt: + 'Build a scheduled workflow that runs a set of standing Airweave searches each morning, summarizes the freshest results per topic, and posts a digest to Slack for the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AirweaveIcon, + title: 'Airweave research-to-table', + prompt: + 'Create a workflow that takes a list of research questions, runs an Airweave search for each, and writes the top answers with their citations into a table for review.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'automation'], + }, + { + icon: AirweaveIcon, + title: 'Airweave answer-quality checker', + prompt: + 'Build a scheduled workflow that runs a benchmark set of questions against Airweave, has an agent grade each answer for relevance and citation quality, and writes a quality report to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: AirweaveIcon, + title: 'Airweave + Slack Q&A', + prompt: + 'Create a Slack bot that searches an Airweave-managed retrieval layer to answer questions in support channels with sourced citations.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'community'], + alsoIntegrations: ['slack'], + }, + { + icon: AirweaveIcon, + title: 'Airweave weekly topic tracker', + prompt: + 'Build a scheduled weekly workflow that searches Airweave for updates on tracked topics, summarizes what is new since last week, and writes a report for the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['research', 'reporting'], + }, + ], + skills: [ + { + name: 'answer-from-collection', + description: + 'Search an Airweave collection across synced sources and answer a question with grounded, cited results.', + content: + '# Answer From Collection\n\nUse Airweave to retrieve current context across connected apps and answer a question.\n\n## Steps\n1. Take the user question and search the relevant Airweave collection.\n2. Review the top results, noting which source each came from (docs, tickets, CRM, etc.).\n3. Synthesize an answer grounded only in the retrieved content.\n4. If the collection returns nothing relevant, say so instead of guessing.\n\n## Output\nA concise answer with citations back to the source records. Do not include claims unsupported by the results.', + }, + { + name: 'build-context-brief', + description: + 'Search an Airweave collection for a person, account, or project and compile a context brief from all sources.', + content: + '# Build Context Brief\n\nGather everything Airweave knows about a subject across synced sources into one brief.\n\n## Steps\n1. Search the collection for the subject (account name, project, customer, or person).\n2. Pull relevant hits from each source type and group them.\n3. Summarize the current state, recent activity, and any open items.\n\n## Output\nA short brief organized by source, highlighting the most recent and relevant facts plus open questions.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/airweave.ts b/apps/sim/blocks/blocks/airweave.ts index 1ca8e146a79..20307586731 100644 --- a/apps/sim/blocks/blocks/airweave.ts +++ b/apps/sim/blocks/blocks/airweave.ts @@ -1,6 +1,5 @@ -import { AirweaveIcon } from '@/components/icons' import { AirweaveBlockDisplay } from '@/blocks/blocks/airweave.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AirweaveSearchResponse } from '@/tools/airweave/types' @@ -93,91 +92,3 @@ export const AirweaveBlock: BlockConfig = { completion: { type: 'string', description: 'AI-generated answer (when enabled)' }, }, } - -export const AirweaveBlockMeta = { - tags: ['vector-search', 'knowledge-base'], - url: 'https://airweave.ai', - templates: [ - { - icon: AirweaveIcon, - title: 'Airweave cross-source answerer', - prompt: - 'Build a workflow that takes a user question, searches across your Airweave-synced sources — Notion, Confluence, Drive — and returns an AI-generated answer with sourced citations.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'enterprise'], - }, - { - icon: AirweaveIcon, - title: 'Airweave + agent answer endpoint', - prompt: - 'Create an agent that searches an Airweave-managed retrieval layer, answers user questions with sourced citations, and deploys as a chat endpoint for internal teams.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'enterprise'], - }, - { - icon: AirweaveIcon, - title: 'Airweave daily knowledge digest', - prompt: - 'Build a scheduled workflow that runs a set of standing Airweave searches each morning, summarizes the freshest results per topic, and posts a digest to Slack for the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AirweaveIcon, - title: 'Airweave research-to-table', - prompt: - 'Create a workflow that takes a list of research questions, runs an Airweave search for each, and writes the top answers with their citations into a table for review.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'automation'], - }, - { - icon: AirweaveIcon, - title: 'Airweave answer-quality checker', - prompt: - 'Build a scheduled workflow that runs a benchmark set of questions against Airweave, has an agent grade each answer for relevance and citation quality, and writes a quality report to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: AirweaveIcon, - title: 'Airweave + Slack Q&A', - prompt: - 'Create a Slack bot that searches an Airweave-managed retrieval layer to answer questions in support channels with sourced citations.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'community'], - alsoIntegrations: ['slack'], - }, - { - icon: AirweaveIcon, - title: 'Airweave weekly topic tracker', - prompt: - 'Build a scheduled weekly workflow that searches Airweave for updates on tracked topics, summarizes what is new since last week, and writes a report for the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['research', 'reporting'], - }, - ], - skills: [ - { - name: 'answer-from-collection', - description: - 'Search an Airweave collection across synced sources and answer a question with grounded, cited results.', - content: - '# Answer From Collection\n\nUse Airweave to retrieve current context across connected apps and answer a question.\n\n## Steps\n1. Take the user question and search the relevant Airweave collection.\n2. Review the top results, noting which source each came from (docs, tickets, CRM, etc.).\n3. Synthesize an answer grounded only in the retrieved content.\n4. If the collection returns nothing relevant, say so instead of guessing.\n\n## Output\nA concise answer with citations back to the source records. Do not include claims unsupported by the results.', - }, - { - name: 'build-context-brief', - description: - 'Search an Airweave collection for a person, account, or project and compile a context brief from all sources.', - content: - '# Build Context Brief\n\nGather everything Airweave knows about a subject across synced sources into one brief.\n\n## Steps\n1. Search the collection for the subject (account name, project, customer, or person).\n2. Pull relevant hits from each source type and group them.\n3. Summarize the current state, recent activity, and any open items.\n\n## Output\nA short brief organized by source, highlighting the most recent and relevant facts plus open questions.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/algolia.display.ts b/apps/sim/blocks/blocks/algolia.display.ts index 94bba2c5a3c..f6fffa5299a 100644 --- a/apps/sim/blocks/blocks/algolia.display.ts +++ b/apps/sim/blocks/blocks/algolia.display.ts @@ -1,6 +1,6 @@ import { AlgoliaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AlgoliaBlockDisplay = { type: 'algolia', @@ -15,3 +15,98 @@ export const AlgoliaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/algolia', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const AlgoliaBlockMeta = { + tags: ['vector-search', 'knowledge-base'], + url: 'https://www.algolia.com', + templates: [ + { + icon: AlgoliaIcon, + title: 'Algolia content indexer', + prompt: + 'Build a workflow that watches a content source — WordPress, knowledge base — and upserts records into an Algolia index, removing deleted items for accurate search.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['wordpress'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia search-quality auditor', + prompt: + 'Create a scheduled workflow that runs benchmark queries against an Algolia index weekly, scores top-result relevance, and writes a quality report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia settings tuner', + prompt: + 'Build a workflow that reads an Algolia index settings, has an agent propose improvements to searchable attributes and ranking, and applies the approved settings update.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia index reconciler', + prompt: + 'Create a workflow that browses all records in an Algolia index, compares them against a source-of-truth table, and batches adds, updates, and deletes to keep the index accurate.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia + knowledge base sync', + prompt: + 'Build a workflow that mirrors a Sim knowledge base into an Algolia index, keeping vector retrieval and keyword search aligned for hybrid retrieval.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia index inventory', + prompt: + 'Create a scheduled workflow that lists all Algolia indices and their record counts, writes a daily inventory snapshot to a table, and pings on-call in Slack when an index record count drops unexpectedly.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: AlgoliaIcon, + title: 'Algolia stale-record sweeper', + prompt: + 'Build a scheduled workflow that browses an Algolia index, flags records older than a freshness threshold, writes them to a cleanup table, and deletes the confirmed stale records.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + ], + skills: [ + { + name: 'answer-from-search-index', + description: + 'Search an Algolia index for a user question and return a grounded answer with the matching records.', + content: + '# Answer From Search Index\n\nUse Algolia retrieval to answer questions over indexed content (docs, products, knowledge base).\n\n## Steps\n1. Take the user question and run a search against the relevant Algolia index.\n2. Apply filters or facets to narrow results (category, status, language) when appropriate.\n3. Read the top hits and synthesize an answer grounded only in the returned records.\n4. If no relevant hits are returned, say so rather than guessing.\n\n## Output\nA concise answer plus the titles and IDs of the records used. Do not invent content not present in the hits.', + }, + { + name: 'index-new-records', + description: + 'Take new or updated content and push it into an Algolia index as searchable records.', + content: + '# Index New Records\n\nKeep an Algolia index in sync with new content.\n\n## Steps\n1. Collect the source items to index (products, articles, entries).\n2. Map each item to a record object with a stable objectID and the searchable/filterable attributes.\n3. Save the records to the target index, updating existing objectIDs in place.\n4. Verify by running a quick search for one of the new records.\n\n## Output\nReport how many records were added or updated and confirm one is retrievable via search.', + }, + { + name: 'audit-search-relevance', + description: + 'Run a set of test queries against an Algolia index and report which return weak or empty results.', + content: + '# Audit Search Relevance\n\nCheck that important queries return good results from an Algolia index.\n\n## Steps\n1. Run each query in the provided test set against the index.\n2. Record the top results, total hit count, and whether the expected record appears.\n3. Flag queries that return zero hits, too many hits, or miss the expected record.\n\n## Output\nA table of queries with result counts and pass/fail, plus suggestions for synonyms or ranking tweaks where relevance is weak.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/algolia.ts b/apps/sim/blocks/blocks/algolia.ts index a81de1af88c..d543898bab8 100644 --- a/apps/sim/blocks/blocks/algolia.ts +++ b/apps/sim/blocks/blocks/algolia.ts @@ -1,6 +1,5 @@ -import { AlgoliaIcon } from '@/components/icons' import { AlgoliaBlockDisplay } from '@/blocks/blocks/algolia.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const AlgoliaBlock: BlockConfig = { @@ -637,98 +636,3 @@ Return ONLY the JSON array.`, }, }, } - -export const AlgoliaBlockMeta = { - tags: ['vector-search', 'knowledge-base'], - url: 'https://www.algolia.com', - templates: [ - { - icon: AlgoliaIcon, - title: 'Algolia content indexer', - prompt: - 'Build a workflow that watches a content source — WordPress, knowledge base — and upserts records into an Algolia index, removing deleted items for accurate search.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['wordpress'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia search-quality auditor', - prompt: - 'Create a scheduled workflow that runs benchmark queries against an Algolia index weekly, scores top-result relevance, and writes a quality report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia settings tuner', - prompt: - 'Build a workflow that reads an Algolia index settings, has an agent propose improvements to searchable attributes and ranking, and applies the approved settings update.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia index reconciler', - prompt: - 'Create a workflow that browses all records in an Algolia index, compares them against a source-of-truth table, and batches adds, updates, and deletes to keep the index accurate.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia + knowledge base sync', - prompt: - 'Build a workflow that mirrors a Sim knowledge base into an Algolia index, keeping vector retrieval and keyword search aligned for hybrid retrieval.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia index inventory', - prompt: - 'Create a scheduled workflow that lists all Algolia indices and their record counts, writes a daily inventory snapshot to a table, and pings on-call in Slack when an index record count drops unexpectedly.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: AlgoliaIcon, - title: 'Algolia stale-record sweeper', - prompt: - 'Build a scheduled workflow that browses an Algolia index, flags records older than a freshness threshold, writes them to a cleanup table, and deletes the confirmed stale records.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - ], - skills: [ - { - name: 'answer-from-search-index', - description: - 'Search an Algolia index for a user question and return a grounded answer with the matching records.', - content: - '# Answer From Search Index\n\nUse Algolia retrieval to answer questions over indexed content (docs, products, knowledge base).\n\n## Steps\n1. Take the user question and run a search against the relevant Algolia index.\n2. Apply filters or facets to narrow results (category, status, language) when appropriate.\n3. Read the top hits and synthesize an answer grounded only in the returned records.\n4. If no relevant hits are returned, say so rather than guessing.\n\n## Output\nA concise answer plus the titles and IDs of the records used. Do not invent content not present in the hits.', - }, - { - name: 'index-new-records', - description: - 'Take new or updated content and push it into an Algolia index as searchable records.', - content: - '# Index New Records\n\nKeep an Algolia index in sync with new content.\n\n## Steps\n1. Collect the source items to index (products, articles, entries).\n2. Map each item to a record object with a stable objectID and the searchable/filterable attributes.\n3. Save the records to the target index, updating existing objectIDs in place.\n4. Verify by running a quick search for one of the new records.\n\n## Output\nReport how many records were added or updated and confirm one is retrievable via search.', - }, - { - name: 'audit-search-relevance', - description: - 'Run a set of test queries against an Algolia index and report which return weak or empty results.', - content: - '# Audit Search Relevance\n\nCheck that important queries return good results from an Algolia index.\n\n## Steps\n1. Run each query in the provided test set against the index.\n2. Record the top results, total hit count, and whether the expected record appears.\n3. Flag queries that return zero hits, too many hits, or miss the expected record.\n\n## Output\nA table of queries with result counts and pass/fail, plus suggestions for synonyms or ranking tweaks where relevance is weak.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/amplitude.display.ts b/apps/sim/blocks/blocks/amplitude.display.ts index cf057fa6155..ad3a01b3837 100644 --- a/apps/sim/blocks/blocks/amplitude.display.ts +++ b/apps/sim/blocks/blocks/amplitude.display.ts @@ -1,6 +1,6 @@ import { AmplitudeIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AmplitudeBlockDisplay = { type: 'amplitude', @@ -15,3 +15,109 @@ export const AmplitudeBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/amplitude', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const AmplitudeBlockMeta = { + tags: ['data-analytics', 'marketing'], + url: 'https://amplitude.com', + templates: [ + { + icon: AmplitudeIcon, + title: 'Product analytics digest', + prompt: + 'Create a scheduled weekly workflow that pulls key product metrics from Amplitude — active users, event segmentation for top events, and revenue — generates an executive summary with week-over-week trends, and posts it to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'reporting', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude event regression watcher', + prompt: + 'Build a scheduled workflow that runs event segmentation on key Amplitude events every morning, compares the counts against the trailing 14-day baseline, and posts a Slack alert when any event drops more than a configurable threshold.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude active-user tracker', + prompt: + 'Create a scheduled workflow that pulls daily and monthly active users from Amplitude, writes the values into a tracking table, and feeds the trend to downstream marketing automations.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'sync'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude revenue digest', + prompt: + 'Build a scheduled weekly workflow that pulls Amplitude revenue data, breaks it down by week-over-week change, and posts a digest to the product Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude + PostHog cross-tool dashboard', + prompt: + 'Build a scheduled workflow that aggregates equivalent active-user and event metrics from both Amplitude and PostHog, writes a side-by-side comparison to a table, and surfaces discrepancies to the product team in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis', 'reporting'], + alsoIntegrations: ['posthog', 'slack'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude + Fathom unified analytics', + prompt: + 'Build a scheduled workflow that joins Amplitude product analytics with Fathom web analytics, writes a unified active-user and engagement report, and surfaces anomalies.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['fathom'], + }, + { + icon: AmplitudeIcon, + title: 'Amplitude + Hex deep-dive notebook', + prompt: + 'Create a workflow that triggers a Hex deep-dive notebook when an Amplitude metric crosses an anomaly threshold, runs analysis, and posts the notebook output to Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['hex', 'slack'], + }, + ], + skills: [ + { + name: 'track-product-event', + description: + 'Send a behavioral event to Amplitude with user and event properties for analytics.', + content: + '# Track Product Event\n\nLog a user action to Amplitude so it shows up in analytics.\n\n## Steps\n1. Determine the event name and the user identifier (user ID or device ID).\n2. Attach relevant event properties (plan, source, value) and user properties.\n3. Send the event to Amplitude.\n\n## Output\nConfirm the event was sent with its name and the user it was attributed to. Note any required field that was missing.', + }, + { + name: 'segment-event-counts', + description: + 'Run Amplitude event segmentation over a date range and report unique and total counts, optionally grouped by a property.', + content: + '# Segment Event Counts\n\nMeasure how often an event fires in Amplitude over a time window.\n\n## Steps\n1. Identify the event type and the start and end dates (YYYYMMDD) to analyze.\n2. Pick the measurement (uniques, totals, or average) and the interval (daily, weekly, monthly).\n3. Optionally group by a user or event property to break the counts down by segment.\n4. Run the event segmentation query and read the resulting time series.\n\n## Output\nThe series of counts per interval, the segment breakdown if grouped, and a callout of the largest movement versus the start of the range.', + }, + { + name: 'summarize-engagement-metrics', + description: + 'Pull Amplitude active users, top events, and revenue and summarize product engagement for a period.', + content: + '# Summarize Engagement Metrics\n\nProduce a short product engagement summary from Amplitude data.\n\n## Steps\n1. Query active and new users for the target period.\n2. Pull the most-triggered events with event segmentation to see what users do most.\n3. Pull revenue metrics for the same period.\n4. Compare each against the prior period to spot trends.\n\n## Output\nA concise summary: active users, top events, revenue, and notable trends versus the prior period.', + }, + { + name: 'lookup-user-activity', + description: + 'Find a user in Amplitude by ID and pull their recent event activity and profile properties.', + content: + '# Lookup User Activity\n\nInvestigate a single user in Amplitude for support or debugging.\n\n## Steps\n1. Search for the user by user ID, device ID, or Amplitude ID to resolve their Amplitude ID.\n2. Pull the user activity stream for that Amplitude ID, ordered latest first.\n3. Optionally fetch the user profile to see their current properties.\n\n## Output\nA timeline of the user recent events plus key profile properties. Note the time range covered.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/amplitude.ts b/apps/sim/blocks/blocks/amplitude.ts index 8f696486cf5..cd98e252379 100644 --- a/apps/sim/blocks/blocks/amplitude.ts +++ b/apps/sim/blocks/blocks/amplitude.ts @@ -1,6 +1,5 @@ -import { AmplitudeIcon } from '@/components/icons' import { AmplitudeBlockDisplay } from '@/blocks/blocks/amplitude.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' export const AmplitudeBlock: BlockConfig = { ...AmplitudeBlockDisplay, @@ -736,109 +735,3 @@ export const AmplitudeBlock: BlockConfig = { }, }, } - -export const AmplitudeBlockMeta = { - tags: ['data-analytics', 'marketing'], - url: 'https://amplitude.com', - templates: [ - { - icon: AmplitudeIcon, - title: 'Product analytics digest', - prompt: - 'Create a scheduled weekly workflow that pulls key product metrics from Amplitude — active users, event segmentation for top events, and revenue — generates an executive summary with week-over-week trends, and posts it to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'reporting', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude event regression watcher', - prompt: - 'Build a scheduled workflow that runs event segmentation on key Amplitude events every morning, compares the counts against the trailing 14-day baseline, and posts a Slack alert when any event drops more than a configurable threshold.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude active-user tracker', - prompt: - 'Create a scheduled workflow that pulls daily and monthly active users from Amplitude, writes the values into a tracking table, and feeds the trend to downstream marketing automations.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'sync'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude revenue digest', - prompt: - 'Build a scheduled weekly workflow that pulls Amplitude revenue data, breaks it down by week-over-week change, and posts a digest to the product Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude + PostHog cross-tool dashboard', - prompt: - 'Build a scheduled workflow that aggregates equivalent active-user and event metrics from both Amplitude and PostHog, writes a side-by-side comparison to a table, and surfaces discrepancies to the product team in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis', 'reporting'], - alsoIntegrations: ['posthog', 'slack'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude + Fathom unified analytics', - prompt: - 'Build a scheduled workflow that joins Amplitude product analytics with Fathom web analytics, writes a unified active-user and engagement report, and surfaces anomalies.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['fathom'], - }, - { - icon: AmplitudeIcon, - title: 'Amplitude + Hex deep-dive notebook', - prompt: - 'Create a workflow that triggers a Hex deep-dive notebook when an Amplitude metric crosses an anomaly threshold, runs analysis, and posts the notebook output to Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['hex', 'slack'], - }, - ], - skills: [ - { - name: 'track-product-event', - description: - 'Send a behavioral event to Amplitude with user and event properties for analytics.', - content: - '# Track Product Event\n\nLog a user action to Amplitude so it shows up in analytics.\n\n## Steps\n1. Determine the event name and the user identifier (user ID or device ID).\n2. Attach relevant event properties (plan, source, value) and user properties.\n3. Send the event to Amplitude.\n\n## Output\nConfirm the event was sent with its name and the user it was attributed to. Note any required field that was missing.', - }, - { - name: 'segment-event-counts', - description: - 'Run Amplitude event segmentation over a date range and report unique and total counts, optionally grouped by a property.', - content: - '# Segment Event Counts\n\nMeasure how often an event fires in Amplitude over a time window.\n\n## Steps\n1. Identify the event type and the start and end dates (YYYYMMDD) to analyze.\n2. Pick the measurement (uniques, totals, or average) and the interval (daily, weekly, monthly).\n3. Optionally group by a user or event property to break the counts down by segment.\n4. Run the event segmentation query and read the resulting time series.\n\n## Output\nThe series of counts per interval, the segment breakdown if grouped, and a callout of the largest movement versus the start of the range.', - }, - { - name: 'summarize-engagement-metrics', - description: - 'Pull Amplitude active users, top events, and revenue and summarize product engagement for a period.', - content: - '# Summarize Engagement Metrics\n\nProduce a short product engagement summary from Amplitude data.\n\n## Steps\n1. Query active and new users for the target period.\n2. Pull the most-triggered events with event segmentation to see what users do most.\n3. Pull revenue metrics for the same period.\n4. Compare each against the prior period to spot trends.\n\n## Output\nA concise summary: active users, top events, revenue, and notable trends versus the prior period.', - }, - { - name: 'lookup-user-activity', - description: - 'Find a user in Amplitude by ID and pull their recent event activity and profile properties.', - content: - '# Lookup User Activity\n\nInvestigate a single user in Amplitude for support or debugging.\n\n## Steps\n1. Search for the user by user ID, device ID, or Amplitude ID to resolve their Amplitude ID.\n2. Pull the user activity stream for that Amplitude ID, ordered latest first.\n3. Optionally fetch the user profile to see their current properties.\n\n## Output\nA timeline of the user recent events plus key profile properties. Note the time range covered.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/apify.display.ts b/apps/sim/blocks/blocks/apify.display.ts index 0d2cb756604..552c552ebff 100644 --- a/apps/sim/blocks/blocks/apify.display.ts +++ b/apps/sim/blocks/blocks/apify.display.ts @@ -1,6 +1,6 @@ import { ApifyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ApifyBlockDisplay = { type: 'apify', @@ -14,3 +14,107 @@ export const ApifyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/apify', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const ApifyBlockMeta = { + tags: ['web-scraping', 'automation', 'data-analytics'], + url: 'https://apify.com', + templates: [ + { + icon: ApifyIcon, + title: 'Apify scraper orchestrator', + prompt: + 'Build a workflow that triggers Apify scrapers on a schedule, captures the output, transforms into structured rows, and writes them to a downstream Sim table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'sync'], + }, + { + icon: ApifyIcon, + title: 'Apify lead-list builder', + prompt: + 'Create a workflow that runs an Apify scraper on a target site, enriches each row with Clay, and writes the enriched lead list into HubSpot.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['clay', 'hubspot'], + }, + { + icon: ApifyIcon, + title: 'Apify monitor digest', + prompt: + 'Build a scheduled workflow that watches an Apify actor’s runs for failures, captures error patterns, and posts a digest to engineering Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ApifyIcon, + title: 'Apify ecommerce price tracker', + prompt: + 'Create a workflow that uses Apify scrapers to capture competitor pricing daily, writes the price history to a table, and posts price-drop alerts to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ApifyIcon, + title: 'Apify event-data collector', + prompt: + 'Build a workflow that uses Apify to scrape event sites — speakers, agendas, sponsors — and writes the data into a target-events research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: ApifyIcon, + title: 'Apify directory scraper', + prompt: + 'Create a workflow that runs an Apify directory scraper, captures business listings, enriches via Hunter or Apollo, and writes the prospect list to a CRM-ready table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo'], + }, + { + icon: ApifyIcon, + title: 'Apify job-listing monitor', + prompt: + 'Build a scheduled workflow that uses Apify to scrape job sites for tracked companies, flags new role types, and writes intel into a sales-research table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'monitoring'], + }, + ], + skills: [ + { + name: 'scrape-site-to-table', + description: + 'Run an Apify actor to scrape a target website and write the extracted rows into a structured table. Use for one-off or recurring data extraction jobs.', + content: + '# Scrape Site to Table\n\nRun an Apify actor against a target site and load the results into a clean table.\n\n## Steps\n1. Pick the actor or saved task (e.g. a web scraper) and assemble its JSON input — start URLs, page or request limits, and proxy settings.\n2. Run the actor synchronously for small jobs, or asynchronously and poll Get Run for larger crawls.\n3. Once the run status is SUCCEEDED, fetch the dataset items, selecting only the fields you need.\n4. Normalize each item into consistent columns and write the rows to the destination table.\n\n## Output\nReport the run ID, final status, and row count. If the run failed, surface the error and the actor input that produced it so it can be retried.', + }, + { + name: 'monitor-prices', + description: + 'Use an Apify scraper to capture competitor or product prices on a schedule, track history, and alert on changes. Use for price and stock monitoring.', + content: + '# Monitor Prices\n\nTrack pricing on target product pages over time and flag meaningful changes.\n\n## Steps\n1. Run the scraping actor with the product or category URLs to watch.\n2. From the dataset, extract product name, price, currency, and stock status for each item.\n3. Compare each price against the last recorded value for that product.\n4. Append the new snapshot to a price-history table.\n\n## Output\nList any products whose price dropped, rose, or went out of stock, with old and new values. If nothing changed, say so briefly.', + }, + { + name: 'build-lead-list', + description: + 'Run an Apify directory or maps scraper to collect business listings and produce a deduplicated, CRM-ready lead list. Use for prospecting and lead generation.', + content: + '# Build Lead List\n\nCollect business listings from a directory and turn them into a usable prospect list.\n\n## Steps\n1. Run the directory or maps scraper actor with the search terms, location, and result limit.\n2. Fetch the dataset and pull company name, website, phone, email, and address for each listing.\n3. Drop entries missing the fields you require, then deduplicate by domain or phone.\n4. Write the cleaned rows to a lead table ready for enrichment or CRM import.\n\n## Output\nReport total listings scraped, how many passed filtering, and how many duplicates were removed.', + }, + { + name: 'collect-content-for-knowledge-base', + description: + 'Use an Apify crawler to extract article or documentation text from a site and prepare it for ingestion into a knowledge base or RAG pipeline.', + content: + '# Collect Content for Knowledge Base\n\nCrawl a content site and gather clean text for downstream ingestion.\n\n## Steps\n1. Run the crawler actor with the start URLs and a request limit, scoped to the relevant section of the site.\n2. Fetch dataset items and extract title, URL, and main body text for each page.\n3. Strip navigation, boilerplate, and empty pages.\n4. Hand the cleaned documents to the knowledge base for chunking and indexing.\n\n## Output\nReport the number of pages crawled and ingested, and list any URLs that failed or returned no usable text.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/apify.ts b/apps/sim/blocks/blocks/apify.ts index 116a7f867e0..8789282bc4b 100644 --- a/apps/sim/blocks/blocks/apify.ts +++ b/apps/sim/blocks/blocks/apify.ts @@ -1,6 +1,5 @@ -import { ApifyIcon } from '@/components/icons' import { ApifyBlockDisplay } from '@/blocks/blocks/apify.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RunActorResult } from '@/tools/apify/types' @@ -229,107 +228,3 @@ Return ONLY the valid JSON object - no explanations, no markdown.`, finishedAt: { type: 'string', description: 'When the run finished (Get Run)' }, }, } - -export const ApifyBlockMeta = { - tags: ['web-scraping', 'automation', 'data-analytics'], - url: 'https://apify.com', - templates: [ - { - icon: ApifyIcon, - title: 'Apify scraper orchestrator', - prompt: - 'Build a workflow that triggers Apify scrapers on a schedule, captures the output, transforms into structured rows, and writes them to a downstream Sim table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'sync'], - }, - { - icon: ApifyIcon, - title: 'Apify lead-list builder', - prompt: - 'Create a workflow that runs an Apify scraper on a target site, enriches each row with Clay, and writes the enriched lead list into HubSpot.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['clay', 'hubspot'], - }, - { - icon: ApifyIcon, - title: 'Apify monitor digest', - prompt: - 'Build a scheduled workflow that watches an Apify actor’s runs for failures, captures error patterns, and posts a digest to engineering Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ApifyIcon, - title: 'Apify ecommerce price tracker', - prompt: - 'Create a workflow that uses Apify scrapers to capture competitor pricing daily, writes the price history to a table, and posts price-drop alerts to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ApifyIcon, - title: 'Apify event-data collector', - prompt: - 'Build a workflow that uses Apify to scrape event sites — speakers, agendas, sponsors — and writes the data into a target-events research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: ApifyIcon, - title: 'Apify directory scraper', - prompt: - 'Create a workflow that runs an Apify directory scraper, captures business listings, enriches via Hunter or Apollo, and writes the prospect list to a CRM-ready table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo'], - }, - { - icon: ApifyIcon, - title: 'Apify job-listing monitor', - prompt: - 'Build a scheduled workflow that uses Apify to scrape job sites for tracked companies, flags new role types, and writes intel into a sales-research table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'monitoring'], - }, - ], - skills: [ - { - name: 'scrape-site-to-table', - description: - 'Run an Apify actor to scrape a target website and write the extracted rows into a structured table. Use for one-off or recurring data extraction jobs.', - content: - '# Scrape Site to Table\n\nRun an Apify actor against a target site and load the results into a clean table.\n\n## Steps\n1. Pick the actor or saved task (e.g. a web scraper) and assemble its JSON input — start URLs, page or request limits, and proxy settings.\n2. Run the actor synchronously for small jobs, or asynchronously and poll Get Run for larger crawls.\n3. Once the run status is SUCCEEDED, fetch the dataset items, selecting only the fields you need.\n4. Normalize each item into consistent columns and write the rows to the destination table.\n\n## Output\nReport the run ID, final status, and row count. If the run failed, surface the error and the actor input that produced it so it can be retried.', - }, - { - name: 'monitor-prices', - description: - 'Use an Apify scraper to capture competitor or product prices on a schedule, track history, and alert on changes. Use for price and stock monitoring.', - content: - '# Monitor Prices\n\nTrack pricing on target product pages over time and flag meaningful changes.\n\n## Steps\n1. Run the scraping actor with the product or category URLs to watch.\n2. From the dataset, extract product name, price, currency, and stock status for each item.\n3. Compare each price against the last recorded value for that product.\n4. Append the new snapshot to a price-history table.\n\n## Output\nList any products whose price dropped, rose, or went out of stock, with old and new values. If nothing changed, say so briefly.', - }, - { - name: 'build-lead-list', - description: - 'Run an Apify directory or maps scraper to collect business listings and produce a deduplicated, CRM-ready lead list. Use for prospecting and lead generation.', - content: - '# Build Lead List\n\nCollect business listings from a directory and turn them into a usable prospect list.\n\n## Steps\n1. Run the directory or maps scraper actor with the search terms, location, and result limit.\n2. Fetch the dataset and pull company name, website, phone, email, and address for each listing.\n3. Drop entries missing the fields you require, then deduplicate by domain or phone.\n4. Write the cleaned rows to a lead table ready for enrichment or CRM import.\n\n## Output\nReport total listings scraped, how many passed filtering, and how many duplicates were removed.', - }, - { - name: 'collect-content-for-knowledge-base', - description: - 'Use an Apify crawler to extract article or documentation text from a site and prepare it for ingestion into a knowledge base or RAG pipeline.', - content: - '# Collect Content for Knowledge Base\n\nCrawl a content site and gather clean text for downstream ingestion.\n\n## Steps\n1. Run the crawler actor with the start URLs and a request limit, scoped to the relevant section of the site.\n2. Fetch dataset items and extract title, URL, and main body text for each page.\n3. Strip navigation, boilerplate, and empty pages.\n4. Hand the cleaned documents to the knowledge base for chunking and indexing.\n\n## Output\nReport the number of pages crawled and ingested, and list any URLs that failed or returned no usable text.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/apollo.display.ts b/apps/sim/blocks/blocks/apollo.display.ts index 29e9c5c63b3..67560b1b511 100644 --- a/apps/sim/blocks/blocks/apollo.display.ts +++ b/apps/sim/blocks/blocks/apollo.display.ts @@ -1,6 +1,7 @@ +import { Users } from '@/components/emcn/icons' import { ApolloIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ApolloBlockDisplay = { type: 'apollo', @@ -14,3 +15,112 @@ export const ApolloBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/apollo', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const ApolloBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.apollo.io', + templates: [ + { + icon: Users, + title: 'Lead enrichment pipeline', + prompt: + 'Build a workflow that watches my leads table for new entries, enriches each lead with company size, funding, tech stack, and decision-maker contacts using Apollo and web search, then updates the table with the enriched information.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation', 'research'], + }, + { + icon: ApolloIcon, + title: 'Prospect researcher', + prompt: + 'Create an agent that takes a company name, deep-researches them across the web and Apollo, finds key decision-makers, recent news, funding rounds, and pain points, then compiles a prospect brief I can review before outreach.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ApolloIcon, + title: 'ICP account builder', + prompt: + 'Build a workflow that runs an Apollo organization search for accounts matching my ideal customer profile — industry, headcount, and tech stack — creates each as an Apollo account, and writes the new target list to a table for the SDR team.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + }, + { + icon: Users, + title: 'Buying committee mapper', + prompt: + 'Create a workflow that takes a target account, runs an Apollo people search across the relevant titles, enriches each contact with verified email and role, and writes a mapped buying committee to a table so reps know exactly who to engage.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'crm'], + }, + { + icon: ApolloIcon, + title: 'Inbound lead enricher to HubSpot', + prompt: + 'Build a workflow that on a new inbound signup enriches the person and their company with Apollo, scores fit against my ICP, and creates or updates the matching contact and company in HubSpot with the enriched fields.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['hubspot'], + }, + { + icon: ApolloIcon, + title: 'Pipeline opportunity tracker', + prompt: + 'Create a scheduled workflow that searches Apollo opportunities by stage, summarizes new and at-risk deals with an agent, logs the snapshot to a pipeline table, and posts a daily deal-movement digest to the sales Slack channel.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'crm'], + alsoIntegrations: ['slack'], + }, + { + icon: Users, + title: 'CRM contact freshness sweep', + prompt: + 'Build a scheduled workflow that pulls contacts from my CRM, bulk-enriches them through Apollo to refresh titles, emails, and company data, and bulk-updates the records so the database stays accurate for outbound.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation', 'enrichment'], + }, + ], + skills: [ + { + name: 'build-prospect-list', + description: + 'Search Apollo for people matching an ideal customer profile and produce a targeted prospect list. Use for outbound prospecting and territory building.', + content: + '# Build Prospect List\n\nFind decision-makers that match an ICP and assemble a clean prospect list.\n\n## Steps\n1. Translate the ICP into an Apollo people search — job titles, seniorities, locations, and company size or industry filters.\n2. Run the search, paging through results up to the requested count.\n3. For each person capture name, title, company, verified email status, and LinkedIn URL.\n4. Write the deduplicated prospects to a table for review or sequencing.\n\n## Output\nReport how many prospects matched and the filters used. Flag any with unverified or missing emails.', + }, + { + name: 'enrich-contacts', + description: + 'Enrich one or many contacts through Apollo to refresh titles, emails, phones, and company data. Use to keep CRM records accurate before outreach.', + content: + '# Enrich Contacts\n\nFill in or refresh missing contact data using Apollo enrichment.\n\n## Steps\n1. Gather the contacts to enrich — a single person, or a batch for bulk enrich.\n2. Provide the strongest identifiers available (email, name plus company domain).\n3. Run people enrich or bulk enrich, optionally revealing personal emails or phone numbers.\n4. Merge the returned fields back onto each record, keeping existing values when enrichment returns nothing.\n\n## Output\nReport how many records were enriched versus left unmatched, and which fields were newly filled. Note any credits consumed.', + }, + { + name: 'sync-leads-to-crm', + description: + 'Create or update Apollo contacts and accounts from an inbound lead, then map them into your CRM. Use to route new signups into pipeline.', + content: + '# Sync Leads to CRM\n\nTurn an inbound lead into structured Apollo records.\n\n## Steps\n1. Take the lead details and enrich the person and their company through Apollo.\n2. Create or update the matching Apollo account for the company.\n3. Create or update the contact, linking it to the account and setting owner and stage.\n4. Pass the enriched fields to the connected CRM to create or update the matching records.\n\n## Output\nReport whether each record was created or updated, with the resulting contact and account IDs.', + }, + { + name: 'add-prospects-to-sequence', + description: + 'Search for matching contacts and add them to an Apollo email sequence. Use to launch or top up outbound campaigns.', + content: + '# Add Prospects to Sequence\n\nEnroll the right contacts into an outbound sequence.\n\n## Steps\n1. Identify the target sequence by name or ID, and confirm the sending email account.\n2. Gather the contact IDs to enroll — from a prior search or a provided list.\n3. Add the contacts to the sequence with the chosen sending account and initial status.\n4. Review which contacts were added versus skipped.\n\n## Output\nReport totals added and skipped, and the reason for each skip (already enrolled, unverified, missing ownership).', + }, + { + name: 'pipeline-deal-digest', + description: + 'Search Apollo opportunities by stage and summarize new and at-risk deals into a digest. Use for recurring pipeline reviews.', + content: + '# Pipeline Deal Digest\n\nSummarize opportunity movement for a sales pipeline review.\n\n## Steps\n1. Search Apollo opportunities filtered by the stages you care about.\n2. For each deal capture name, amount, stage, owner, and close date.\n3. Group deals into new, advancing, and at-risk (stalled or past close date).\n4. Write a concise digest grouped by category.\n\n## Output\nA short digest: deal counts and total value per stage, with at-risk deals called out by name, owner, and reason.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/apollo.ts b/apps/sim/blocks/blocks/apollo.ts index 4d12c6d9aad..ff61a8631ea 100644 --- a/apps/sim/blocks/blocks/apollo.ts +++ b/apps/sim/blocks/blocks/apollo.ts @@ -1,8 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { Users } from '@/components/emcn/icons' -import { ApolloIcon } from '@/components/icons' import { ApolloBlockDisplay } from '@/blocks/blocks/apollo.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ApolloResponse } from '@/tools/apollo/types' @@ -1364,112 +1362,3 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes }, }, } - -export const ApolloBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.apollo.io', - templates: [ - { - icon: Users, - title: 'Lead enrichment pipeline', - prompt: - 'Build a workflow that watches my leads table for new entries, enriches each lead with company size, funding, tech stack, and decision-maker contacts using Apollo and web search, then updates the table with the enriched information.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation', 'research'], - }, - { - icon: ApolloIcon, - title: 'Prospect researcher', - prompt: - 'Create an agent that takes a company name, deep-researches them across the web and Apollo, finds key decision-makers, recent news, funding rounds, and pain points, then compiles a prospect brief I can review before outreach.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ApolloIcon, - title: 'ICP account builder', - prompt: - 'Build a workflow that runs an Apollo organization search for accounts matching my ideal customer profile — industry, headcount, and tech stack — creates each as an Apollo account, and writes the new target list to a table for the SDR team.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - }, - { - icon: Users, - title: 'Buying committee mapper', - prompt: - 'Create a workflow that takes a target account, runs an Apollo people search across the relevant titles, enriches each contact with verified email and role, and writes a mapped buying committee to a table so reps know exactly who to engage.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'crm'], - }, - { - icon: ApolloIcon, - title: 'Inbound lead enricher to HubSpot', - prompt: - 'Build a workflow that on a new inbound signup enriches the person and their company with Apollo, scores fit against my ICP, and creates or updates the matching contact and company in HubSpot with the enriched fields.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['hubspot'], - }, - { - icon: ApolloIcon, - title: 'Pipeline opportunity tracker', - prompt: - 'Create a scheduled workflow that searches Apollo opportunities by stage, summarizes new and at-risk deals with an agent, logs the snapshot to a pipeline table, and posts a daily deal-movement digest to the sales Slack channel.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'crm'], - alsoIntegrations: ['slack'], - }, - { - icon: Users, - title: 'CRM contact freshness sweep', - prompt: - 'Build a scheduled workflow that pulls contacts from my CRM, bulk-enriches them through Apollo to refresh titles, emails, and company data, and bulk-updates the records so the database stays accurate for outbound.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation', 'enrichment'], - }, - ], - skills: [ - { - name: 'build-prospect-list', - description: - 'Search Apollo for people matching an ideal customer profile and produce a targeted prospect list. Use for outbound prospecting and territory building.', - content: - '# Build Prospect List\n\nFind decision-makers that match an ICP and assemble a clean prospect list.\n\n## Steps\n1. Translate the ICP into an Apollo people search — job titles, seniorities, locations, and company size or industry filters.\n2. Run the search, paging through results up to the requested count.\n3. For each person capture name, title, company, verified email status, and LinkedIn URL.\n4. Write the deduplicated prospects to a table for review or sequencing.\n\n## Output\nReport how many prospects matched and the filters used. Flag any with unverified or missing emails.', - }, - { - name: 'enrich-contacts', - description: - 'Enrich one or many contacts through Apollo to refresh titles, emails, phones, and company data. Use to keep CRM records accurate before outreach.', - content: - '# Enrich Contacts\n\nFill in or refresh missing contact data using Apollo enrichment.\n\n## Steps\n1. Gather the contacts to enrich — a single person, or a batch for bulk enrich.\n2. Provide the strongest identifiers available (email, name plus company domain).\n3. Run people enrich or bulk enrich, optionally revealing personal emails or phone numbers.\n4. Merge the returned fields back onto each record, keeping existing values when enrichment returns nothing.\n\n## Output\nReport how many records were enriched versus left unmatched, and which fields were newly filled. Note any credits consumed.', - }, - { - name: 'sync-leads-to-crm', - description: - 'Create or update Apollo contacts and accounts from an inbound lead, then map them into your CRM. Use to route new signups into pipeline.', - content: - '# Sync Leads to CRM\n\nTurn an inbound lead into structured Apollo records.\n\n## Steps\n1. Take the lead details and enrich the person and their company through Apollo.\n2. Create or update the matching Apollo account for the company.\n3. Create or update the contact, linking it to the account and setting owner and stage.\n4. Pass the enriched fields to the connected CRM to create or update the matching records.\n\n## Output\nReport whether each record was created or updated, with the resulting contact and account IDs.', - }, - { - name: 'add-prospects-to-sequence', - description: - 'Search for matching contacts and add them to an Apollo email sequence. Use to launch or top up outbound campaigns.', - content: - '# Add Prospects to Sequence\n\nEnroll the right contacts into an outbound sequence.\n\n## Steps\n1. Identify the target sequence by name or ID, and confirm the sending email account.\n2. Gather the contact IDs to enroll — from a prior search or a provided list.\n3. Add the contacts to the sequence with the chosen sending account and initial status.\n4. Review which contacts were added versus skipped.\n\n## Output\nReport totals added and skipped, and the reason for each skip (already enrolled, unverified, missing ownership).', - }, - { - name: 'pipeline-deal-digest', - description: - 'Search Apollo opportunities by stage and summarize new and at-risk deals into a digest. Use for recurring pipeline reviews.', - content: - '# Pipeline Deal Digest\n\nSummarize opportunity movement for a sales pipeline review.\n\n## Steps\n1. Search Apollo opportunities filtered by the stages you care about.\n2. For each deal capture name, amount, stage, owner, and close date.\n3. Group deals into new, advancing, and at-risk (stalled or past close date).\n4. Write a concise digest grouped by category.\n\n## Output\nA short digest: deal counts and total value per stage, with at-risk deals called out by name, owner, and reason.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/appconfig.display.ts b/apps/sim/blocks/blocks/appconfig.display.ts index 783de0cb31d..95821742d6a 100644 --- a/apps/sim/blocks/blocks/appconfig.display.ts +++ b/apps/sim/blocks/blocks/appconfig.display.ts @@ -1,6 +1,6 @@ import { AppConfigIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AppConfigBlockDisplay = { type: 'appconfig', @@ -14,3 +14,116 @@ export const AppConfigBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/appconfig', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const AppConfigBlockMeta = { + tags: ['cloud', 'feature-flags', 'automation'], + url: 'https://aws.amazon.com/systems-manager/features/appconfig', + templates: [ + { + icon: AppConfigIcon, + title: 'AppConfig runtime config loader', + prompt: + 'Build a workflow that retrieves the latest deployed AWS AppConfig configuration for a given application, environment, and profile, parses the JSON, and uses the feature flags to branch downstream agent behavior.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'feature-flags', 'automation'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig feature-flag publisher', + prompt: + 'Create a workflow that takes a JSON feature-flag document, creates a new hosted configuration version in an AWS AppConfig configuration profile, and starts a deployment to the target environment using a chosen deployment strategy.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'feature-flags', 'automation'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig deployment monitor', + prompt: + 'Build a scheduled workflow that lists in-progress AWS AppConfig deployments for an environment, gets each deployment status, and posts a Slack alert when a deployment is rolling back or has stalled.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig config inventory', + prompt: + 'Create a scheduled workflow that lists every AWS AppConfig application, its environments, and its configuration profiles, and writes a unified inventory into a tracking table so the platform team has a single source of truth.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'reporting'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig change auditor', + prompt: + 'Build a scheduled workflow that lists recent AWS AppConfig deployments across environments, summarizes which configuration versions were deployed when, and writes an audit report file for compliance review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting', 'enterprise'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig drift checker', + prompt: + 'Create a scheduled workflow that retrieves the live AWS AppConfig configuration and compares it against an expected baseline stored in a table, alerting Slack when the deployed configuration drifts from the approved version.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig bootstrap from GitHub', + prompt: + 'Build a workflow triggered when a config file changes in a GitHub pull request that creates a new hosted AWS AppConfig configuration version from the file contents and deploys it to a staging environment for validation.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'engineering'], + alsoIntegrations: ['github'], + }, + { + icon: AppConfigIcon, + title: 'AppConfig gated rollout', + prompt: + 'Create a workflow that gates an AWS AppConfig deployment behind a Slack approval: it creates the configuration version, waits for sign-off, starts the deployment with a linear strategy, and monitors completion before reporting back.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'read-feature-flags', + description: + 'Retrieve the latest deployed AWS AppConfig configuration for an application, environment, and profile and use the values to drive feature flags or dynamic settings.', + content: + '# Read AppConfig Feature Flags\n\nLoad live configuration to branch workflow behavior.\n\n## Steps\n1. Identify the target application, environment, and configuration profile (IDs or names).\n2. Get the latest deployed configuration for that combination.\n3. Parse the returned content (usually JSON) into a structured object.\n4. Use the flag or setting values to decide which downstream path to take.\n\n## Output\nThe resolved configuration values and the decision they drive. Do not hardcode flag values — always read them fresh from AppConfig.', + }, + { + name: 'publish-and-deploy-config', + description: + 'Create a new hosted AWS AppConfig configuration version from a document and deploy it to an environment with a chosen deployment strategy.', + content: + '# Publish and Deploy Config\n\nShip a new configuration version safely.\n\n## Steps\n1. Assemble the configuration content (JSON, YAML, or text) and confirm the target application and configuration profile.\n2. Create a new hosted configuration version with the correct content type.\n3. Start a deployment of that version to the target environment using an appropriate deployment strategy.\n4. Record the returned deployment number for follow-up monitoring.\n\n## Output\nThe new version number and the started deployment number, plus the deployment state.', + }, + { + name: 'monitor-deployment-rollback', + description: + 'Watch in-progress AWS AppConfig deployments for an environment and surface rollbacks or stalled rollouts so they can be acted on.', + content: + '# Monitor Deployment Rollback\n\nKeep an eye on configuration rollouts.\n\n## Steps\n1. List deployments for the target environment and find in-progress ones.\n2. Get the status of each active deployment, capturing state and percentage complete.\n3. Flag deployments that are rolling back or have stopped making progress.\n4. Optionally stop a deployment that needs to be halted.\n\n## Output\nA per-deployment status summary with any rollbacks or stalls called out for action.', + }, + { + name: 'inventory-appconfig', + description: + 'List AWS AppConfig applications, environments, and configuration profiles to build a single inventory of what configuration exists across the account.', + content: + '# Inventory AppConfig\n\nBuild a unified view of all AppConfig resources.\n\n## Steps\n1. List every application and capture its ID, name, and description.\n2. For each application, list its environments and configuration profiles.\n3. Note the profile type (freeform vs feature flags) and where each profile is stored.\n4. Assemble the results into a single structured inventory.\n\n## Output\nAn inventory of applications with their environments and configuration profiles, suitable for writing to a tracking table.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/appconfig.ts b/apps/sim/blocks/blocks/appconfig.ts index 8bf1276c7df..394ec9bcee0 100644 --- a/apps/sim/blocks/blocks/appconfig.ts +++ b/apps/sim/blocks/blocks/appconfig.ts @@ -1,6 +1,5 @@ -import { AppConfigIcon } from '@/components/icons' import { AppConfigBlockDisplay } from '@/blocks/blocks/appconfig.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AppConfigGetConfigurationResponse, @@ -577,116 +576,3 @@ export const AppConfigBlock: BlockConfig< count: { type: 'number', description: 'Number of items returned' }, }, } - -export const AppConfigBlockMeta = { - tags: ['cloud', 'feature-flags', 'automation'], - url: 'https://aws.amazon.com/systems-manager/features/appconfig', - templates: [ - { - icon: AppConfigIcon, - title: 'AppConfig runtime config loader', - prompt: - 'Build a workflow that retrieves the latest deployed AWS AppConfig configuration for a given application, environment, and profile, parses the JSON, and uses the feature flags to branch downstream agent behavior.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'feature-flags', 'automation'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig feature-flag publisher', - prompt: - 'Create a workflow that takes a JSON feature-flag document, creates a new hosted configuration version in an AWS AppConfig configuration profile, and starts a deployment to the target environment using a chosen deployment strategy.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'feature-flags', 'automation'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig deployment monitor', - prompt: - 'Build a scheduled workflow that lists in-progress AWS AppConfig deployments for an environment, gets each deployment status, and posts a Slack alert when a deployment is rolling back or has stalled.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig config inventory', - prompt: - 'Create a scheduled workflow that lists every AWS AppConfig application, its environments, and its configuration profiles, and writes a unified inventory into a tracking table so the platform team has a single source of truth.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'reporting'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig change auditor', - prompt: - 'Build a scheduled workflow that lists recent AWS AppConfig deployments across environments, summarizes which configuration versions were deployed when, and writes an audit report file for compliance review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting', 'enterprise'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig drift checker', - prompt: - 'Create a scheduled workflow that retrieves the live AWS AppConfig configuration and compares it against an expected baseline stored in a table, alerting Slack when the deployed configuration drifts from the approved version.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig bootstrap from GitHub', - prompt: - 'Build a workflow triggered when a config file changes in a GitHub pull request that creates a new hosted AWS AppConfig configuration version from the file contents and deploys it to a staging environment for validation.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'engineering'], - alsoIntegrations: ['github'], - }, - { - icon: AppConfigIcon, - title: 'AppConfig gated rollout', - prompt: - 'Create a workflow that gates an AWS AppConfig deployment behind a Slack approval: it creates the configuration version, waits for sign-off, starts the deployment with a linear strategy, and monitors completion before reporting back.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'read-feature-flags', - description: - 'Retrieve the latest deployed AWS AppConfig configuration for an application, environment, and profile and use the values to drive feature flags or dynamic settings.', - content: - '# Read AppConfig Feature Flags\n\nLoad live configuration to branch workflow behavior.\n\n## Steps\n1. Identify the target application, environment, and configuration profile (IDs or names).\n2. Get the latest deployed configuration for that combination.\n3. Parse the returned content (usually JSON) into a structured object.\n4. Use the flag or setting values to decide which downstream path to take.\n\n## Output\nThe resolved configuration values and the decision they drive. Do not hardcode flag values — always read them fresh from AppConfig.', - }, - { - name: 'publish-and-deploy-config', - description: - 'Create a new hosted AWS AppConfig configuration version from a document and deploy it to an environment with a chosen deployment strategy.', - content: - '# Publish and Deploy Config\n\nShip a new configuration version safely.\n\n## Steps\n1. Assemble the configuration content (JSON, YAML, or text) and confirm the target application and configuration profile.\n2. Create a new hosted configuration version with the correct content type.\n3. Start a deployment of that version to the target environment using an appropriate deployment strategy.\n4. Record the returned deployment number for follow-up monitoring.\n\n## Output\nThe new version number and the started deployment number, plus the deployment state.', - }, - { - name: 'monitor-deployment-rollback', - description: - 'Watch in-progress AWS AppConfig deployments for an environment and surface rollbacks or stalled rollouts so they can be acted on.', - content: - '# Monitor Deployment Rollback\n\nKeep an eye on configuration rollouts.\n\n## Steps\n1. List deployments for the target environment and find in-progress ones.\n2. Get the status of each active deployment, capturing state and percentage complete.\n3. Flag deployments that are rolling back or have stopped making progress.\n4. Optionally stop a deployment that needs to be halted.\n\n## Output\nA per-deployment status summary with any rollbacks or stalls called out for action.', - }, - { - name: 'inventory-appconfig', - description: - 'List AWS AppConfig applications, environments, and configuration profiles to build a single inventory of what configuration exists across the account.', - content: - '# Inventory AppConfig\n\nBuild a unified view of all AppConfig resources.\n\n## Steps\n1. List every application and capture its ID, name, and description.\n2. For each application, list its environments and configuration profiles.\n3. Note the profile type (freeform vs feature flags) and where each profile is stored.\n4. Assemble the results into a single structured inventory.\n\n## Output\nAn inventory of applications with their environments and configuration profiles, suitable for writing to a tracking table.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/arxiv.display.ts b/apps/sim/blocks/blocks/arxiv.display.ts index 5a843e0b5af..3616bd26e80 100644 --- a/apps/sim/blocks/blocks/arxiv.display.ts +++ b/apps/sim/blocks/blocks/arxiv.display.ts @@ -1,6 +1,6 @@ import { ArxivIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ArxivBlockDisplay = { type: 'arxiv', @@ -14,3 +14,107 @@ export const ArxivBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/arxiv', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const ArxivBlockMeta = { + tags: ['document-processing', 'knowledge-base'], + url: 'https://arxiv.org', + templates: [ + { + icon: ArxivIcon, + title: 'ArXiv paper alerter', + prompt: + 'Build a scheduled workflow that queries ArXiv for new papers on tracked topics, summarizes abstracts with an agent, and emails the digest to the research team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research'], + alsoIntegrations: ['gmail'], + }, + { + icon: ArxivIcon, + title: 'ArXiv literature review builder', + prompt: + 'Create a workflow that takes a research topic, queries ArXiv for the most cited recent papers, summarizes each, and writes a literature review file.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + { + icon: ArxivIcon, + title: 'ArXiv knowledge-base feeder', + prompt: + 'Build a scheduled workflow that polls ArXiv for new papers in a topic, fetches PDFs, parses with Mistral Parser, and upserts the chunks into a research knowledge base.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'sync'], + alsoIntegrations: ['mistral_parse'], + }, + { + icon: ArxivIcon, + title: 'ArXiv top-author tracker', + prompt: + 'Create a scheduled workflow that monitors ArXiv for new papers by tracked authors and posts a Slack alert when a watched author publishes new work.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ArxivIcon, + title: 'ArXiv weekly digest', + prompt: + 'Build a scheduled weekly workflow that gathers the top ArXiv papers per tracked category, clusters them by theme, and writes a digest file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + }, + { + icon: ArxivIcon, + title: 'ArXiv author-topic grapher', + prompt: + 'Create a workflow that for a chosen ArXiv topic pulls papers and their authors, builds a co-authorship and topic graph in Neo4j, and exposes a visualization for the research team.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['research', 'analysis'], + alsoIntegrations: ['neo4j'], + }, + { + icon: ArxivIcon, + title: 'ArXiv survey-paper generator', + prompt: + 'Build a workflow that takes a topic, finds the most influential ArXiv papers, summarizes themes, and writes a survey-style file as a starting point for research.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + ], + skills: [ + { + name: 'search-recent-papers', + description: + 'Search ArXiv for the most relevant or most recent papers on a topic and return a ranked, summarized list. Use for literature discovery and topic scans.', + content: + '# Search Recent Papers\n\nFind the papers most worth reading on a given topic.\n\n## Steps\n1. Build the ArXiv query from the topic, choosing the search field (title, abstract, or all) and a result limit.\n2. Sort by relevance for a broad scan, or by submitted date to surface the newest work.\n3. For each result capture title, authors, ArXiv ID, publication date, and abstract.\n4. Write a one-line summary per paper highlighting the contribution.\n\n## Output\nA ranked list of papers with ID, title, authors, date, and a one-line takeaway each. Lead with the most relevant.', + }, + { + name: 'summarize-paper', + description: + 'Fetch a specific ArXiv paper by ID and produce a structured summary of its contribution, method, and results. Use to digest a single paper quickly.', + content: + '# Summarize Paper\n\nProduce a structured read of one ArXiv paper.\n\n## Steps\n1. Fetch the paper details using its ArXiv ID.\n2. Read the abstract and metadata to identify the problem, approach, and headline results.\n3. Note the authors, publication date, and primary category.\n4. Write a structured summary.\n\n## Output\nA brief covering: problem addressed, method, key results, and why it matters — plus the ArXiv ID and link. Keep it tight and skip filler.', + }, + { + name: 'track-author-publications', + description: + "Retrieve an author's recent ArXiv papers and report new work since the last check. Use to follow specific researchers or labs.", + content: + "# Track Author Publications\n\nMonitor a researcher for new ArXiv output.\n\n## Steps\n1. Fetch the author's papers by name, sorted by submitted date.\n2. Compare the results against the previously seen list to find new entries.\n3. For each new paper capture title, ID, date, and abstract.\n4. Summarize what is new since the last check.\n\n## Output\nList only the new papers with title, ID, date, and a one-line summary. If there is nothing new, say so.", + }, + { + name: 'build-literature-review', + description: + 'Search ArXiv on a topic, summarize the key papers, and assemble a themed literature review. Use to bootstrap research on a new area.', + content: + '# Build Literature Review\n\nAssemble a starting literature review for a research topic.\n\n## Steps\n1. Search ArXiv for the most relevant and most cited recent papers on the topic.\n2. Fetch details and summarize each selected paper.\n3. Cluster the papers into themes or sub-questions.\n4. Write a review that introduces the topic, walks through each theme citing the papers, and notes open gaps.\n\n## Output\nA structured review document with a theme-by-theme synthesis and a reference list of ArXiv IDs and titles.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/arxiv.ts b/apps/sim/blocks/blocks/arxiv.ts index d0eed22d526..7d4d7a1dde4 100644 --- a/apps/sim/blocks/blocks/arxiv.ts +++ b/apps/sim/blocks/blocks/arxiv.ts @@ -1,6 +1,5 @@ -import { ArxivIcon } from '@/components/icons' import { ArxivBlockDisplay } from '@/blocks/blocks/arxiv.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { ArxivResponse } from '@/tools/arxiv/types' export const ArxivBlock: BlockConfig = { @@ -144,107 +143,3 @@ export const ArxivBlock: BlockConfig = { authorPapers: { type: 'json', description: 'Author papers list' }, }, } - -export const ArxivBlockMeta = { - tags: ['document-processing', 'knowledge-base'], - url: 'https://arxiv.org', - templates: [ - { - icon: ArxivIcon, - title: 'ArXiv paper alerter', - prompt: - 'Build a scheduled workflow that queries ArXiv for new papers on tracked topics, summarizes abstracts with an agent, and emails the digest to the research team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research'], - alsoIntegrations: ['gmail'], - }, - { - icon: ArxivIcon, - title: 'ArXiv literature review builder', - prompt: - 'Create a workflow that takes a research topic, queries ArXiv for the most cited recent papers, summarizes each, and writes a literature review file.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - { - icon: ArxivIcon, - title: 'ArXiv knowledge-base feeder', - prompt: - 'Build a scheduled workflow that polls ArXiv for new papers in a topic, fetches PDFs, parses with Mistral Parser, and upserts the chunks into a research knowledge base.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'sync'], - alsoIntegrations: ['mistral_parse'], - }, - { - icon: ArxivIcon, - title: 'ArXiv top-author tracker', - prompt: - 'Create a scheduled workflow that monitors ArXiv for new papers by tracked authors and posts a Slack alert when a watched author publishes new work.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ArxivIcon, - title: 'ArXiv weekly digest', - prompt: - 'Build a scheduled weekly workflow that gathers the top ArXiv papers per tracked category, clusters them by theme, and writes a digest file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - }, - { - icon: ArxivIcon, - title: 'ArXiv author-topic grapher', - prompt: - 'Create a workflow that for a chosen ArXiv topic pulls papers and their authors, builds a co-authorship and topic graph in Neo4j, and exposes a visualization for the research team.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['research', 'analysis'], - alsoIntegrations: ['neo4j'], - }, - { - icon: ArxivIcon, - title: 'ArXiv survey-paper generator', - prompt: - 'Build a workflow that takes a topic, finds the most influential ArXiv papers, summarizes themes, and writes a survey-style file as a starting point for research.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - ], - skills: [ - { - name: 'search-recent-papers', - description: - 'Search ArXiv for the most relevant or most recent papers on a topic and return a ranked, summarized list. Use for literature discovery and topic scans.', - content: - '# Search Recent Papers\n\nFind the papers most worth reading on a given topic.\n\n## Steps\n1. Build the ArXiv query from the topic, choosing the search field (title, abstract, or all) and a result limit.\n2. Sort by relevance for a broad scan, or by submitted date to surface the newest work.\n3. For each result capture title, authors, ArXiv ID, publication date, and abstract.\n4. Write a one-line summary per paper highlighting the contribution.\n\n## Output\nA ranked list of papers with ID, title, authors, date, and a one-line takeaway each. Lead with the most relevant.', - }, - { - name: 'summarize-paper', - description: - 'Fetch a specific ArXiv paper by ID and produce a structured summary of its contribution, method, and results. Use to digest a single paper quickly.', - content: - '# Summarize Paper\n\nProduce a structured read of one ArXiv paper.\n\n## Steps\n1. Fetch the paper details using its ArXiv ID.\n2. Read the abstract and metadata to identify the problem, approach, and headline results.\n3. Note the authors, publication date, and primary category.\n4. Write a structured summary.\n\n## Output\nA brief covering: problem addressed, method, key results, and why it matters — plus the ArXiv ID and link. Keep it tight and skip filler.', - }, - { - name: 'track-author-publications', - description: - "Retrieve an author's recent ArXiv papers and report new work since the last check. Use to follow specific researchers or labs.", - content: - "# Track Author Publications\n\nMonitor a researcher for new ArXiv output.\n\n## Steps\n1. Fetch the author's papers by name, sorted by submitted date.\n2. Compare the results against the previously seen list to find new entries.\n3. For each new paper capture title, ID, date, and abstract.\n4. Summarize what is new since the last check.\n\n## Output\nList only the new papers with title, ID, date, and a one-line summary. If there is nothing new, say so.", - }, - { - name: 'build-literature-review', - description: - 'Search ArXiv on a topic, summarize the key papers, and assemble a themed literature review. Use to bootstrap research on a new area.', - content: - '# Build Literature Review\n\nAssemble a starting literature review for a research topic.\n\n## Steps\n1. Search ArXiv for the most relevant and most cited recent papers on the topic.\n2. Fetch details and summarize each selected paper.\n3. Cluster the papers into themes or sub-questions.\n4. Write a review that introduces the topic, walks through each theme citing the papers, and notes open gaps.\n\n## Output\nA structured review document with a theme-by-theme synthesis and a reference list of ArXiv IDs and titles.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/asana.display.ts b/apps/sim/blocks/blocks/asana.display.ts index 01f5b89e027..ac7347d8eab 100644 --- a/apps/sim/blocks/blocks/asana.display.ts +++ b/apps/sim/blocks/blocks/asana.display.ts @@ -1,6 +1,6 @@ import { AsanaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AsanaBlockDisplay = { type: 'asana', @@ -13,3 +13,103 @@ export const AsanaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/asana', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const AsanaBlockMeta = { + tags: ['project-management', 'ticketing', 'automation'], + url: 'https://asana.com', + templates: [ + { + icon: AsanaIcon, + title: 'Asana sprint planner', + prompt: + 'Build a workflow that on Monday morning compiles uncompleted Asana tasks, rebalances against capacity, and posts the sprint plan to the team Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AsanaIcon, + title: 'Asana stuck-task surfacer', + prompt: + 'Create a scheduled workflow that finds Asana tasks with no progress for 5+ days, pings the assignee in Slack with a quick-action prompt, and updates the task status based on their answer.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: AsanaIcon, + title: 'Asana cross-team blocker watcher', + prompt: + 'Build a scheduled workflow that searches Asana for tasks tagged blocked, identifies the blocking team based on dependency metadata, and posts a request to the right channel in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AsanaIcon, + title: 'Asana onboarding task launcher', + prompt: + 'Create a workflow that on a new Salesforce opportunity creates a customer-onboarding Asana task with the right assignee and due date, and writes the task link back to the opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: AsanaIcon, + title: 'Asana weekly project digest', + prompt: + 'Build a scheduled weekly workflow that summarizes Asana project progress — completed, in-progress, at-risk — and emails a status update to each project sponsor.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: AsanaIcon, + title: 'Asana retro generator', + prompt: + 'Create a workflow that pulls Asana tasks completed in a sprint, summarizes wins, blockers, and patterns, and writes a retro doc shared with the team via Slack.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AsanaIcon, + title: 'Asana bug intake triager', + prompt: + 'Build a workflow that searches Asana for newly created tasks in the bug project, classifies each by severity and component with an agent, adds a triage comment, and creates a matching GitHub issue for engineering pickup.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + alsoIntegrations: ['github'], + }, + ], + skills: [ + { + name: 'create-task-from-request', + description: + 'Turn an incoming request or message into a well-formed Asana task in the right project with assignee and due date. Use for intake and ticket creation.', + content: + '# Create Task from Request\n\nConvert an incoming request into a structured Asana task.\n\n## Steps\n1. Extract the work to be done, the relevant project, an assignee if named, and any due date.\n2. If the project is referenced by name, list projects to resolve its ID.\n3. Create the task with a clear name, a description capturing the request details, the project, assignee, and due date.\n4. Add a comment with any links or source context if helpful.\n\n## Output\nReport the created task name, its URL or ID, project, assignee, and due date.', + }, + { + name: 'summarize-project-tasks', + description: + 'Search tasks in an Asana project and summarize status, overdue items, and who owns what. Use for standups and project status checks.', + content: + '# Summarize Project Tasks\n\nProduce a status snapshot of an Asana project.\n\n## Steps\n1. Resolve the project, then search its tasks.\n2. For each task capture name, assignee, due date, and completion state.\n3. Group into completed, in progress, and overdue or due soon.\n4. Note any unassigned tasks or tasks with no due date.\n\n## Output\nA concise status summary: counts per group, overdue tasks called out by name and owner, and any gaps to address.', + }, + { + name: 'update-task-status', + description: + 'Find an Asana task and update its fields — assignee, due date, completion, or add a progress comment. Use to keep tasks current from other systems.', + content: + '# Update Task Status\n\nKeep an Asana task in sync with the latest state.\n\n## Steps\n1. Identify the target task by ID, or search to find it by name.\n2. Read the current task to confirm it is the right one.\n3. Update the relevant fields — completion, assignee, or due date.\n4. Add a comment summarizing what changed and why.\n\n## Output\nReport which fields changed and confirm the task ID. If no matching task was found, say so.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/asana.ts b/apps/sim/blocks/blocks/asana.ts index 18ede16093d..6cecedff777 100644 --- a/apps/sim/blocks/blocks/asana.ts +++ b/apps/sim/blocks/blocks/asana.ts @@ -1,7 +1,6 @@ -import { AsanaIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { AsanaBlockDisplay } from '@/blocks/blocks/asana.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AsanaResponse } from '@/tools/asana/types' @@ -359,103 +358,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n projects: { type: 'json', description: 'Array of projects' }, }, } - -export const AsanaBlockMeta = { - tags: ['project-management', 'ticketing', 'automation'], - url: 'https://asana.com', - templates: [ - { - icon: AsanaIcon, - title: 'Asana sprint planner', - prompt: - 'Build a workflow that on Monday morning compiles uncompleted Asana tasks, rebalances against capacity, and posts the sprint plan to the team Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AsanaIcon, - title: 'Asana stuck-task surfacer', - prompt: - 'Create a scheduled workflow that finds Asana tasks with no progress for 5+ days, pings the assignee in Slack with a quick-action prompt, and updates the task status based on their answer.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: AsanaIcon, - title: 'Asana cross-team blocker watcher', - prompt: - 'Build a scheduled workflow that searches Asana for tasks tagged blocked, identifies the blocking team based on dependency metadata, and posts a request to the right channel in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AsanaIcon, - title: 'Asana onboarding task launcher', - prompt: - 'Create a workflow that on a new Salesforce opportunity creates a customer-onboarding Asana task with the right assignee and due date, and writes the task link back to the opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: AsanaIcon, - title: 'Asana weekly project digest', - prompt: - 'Build a scheduled weekly workflow that summarizes Asana project progress — completed, in-progress, at-risk — and emails a status update to each project sponsor.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: AsanaIcon, - title: 'Asana retro generator', - prompt: - 'Create a workflow that pulls Asana tasks completed in a sprint, summarizes wins, blockers, and patterns, and writes a retro doc shared with the team via Slack.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AsanaIcon, - title: 'Asana bug intake triager', - prompt: - 'Build a workflow that searches Asana for newly created tasks in the bug project, classifies each by severity and component with an agent, adds a triage comment, and creates a matching GitHub issue for engineering pickup.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - alsoIntegrations: ['github'], - }, - ], - skills: [ - { - name: 'create-task-from-request', - description: - 'Turn an incoming request or message into a well-formed Asana task in the right project with assignee and due date. Use for intake and ticket creation.', - content: - '# Create Task from Request\n\nConvert an incoming request into a structured Asana task.\n\n## Steps\n1. Extract the work to be done, the relevant project, an assignee if named, and any due date.\n2. If the project is referenced by name, list projects to resolve its ID.\n3. Create the task with a clear name, a description capturing the request details, the project, assignee, and due date.\n4. Add a comment with any links or source context if helpful.\n\n## Output\nReport the created task name, its URL or ID, project, assignee, and due date.', - }, - { - name: 'summarize-project-tasks', - description: - 'Search tasks in an Asana project and summarize status, overdue items, and who owns what. Use for standups and project status checks.', - content: - '# Summarize Project Tasks\n\nProduce a status snapshot of an Asana project.\n\n## Steps\n1. Resolve the project, then search its tasks.\n2. For each task capture name, assignee, due date, and completion state.\n3. Group into completed, in progress, and overdue or due soon.\n4. Note any unassigned tasks or tasks with no due date.\n\n## Output\nA concise status summary: counts per group, overdue tasks called out by name and owner, and any gaps to address.', - }, - { - name: 'update-task-status', - description: - 'Find an Asana task and update its fields — assignee, due date, completion, or add a progress comment. Use to keep tasks current from other systems.', - content: - '# Update Task Status\n\nKeep an Asana task in sync with the latest state.\n\n## Steps\n1. Identify the target task by ID, or search to find it by name.\n2. Read the current task to confirm it is the right one.\n3. Update the relevant fields — completion, assignee, or due date.\n4. Add a comment summarizing what changed and why.\n\n## Output\nReport which fields changed and confirm the task ID. If no matching task was found, say so.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ashby.display.ts b/apps/sim/blocks/blocks/ashby.display.ts index 4e7a85b73d9..a548cf3387c 100644 --- a/apps/sim/blocks/blocks/ashby.display.ts +++ b/apps/sim/blocks/blocks/ashby.display.ts @@ -1,6 +1,6 @@ import { AshbyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AshbyBlockDisplay = { type: 'ashby', @@ -15,3 +15,101 @@ export const AshbyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/ashby', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const AshbyBlockMeta = { + tags: ['hiring'], + url: 'https://ashbyhq.com', + templates: [ + { + icon: AshbyIcon, + title: 'Ashby pipeline digest', + prompt: + 'Build a scheduled daily workflow that lists open Ashby jobs, summarizes candidate counts per stage, flags applications stalled for more than five days, logs metrics to a tracking table, and Slacks hiring managers a personalized pipeline digest.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AshbyIcon, + title: 'Resume to Ashby candidate', + prompt: + 'Create a workflow that watches a folder of inbound resumes, extracts contact info and work history, deduplicates against existing Ashby candidates, creates new candidate records when needed, and tags them with the source job they applied through.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'automation'], + }, + { + icon: AshbyIcon, + title: 'Interview note logger', + prompt: + 'Build a workflow that runs after every interview is logged in your meeting tool, summarizes the transcript, scores the candidate against the job requirements, creates a structured note on the matching Ashby candidate, and notifies the hiring manager in Slack.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'team'], + alsoIntegrations: ['slack'], + }, + { + icon: AshbyIcon, + title: 'Stage-change responder', + prompt: + 'Create a workflow that detects when an Ashby application moves into a new stage, sends the candidate a stage-appropriate email, prepares the interviewer brief in a file, and updates a recruiting tracking table so coordinators always know who is next.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: AshbyIcon, + title: 'Ashby DEI snapshot', + prompt: + 'Build a scheduled monthly workflow that pulls Ashby candidates, applications, and openings, computes funnel diversity metrics by stage, role, and source, and writes a confidential report file shared with people leadership and compliance.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'reporting'], + }, + { + icon: AshbyIcon, + title: 'Candidate research enricher', + prompt: + 'Create a workflow that takes new Ashby candidates, researches each across LinkedIn and the web for relevant background, writes a structured profile summary onto the candidate as an Ashby note, and updates a recruiting table with research links.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'research'], + alsoIntegrations: ['linkedin'], + }, + { + icon: AshbyIcon, + title: 'Offer ready brief', + prompt: + 'Build a workflow that runs when an Ashby application reaches the offer stage, gathers compensation benchmarks, interview feedback, and candidate priorities, drafts an offer brief file for the hiring manager, and Slacks the people team to start the offer process.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'add-candidate', + description: + 'Create a candidate in Ashby from an inbound application or referral and attach them to a job. Use for sourcing and referral intake.', + content: + '# Add Candidate\n\nCapture a new candidate into Ashby and link them to the right role.\n\n## Steps\n1. Gather the candidate name, email, source, and the target job.\n2. If the job is named, list jobs to resolve its ID.\n3. Create the candidate, then create an application linking them to the job with the correct source.\n4. Add a note with referral context or screening details, and apply any relevant tags.\n\n## Output\nReport the created candidate and application IDs, the linked job, and the source applied.', + }, + { + name: 'advance-candidate-stage', + description: + 'Move a candidate application to a new interview stage in Ashby and log the decision. Use to keep the pipeline moving after interviews.', + content: + '# Advance Candidate Stage\n\nProgress a candidate through the hiring pipeline.\n\n## Steps\n1. Find the application — by ID, or list applications for the candidate or job.\n2. Confirm the current stage by getting the application.\n3. Change the application stage to the target stage.\n4. Add a note capturing the rationale and any interview feedback.\n\n## Output\nConfirm the candidate, the stage moved from and to, and the note added.', + }, + { + name: 'pipeline-status-report', + description: + 'List candidates and applications by status or job in Ashby and summarize pipeline health. Use for recruiting standups and weekly reports.', + content: + '# Pipeline Status Report\n\nSummarize the state of an Ashby hiring pipeline.\n\n## Steps\n1. List the relevant jobs, or focus on one role.\n2. List applications, grouping candidates by current stage and status (active, hired, archived).\n3. Flag candidates stalled in a stage or awaiting feedback.\n4. Note new candidates added since the last report.\n\n## Output\nA pipeline summary: candidate counts per stage and status, stalled candidates called out by name and role, and recent additions.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ashby.ts b/apps/sim/blocks/blocks/ashby.ts index 512f1bc6daa..445ae28349e 100644 --- a/apps/sim/blocks/blocks/ashby.ts +++ b/apps/sim/blocks/blocks/ashby.ts @@ -1,6 +1,5 @@ -import { AshbyIcon } from '@/components/icons' import { AshbyBlockDisplay } from '@/blocks/blocks/ashby.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const AshbyBlock: BlockConfig = { @@ -958,101 +957,3 @@ Output only the ISO 8601 timestamp string, nothing else.`, syncToken: { type: 'string', description: 'Sync token for incremental updates' }, }, } - -export const AshbyBlockMeta = { - tags: ['hiring'], - url: 'https://ashbyhq.com', - templates: [ - { - icon: AshbyIcon, - title: 'Ashby pipeline digest', - prompt: - 'Build a scheduled daily workflow that lists open Ashby jobs, summarizes candidate counts per stage, flags applications stalled for more than five days, logs metrics to a tracking table, and Slacks hiring managers a personalized pipeline digest.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AshbyIcon, - title: 'Resume to Ashby candidate', - prompt: - 'Create a workflow that watches a folder of inbound resumes, extracts contact info and work history, deduplicates against existing Ashby candidates, creates new candidate records when needed, and tags them with the source job they applied through.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'automation'], - }, - { - icon: AshbyIcon, - title: 'Interview note logger', - prompt: - 'Build a workflow that runs after every interview is logged in your meeting tool, summarizes the transcript, scores the candidate against the job requirements, creates a structured note on the matching Ashby candidate, and notifies the hiring manager in Slack.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'team'], - alsoIntegrations: ['slack'], - }, - { - icon: AshbyIcon, - title: 'Stage-change responder', - prompt: - 'Create a workflow that detects when an Ashby application moves into a new stage, sends the candidate a stage-appropriate email, prepares the interviewer brief in a file, and updates a recruiting tracking table so coordinators always know who is next.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: AshbyIcon, - title: 'Ashby DEI snapshot', - prompt: - 'Build a scheduled monthly workflow that pulls Ashby candidates, applications, and openings, computes funnel diversity metrics by stage, role, and source, and writes a confidential report file shared with people leadership and compliance.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'reporting'], - }, - { - icon: AshbyIcon, - title: 'Candidate research enricher', - prompt: - 'Create a workflow that takes new Ashby candidates, researches each across LinkedIn and the web for relevant background, writes a structured profile summary onto the candidate as an Ashby note, and updates a recruiting table with research links.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'research'], - alsoIntegrations: ['linkedin'], - }, - { - icon: AshbyIcon, - title: 'Offer ready brief', - prompt: - 'Build a workflow that runs when an Ashby application reaches the offer stage, gathers compensation benchmarks, interview feedback, and candidate priorities, drafts an offer brief file for the hiring manager, and Slacks the people team to start the offer process.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'add-candidate', - description: - 'Create a candidate in Ashby from an inbound application or referral and attach them to a job. Use for sourcing and referral intake.', - content: - '# Add Candidate\n\nCapture a new candidate into Ashby and link them to the right role.\n\n## Steps\n1. Gather the candidate name, email, source, and the target job.\n2. If the job is named, list jobs to resolve its ID.\n3. Create the candidate, then create an application linking them to the job with the correct source.\n4. Add a note with referral context or screening details, and apply any relevant tags.\n\n## Output\nReport the created candidate and application IDs, the linked job, and the source applied.', - }, - { - name: 'advance-candidate-stage', - description: - 'Move a candidate application to a new interview stage in Ashby and log the decision. Use to keep the pipeline moving after interviews.', - content: - '# Advance Candidate Stage\n\nProgress a candidate through the hiring pipeline.\n\n## Steps\n1. Find the application — by ID, or list applications for the candidate or job.\n2. Confirm the current stage by getting the application.\n3. Change the application stage to the target stage.\n4. Add a note capturing the rationale and any interview feedback.\n\n## Output\nConfirm the candidate, the stage moved from and to, and the note added.', - }, - { - name: 'pipeline-status-report', - description: - 'List candidates and applications by status or job in Ashby and summarize pipeline health. Use for recruiting standups and weekly reports.', - content: - '# Pipeline Status Report\n\nSummarize the state of an Ashby hiring pipeline.\n\n## Steps\n1. List the relevant jobs, or focus on one role.\n2. List applications, grouping candidates by current stage and status (active, hired, archived).\n3. Flag candidates stalled in a stage or awaiting feedback.\n4. Note new candidates added since the last report.\n\n## Output\nA pipeline summary: candidate counts per stage and status, stalled candidates called out by name and role, and recent additions.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/athena.display.ts b/apps/sim/blocks/blocks/athena.display.ts index 0a144badc69..2a6ffa12b98 100644 --- a/apps/sim/blocks/blocks/athena.display.ts +++ b/apps/sim/blocks/blocks/athena.display.ts @@ -1,6 +1,6 @@ import { AthenaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AthenaBlockDisplay = { type: 'athena', @@ -15,3 +15,103 @@ export const AthenaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/athena', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const AthenaBlockMeta = { + tags: ['cloud', 'data-analytics'], + url: 'https://aws.amazon.com/athena', + templates: [ + { + icon: AthenaIcon, + title: 'Athena scheduled report runner', + prompt: + 'Create a scheduled workflow that runs a saved AWS Athena query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AthenaIcon, + title: 'Athena S3 access audit', + prompt: + 'Build a workflow that runs Athena queries against S3 access logs weekly, identifies unusual access patterns or new principals, and writes findings to a security audit table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['s3'], + }, + { + icon: AthenaIcon, + title: 'Athena cost-explorer query', + prompt: + 'Build a scheduled workflow that runs Athena queries against AWS cost-and-usage reports daily, writes top cost movers per service to a table, and posts an anomaly digest to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: AthenaIcon, + title: 'Athena + Tinybird real-time bridge', + prompt: + 'Build a workflow that combines historical Athena queries with realtime Tinybird endpoints into a unified reporting view, writes results to a dashboard table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + alsoIntegrations: ['tinybird'], + }, + { + icon: AthenaIcon, + title: 'Athena + PostHog data-warehouse join', + prompt: + 'Create a scheduled workflow that joins PostHog event exports with Athena historical data, computes funnel conversion across the join, and writes a daily report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['product', 'analysis'], + alsoIntegrations: ['posthog'], + }, + { + icon: AthenaIcon, + title: 'Athena ad-hoc query agent', + prompt: + 'Build a Slack agent that translates natural-language analytics questions into safe AWS Athena queries, executes them, and returns the table answer with the query for review.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'engineering'], + alsoIntegrations: ['slack'], + }, + { + icon: AthenaIcon, + title: 'Athena weekly executive metrics', + prompt: + 'Create a scheduled weekly workflow that runs a set of AWS Athena queries against the data lake for revenue, retention, and usage metrics, writes the results to a metrics table, and emails a formatted scorecard to leadership.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'run-query', + description: + 'Run a SQL query against data in S3 via Athena, wait for completion, and return the results. Use for ad-hoc analysis and reporting over your data lake.', + content: + '# Run Query\n\nExecute a SQL query in Athena and return the results.\n\n## Steps\n1. Compose the SQL, naming the database and confirming the output location.\n2. Start the query to obtain a query execution ID.\n3. Poll get query execution until the state is SUCCEEDED, FAILED, or CANCELLED.\n4. On success, fetch the query results and shape the rows into a clean table.\n\n## Output\nReturn the result rows plus the execution ID, data scanned, and runtime. On failure, surface the Athena error message and the SQL that caused it.', + }, + { + name: 'scheduled-metrics-report', + description: + 'Run a saved or composed Athena query on a schedule to compute metrics and produce a report. Use for recurring KPI and usage reporting.', + content: + '# Scheduled Metrics Report\n\nCompute recurring metrics from data in S3.\n\n## Steps\n1. Use a named query, or compose the metrics SQL for the reporting period.\n2. Start the query and poll execution until it completes.\n3. Fetch the results and format the metrics for reporting.\n4. Compare against the prior period to highlight movement where relevant.\n\n## Output\nA metrics summary with current values, period-over-period change, and the execution ID for traceability.', + }, + { + name: 'manage-named-queries', + description: + 'Create, look up, and list saved (named) queries in Athena to standardize reusable SQL. Use to maintain a library of vetted analytics queries.', + content: + '# Manage Named Queries\n\nMaintain a library of reusable Athena queries.\n\n## Steps\n1. To save a query, create a named query with a clear name, description, database, and the SQL body.\n2. To reuse one, list named queries or get a named query by ID to retrieve its SQL.\n3. Run the retrieved SQL via start query when execution is needed.\n4. Keep names and descriptions accurate so the right query is easy to find.\n\n## Output\nReport the named query ID and name for creates, or the resolved SQL for lookups.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/athena.ts b/apps/sim/blocks/blocks/athena.ts index 621f2d22767..ed202140d37 100644 --- a/apps/sim/blocks/blocks/athena.ts +++ b/apps/sim/blocks/blocks/athena.ts @@ -1,6 +1,5 @@ -import { AthenaIcon } from '@/components/icons' import { AthenaBlockDisplay } from '@/blocks/blocks/athena.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { AthenaCreateNamedQueryResponse, AthenaGetNamedQueryResponse, @@ -457,103 +456,3 @@ Return ONLY the SQL query — no explanations, no markdown code blocks.`, }, }, } - -export const AthenaBlockMeta = { - tags: ['cloud', 'data-analytics'], - url: 'https://aws.amazon.com/athena', - templates: [ - { - icon: AthenaIcon, - title: 'Athena scheduled report runner', - prompt: - 'Create a scheduled workflow that runs a saved AWS Athena query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AthenaIcon, - title: 'Athena S3 access audit', - prompt: - 'Build a workflow that runs Athena queries against S3 access logs weekly, identifies unusual access patterns or new principals, and writes findings to a security audit table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['s3'], - }, - { - icon: AthenaIcon, - title: 'Athena cost-explorer query', - prompt: - 'Build a scheduled workflow that runs Athena queries against AWS cost-and-usage reports daily, writes top cost movers per service to a table, and posts an anomaly digest to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: AthenaIcon, - title: 'Athena + Tinybird real-time bridge', - prompt: - 'Build a workflow that combines historical Athena queries with realtime Tinybird endpoints into a unified reporting view, writes results to a dashboard table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - alsoIntegrations: ['tinybird'], - }, - { - icon: AthenaIcon, - title: 'Athena + PostHog data-warehouse join', - prompt: - 'Create a scheduled workflow that joins PostHog event exports with Athena historical data, computes funnel conversion across the join, and writes a daily report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['product', 'analysis'], - alsoIntegrations: ['posthog'], - }, - { - icon: AthenaIcon, - title: 'Athena ad-hoc query agent', - prompt: - 'Build a Slack agent that translates natural-language analytics questions into safe AWS Athena queries, executes them, and returns the table answer with the query for review.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'engineering'], - alsoIntegrations: ['slack'], - }, - { - icon: AthenaIcon, - title: 'Athena weekly executive metrics', - prompt: - 'Create a scheduled weekly workflow that runs a set of AWS Athena queries against the data lake for revenue, retention, and usage metrics, writes the results to a metrics table, and emails a formatted scorecard to leadership.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'run-query', - description: - 'Run a SQL query against data in S3 via Athena, wait for completion, and return the results. Use for ad-hoc analysis and reporting over your data lake.', - content: - '# Run Query\n\nExecute a SQL query in Athena and return the results.\n\n## Steps\n1. Compose the SQL, naming the database and confirming the output location.\n2. Start the query to obtain a query execution ID.\n3. Poll get query execution until the state is SUCCEEDED, FAILED, or CANCELLED.\n4. On success, fetch the query results and shape the rows into a clean table.\n\n## Output\nReturn the result rows plus the execution ID, data scanned, and runtime. On failure, surface the Athena error message and the SQL that caused it.', - }, - { - name: 'scheduled-metrics-report', - description: - 'Run a saved or composed Athena query on a schedule to compute metrics and produce a report. Use for recurring KPI and usage reporting.', - content: - '# Scheduled Metrics Report\n\nCompute recurring metrics from data in S3.\n\n## Steps\n1. Use a named query, or compose the metrics SQL for the reporting period.\n2. Start the query and poll execution until it completes.\n3. Fetch the results and format the metrics for reporting.\n4. Compare against the prior period to highlight movement where relevant.\n\n## Output\nA metrics summary with current values, period-over-period change, and the execution ID for traceability.', - }, - { - name: 'manage-named-queries', - description: - 'Create, look up, and list saved (named) queries in Athena to standardize reusable SQL. Use to maintain a library of vetted analytics queries.', - content: - '# Manage Named Queries\n\nMaintain a library of reusable Athena queries.\n\n## Steps\n1. To save a query, create a named query with a clear name, description, database, and the SQL body.\n2. To reuse one, list named queries or get a named query by ID to retrieve its SQL.\n3. Run the retrieved SQL via start query when execution is needed.\n4. Keep names and descriptions accurate so the right query is easy to find.\n\n## Output\nReport the named query ID and name for creates, or the resolved SQL for lookups.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/attio.display.ts b/apps/sim/blocks/blocks/attio.display.ts index 96128029a8f..9eb48cd217e 100644 --- a/apps/sim/blocks/blocks/attio.display.ts +++ b/apps/sim/blocks/blocks/attio.display.ts @@ -1,6 +1,6 @@ import { AttioIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AttioBlockDisplay = { type: 'attio', @@ -14,3 +14,109 @@ export const AttioBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/attio', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const AttioBlockMeta = { + tags: ['sales-engagement', 'enrichment'], + url: 'https://attio.com', + templates: [ + { + icon: AttioIcon, + title: 'Attio enrichment pipeline', + prompt: + 'Build a workflow that watches new Attio records, enriches each contact with company size, funding, and tech stack via Apollo, and writes the enriched fields back to Attio.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['apollo'], + }, + { + icon: AttioIcon, + title: 'Attio deal pipeline tracker', + prompt: + 'Create a scheduled workflow that mirrors Attio deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: AttioIcon, + title: 'Attio email-to-record logger', + prompt: + 'Build a workflow that watches Gmail for emails to or from Attio contacts, logs each as an interaction on the matching record, and creates a follow-up task if mentioned.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: AttioIcon, + title: 'Attio call-summary updater', + prompt: + 'Create a workflow that runs after a Fireflies sales call, summarizes the transcript into a deal-ready summary, and updates the matching Attio deal record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['fireflies'], + }, + { + icon: AttioIcon, + title: 'Attio win/loss analyzer', + prompt: + 'Build a scheduled monthly workflow that pulls closed Attio deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + }, + { + icon: AttioIcon, + title: 'Attio outreach orchestrator', + prompt: + 'Create a workflow that watches Attio for contacts entering the outreach stage, drafts a personalized first-touch email, and queues it for the rep to review and send.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: AttioIcon, + title: 'Attio Slack channel-per-deal', + prompt: + 'Build a workflow that for Attio deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'upsert-record', + description: + 'Create or update a person, company, or deal record in Attio, matching on a key field to avoid duplicates. Use to sync external data into the CRM.', + content: + '# Upsert Record\n\nKeep an Attio record in sync without creating duplicates.\n\n## Steps\n1. Identify the target object (people, companies, or a custom object) and the matching attribute, such as email or domain.\n2. Assemble the record values to set.\n3. Use assert record to upsert on the matching attribute so an existing record is updated and a new one is created only when needed.\n4. Verify the resulting record by getting it back.\n\n## Output\nReport whether the record was created or updated and its record ID.', + }, + { + name: 'log-note-on-record', + description: + 'Attach a note to an Attio record capturing a call, meeting, or update. Use to keep CRM context current after interactions.', + content: + '# Log Note on Record\n\nRecord context against the right Attio record.\n\n## Steps\n1. Find the target record — by ID, or search records to locate it by name or domain.\n2. Compose the note title and body summarizing the interaction or update.\n3. Create the note on that record.\n4. Optionally create a follow-up task if next steps were agreed.\n\n## Output\nConfirm the record the note was attached to and the note ID, plus any follow-up task created.', + }, + { + name: 'create-followup-task', + description: + 'Create a task in Attio linked to a record with an owner and due date. Use to capture follow-ups and next steps from deals or conversations.', + content: + '# Create Follow-up Task\n\nTurn a next step into a tracked Attio task.\n\n## Steps\n1. Identify the related record and the work to be done.\n2. Determine the assignee and a due date.\n3. Create the task with a clear description, linked record, owner, and deadline.\n4. Confirm the task was created against the right record.\n\n## Output\nReport the created task ID, the linked record, assignee, and due date.', + }, + { + name: 'manage-list-pipeline', + description: + 'Query and update entries in an Attio list to move records through a pipeline or segment. Use for managing deal stages and curated segments.', + content: + '# Manage List Pipeline\n\nMove records through an Attio list-based pipeline.\n\n## Steps\n1. Resolve the target list, then query list entries to see current state.\n2. Identify which entries need to change stage or attributes.\n3. Create, update, or remove list entries as needed to reflect the new state.\n4. Summarize the pipeline distribution after the changes.\n\n## Output\nReport which entries moved and their new stage, plus the resulting count of records per stage.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/attio.ts b/apps/sim/blocks/blocks/attio.ts index 415c8bca153..ef72d891d9d 100644 --- a/apps/sim/blocks/blocks/attio.ts +++ b/apps/sim/blocks/blocks/attio.ts @@ -1,6 +1,5 @@ -import { AttioIcon } from '@/components/icons' import { AttioBlockDisplay } from '@/blocks/blocks/attio.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AttioResponse } from '@/tools/attio/types' import { getTrigger } from '@/triggers' @@ -1316,109 +1315,3 @@ workspace-member.created success: { type: 'boolean', description: 'Whether the operation succeeded' }, }, } - -export const AttioBlockMeta = { - tags: ['sales-engagement', 'enrichment'], - url: 'https://attio.com', - templates: [ - { - icon: AttioIcon, - title: 'Attio enrichment pipeline', - prompt: - 'Build a workflow that watches new Attio records, enriches each contact with company size, funding, and tech stack via Apollo, and writes the enriched fields back to Attio.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['apollo'], - }, - { - icon: AttioIcon, - title: 'Attio deal pipeline tracker', - prompt: - 'Create a scheduled workflow that mirrors Attio deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: AttioIcon, - title: 'Attio email-to-record logger', - prompt: - 'Build a workflow that watches Gmail for emails to or from Attio contacts, logs each as an interaction on the matching record, and creates a follow-up task if mentioned.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: AttioIcon, - title: 'Attio call-summary updater', - prompt: - 'Create a workflow that runs after a Fireflies sales call, summarizes the transcript into a deal-ready summary, and updates the matching Attio deal record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['fireflies'], - }, - { - icon: AttioIcon, - title: 'Attio win/loss analyzer', - prompt: - 'Build a scheduled monthly workflow that pulls closed Attio deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - }, - { - icon: AttioIcon, - title: 'Attio outreach orchestrator', - prompt: - 'Create a workflow that watches Attio for contacts entering the outreach stage, drafts a personalized first-touch email, and queues it for the rep to review and send.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: AttioIcon, - title: 'Attio Slack channel-per-deal', - prompt: - 'Build a workflow that for Attio deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'upsert-record', - description: - 'Create or update a person, company, or deal record in Attio, matching on a key field to avoid duplicates. Use to sync external data into the CRM.', - content: - '# Upsert Record\n\nKeep an Attio record in sync without creating duplicates.\n\n## Steps\n1. Identify the target object (people, companies, or a custom object) and the matching attribute, such as email or domain.\n2. Assemble the record values to set.\n3. Use assert record to upsert on the matching attribute so an existing record is updated and a new one is created only when needed.\n4. Verify the resulting record by getting it back.\n\n## Output\nReport whether the record was created or updated and its record ID.', - }, - { - name: 'log-note-on-record', - description: - 'Attach a note to an Attio record capturing a call, meeting, or update. Use to keep CRM context current after interactions.', - content: - '# Log Note on Record\n\nRecord context against the right Attio record.\n\n## Steps\n1. Find the target record — by ID, or search records to locate it by name or domain.\n2. Compose the note title and body summarizing the interaction or update.\n3. Create the note on that record.\n4. Optionally create a follow-up task if next steps were agreed.\n\n## Output\nConfirm the record the note was attached to and the note ID, plus any follow-up task created.', - }, - { - name: 'create-followup-task', - description: - 'Create a task in Attio linked to a record with an owner and due date. Use to capture follow-ups and next steps from deals or conversations.', - content: - '# Create Follow-up Task\n\nTurn a next step into a tracked Attio task.\n\n## Steps\n1. Identify the related record and the work to be done.\n2. Determine the assignee and a due date.\n3. Create the task with a clear description, linked record, owner, and deadline.\n4. Confirm the task was created against the right record.\n\n## Output\nReport the created task ID, the linked record, assignee, and due date.', - }, - { - name: 'manage-list-pipeline', - description: - 'Query and update entries in an Attio list to move records through a pipeline or segment. Use for managing deal stages and curated segments.', - content: - '# Manage List Pipeline\n\nMove records through an Attio list-based pipeline.\n\n## Steps\n1. Resolve the target list, then query list entries to see current state.\n2. Identify which entries need to change stage or attributes.\n3. Create, update, or remove list entries as needed to reflect the new state.\n4. Summarize the pipeline distribution after the changes.\n\n## Output\nReport which entries moved and their new stage, plus the resulting count of records per stage.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/azure_devops.display.ts b/apps/sim/blocks/blocks/azure_devops.display.ts index f15a4daa3dd..7c7842eb312 100644 --- a/apps/sim/blocks/blocks/azure_devops.display.ts +++ b/apps/sim/blocks/blocks/azure_devops.display.ts @@ -1,6 +1,6 @@ import { AzureIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const AzureDevOpsBlockDisplay = { type: 'azure_devops', @@ -15,3 +15,108 @@ export const AzureDevOpsBlockDisplay = { integrationType: IntegrationType.DevOps, triggerAllowed: true, } satisfies BlockDisplay + +export const AzureDevOpsBlockMeta = { + tags: ['version-control', 'ci-cd', 'project-management'], + url: 'https://azure.microsoft.com/products/devops', + templates: [ + { + icon: AzureIcon, + title: 'Azure DevOps build failure alerter', + prompt: + 'Build a workflow triggered when an Azure DevOps build fails that fetches the build timeline and failing-stage logs, summarizes the root cause with an agent, and posts an actionable Slack alert with a deep link to the run.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['slack'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps work-item triager', + prompt: + 'Create a workflow triggered when an Azure DevOps work item is created that classifies it by type and priority, enriches the description, assigns the right area path, and posts a summary to the team channel.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'project-management', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps release notes generator', + prompt: + 'Build a workflow that pulls the work items completed between two Azure DevOps builds, groups them by type with an agent, and writes formatted release notes to a file for the release manager.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting', 'engineering'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps pipeline health report', + prompt: + 'Create a scheduled daily workflow that lists Azure DevOps pipeline runs, computes pass rate and average duration per pipeline, logs them to a table for trend tracking, and Slacks a morning summary highlighting any regressions.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps to Linear bridge', + prompt: + 'Build a workflow that watches new Azure DevOps work items, mirrors each as a Linear issue with full context and a back-link, and keeps the team aligned across both trackers.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'project-management'], + alsoIntegrations: ['linear'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps PR review summarizer', + prompt: + 'Create a workflow triggered on a new Azure DevOps pull request that fetches the diff and linked work items, drafts a concise review summary and risk callouts with an agent, and posts it as a PR comment for reviewers.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'engineering', 'automation'], + }, + { + icon: AzureIcon, + title: 'Azure DevOps sprint burndown digest', + prompt: + 'Build a scheduled daily workflow that queries Azure DevOps work items in the active sprint, computes remaining effort and at-risk items, logs the burndown to a table, and posts a morning summary to the team Slack channel.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'project-management', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'triage-build-failure', + description: + 'Investigate a failed Azure DevOps build, pinpoint the failing stage, and summarize the root cause. Use when a pipeline run breaks.', + content: + '# Triage Build Failure\n\nDiagnose why an Azure DevOps build failed.\n\n## Steps\n1. Use Get Build Timeline for the build id to find which stage, job, or task failed.\n2. Use List Build Logs to locate the log id for the failing step, then Get Build Log to read its contents.\n3. Scan the log for the first error, the failing command, and the exit code; ignore noise after the initial failure.\n4. Optionally use Get Work Items Between Builds against the last successful build to see what changed.\n\n## Output\nReturn a concise root-cause summary: the failing stage/task, the key error line, the likely cause, and a suggested next action. Include a deep link to the run when available.', + }, + { + name: 'create-work-item', + description: + 'Create a new Azure DevOps work item (Issue, Task, or Epic) with the right fields. Use to file bugs, tasks, or features from another system.', + content: + '# Create Work Item\n\nFile a structured Azure DevOps work item.\n\n## Steps\n1. Choose the work item type: Issue, Task, or Epic, matching the request.\n2. Use Create Work Item with a clear title and an HTML or plain-text description.\n3. Set context fields where known: assignee, priority (1-4), area path, iteration path, and semicolon-separated tags.\n4. For a Task, set Activity, Remaining Work, and Completed Work; for an Epic, set Start Date and Target Date.\n\n## Output\nReturn the new work item id, type, title, state, and a link. Confirm the assignee and iteration. If a required field is missing, ask for it rather than guessing.', + }, + { + name: 'generate-release-notes', + description: + 'Compile release notes from the work items completed between two Azure DevOps builds. Use at release time to summarize what shipped.', + content: + '# Generate Release Notes\n\nProduce release notes for a build range.\n\n## Steps\n1. Identify the From Build ID (previous release) and To Build ID (current release).\n2. Use Get Work Items Between Builds to list the associated work items.\n3. For each work item, use Get Work Items Batch or Get Work Item to pull title, type, and state.\n4. Group items by type (Features/Epics, Tasks, Bugs/Issues) and write a one-line summary per item.\n\n## Output\nReturn formatted Markdown release notes grouped by category, each line linking the work item id and title. Add a short headline summary of the most user-facing changes at the top.', + }, + { + name: 'report-pipeline-health', + description: + 'Summarize recent Azure DevOps pipeline run results to surface pass rate and regressions. Use for daily or weekly engineering health reports.', + content: + '# Report Pipeline Health\n\nSummarize recent pipeline reliability.\n\n## Steps\n1. Use List Pipelines to enumerate the pipelines you care about.\n2. For each, use List Pipeline Runs to pull recent runs within your window.\n3. Compute pass rate (succeeded vs total), average duration, and the count of recent failures per pipeline.\n4. Flag pipelines whose pass rate dropped or whose duration increased noticeably versus prior runs.\n\n## Output\nReturn a per-pipeline summary table (name, pass rate, avg duration, recent failures) and a short narrative calling out regressions and any pipeline that is consistently red.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/azure_devops.ts b/apps/sim/blocks/blocks/azure_devops.ts index 52a61ed53fd..6d6369f1ca1 100644 --- a/apps/sim/blocks/blocks/azure_devops.ts +++ b/apps/sim/blocks/blocks/azure_devops.ts @@ -1,6 +1,5 @@ -import { AzureIcon } from '@/components/icons' import { AzureDevOpsBlockDisplay } from '@/blocks/blocks/azure_devops.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { AzureDevOpsBasicWorkItemType, AzureDevOpsResponse } from '@/tools/azure_devops/types' import { AZURE_DEVOPS_BASIC_WORK_ITEM_STATES } from '@/tools/azure_devops/utils' @@ -615,108 +614,3 @@ export const AzureDevOpsBlock: BlockConfig = { ], }, } - -export const AzureDevOpsBlockMeta = { - tags: ['version-control', 'ci-cd', 'project-management'], - url: 'https://azure.microsoft.com/products/devops', - templates: [ - { - icon: AzureIcon, - title: 'Azure DevOps build failure alerter', - prompt: - 'Build a workflow triggered when an Azure DevOps build fails that fetches the build timeline and failing-stage logs, summarizes the root cause with an agent, and posts an actionable Slack alert with a deep link to the run.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['slack'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps work-item triager', - prompt: - 'Create a workflow triggered when an Azure DevOps work item is created that classifies it by type and priority, enriches the description, assigns the right area path, and posts a summary to the team channel.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'project-management', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps release notes generator', - prompt: - 'Build a workflow that pulls the work items completed between two Azure DevOps builds, groups them by type with an agent, and writes formatted release notes to a file for the release manager.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting', 'engineering'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps pipeline health report', - prompt: - 'Create a scheduled daily workflow that lists Azure DevOps pipeline runs, computes pass rate and average duration per pipeline, logs them to a table for trend tracking, and Slacks a morning summary highlighting any regressions.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps to Linear bridge', - prompt: - 'Build a workflow that watches new Azure DevOps work items, mirrors each as a Linear issue with full context and a back-link, and keeps the team aligned across both trackers.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'project-management'], - alsoIntegrations: ['linear'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps PR review summarizer', - prompt: - 'Create a workflow triggered on a new Azure DevOps pull request that fetches the diff and linked work items, drafts a concise review summary and risk callouts with an agent, and posts it as a PR comment for reviewers.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'engineering', 'automation'], - }, - { - icon: AzureIcon, - title: 'Azure DevOps sprint burndown digest', - prompt: - 'Build a scheduled daily workflow that queries Azure DevOps work items in the active sprint, computes remaining effort and at-risk items, logs the burndown to a table, and posts a morning summary to the team Slack channel.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'project-management', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'triage-build-failure', - description: - 'Investigate a failed Azure DevOps build, pinpoint the failing stage, and summarize the root cause. Use when a pipeline run breaks.', - content: - '# Triage Build Failure\n\nDiagnose why an Azure DevOps build failed.\n\n## Steps\n1. Use Get Build Timeline for the build id to find which stage, job, or task failed.\n2. Use List Build Logs to locate the log id for the failing step, then Get Build Log to read its contents.\n3. Scan the log for the first error, the failing command, and the exit code; ignore noise after the initial failure.\n4. Optionally use Get Work Items Between Builds against the last successful build to see what changed.\n\n## Output\nReturn a concise root-cause summary: the failing stage/task, the key error line, the likely cause, and a suggested next action. Include a deep link to the run when available.', - }, - { - name: 'create-work-item', - description: - 'Create a new Azure DevOps work item (Issue, Task, or Epic) with the right fields. Use to file bugs, tasks, or features from another system.', - content: - '# Create Work Item\n\nFile a structured Azure DevOps work item.\n\n## Steps\n1. Choose the work item type: Issue, Task, or Epic, matching the request.\n2. Use Create Work Item with a clear title and an HTML or plain-text description.\n3. Set context fields where known: assignee, priority (1-4), area path, iteration path, and semicolon-separated tags.\n4. For a Task, set Activity, Remaining Work, and Completed Work; for an Epic, set Start Date and Target Date.\n\n## Output\nReturn the new work item id, type, title, state, and a link. Confirm the assignee and iteration. If a required field is missing, ask for it rather than guessing.', - }, - { - name: 'generate-release-notes', - description: - 'Compile release notes from the work items completed between two Azure DevOps builds. Use at release time to summarize what shipped.', - content: - '# Generate Release Notes\n\nProduce release notes for a build range.\n\n## Steps\n1. Identify the From Build ID (previous release) and To Build ID (current release).\n2. Use Get Work Items Between Builds to list the associated work items.\n3. For each work item, use Get Work Items Batch or Get Work Item to pull title, type, and state.\n4. Group items by type (Features/Epics, Tasks, Bugs/Issues) and write a one-line summary per item.\n\n## Output\nReturn formatted Markdown release notes grouped by category, each line linking the work item id and title. Add a short headline summary of the most user-facing changes at the top.', - }, - { - name: 'report-pipeline-health', - description: - 'Summarize recent Azure DevOps pipeline run results to surface pass rate and regressions. Use for daily or weekly engineering health reports.', - content: - '# Report Pipeline Health\n\nSummarize recent pipeline reliability.\n\n## Steps\n1. Use List Pipelines to enumerate the pipelines you care about.\n2. For each, use List Pipeline Runs to pull recent runs within your window.\n3. Compute pass rate (succeeded vs total), average duration, and the count of recent failures per pipeline.\n4. Flag pipelines whose pass rate dropped or whose duration increased noticeably versus prior runs.\n\n## Output\nReturn a per-pipeline summary table (name, pass rate, avg duration, recent failures) and a short narrative calling out regressions and any pipeline that is consistently red.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/box.display.ts b/apps/sim/blocks/blocks/box.display.ts index 11e442dc6f9..8af0d4c9d2d 100644 --- a/apps/sim/blocks/blocks/box.display.ts +++ b/apps/sim/blocks/blocks/box.display.ts @@ -1,6 +1,6 @@ import { BoxCompanyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const BoxBlockDisplay = { type: 'box', @@ -14,3 +14,106 @@ export const BoxBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/box', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const BoxBlockMeta = { + tags: ['cloud', 'content-management', 'e-signatures'], + url: 'https://www.box.com', + templates: [ + { + icon: BoxCompanyIcon, + title: 'Box folder onboarding', + prompt: + 'Create a workflow that watches a Box folder for new customer subfolders, applies the standard permissions matrix, seeds template files, and notifies the account owner.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + }, + { + icon: BoxCompanyIcon, + title: 'Box external-share auditor', + prompt: + 'Build a scheduled weekly workflow that lists Box shared links shared with external collaborators, flags items above the sensitivity threshold, and writes a security review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: BoxCompanyIcon, + title: 'Box compliance retention', + prompt: + 'Create a scheduled workflow that finds Box documents past retention, applies legal hold or archives them, and writes the disposition record to an audit table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: BoxCompanyIcon, + title: 'Box document Q&A agent', + prompt: + 'Build an agent that indexes Box content into a knowledge base, answers user questions with sourced citations, and deploys as a chat endpoint for internal teams.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'enterprise'], + }, + { + icon: BoxCompanyIcon, + title: 'Box to S3 backup', + prompt: + 'Create a scheduled workflow that mirrors a Box folder tree into S3 nightly with incremental sync, captures the manifest, and pings Slack on any failed files.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: BoxCompanyIcon, + title: 'Box new-vendor folder setup', + prompt: + 'Build a workflow triggered when a new vendor is created in a CRM that provisions a standard Box folder structure for that vendor, invites the right users, and writes the folder link to the vendor record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + alsoIntegrations: ['salesforce'], + }, + { + icon: BoxCompanyIcon, + title: 'Box approval-flow router', + prompt: + 'Create a workflow that watches a Box approval folder, posts a Slack request with quick-action buttons for each new doc, captures the decision, and labels the file accordingly.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'send-document-for-signature', + description: + 'Send a Box document for e-signature and confirm the request. Use for contracts, NDAs, and approval forms that need a signer.', + content: + '# Send Document For Signature\n\nKick off a Box Sign request for one or more documents.\n\n## Steps\n1. Identify the Box file id(s) to sign (use Search or List Folder Items if you only have a name).\n2. Use Create Sign Request with the source file ids and the primary signer email; set the signer role (signer, approver, or final copy reader).\n3. Add a clear email subject and message, and add any additional signers as a JSON array of email/role objects.\n4. Optionally set a destination folder for the signed copy, days valid, and reminders.\n\n## Output\nReturn the sign request id, status, signer list, and the prepare/sign URL. Tell the user the request was sent and how to track it. If a file id cannot be resolved, ask for clarification.', + }, + { + name: 'track-signature-status', + description: + 'Check the status of Box Sign requests and follow up on pending signers. Use to monitor outstanding e-signature requests.', + content: + '# Track Signature Status\n\nReport on outstanding and completed Box Sign requests.\n\n## Steps\n1. Use List Sign Requests to retrieve recent requests, paging with the marker when needed.\n2. For a specific request, use Get Sign Request with the sign request id to read per-signer status.\n3. Identify requests that are still pending versus signed, declined, or expired.\n4. For stalled requests, use Resend Sign Request to nudge signers, or Cancel Sign Request if it is no longer needed.\n\n## Output\nReturn a status summary per request: name, overall status, which signers have signed, and which are outstanding. Recommend resend or cancel actions for stale requests.', + }, + { + name: 'organize-files-into-folder', + description: + 'Upload files into a structured Box folder, creating folders as needed. Use to file documents into a standard organized layout.', + content: + '# Organize Files Into Folder\n\nPlace documents into the correct Box folder structure.\n\n## Steps\n1. Determine the destination. Use List Folder Items or Search to find an existing folder, or Create Folder under the right parent (use "0" for root) if it does not exist.\n2. Upload each file with Upload File, setting the parent folder id and an explicit file name when needed.\n3. To reorganize existing files, use Update File to rename, move (set Move to Folder ID), tag, or describe them.\n4. Use Copy File when a document must live in more than one folder.\n\n## Output\nReturn the created folder id (if any) and a list of the files placed, each with its id, name, and final folder. Confirm the resulting structure.', + }, + { + name: 'search-box-content', + description: + 'Find files and folders in Box matching a query and return their details. Use to locate documents before acting on them.', + content: + '# Search Box Content\n\nLocate documents in Box.\n\n## Steps\n1. Use Search with the query string. Narrow with optional filters: ancestor folder id, file extensions (e.g. pdf,docx), and content type (file, folder, or web link).\n2. Page through results with limit and offset if there are many matches.\n3. For promising hits, use Get File Info to confirm name, size, owner, and modified date.\n\n## Output\nReturn the matching items with id, name, type, owner, and last-modified date. If the query is ambiguous or returns too many results, suggest a tighter query or folder scope.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/box.ts b/apps/sim/blocks/blocks/box.ts index e7066f2b5a3..608ba8b8095 100644 --- a/apps/sim/blocks/blocks/box.ts +++ b/apps/sim/blocks/blocks/box.ts @@ -1,7 +1,6 @@ -import { BoxCompanyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { BoxBlockDisplay } from '@/blocks/blocks/box.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' @@ -590,106 +589,3 @@ export const BoxBlock: BlockConfig = { nextMarker: 'string', }, } - -export const BoxBlockMeta = { - tags: ['cloud', 'content-management', 'e-signatures'], - url: 'https://www.box.com', - templates: [ - { - icon: BoxCompanyIcon, - title: 'Box folder onboarding', - prompt: - 'Create a workflow that watches a Box folder for new customer subfolders, applies the standard permissions matrix, seeds template files, and notifies the account owner.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - }, - { - icon: BoxCompanyIcon, - title: 'Box external-share auditor', - prompt: - 'Build a scheduled weekly workflow that lists Box shared links shared with external collaborators, flags items above the sensitivity threshold, and writes a security review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: BoxCompanyIcon, - title: 'Box compliance retention', - prompt: - 'Create a scheduled workflow that finds Box documents past retention, applies legal hold or archives them, and writes the disposition record to an audit table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: BoxCompanyIcon, - title: 'Box document Q&A agent', - prompt: - 'Build an agent that indexes Box content into a knowledge base, answers user questions with sourced citations, and deploys as a chat endpoint for internal teams.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'enterprise'], - }, - { - icon: BoxCompanyIcon, - title: 'Box to S3 backup', - prompt: - 'Create a scheduled workflow that mirrors a Box folder tree into S3 nightly with incremental sync, captures the manifest, and pings Slack on any failed files.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: BoxCompanyIcon, - title: 'Box new-vendor folder setup', - prompt: - 'Build a workflow triggered when a new vendor is created in a CRM that provisions a standard Box folder structure for that vendor, invites the right users, and writes the folder link to the vendor record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - alsoIntegrations: ['salesforce'], - }, - { - icon: BoxCompanyIcon, - title: 'Box approval-flow router', - prompt: - 'Create a workflow that watches a Box approval folder, posts a Slack request with quick-action buttons for each new doc, captures the decision, and labels the file accordingly.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'send-document-for-signature', - description: - 'Send a Box document for e-signature and confirm the request. Use for contracts, NDAs, and approval forms that need a signer.', - content: - '# Send Document For Signature\n\nKick off a Box Sign request for one or more documents.\n\n## Steps\n1. Identify the Box file id(s) to sign (use Search or List Folder Items if you only have a name).\n2. Use Create Sign Request with the source file ids and the primary signer email; set the signer role (signer, approver, or final copy reader).\n3. Add a clear email subject and message, and add any additional signers as a JSON array of email/role objects.\n4. Optionally set a destination folder for the signed copy, days valid, and reminders.\n\n## Output\nReturn the sign request id, status, signer list, and the prepare/sign URL. Tell the user the request was sent and how to track it. If a file id cannot be resolved, ask for clarification.', - }, - { - name: 'track-signature-status', - description: - 'Check the status of Box Sign requests and follow up on pending signers. Use to monitor outstanding e-signature requests.', - content: - '# Track Signature Status\n\nReport on outstanding and completed Box Sign requests.\n\n## Steps\n1. Use List Sign Requests to retrieve recent requests, paging with the marker when needed.\n2. For a specific request, use Get Sign Request with the sign request id to read per-signer status.\n3. Identify requests that are still pending versus signed, declined, or expired.\n4. For stalled requests, use Resend Sign Request to nudge signers, or Cancel Sign Request if it is no longer needed.\n\n## Output\nReturn a status summary per request: name, overall status, which signers have signed, and which are outstanding. Recommend resend or cancel actions for stale requests.', - }, - { - name: 'organize-files-into-folder', - description: - 'Upload files into a structured Box folder, creating folders as needed. Use to file documents into a standard organized layout.', - content: - '# Organize Files Into Folder\n\nPlace documents into the correct Box folder structure.\n\n## Steps\n1. Determine the destination. Use List Folder Items or Search to find an existing folder, or Create Folder under the right parent (use "0" for root) if it does not exist.\n2. Upload each file with Upload File, setting the parent folder id and an explicit file name when needed.\n3. To reorganize existing files, use Update File to rename, move (set Move to Folder ID), tag, or describe them.\n4. Use Copy File when a document must live in more than one folder.\n\n## Output\nReturn the created folder id (if any) and a list of the files placed, each with its id, name, and final folder. Confirm the resulting structure.', - }, - { - name: 'search-box-content', - description: - 'Find files and folders in Box matching a query and return their details. Use to locate documents before acting on them.', - content: - '# Search Box Content\n\nLocate documents in Box.\n\n## Steps\n1. Use Search with the query string. Narrow with optional filters: ancestor folder id, file extensions (e.g. pdf,docx), and content type (file, folder, or web link).\n2. Page through results with limit and offset if there are many matches.\n3. For promising hits, use Get File Info to confirm name, size, owner, and modified date.\n\n## Output\nReturn the matching items with id, name, type, owner, and last-modified date. If the query is ambiguous or returns too many results, suggest a tighter query or folder scope.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/brandfetch.display.ts b/apps/sim/blocks/blocks/brandfetch.display.ts index e66d971eaaa..3fedbf65feb 100644 --- a/apps/sim/blocks/blocks/brandfetch.display.ts +++ b/apps/sim/blocks/blocks/brandfetch.display.ts @@ -1,6 +1,6 @@ import { BrandfetchIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const BrandfetchBlockDisplay = { type: 'brandfetch', @@ -14,3 +14,100 @@ export const BrandfetchBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/brandfetch', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const BrandfetchBlockMeta = { + tags: ['enrichment', 'marketing'], + url: 'https://brandfetch.com', + templates: [ + { + icon: BrandfetchIcon, + title: 'Brandfetch logo enricher', + prompt: + 'Build a workflow that pulls company logos and brand colors from Brandfetch for each lead in a table, writes the asset URLs back, and uses them in personalized outreach.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch CRM enrichment', + prompt: + 'Create a workflow that watches new HubSpot accounts, pulls Brandfetch data for each company domain, and writes brand colors and logo URLs to the company record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch deck personalizer', + prompt: + 'Build a workflow that on a new opportunity pulls the prospect’s brand assets from Brandfetch, generates a personalized pitch deck with their logo and colors, and attaches it.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'content'], + alsoIntegrations: ['salesforce', 'gamma'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch competitor logo collector', + prompt: + 'Create a workflow that takes a list of competitor domains, pulls Brandfetch brand assets for each, and writes a competitive matrix file the marketing team can use.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch customer-portal personalizer', + prompt: + 'Build a workflow that auto-themes a customer portal experience using Brandfetch brand colors for each new enterprise account.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enterprise'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch outbound enricher', + prompt: + 'Create a workflow that enriches outbound prospect data with Brandfetch logos and brand metadata, and writes the enriched contact record to Email Bison for personalization.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: BrandfetchIcon, + title: 'Brandfetch contract personalizer', + prompt: + 'Build a workflow that pulls Brandfetch assets for the counterparty on a DocuSign envelope, embeds the right logo in the cover sheet, and sends.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'legal'], + alsoIntegrations: ['docusign'], + }, + ], + skills: [ + { + name: 'enrich-company-by-domain', + description: + 'Look up a company by domain and return its brand assets and firmographics. Use to enrich a CRM record, lead, or account with logo, colors, and company data.', + content: + '# Enrich Company By Domain\n\nFetch brand and company data for a known domain.\n\n## Steps\n1. Use Get Brand with the company domain as the identifier (e.g. nike.com). A stock ticker, ISIN, or crypto symbol also works.\n2. Read the returned logos, colors, fonts, links, description, and company firmographics.\n3. Pick the best logo for the use case (prefer a transparent or themed variant) and the primary brand color.\n\n## Output\nReturn a tidy record: company name, domain, description, primary logo URL, primary brand color hex, social links, and key firmographics. If the quality score is low or the brand is unclaimed, note that the data may be incomplete.', + }, + { + name: 'resolve-brand-by-name', + description: + 'Search for a brand by name to find its domain and logo when you only have the company name. Use to disambiguate or resolve a domain before deeper enrichment.', + content: + '# Resolve Brand By Name\n\nFind a brand when you only know its name.\n\n## Steps\n1. Use Search Brands with the company name (e.g. "Nike").\n2. Review the results array; each entry has a brand name, domain, and icon.\n3. Choose the best match by exact name and most likely official domain.\n4. Optionally follow up with Get Brand on the chosen domain for full assets and firmographics.\n\n## Output\nReturn the resolved brand name, domain, and icon URL. If several plausible matches exist, list the top candidates with their domains so the user can confirm.', + }, + { + name: 'collect-brand-assets-for-personalization', + description: + 'Gather a prospect or customer brand kit (logo, colors, fonts) for personalizing decks, emails, or portals. Use ahead of personalized outreach or design work.', + content: + '# Collect Brand Assets For Personalization\n\nBuild a usable brand kit for a target company.\n\n## Steps\n1. Resolve the company domain (use Search Brands first if you only have a name).\n2. Use Get Brand to retrieve logos, colors, and fonts.\n3. Select assets fit for purpose: a high-contrast logo for a deck cover, the primary and secondary colors, and the brand font names.\n\n## Output\nReturn a brand kit object: logo URLs by theme (light/dark), an ordered color palette with hex values, and font names. Note any missing asset so the design step can fall back to a neutral default.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/brandfetch.ts b/apps/sim/blocks/blocks/brandfetch.ts index 75896a6a21c..7ce9f6b5b4b 100644 --- a/apps/sim/blocks/blocks/brandfetch.ts +++ b/apps/sim/blocks/blocks/brandfetch.ts @@ -1,6 +1,5 @@ -import { BrandfetchIcon } from '@/components/icons' import { BrandfetchBlockDisplay } from '@/blocks/blocks/brandfetch.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { BrandfetchGetBrandResponse, BrandfetchSearchResponse } from '@/tools/brandfetch/types' @@ -89,100 +88,3 @@ export const BrandfetchBlock: BlockConfig = { externalMemo: { type: 'string', description: 'External memo of the transfer' }, }, } - -export const BrexBlockMeta = { - tags: ['payments'], - url: 'https://www.brex.com', - templates: [ - { - icon: BrexIcon, - title: 'Brex receipt auto-attach', - prompt: - 'Build a workflow that takes an uploaded receipt file and sends it to Brex with the Match Receipt operation so Brex automatically pairs it with the right card expense.', - modules: ['workflows', 'files'], - category: 'operations', - tags: ['automation'], - }, - { - icon: BrexIcon, - title: 'Brex daily expense digest', - prompt: - 'Build a scheduled workflow that runs every weekday morning, lists Brex expenses settled in the last 24 hours, summarizes total spend by merchant category, and posts the digest to a Slack channel.', - modules: ['workflows', 'scheduled'], - category: 'operations', - tags: ['automation'], - alsoIntegrations: ['slack'], - }, - { - icon: BrexIcon, - title: 'Brex memo enforcer', - prompt: - 'Build a scheduled workflow that lists approved Brex expenses, finds ones missing a memo, has an agent draft a memo from the merchant and amount details, and updates each expense with the drafted memo.', - modules: ['agent', 'workflows', 'scheduled'], - category: 'operations', - tags: ['automation'], - }, - { - icon: BrexIcon, - title: 'Brex spend anomaly alert', - prompt: - 'Build a scheduled workflow that lists recent Brex card transactions, flags any transaction above a configurable threshold, and emails the finance team a report of flagged transactions with merchant details.', - modules: ['workflows', 'scheduled'], - category: 'operations', - tags: ['automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: BrexIcon, - title: 'Brex cash balance monitor', - prompt: - 'Build a scheduled workflow that checks Brex cash account balances every morning and sends a Slack alert when the available balance of any account drops below a set threshold.', - modules: ['workflows', 'scheduled'], - category: 'operations', - tags: ['automation'], - alsoIntegrations: ['slack'], - }, - { - icon: BrexIcon, - title: 'Brex budget utilization report', - prompt: - 'Build a weekly workflow that lists Brex budgets and spend limits, computes utilization for each budget from its amount and current period balance, stores the results in a table, and emails a summary report.', - modules: ['workflows', 'scheduled', 'tables'], - category: 'operations', - tags: ['automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: BrexIcon, - title: 'Brex team directory assistant', - prompt: - 'Build an agent that answers questions about company spend and team structure by looking up Brex users, departments, locations, and their expenses on demand.', - modules: ['agent'], - category: 'productivity', - tags: ['automation'], - }, - { - icon: BrexIcon, - title: 'Brex vendor payment tracker', - prompt: - 'Build a workflow that lists Brex vendors and recent transfers, reconciles transfer statuses against expected payments stored in a table, and flags any failed or delayed payments.', - modules: ['workflows', 'tables'], - category: 'operations', - tags: ['automation'], - }, - ], - skills: [ - { - name: 'spend-report', - description: - 'Summarize Brex spend over a period, broken down by category, merchant, and user.', - content: - '# Spend Report\n\nBuild a clear summary of company spend from Brex expenses.\n\n## Steps\n1. List expenses filtered to the requested period using the purchased-at date filters.\n2. Group expenses by merchant category, merchant, and user, totaling billing amounts (amounts are in cents).\n3. Highlight the largest expenses and any with OUT_OF_POLICY status.\n\n## Output\nReturn total spend, a breakdown by category and merchant, the top spenders, and any flagged out-of-policy expenses with dashboard links.', - }, - { - name: 'attach-receipt', - description: 'Upload a receipt file and attach it to the right Brex expense.', - content: - '# Attach a Receipt\n\nGet a receipt onto the correct Brex expense.\n\n## Steps\n1. If the target expense is known, use Upload Receipt with the expense ID.\n2. If not, use Match Receipt so Brex pairs the receipt with the right expense automatically.\n3. Confirm the upload succeeded and capture the receipt ID.\n\n## Output\nReturn the receipt ID, the receipt name, and the expense it was attached to (or note that Brex is matching it automatically).', - }, - { - name: 'memo-cleanup', - description: 'Find Brex expenses missing memos and fill them in from merchant details.', - content: - '# Memo Cleanup\n\nKeep expense memos complete for accounting.\n\n## Steps\n1. List recent expenses and find ones with an empty memo.\n2. For each, draft a short memo from the merchant descriptor, category, and amount.\n3. Update each expense with the drafted memo using Update Expense Memo.\n\n## Output\nReturn the list of expenses updated, each with its new memo, and any expenses that could not be updated.', - }, - { - name: 'budget-utilization', - description: 'Report utilization for Brex budgets and spend limits.', - content: - '# Budget Utilization\n\nShow how much of each budget and spend limit has been used.\n\n## Steps\n1. List budgets and capture each amount and status.\n2. List spend limits and capture each current period balance.\n3. Compute utilization where both an amount and a balance are available (amounts are in cents).\n\n## Output\nReturn each budget and spend limit with its owner, period, amount, and utilization, flagging any that are near or over their limit.', - }, - { - name: 'cash-balance-check', - description: 'Check Brex cash account balances and recent account activity.', - content: - '# Cash Balance Check\n\nGive a quick read on company cash in Brex.\n\n## Steps\n1. List cash accounts and capture current and available balances (amounts are in cents).\n2. For the primary account, list recent cash transactions.\n3. Note any unusually large recent movements.\n\n## Output\nReturn each account with its balances, the most recent transactions for the primary account, and any large movements worth a look.', - }, - { - name: 'statement-reconciliation', - description: 'Reconcile a Brex card statement period against its settled transactions.', - content: - '# Statement Reconciliation\n\nTie a card statement back to its underlying transactions.\n\n## Steps\n1. List card statements and pick the period to reconcile.\n2. List card transactions posted within that period using the posted-at filter.\n3. Compare transaction totals to the statement start and end balances and flag gaps.\n\n## Output\nReturn the statement period, its balances, the transaction total for the period, and any discrepancy that needs review.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/brightdata.display.ts b/apps/sim/blocks/blocks/brightdata.display.ts index 372d8f7d6fe..421e9cdc6f4 100644 --- a/apps/sim/blocks/blocks/brightdata.display.ts +++ b/apps/sim/blocks/blocks/brightdata.display.ts @@ -1,6 +1,6 @@ import { BrightDataIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const BrightDataBlockDisplay = { type: 'brightdata', @@ -14,3 +14,106 @@ export const BrightDataBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/brightdata', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const BrightDataBlockMeta = { + tags: ['web-scraping', 'automation'], + url: 'https://brightdata.com', + templates: [ + { + icon: BrightDataIcon, + title: 'Bright Data scraper orchestrator', + prompt: + 'Build a workflow that uses Bright Data unblockers to scrape geo-restricted competitor pages, captures the data daily, and writes to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['research', 'monitoring'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data competitor pricing', + prompt: + 'Create a workflow that uses Bright Data to track competitor pricing across regions, captures geo-priced data, and posts notable price changes to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data SERP collector', + prompt: + 'Build a scheduled workflow that uses Bright Data SERP scraping to capture rankings for tracked keywords across regions, and writes the results to an SEO scoreboard.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data review collector', + prompt: + 'Create a workflow that uses Bright Data to scrape product reviews across geos, classifies sentiment, and writes findings into a product-feedback table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'support', + tags: ['product', 'analysis'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data localization checker', + prompt: + 'Build a scheduled workflow that uses Bright Data geo-targeted browsing to verify the brand’s site renders correctly in tracked regions, and writes findings to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data brand mention search', + prompt: + 'Create a workflow that uses Bright Data to scrape mentions of the brand across global forums and review sites, writes mentions into a tracking table, and pings on spikes.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: BrightDataIcon, + title: 'Bright Data inventory tracker', + prompt: + 'Build a scheduled workflow that uses Bright Data to track competitor stock availability across regions, writes the data, and pings on low-stock signals indicating shifts.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'research'], + }, + ], + skills: [ + { + name: 'scrape-page-content', + description: + 'Fetch the content of a single web page through Bright Data Web Unlocker, bypassing bot blocks and geo-restrictions. Use to read a page an agent cannot otherwise access.', + content: + '# Scrape Page Content\n\nRetrieve a page that is normally blocked or geo-restricted.\n\n## Steps\n1. Use Scrape URL with the target URL and your unlocker zone (e.g. web_unlocker1).\n2. Choose the format: Raw HTML for full markup, or JSON for a parsed response.\n3. Set the Country code when the page differs by region.\n4. Run it and read the returned content and HTTP status code.\n\n## Output\nReturn the cleaned page content (text or relevant HTML) and the status code. If the status indicates a block or error, report it and suggest a different zone or country rather than returning empty content.', + }, + { + name: 'search-the-web', + description: + 'Run a search-engine query through Bright Data SERP API and return ranked results. Use for keyword research, competitive monitoring, or grounding an answer in fresh results.', + content: + '# Search The Web\n\nGet structured search results for a query.\n\n## Steps\n1. Use SERP Search with the query and your SERP zone.\n2. Pick the search engine (Google, Bing, DuckDuckGo, or Yandex) and set country/language for localized results.\n3. Set the number of results to the amount you need.\n4. Read the results array (title, URL, snippet, rank).\n\n## Output\nReturn the ranked results as a list with title, URL, and snippet. Summarize the top findings for the user, and note the engine, country, and query used so the result is reproducible.', + }, + { + name: 'discover-pages-by-intent', + description: + 'Find web pages that match a described intent using Bright Data Discover, optionally pulling page content. Use to gather sources on a topic without crafting exact queries.', + content: + '# Discover Pages By Intent\n\nFind relevant pages from a natural-language description.\n\n## Steps\n1. Use Discover with a search query and an Intent describing what you actually want (e.g. "official pricing pages and recent change notes").\n2. Set the number of results, country, and language as needed.\n3. Enable Include Page Content and choose Markdown or JSON when you want the page bodies, not just links.\n\n## Output\nReturn the discovered pages ranked by relevance with URL, title, and (if requested) extracted content. Summarize what was found and flag any low-relevance results so they can be filtered out.', + }, + { + name: 'run-dataset-scraper', + description: + 'Trigger a Bright Data pre-built dataset scraper for structured extraction across many URLs and retrieve the results. Use for bulk structured data from sites like e-commerce or social.', + content: + '# Run Dataset Scraper\n\nExtract structured records across many URLs with a pre-built scraper.\n\n## Steps\n1. Identify the dataset scraper id for the target site (e.g. gd_...).\n2. For small batches (up to 20 URLs), use Sync Scrape to get results back inline; choose JSON, NDJSON, or CSV.\n3. For larger jobs, use Scrape Dataset, which returns a snapshot id.\n4. Poll Snapshot Status until it is ready, then use Download Snapshot to fetch the data. Use Cancel Snapshot to abort a job that is no longer needed.\n\n## Output\nReturn the structured records (or the snapshot id and status for async jobs). For async runs, report progress and only return data once the snapshot is complete.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/brightdata.ts b/apps/sim/blocks/blocks/brightdata.ts index aebb5cfa086..aeef5779801 100644 --- a/apps/sim/blocks/blocks/brightdata.ts +++ b/apps/sim/blocks/blocks/brightdata.ts @@ -1,6 +1,5 @@ -import { BrightDataIcon } from '@/components/icons' import { BrightDataBlockDisplay } from '@/blocks/blocks/brightdata.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { BrightDataResponse } from '@/tools/brightdata/types' @@ -335,106 +334,3 @@ export const BrightDataBlock: BlockConfig = { cancelled: { type: 'boolean', description: 'Whether cancellation was successful' }, }, } - -export const BrightDataBlockMeta = { - tags: ['web-scraping', 'automation'], - url: 'https://brightdata.com', - templates: [ - { - icon: BrightDataIcon, - title: 'Bright Data scraper orchestrator', - prompt: - 'Build a workflow that uses Bright Data unblockers to scrape geo-restricted competitor pages, captures the data daily, and writes to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['research', 'monitoring'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data competitor pricing', - prompt: - 'Create a workflow that uses Bright Data to track competitor pricing across regions, captures geo-priced data, and posts notable price changes to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data SERP collector', - prompt: - 'Build a scheduled workflow that uses Bright Data SERP scraping to capture rankings for tracked keywords across regions, and writes the results to an SEO scoreboard.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data review collector', - prompt: - 'Create a workflow that uses Bright Data to scrape product reviews across geos, classifies sentiment, and writes findings into a product-feedback table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'support', - tags: ['product', 'analysis'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data localization checker', - prompt: - 'Build a scheduled workflow that uses Bright Data geo-targeted browsing to verify the brand’s site renders correctly in tracked regions, and writes findings to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data brand mention search', - prompt: - 'Create a workflow that uses Bright Data to scrape mentions of the brand across global forums and review sites, writes mentions into a tracking table, and pings on spikes.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: BrightDataIcon, - title: 'Bright Data inventory tracker', - prompt: - 'Build a scheduled workflow that uses Bright Data to track competitor stock availability across regions, writes the data, and pings on low-stock signals indicating shifts.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'research'], - }, - ], - skills: [ - { - name: 'scrape-page-content', - description: - 'Fetch the content of a single web page through Bright Data Web Unlocker, bypassing bot blocks and geo-restrictions. Use to read a page an agent cannot otherwise access.', - content: - '# Scrape Page Content\n\nRetrieve a page that is normally blocked or geo-restricted.\n\n## Steps\n1. Use Scrape URL with the target URL and your unlocker zone (e.g. web_unlocker1).\n2. Choose the format: Raw HTML for full markup, or JSON for a parsed response.\n3. Set the Country code when the page differs by region.\n4. Run it and read the returned content and HTTP status code.\n\n## Output\nReturn the cleaned page content (text or relevant HTML) and the status code. If the status indicates a block or error, report it and suggest a different zone or country rather than returning empty content.', - }, - { - name: 'search-the-web', - description: - 'Run a search-engine query through Bright Data SERP API and return ranked results. Use for keyword research, competitive monitoring, or grounding an answer in fresh results.', - content: - '# Search The Web\n\nGet structured search results for a query.\n\n## Steps\n1. Use SERP Search with the query and your SERP zone.\n2. Pick the search engine (Google, Bing, DuckDuckGo, or Yandex) and set country/language for localized results.\n3. Set the number of results to the amount you need.\n4. Read the results array (title, URL, snippet, rank).\n\n## Output\nReturn the ranked results as a list with title, URL, and snippet. Summarize the top findings for the user, and note the engine, country, and query used so the result is reproducible.', - }, - { - name: 'discover-pages-by-intent', - description: - 'Find web pages that match a described intent using Bright Data Discover, optionally pulling page content. Use to gather sources on a topic without crafting exact queries.', - content: - '# Discover Pages By Intent\n\nFind relevant pages from a natural-language description.\n\n## Steps\n1. Use Discover with a search query and an Intent describing what you actually want (e.g. "official pricing pages and recent change notes").\n2. Set the number of results, country, and language as needed.\n3. Enable Include Page Content and choose Markdown or JSON when you want the page bodies, not just links.\n\n## Output\nReturn the discovered pages ranked by relevance with URL, title, and (if requested) extracted content. Summarize what was found and flag any low-relevance results so they can be filtered out.', - }, - { - name: 'run-dataset-scraper', - description: - 'Trigger a Bright Data pre-built dataset scraper for structured extraction across many URLs and retrieve the results. Use for bulk structured data from sites like e-commerce or social.', - content: - '# Run Dataset Scraper\n\nExtract structured records across many URLs with a pre-built scraper.\n\n## Steps\n1. Identify the dataset scraper id for the target site (e.g. gd_...).\n2. For small batches (up to 20 URLs), use Sync Scrape to get results back inline; choose JSON, NDJSON, or CSV.\n3. For larger jobs, use Scrape Dataset, which returns a snapshot id.\n4. Poll Snapshot Status until it is ready, then use Download Snapshot to fetch the data. Use Cancel Snapshot to abort a job that is no longer needed.\n\n## Output\nReturn the structured records (or the snapshot id and status for async jobs). For async runs, report progress and only return data once the snapshot is complete.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/browser_use.display.ts b/apps/sim/blocks/blocks/browser_use.display.ts index 098b3550779..996105dcf86 100644 --- a/apps/sim/blocks/blocks/browser_use.display.ts +++ b/apps/sim/blocks/blocks/browser_use.display.ts @@ -1,6 +1,6 @@ import { BrowserUseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const BrowserUseBlockDisplay = { type: 'browser_use', @@ -14,3 +14,100 @@ export const BrowserUseBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/browser_use', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const BrowserUseBlockMeta = { + tags: ['web-scraping', 'automation', 'agentic'], + url: 'https://browser-use.com', + templates: [ + { + icon: BrowserUseIcon, + title: 'Browser Use form filler', + prompt: + 'Build a workflow that uses Browser Use to automate filling complex web forms — vendor portals, compliance questionnaires — with data pulled from a table, and captures screenshots to a file as audit trail.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use competitor pricing scraper', + prompt: + 'Create a scheduled workflow that runs Browser Use weekly to navigate competitor pricing pages, captures the current plans and prices, diffs against last week, and posts changes to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['research', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use legacy ERP scraper', + prompt: + 'Create a workflow that uses Browser Use to log into a legacy ERP without an API, exports daily reports, parses them into a table, and posts a summary to Slack so old systems still feed modern ops.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use + Stagehand cross-tool QA', + prompt: + 'Create a workflow that uses Browser Use and Stagehand together to run scripted browser flows against staging, captures screenshots, and writes a regression report.', + modules: ['files', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + alsoIntegrations: ['stagehand'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use + Stagehand expense-portal grabber', + prompt: + 'Build a workflow that uses Browser Use and Stagehand to automate expense-portal data pulls from suppliers, captures the structured data, and writes to a finance table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['stagehand'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use invoice-portal collector', + prompt: + 'Create a workflow that uses Browser Use to log into vendor invoice portals weekly, downloads outstanding invoices, and writes the metadata to a finance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + }, + { + icon: BrowserUseIcon, + title: 'Browser Use review-site monitor', + prompt: + 'Build a workflow that uses Browser Use to scrape G2 and Capterra review pages for brand mentions, classifies sentiment, and writes notable reviews to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + ], + skills: [ + { + name: 'automate-web-task', + description: + 'Drive a browser agent to complete a multi-step task on a website, like navigating, clicking, and submitting. Use when a site has no API and a human would normally do the clicks.', + content: + '# Automate Web Task\n\nHave the browser agent perform a goal-oriented task on the web.\n\n## Steps\n1. Write a clear, step-by-step Task describing the goal and any success condition (e.g. "log in, open Billing, download the latest invoice").\n2. Set the Start URL so the agent begins on the right page.\n3. Put any credentials or sensitive inputs in Variables (Secrets) and reference them in the task by name rather than pasting them inline.\n4. Restrict Allowed Domains to keep the agent on the intended site, and raise Max Steps for longer flows.\n\n## Output\nReturn whether the task succeeded, the final output, and the share URL for the recorded session so the run can be audited. If the agent gets stuck, report the last step and what blocked it.', + }, + { + name: 'extract-structured-data-from-site', + description: + 'Use a browser agent to navigate a site and return data in a defined JSON schema. Use to pull structured records (prices, listings, table rows) from pages without an API.', + content: + '# Extract Structured Data From Site\n\nNavigate a website and return structured data.\n\n## Steps\n1. Write a Task that tells the agent what to find and where (e.g. "go to the pricing page and collect every plan name and monthly price").\n2. Set the Start URL and limit Allowed Domains to the target site.\n3. Provide a Structured Output Schema (stringified JSON schema) describing the exact fields you want back.\n4. Run it; the agent fills the schema from what it observes on the page.\n\n## Output\nReturn the data as objects matching the provided schema. Confirm each field was actually found on the page; if a field could not be located, leave it null and note it rather than fabricating a value.', + }, + { + name: 'fill-and-submit-form', + description: + 'Have a browser agent fill out and submit a web form using supplied field values. Use for vendor portals, questionnaires, or applications that have no API.', + content: + '# Fill And Submit Form\n\nComplete a web form end to end.\n\n## Steps\n1. Describe the form and the mapping of values to fields in the Task (e.g. "fill the contact form: name, company, message, then submit").\n2. Set the Start URL to the form page and constrain Allowed Domains.\n3. Pass any private values through Variables (Secrets) so they are injected securely.\n4. Ask the agent to confirm the submission succeeded (look for a success message or confirmation page) before finishing.\n\n## Output\nReturn whether the form submitted successfully, any confirmation text or reference number shown, and the session share URL as an audit trail. If a required field was missing or validation failed, report which field and why.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/browser_use.ts b/apps/sim/blocks/blocks/browser_use.ts index 3e5e908edfd..51dc137fc9b 100644 --- a/apps/sim/blocks/blocks/browser_use.ts +++ b/apps/sim/blocks/blocks/browser_use.ts @@ -1,6 +1,5 @@ -import { BrowserUseIcon } from '@/components/icons' import { BrowserUseBlockDisplay } from '@/blocks/blocks/browser_use.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { BrowserUseResponse } from '@/tools/browser_use/types' export const BrowserUseBlock: BlockConfig = { @@ -203,100 +202,3 @@ export const BrowserUseBlock: BlockConfig = { sessionId: { type: 'string', description: 'Browser Use session identifier' }, }, } - -export const BrowserUseBlockMeta = { - tags: ['web-scraping', 'automation', 'agentic'], - url: 'https://browser-use.com', - templates: [ - { - icon: BrowserUseIcon, - title: 'Browser Use form filler', - prompt: - 'Build a workflow that uses Browser Use to automate filling complex web forms — vendor portals, compliance questionnaires — with data pulled from a table, and captures screenshots to a file as audit trail.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use competitor pricing scraper', - prompt: - 'Create a scheduled workflow that runs Browser Use weekly to navigate competitor pricing pages, captures the current plans and prices, diffs against last week, and posts changes to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['research', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use legacy ERP scraper', - prompt: - 'Create a workflow that uses Browser Use to log into a legacy ERP without an API, exports daily reports, parses them into a table, and posts a summary to Slack so old systems still feed modern ops.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use + Stagehand cross-tool QA', - prompt: - 'Create a workflow that uses Browser Use and Stagehand together to run scripted browser flows against staging, captures screenshots, and writes a regression report.', - modules: ['files', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - alsoIntegrations: ['stagehand'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use + Stagehand expense-portal grabber', - prompt: - 'Build a workflow that uses Browser Use and Stagehand to automate expense-portal data pulls from suppliers, captures the structured data, and writes to a finance table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['stagehand'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use invoice-portal collector', - prompt: - 'Create a workflow that uses Browser Use to log into vendor invoice portals weekly, downloads outstanding invoices, and writes the metadata to a finance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - }, - { - icon: BrowserUseIcon, - title: 'Browser Use review-site monitor', - prompt: - 'Build a workflow that uses Browser Use to scrape G2 and Capterra review pages for brand mentions, classifies sentiment, and writes notable reviews to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - ], - skills: [ - { - name: 'automate-web-task', - description: - 'Drive a browser agent to complete a multi-step task on a website, like navigating, clicking, and submitting. Use when a site has no API and a human would normally do the clicks.', - content: - '# Automate Web Task\n\nHave the browser agent perform a goal-oriented task on the web.\n\n## Steps\n1. Write a clear, step-by-step Task describing the goal and any success condition (e.g. "log in, open Billing, download the latest invoice").\n2. Set the Start URL so the agent begins on the right page.\n3. Put any credentials or sensitive inputs in Variables (Secrets) and reference them in the task by name rather than pasting them inline.\n4. Restrict Allowed Domains to keep the agent on the intended site, and raise Max Steps for longer flows.\n\n## Output\nReturn whether the task succeeded, the final output, and the share URL for the recorded session so the run can be audited. If the agent gets stuck, report the last step and what blocked it.', - }, - { - name: 'extract-structured-data-from-site', - description: - 'Use a browser agent to navigate a site and return data in a defined JSON schema. Use to pull structured records (prices, listings, table rows) from pages without an API.', - content: - '# Extract Structured Data From Site\n\nNavigate a website and return structured data.\n\n## Steps\n1. Write a Task that tells the agent what to find and where (e.g. "go to the pricing page and collect every plan name and monthly price").\n2. Set the Start URL and limit Allowed Domains to the target site.\n3. Provide a Structured Output Schema (stringified JSON schema) describing the exact fields you want back.\n4. Run it; the agent fills the schema from what it observes on the page.\n\n## Output\nReturn the data as objects matching the provided schema. Confirm each field was actually found on the page; if a field could not be located, leave it null and note it rather than fabricating a value.', - }, - { - name: 'fill-and-submit-form', - description: - 'Have a browser agent fill out and submit a web form using supplied field values. Use for vendor portals, questionnaires, or applications that have no API.', - content: - '# Fill And Submit Form\n\nComplete a web form end to end.\n\n## Steps\n1. Describe the form and the mapping of values to fields in the Task (e.g. "fill the contact form: name, company, message, then submit").\n2. Set the Start URL to the form page and constrain Allowed Domains.\n3. Pass any private values through Variables (Secrets) so they are injected securely.\n4. Ask the agent to confirm the submission succeeded (look for a success message or confirmation page) before finishing.\n\n## Output\nReturn whether the form submitted successfully, any confirmation text or reference number shown, and the session share URL as an audit trail. If a required field was missing or validation failed, report which field and why.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/calcom.display.ts b/apps/sim/blocks/blocks/calcom.display.ts index ed50519a4ef..0e719127389 100644 --- a/apps/sim/blocks/blocks/calcom.display.ts +++ b/apps/sim/blocks/blocks/calcom.display.ts @@ -1,6 +1,6 @@ import { CalComIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CalComBlockDisplay = { type: 'calcom', @@ -15,3 +15,109 @@ export const CalComBlockDisplay = { integrationType: IntegrationType.Productivity, triggerAllowed: true, } satisfies BlockDisplay + +export const CalComBlockMeta = { + tags: ['scheduling', 'calendar', 'meeting'], + url: 'https://cal.com', + templates: [ + { + icon: CalComIcon, + title: 'Cal.com booking prep brief', + prompt: + 'Build a workflow that runs 30 minutes before a Cal.com booking, researches the attendee with Apollo, and emails the host a structured prep brief.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo', 'gmail'], + }, + { + icon: CalComIcon, + title: 'Cal.com post-meeting recap', + prompt: + 'Create a workflow that runs after a Cal.com meeting ends, summarizes the meeting notes, and updates the linked Salesforce or HubSpot opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: CalComIcon, + title: 'Cal.com no-show recovery', + prompt: + 'Build a workflow that detects Cal.com no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: CalComIcon, + title: 'Cal.com + Loops nurture', + prompt: + 'Create a workflow that on a Cal.com booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: CalComIcon, + title: 'Cal.com round-robin balancer', + prompt: + 'Build a workflow that watches Cal.com round-robin assignments, ensures equitable distribution across the team weekly, and adjusts the weights based on capacity.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: CalComIcon, + title: 'Cal.com webhook to CRM', + prompt: + 'Create a workflow triggered by a Cal.com booking webhook that creates or updates the contact in HubSpot, sets the lifecycle stage, and assigns the right owner.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: CalComIcon, + title: 'Cal.com reschedule chaser', + prompt: + 'Build a scheduled workflow that finds Cal.com bookings that have been rescheduled more than twice, posts a Slack alert to the host, and proposes a fixed time.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'book-a-meeting', + description: + 'Create a Cal.com booking for an attendee on a chosen event type and time. Use to schedule a call once you know the slot and attendee details.', + content: + '# Book A Meeting\n\nCreate a confirmed Cal.com booking.\n\n## Steps\n1. Identify the event type to book (select it or pass its numeric event type id).\n2. Set the Start Time as an ISO 8601 UTC timestamp.\n3. Provide the attendee name, email, and IANA time zone (e.g. America/New_York). Add guests or a duration override if needed.\n4. Create the booking.\n\n## Output\nReturn the booking UID, start and end time, attendee, and the meeting URL. Confirm the booking to the user. If the slot is unavailable, suggest checking available slots first and propose alternatives.', + }, + { + name: 'find-available-slots', + description: + 'Look up open time slots for a Cal.com event type within a date range. Use before booking to offer the attendee valid times.', + content: + '# Find Available Slots\n\nRetrieve bookable time slots for an event type.\n\n## Steps\n1. Select the event type (or pass its id, or an event type slug plus username).\n2. Set the Start Time and End Time of the window to search (ISO 8601 UTC).\n3. Set the attendee time zone so slots are returned in their local time, and a duration if the event supports multiple lengths.\n4. Read the returned slots.\n\n## Output\nReturn the available slots as a clean list of start times in the requested time zone. Summarize the next few openings for the user; if none exist in the window, widen the range and retry.', + }, + { + name: 'reschedule-or-cancel-booking', + description: + 'Move a Cal.com booking to a new time or cancel it, with a reason. Use to handle change or cancellation requests for an existing booking.', + content: + '# Reschedule Or Cancel Booking\n\nChange or cancel an existing Cal.com booking.\n\n## Steps\n1. Identify the booking by its UID (use List Bookings to find it if you only have attendee or date details).\n2. To move it, use Reschedule Booking with the new Start Time (ISO 8601) and an optional rescheduling reason.\n3. To cancel, use Cancel Booking with an optional cancellation reason.\n4. For request-based event types, use Confirm Booking or Decline Booking instead.\n\n## Output\nReturn the booking UID and its new status (rescheduled, cancelled, confirmed, or declined) plus the updated time when applicable. Confirm the change to the user.', + }, + { + name: 'summarize-upcoming-bookings', + description: + 'List and summarize upcoming Cal.com bookings for a period. Use for a daily agenda or to brief a host on their schedule.', + content: + '# Summarize Upcoming Bookings\n\nProduce an agenda from Cal.com bookings.\n\n## Steps\n1. Use List Bookings with status Upcoming.\n2. For each booking, read the title, start/end time, attendees, and meeting URL.\n3. Sort chronologically and group by day if the range spans multiple days.\n\n## Output\nReturn an ordered agenda: each entry with time, title, attendee name, and join link. Add a short headline like the number of meetings and the first start time so the host gets a quick read on the day.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/calcom.ts b/apps/sim/blocks/blocks/calcom.ts index 9ddc026d34c..b23f35d4c1a 100644 --- a/apps/sim/blocks/blocks/calcom.ts +++ b/apps/sim/blocks/blocks/calcom.ts @@ -1,6 +1,5 @@ -import { CalComIcon } from '@/components/icons' import { CalComBlockDisplay } from '@/blocks/blocks/calcom.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' @@ -908,109 +907,3 @@ Return ONLY valid JSON - no explanations.`, ], }, } - -export const CalComBlockMeta = { - tags: ['scheduling', 'calendar', 'meeting'], - url: 'https://cal.com', - templates: [ - { - icon: CalComIcon, - title: 'Cal.com booking prep brief', - prompt: - 'Build a workflow that runs 30 minutes before a Cal.com booking, researches the attendee with Apollo, and emails the host a structured prep brief.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo', 'gmail'], - }, - { - icon: CalComIcon, - title: 'Cal.com post-meeting recap', - prompt: - 'Create a workflow that runs after a Cal.com meeting ends, summarizes the meeting notes, and updates the linked Salesforce or HubSpot opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: CalComIcon, - title: 'Cal.com no-show recovery', - prompt: - 'Build a workflow that detects Cal.com no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: CalComIcon, - title: 'Cal.com + Loops nurture', - prompt: - 'Create a workflow that on a Cal.com booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: CalComIcon, - title: 'Cal.com round-robin balancer', - prompt: - 'Build a workflow that watches Cal.com round-robin assignments, ensures equitable distribution across the team weekly, and adjusts the weights based on capacity.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: CalComIcon, - title: 'Cal.com webhook to CRM', - prompt: - 'Create a workflow triggered by a Cal.com booking webhook that creates or updates the contact in HubSpot, sets the lifecycle stage, and assigns the right owner.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: CalComIcon, - title: 'Cal.com reschedule chaser', - prompt: - 'Build a scheduled workflow that finds Cal.com bookings that have been rescheduled more than twice, posts a Slack alert to the host, and proposes a fixed time.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'book-a-meeting', - description: - 'Create a Cal.com booking for an attendee on a chosen event type and time. Use to schedule a call once you know the slot and attendee details.', - content: - '# Book A Meeting\n\nCreate a confirmed Cal.com booking.\n\n## Steps\n1. Identify the event type to book (select it or pass its numeric event type id).\n2. Set the Start Time as an ISO 8601 UTC timestamp.\n3. Provide the attendee name, email, and IANA time zone (e.g. America/New_York). Add guests or a duration override if needed.\n4. Create the booking.\n\n## Output\nReturn the booking UID, start and end time, attendee, and the meeting URL. Confirm the booking to the user. If the slot is unavailable, suggest checking available slots first and propose alternatives.', - }, - { - name: 'find-available-slots', - description: - 'Look up open time slots for a Cal.com event type within a date range. Use before booking to offer the attendee valid times.', - content: - '# Find Available Slots\n\nRetrieve bookable time slots for an event type.\n\n## Steps\n1. Select the event type (or pass its id, or an event type slug plus username).\n2. Set the Start Time and End Time of the window to search (ISO 8601 UTC).\n3. Set the attendee time zone so slots are returned in their local time, and a duration if the event supports multiple lengths.\n4. Read the returned slots.\n\n## Output\nReturn the available slots as a clean list of start times in the requested time zone. Summarize the next few openings for the user; if none exist in the window, widen the range and retry.', - }, - { - name: 'reschedule-or-cancel-booking', - description: - 'Move a Cal.com booking to a new time or cancel it, with a reason. Use to handle change or cancellation requests for an existing booking.', - content: - '# Reschedule Or Cancel Booking\n\nChange or cancel an existing Cal.com booking.\n\n## Steps\n1. Identify the booking by its UID (use List Bookings to find it if you only have attendee or date details).\n2. To move it, use Reschedule Booking with the new Start Time (ISO 8601) and an optional rescheduling reason.\n3. To cancel, use Cancel Booking with an optional cancellation reason.\n4. For request-based event types, use Confirm Booking or Decline Booking instead.\n\n## Output\nReturn the booking UID and its new status (rescheduled, cancelled, confirmed, or declined) plus the updated time when applicable. Confirm the change to the user.', - }, - { - name: 'summarize-upcoming-bookings', - description: - 'List and summarize upcoming Cal.com bookings for a period. Use for a daily agenda or to brief a host on their schedule.', - content: - '# Summarize Upcoming Bookings\n\nProduce an agenda from Cal.com bookings.\n\n## Steps\n1. Use List Bookings with status Upcoming.\n2. For each booking, read the title, start/end time, attendees, and meeting URL.\n3. Sort chronologically and group by day if the range spans multiple days.\n\n## Output\nReturn an ordered agenda: each entry with time, title, attendee name, and join link. Add a short headline like the number of meetings and the first start time so the host gets a quick read on the day.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/calendly.display.ts b/apps/sim/blocks/blocks/calendly.display.ts index babebab7fff..8762198aa80 100644 --- a/apps/sim/blocks/blocks/calendly.display.ts +++ b/apps/sim/blocks/blocks/calendly.display.ts @@ -1,6 +1,6 @@ import { CalendlyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CalendlyBlockDisplay = { type: 'calendly', @@ -15,3 +15,102 @@ export const CalendlyBlockDisplay = { integrationType: IntegrationType.Productivity, triggerAllowed: true, } satisfies BlockDisplay + +export const CalendlyBlockMeta = { + tags: ['scheduling', 'calendar', 'meeting'], + url: 'https://calendly.com', + templates: [ + { + icon: CalendlyIcon, + title: 'Scheduling follow-up automator', + prompt: + 'Build a workflow that monitors new Calendly bookings, researches each attendee and their company, prepares a pre-meeting brief with relevant context, and sends a personalized confirmation email with an agenda and any prep materials.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['sales', 'research', 'automation'], + }, + { + icon: CalendlyIcon, + title: 'Calendly meeting-prep brief', + prompt: + 'Build a workflow that runs 30 minutes before a Calendly booking, researches the attendee and company with Apollo, and emails the host a structured prep brief.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo', 'gmail'], + }, + { + icon: CalendlyIcon, + title: 'Calendly post-meeting recap', + prompt: + 'Create a workflow that runs after a Calendly meeting ends, pulls the meeting notes from the calendar, writes a CRM-ready summary, and updates the linked Salesforce opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: CalendlyIcon, + title: 'Calendly no-show recovery', + prompt: + 'Build a workflow that detects Calendly no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: CalendlyIcon, + title: 'Calendly + Loops nurture', + prompt: + 'Create a workflow that on a Calendly booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic, ensuring follow-up emails reach them before the meeting.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: CalendlyIcon, + title: 'Calendly no-show tracker', + prompt: + "Build a scheduled workflow that lists yesterday's Calendly scheduled events, checks invitee status to find no-shows, logs them to a table for follow-up, and posts a recap of attended versus missed meetings to Slack.", + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: CalendlyIcon, + title: 'Calendly booking prep brief', + prompt: + 'Create a workflow that on a new Calendly booking fetches the scheduled event and invitee details, researches the attendee and their company, and emails the meeting owner a one-page prep brief before the call.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'list-upcoming-meetings', + description: + 'Pull upcoming Calendly scheduled events for a date range and summarize them. Use to brief a host on their schedule or build a daily agenda.', + content: + '# List Upcoming Meetings\n\nSummarize upcoming Calendly events.\n\n## Steps\n1. Use List Scheduled Events. Filter to status active and set Min Start Time and Max Start Time (ISO 8601 UTC) for the window.\n2. Filter by user or organization URI when scoping to a specific host (Get Current User returns your URI if needed).\n3. For each event, read name, start_time, end_time, location, and scheduling_url; page with the page token if there are many.\n\n## Output\nReturn an ordered agenda: each meeting with time, name, location/join link, and the invitee. Add a one-line headline (count and first start time) for a quick read.', + }, + { + name: 'get-event-attendees', + description: + 'Retrieve the invitees for a Calendly scheduled event, including answers and contact info. Use to prep for a meeting or sync attendees to a CRM.', + content: + '# Get Event Attendees\n\nList who is attending a Calendly event.\n\n## Steps\n1. Identify the scheduled event by its UUID or URI (use List Scheduled Events to locate it).\n2. Use List Event Invitees for that event; optionally filter by email or status.\n3. Read each invitee record: name, email, status, and any questions and answers captured at booking.\n\n## Output\nReturn the invitees with name, email, status, and their intake answers. Flag canceled or no-show invitees so they can be handled differently from confirmed attendees.', + }, + { + name: 'cancel-scheduled-event', + description: + 'Cancel a Calendly scheduled event with an optional reason. Use to call off a meeting and notify the invitee through Calendly.', + content: + '# Cancel Scheduled Event\n\nCall off a Calendly meeting.\n\n## Steps\n1. Find the scheduled event UUID or URI (use List Scheduled Events filtered by invitee email or time if you only have those details).\n2. Use Cancel Event with the event UUID and a clear cancellation reason.\n3. Calendly notifies the invitee automatically.\n\n## Output\nReturn the event UUID and confirmation that it was canceled. Echo the reason. If the event is already canceled or cannot be found, report that instead of retrying.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/calendly.ts b/apps/sim/blocks/blocks/calendly.ts index 749f39dda8b..a37279c92d1 100644 --- a/apps/sim/blocks/blocks/calendly.ts +++ b/apps/sim/blocks/blocks/calendly.ts @@ -1,6 +1,5 @@ -import { CalendlyIcon } from '@/components/icons' import { CalendlyBlockDisplay } from '@/blocks/blocks/calendly.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' @@ -318,102 +317,3 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes ], }, } - -export const CalendlyBlockMeta = { - tags: ['scheduling', 'calendar', 'meeting'], - url: 'https://calendly.com', - templates: [ - { - icon: CalendlyIcon, - title: 'Scheduling follow-up automator', - prompt: - 'Build a workflow that monitors new Calendly bookings, researches each attendee and their company, prepares a pre-meeting brief with relevant context, and sends a personalized confirmation email with an agenda and any prep materials.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['sales', 'research', 'automation'], - }, - { - icon: CalendlyIcon, - title: 'Calendly meeting-prep brief', - prompt: - 'Build a workflow that runs 30 minutes before a Calendly booking, researches the attendee and company with Apollo, and emails the host a structured prep brief.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo', 'gmail'], - }, - { - icon: CalendlyIcon, - title: 'Calendly post-meeting recap', - prompt: - 'Create a workflow that runs after a Calendly meeting ends, pulls the meeting notes from the calendar, writes a CRM-ready summary, and updates the linked Salesforce opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: CalendlyIcon, - title: 'Calendly no-show recovery', - prompt: - 'Build a workflow that detects Calendly no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: CalendlyIcon, - title: 'Calendly + Loops nurture', - prompt: - 'Create a workflow that on a Calendly booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic, ensuring follow-up emails reach them before the meeting.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: CalendlyIcon, - title: 'Calendly no-show tracker', - prompt: - "Build a scheduled workflow that lists yesterday's Calendly scheduled events, checks invitee status to find no-shows, logs them to a table for follow-up, and posts a recap of attended versus missed meetings to Slack.", - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: CalendlyIcon, - title: 'Calendly booking prep brief', - prompt: - 'Create a workflow that on a new Calendly booking fetches the scheduled event and invitee details, researches the attendee and their company, and emails the meeting owner a one-page prep brief before the call.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'list-upcoming-meetings', - description: - 'Pull upcoming Calendly scheduled events for a date range and summarize them. Use to brief a host on their schedule or build a daily agenda.', - content: - '# List Upcoming Meetings\n\nSummarize upcoming Calendly events.\n\n## Steps\n1. Use List Scheduled Events. Filter to status active and set Min Start Time and Max Start Time (ISO 8601 UTC) for the window.\n2. Filter by user or organization URI when scoping to a specific host (Get Current User returns your URI if needed).\n3. For each event, read name, start_time, end_time, location, and scheduling_url; page with the page token if there are many.\n\n## Output\nReturn an ordered agenda: each meeting with time, name, location/join link, and the invitee. Add a one-line headline (count and first start time) for a quick read.', - }, - { - name: 'get-event-attendees', - description: - 'Retrieve the invitees for a Calendly scheduled event, including answers and contact info. Use to prep for a meeting or sync attendees to a CRM.', - content: - '# Get Event Attendees\n\nList who is attending a Calendly event.\n\n## Steps\n1. Identify the scheduled event by its UUID or URI (use List Scheduled Events to locate it).\n2. Use List Event Invitees for that event; optionally filter by email or status.\n3. Read each invitee record: name, email, status, and any questions and answers captured at booking.\n\n## Output\nReturn the invitees with name, email, status, and their intake answers. Flag canceled or no-show invitees so they can be handled differently from confirmed attendees.', - }, - { - name: 'cancel-scheduled-event', - description: - 'Cancel a Calendly scheduled event with an optional reason. Use to call off a meeting and notify the invitee through Calendly.', - content: - '# Cancel Scheduled Event\n\nCall off a Calendly meeting.\n\n## Steps\n1. Find the scheduled event UUID or URI (use List Scheduled Events filtered by invitee email or time if you only have those details).\n2. Use Cancel Event with the event UUID and a clear cancellation reason.\n3. Calendly notifies the invitee automatically.\n\n## Output\nReturn the event UUID and confirmation that it was canceled. Echo the reason. If the event is already canceled or cannot be found, report that instead of retrying.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/circleback.display.ts b/apps/sim/blocks/blocks/circleback.display.ts index 54c948db2c4..75b55d77e94 100644 --- a/apps/sim/blocks/blocks/circleback.display.ts +++ b/apps/sim/blocks/blocks/circleback.display.ts @@ -1,6 +1,7 @@ +import { ClipboardList, Table } from '@/components/emcn/icons' import { CirclebackIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CirclebackBlockDisplay = { type: 'circleback', @@ -15,3 +16,39 @@ export const CirclebackBlockDisplay = { integrationType: IntegrationType.AI, triggerAllowed: true, } satisfies BlockDisplay + +export const CirclebackBlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://circleback.ai', + templates: [ + { + icon: CirclebackIcon, + title: 'Circleback recap to Slack', + prompt: + 'Build a workflow that triggers when a meeting is processed in Circleback, takes the notes and action items from the payload, and posts a clean recap to the relevant Slack channel.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: ClipboardList, + title: 'Circleback action-item tracker', + prompt: + 'Create a workflow that triggers when a Circleback meeting is processed, reads the action items from the payload, and writes each one to a tasks table with the owner and due date.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'automation'], + }, + { + icon: Table, + title: 'Circleback notes to Notion', + prompt: + 'Build a workflow that triggers when a meeting is processed in Circleback, pulls the notes, attendees, and transcript from the payload, and writes a structured meeting note to Notion with next steps.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'note-taking'], + alsoIntegrations: ['notion'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/circleback.ts b/apps/sim/blocks/blocks/circleback.ts index d09dcb87444..d33f074a502 100644 --- a/apps/sim/blocks/blocks/circleback.ts +++ b/apps/sim/blocks/blocks/circleback.ts @@ -1,7 +1,5 @@ -import { ClipboardList, Table } from '@/components/emcn/icons' -import { CirclebackIcon } from '@/components/icons' import { CirclebackBlockDisplay } from '@/blocks/blocks/circleback.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const CirclebackBlock: BlockConfig = { @@ -40,39 +38,3 @@ export const CirclebackBlock: BlockConfig = { available: ['circleback_meeting_completed', 'circleback_meeting_notes', 'circleback_webhook'], }, } - -export const CirclebackBlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://circleback.ai', - templates: [ - { - icon: CirclebackIcon, - title: 'Circleback recap to Slack', - prompt: - 'Build a workflow that triggers when a meeting is processed in Circleback, takes the notes and action items from the payload, and posts a clean recap to the relevant Slack channel.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: ClipboardList, - title: 'Circleback action-item tracker', - prompt: - 'Create a workflow that triggers when a Circleback meeting is processed, reads the action items from the payload, and writes each one to a tasks table with the owner and due date.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'automation'], - }, - { - icon: Table, - title: 'Circleback notes to Notion', - prompt: - 'Build a workflow that triggers when a meeting is processed in Circleback, pulls the notes, attendees, and transcript from the payload, and writes a structured meeting note to Notion with next steps.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'note-taking'], - alsoIntegrations: ['notion'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clay.display.ts b/apps/sim/blocks/blocks/clay.display.ts index 35f070dee8a..65e981f132c 100644 --- a/apps/sim/blocks/blocks/clay.display.ts +++ b/apps/sim/blocks/blocks/clay.display.ts @@ -1,6 +1,6 @@ import { ClayIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ClayBlockDisplay = { type: 'clay', @@ -13,3 +13,93 @@ export const ClayBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/clay', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const ClayBlockMeta = { + tags: ['enrichment', 'sales-engagement', 'data-analytics'], + url: 'https://www.clay.com', + templates: [ + { + icon: ClayIcon, + title: 'Clay lead-list builder', + prompt: + 'Build a workflow that reads a list of target prospects from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with role and intent signals through its own waterfall.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ClayIcon, + title: 'Clay CRM enricher', + prompt: + 'Create a scheduled workflow that reads new HubSpot contacts and pushes each one to a Clay table via the populate webhook, so Clay runs its enrichment waterfall on role, seniority, and tech-stack signals.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: ClayIcon, + title: 'Clay account pusher', + prompt: + 'Build a scheduled workflow that reads target accounts from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with hiring, funding, and tech-change signals through its waterfall.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ClayIcon, + title: 'Clay outbound personalizer', + prompt: + 'Create a workflow that reads a prospect record from a Sim table — including the role and company signals already gathered — drafts a personalized first-touch email, queues it for review, and pushes the prospect to a Clay table via the populate webhook for further enrichment.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: ClayIcon, + title: 'Clay TAM seeder', + prompt: + 'Build a workflow that reads a seed account list from Salesforce and pushes each account to a Clay table via the populate webhook, so Clay runs its lookalike and enrichment waterfall to expand the TAM.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ClayIcon, + title: 'Clay inbound lead router', + prompt: + 'Create a workflow that scores each inbound HubSpot lead against the ICP using the fields already on the contact, routes high-fit leads to sales while parking the rest for nurture, and pushes every lead to a Clay table via the populate webhook for enrichment.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: ClayIcon, + title: 'Clay enrichment pusher', + prompt: + 'Build a scheduled workflow that reads new rows from a leads table and pushes each record to a Clay table via the populate webhook, so Clay runs its enrichment waterfall and the data flows back into my outbound stack automatically.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'enrichment'], + }, + ], + skills: [ + { + name: 'push-record-to-clay', + description: + 'Send a single contact or account record to a Clay table via its populate webhook so Clay can enrich it. Use to hand a lead off to a Clay enrichment waterfall.', + content: + '# Push Record To Clay\n\nSend one record into a Clay table for enrichment.\n\n## Steps\n1. Get the Clay table populate webhook URL (Clay shows it on the table when you add a "Webhook" source).\n2. Build the record as a JSON object whose keys match the Clay table column names you want to populate (e.g. name, email, company, domain, linkedin_url).\n3. If the table has webhook authentication enabled, supply the auth token; it is sent in the x-clay-webhook-auth header.\n4. Populate the table with the record.\n\n## Output\nReturn the webhook response and metadata (status, timestamp). Confirm the record was accepted. Note that enrichment runs asynchronously inside Clay, so the enriched columns appear there, not in the immediate response.', + }, + { + name: 'bulk-load-list-into-clay', + description: + 'Push many prospect or account rows from a table into a Clay workbook for enrichment. Use to seed a lead list or sync a CRM segment into Clay.', + content: + '# Bulk Load List Into Clay\n\nLoad a list of records into a Clay table.\n\n## Steps\n1. Gather the source rows (e.g. from a Sim table or a CRM query).\n2. Get the Clay table populate webhook URL and any auth token.\n3. For each row, map your fields to the Clay column names and populate the table once per record. Keep the JSON keys consistent across all records so columns line up.\n4. Send the records, pacing them if the list is large.\n\n## Output\nReturn a count of records pushed and any that failed (with the error). Remind the user that Clay enriches the rows on its side, and suggest they verify the row count in the Clay table once ingestion completes.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clay.ts b/apps/sim/blocks/blocks/clay.ts index a88020743ab..24aaa1dc90e 100644 --- a/apps/sim/blocks/blocks/clay.ts +++ b/apps/sim/blocks/blocks/clay.ts @@ -1,6 +1,5 @@ -import { ClayIcon } from '@/components/icons' import { ClayBlockDisplay } from '@/blocks/blocks/clay.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ClayPopulateResponse } from '@/tools/clay/types' export const ClayBlock: BlockConfig = { @@ -61,93 +60,3 @@ Plain Text: Best for populating a table in free-form style. }, }, } - -export const ClayBlockMeta = { - tags: ['enrichment', 'sales-engagement', 'data-analytics'], - url: 'https://www.clay.com', - templates: [ - { - icon: ClayIcon, - title: 'Clay lead-list builder', - prompt: - 'Build a workflow that reads a list of target prospects from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with role and intent signals through its own waterfall.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ClayIcon, - title: 'Clay CRM enricher', - prompt: - 'Create a scheduled workflow that reads new HubSpot contacts and pushes each one to a Clay table via the populate webhook, so Clay runs its enrichment waterfall on role, seniority, and tech-stack signals.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: ClayIcon, - title: 'Clay account pusher', - prompt: - 'Build a scheduled workflow that reads target accounts from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with hiring, funding, and tech-change signals through its waterfall.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ClayIcon, - title: 'Clay outbound personalizer', - prompt: - 'Create a workflow that reads a prospect record from a Sim table — including the role and company signals already gathered — drafts a personalized first-touch email, queues it for review, and pushes the prospect to a Clay table via the populate webhook for further enrichment.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: ClayIcon, - title: 'Clay TAM seeder', - prompt: - 'Build a workflow that reads a seed account list from Salesforce and pushes each account to a Clay table via the populate webhook, so Clay runs its lookalike and enrichment waterfall to expand the TAM.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ClayIcon, - title: 'Clay inbound lead router', - prompt: - 'Create a workflow that scores each inbound HubSpot lead against the ICP using the fields already on the contact, routes high-fit leads to sales while parking the rest for nurture, and pushes every lead to a Clay table via the populate webhook for enrichment.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: ClayIcon, - title: 'Clay enrichment pusher', - prompt: - 'Build a scheduled workflow that reads new rows from a leads table and pushes each record to a Clay table via the populate webhook, so Clay runs its enrichment waterfall and the data flows back into my outbound stack automatically.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'enrichment'], - }, - ], - skills: [ - { - name: 'push-record-to-clay', - description: - 'Send a single contact or account record to a Clay table via its populate webhook so Clay can enrich it. Use to hand a lead off to a Clay enrichment waterfall.', - content: - '# Push Record To Clay\n\nSend one record into a Clay table for enrichment.\n\n## Steps\n1. Get the Clay table populate webhook URL (Clay shows it on the table when you add a "Webhook" source).\n2. Build the record as a JSON object whose keys match the Clay table column names you want to populate (e.g. name, email, company, domain, linkedin_url).\n3. If the table has webhook authentication enabled, supply the auth token; it is sent in the x-clay-webhook-auth header.\n4. Populate the table with the record.\n\n## Output\nReturn the webhook response and metadata (status, timestamp). Confirm the record was accepted. Note that enrichment runs asynchronously inside Clay, so the enriched columns appear there, not in the immediate response.', - }, - { - name: 'bulk-load-list-into-clay', - description: - 'Push many prospect or account rows from a table into a Clay workbook for enrichment. Use to seed a lead list or sync a CRM segment into Clay.', - content: - '# Bulk Load List Into Clay\n\nLoad a list of records into a Clay table.\n\n## Steps\n1. Gather the source rows (e.g. from a Sim table or a CRM query).\n2. Get the Clay table populate webhook URL and any auth token.\n3. For each row, map your fields to the Clay column names and populate the table once per record. Keep the JSON keys consistent across all records so columns line up.\n4. Send the records, pacing them if the list is large.\n\n## Output\nReturn a count of records pushed and any that failed (with the error). Remind the user that Clay enriches the rows on its side, and suggest they verify the row count in the Clay table once ingestion completes.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clerk.display.ts b/apps/sim/blocks/blocks/clerk.display.ts index 7d05cb8799a..b2c8c65f1f0 100644 --- a/apps/sim/blocks/blocks/clerk.display.ts +++ b/apps/sim/blocks/blocks/clerk.display.ts @@ -1,6 +1,6 @@ import { ClerkIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ClerkBlockDisplay = { type: 'clerk', @@ -14,3 +14,109 @@ export const ClerkBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/clerk', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const ClerkBlockMeta = { + tags: ['identity', 'automation'], + url: 'https://clerk.com', + templates: [ + { + icon: ClerkIcon, + title: 'Clerk new-signup pipeline', + prompt: + 'Build a scheduled workflow that lists recent Clerk users, creates each new signup in HubSpot with the right lifecycle stage, and enrolls them in a Loops onboarding sequence.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['hubspot', 'loops'], + }, + { + icon: ClerkIcon, + title: 'Clerk MFA enrollment chaser', + prompt: + 'Create a scheduled workflow that finds Clerk users without MFA enrolled in 30 days, sends in-app prompts via Loops, and writes enrollment progress to a security dashboard.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: ClerkIcon, + title: 'Clerk session anomaly watcher', + prompt: + 'Build a scheduled workflow that lists recent Clerk sessions, flags unusual patterns — impossible travel, repeated login failures — and pings the security Slack channel on real threats.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ClerkIcon, + title: 'Clerk org-management automator', + prompt: + 'Create a workflow that on a new enterprise plan via Stripe creates a Clerk organization, invites the admin, and writes the Clerk org ID back to the Stripe customer.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['stripe'], + }, + { + icon: ClerkIcon, + title: 'Clerk inactive-user cleaner', + prompt: + 'Build a scheduled workflow that finds Clerk users with no sign-ins in 180 days, sends a re-engagement email, and removes accounts after a grace period.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise'], + alsoIntegrations: ['gmail'], + }, + { + icon: ClerkIcon, + title: 'Clerk access-review automator', + prompt: + 'Create a scheduled quarterly workflow that lists Clerk organizations and their users, requires owner re-attestation, and writes the review trail to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: ClerkIcon, + title: 'Clerk user roster archiver', + prompt: + 'Build a scheduled workflow that exports the full Clerk user and organization roster to S3 on a retention schedule, and writes the snapshot manifest to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['s3'], + }, + ], + skills: [ + { + name: 'find-user', + description: + 'Look up a Clerk user by email, username, or name and return their profile. Use to resolve a user before acting on their account or syncing them elsewhere.', + content: + '# Find User\n\nLocate a Clerk user account.\n\n## Steps\n1. Use List Users with a Search Query (matches email, phone, username, or name), or the email/username filters for an exact match.\n2. If you already have the Clerk user id (user_...), use Get User instead for the full record.\n3. Review the returned profile: id, primary email, name, externalId, and flags like banned, locked, and twoFactorEnabled.\n\n## Output\nReturn the matched user id, primary email, name, and key status flags. If multiple users match, list the candidates with their emails so the right one can be confirmed; if none match, say so.', + }, + { + name: 'provision-user', + description: + 'Create or update a Clerk user with email, name, and metadata. Use to onboard a user or sync profile changes from another system into Clerk.', + content: + '# Provision User\n\nCreate or update a Clerk user.\n\n## Steps\n1. To create, use Create User with at least an email address (and optionally phone, username, password, first/last name).\n2. To set application roles or app data, pass Public Metadata (visible to the frontend) and Private Metadata (server-only) as JSON.\n3. Set External ID to link the Clerk user to your own system id.\n4. To modify an existing user, use Update User with the user id and only the fields that change.\n\n## Output\nReturn the user id, primary email, and the metadata that was set. Confirm whether the user was created or updated. If a required field is missing or the email already exists, report it clearly.', + }, + { + name: 'audit-user-sessions', + description: + 'List and inspect a Clerk user active sessions and revoke suspicious ones. Use for security review or forced sign-out.', + content: + '# Audit User Sessions\n\nReview and control Clerk sessions.\n\n## Steps\n1. Use List Sessions filtered by user id and status (e.g. active) to see current sessions.\n2. For a specific session, use Get Session to read its details: client, status, lastActiveAt.\n3. Identify sessions that look risky (stale, unexpected client, or flagged by your own logic).\n4. Use Revoke Session with the session id to force sign-out of any session that should not continue.\n\n## Output\nReturn the list of sessions reviewed with status and last-active time, and the ids of any sessions revoked. Summarize the action taken so the security trail is clear.', + }, + { + name: 'manage-organization', + description: + 'Create a Clerk organization or look up its details and membership. Use when provisioning a new team or tenant in a multi-tenant app.', + content: + '# Manage Organization\n\nCreate or inspect a Clerk organization.\n\n## Steps\n1. To create, use Create Organization with the organization name and the Creator User ID (that user becomes the admin); optionally set a slug and max members.\n2. To inspect, use Get Organization by org id or slug, or List Organizations with a search query and include members count.\n3. Read back the org id, slug, members count, and limits.\n\n## Output\nReturn the organization id, name, slug, and member count. When creating, confirm the admin user and echo the org id so it can be linked back to your billing or CRM record.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clerk.ts b/apps/sim/blocks/blocks/clerk.ts index e6b4314df4d..edbcec3eecd 100644 --- a/apps/sim/blocks/blocks/clerk.ts +++ b/apps/sim/blocks/blocks/clerk.ts @@ -1,6 +1,5 @@ -import { ClerkIcon } from '@/components/icons' import { ClerkBlockDisplay } from '@/blocks/blocks/clerk.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { ClerkResponse } from '@/tools/clerk/types' export const ClerkBlock: BlockConfig = { @@ -399,109 +398,3 @@ export const ClerkBlock: BlockConfig = { success: { type: 'boolean', description: 'Operation success status' }, }, } - -export const ClerkBlockMeta = { - tags: ['identity', 'automation'], - url: 'https://clerk.com', - templates: [ - { - icon: ClerkIcon, - title: 'Clerk new-signup pipeline', - prompt: - 'Build a scheduled workflow that lists recent Clerk users, creates each new signup in HubSpot with the right lifecycle stage, and enrolls them in a Loops onboarding sequence.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['hubspot', 'loops'], - }, - { - icon: ClerkIcon, - title: 'Clerk MFA enrollment chaser', - prompt: - 'Create a scheduled workflow that finds Clerk users without MFA enrolled in 30 days, sends in-app prompts via Loops, and writes enrollment progress to a security dashboard.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: ClerkIcon, - title: 'Clerk session anomaly watcher', - prompt: - 'Build a scheduled workflow that lists recent Clerk sessions, flags unusual patterns — impossible travel, repeated login failures — and pings the security Slack channel on real threats.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ClerkIcon, - title: 'Clerk org-management automator', - prompt: - 'Create a workflow that on a new enterprise plan via Stripe creates a Clerk organization, invites the admin, and writes the Clerk org ID back to the Stripe customer.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['stripe'], - }, - { - icon: ClerkIcon, - title: 'Clerk inactive-user cleaner', - prompt: - 'Build a scheduled workflow that finds Clerk users with no sign-ins in 180 days, sends a re-engagement email, and removes accounts after a grace period.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise'], - alsoIntegrations: ['gmail'], - }, - { - icon: ClerkIcon, - title: 'Clerk access-review automator', - prompt: - 'Create a scheduled quarterly workflow that lists Clerk organizations and their users, requires owner re-attestation, and writes the review trail to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: ClerkIcon, - title: 'Clerk user roster archiver', - prompt: - 'Build a scheduled workflow that exports the full Clerk user and organization roster to S3 on a retention schedule, and writes the snapshot manifest to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['s3'], - }, - ], - skills: [ - { - name: 'find-user', - description: - 'Look up a Clerk user by email, username, or name and return their profile. Use to resolve a user before acting on their account or syncing them elsewhere.', - content: - '# Find User\n\nLocate a Clerk user account.\n\n## Steps\n1. Use List Users with a Search Query (matches email, phone, username, or name), or the email/username filters for an exact match.\n2. If you already have the Clerk user id (user_...), use Get User instead for the full record.\n3. Review the returned profile: id, primary email, name, externalId, and flags like banned, locked, and twoFactorEnabled.\n\n## Output\nReturn the matched user id, primary email, name, and key status flags. If multiple users match, list the candidates with their emails so the right one can be confirmed; if none match, say so.', - }, - { - name: 'provision-user', - description: - 'Create or update a Clerk user with email, name, and metadata. Use to onboard a user or sync profile changes from another system into Clerk.', - content: - '# Provision User\n\nCreate or update a Clerk user.\n\n## Steps\n1. To create, use Create User with at least an email address (and optionally phone, username, password, first/last name).\n2. To set application roles or app data, pass Public Metadata (visible to the frontend) and Private Metadata (server-only) as JSON.\n3. Set External ID to link the Clerk user to your own system id.\n4. To modify an existing user, use Update User with the user id and only the fields that change.\n\n## Output\nReturn the user id, primary email, and the metadata that was set. Confirm whether the user was created or updated. If a required field is missing or the email already exists, report it clearly.', - }, - { - name: 'audit-user-sessions', - description: - 'List and inspect a Clerk user active sessions and revoke suspicious ones. Use for security review or forced sign-out.', - content: - '# Audit User Sessions\n\nReview and control Clerk sessions.\n\n## Steps\n1. Use List Sessions filtered by user id and status (e.g. active) to see current sessions.\n2. For a specific session, use Get Session to read its details: client, status, lastActiveAt.\n3. Identify sessions that look risky (stale, unexpected client, or flagged by your own logic).\n4. Use Revoke Session with the session id to force sign-out of any session that should not continue.\n\n## Output\nReturn the list of sessions reviewed with status and last-active time, and the ids of any sessions revoked. Summarize the action taken so the security trail is clear.', - }, - { - name: 'manage-organization', - description: - 'Create a Clerk organization or look up its details and membership. Use when provisioning a new team or tenant in a multi-tenant app.', - content: - '# Manage Organization\n\nCreate or inspect a Clerk organization.\n\n## Steps\n1. To create, use Create Organization with the organization name and the Creator User ID (that user becomes the admin); optionally set a slug and max members.\n2. To inspect, use Get Organization by org id or slug, or List Organizations with a search query and include members count.\n3. Read back the org id, slug, members count, and limits.\n\n## Output\nReturn the organization id, name, slug, and member count. When creating, confirm the admin user and echo the org id so it can be linked back to your billing or CRM record.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clickhouse.display.ts b/apps/sim/blocks/blocks/clickhouse.display.ts index 2bce79ed8ca..17bfe4e3bd7 100644 --- a/apps/sim/blocks/blocks/clickhouse.display.ts +++ b/apps/sim/blocks/blocks/clickhouse.display.ts @@ -1,6 +1,7 @@ +import { ClipboardList, File } from '@/components/emcn/icons' import { ClickHouseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ClickHouseBlockDisplay = { type: 'clickhouse', @@ -14,3 +15,61 @@ export const ClickHouseBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/clickhouse', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const ClickHouseBlockMeta = { + tags: ['data-warehouse', 'data-analytics'], + url: 'https://clickhouse.com', + templates: [ + { + icon: ClickHouseIcon, + title: 'Natural-language ClickHouse query', + prompt: + 'Build a workflow where I ask a question in plain English, an agent writes the matching ClickHouse SQL against my events table, runs the query, and returns the results formatted as a readable answer.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['data-analytics', 'data-warehouse'], + }, + { + icon: File, + title: 'Daily ClickHouse metrics digest', + prompt: + 'Create a scheduled workflow that runs a set of ClickHouse aggregation queries each morning, summarizes the key trends and anomalies with an agent, and posts the digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['data-analytics', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ClipboardList, + title: 'Event ingestion to ClickHouse', + prompt: + 'Build a workflow that takes incoming event payloads, maps them to the right columns with an agent, and bulk-inserts the rows into a ClickHouse table for analytics.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['data-analytics', 'data-warehouse'], + }, + ], + skills: [ + { + name: 'answer-question-with-sql', + description: + 'Translate a plain-English analytics question into ClickHouse SQL, run it, and return the answer. Use for ad-hoc data questions over a ClickHouse table.', + content: + '# Answer Question With SQL\n\nTurn a natural-language question into a ClickHouse query and report the result.\n\n## Steps\n1. If you do not know the schema, use Introspect Schema or Describe Table to learn the columns and types.\n2. Write a ClickHouse SELECT using ClickHouse functions (toDate, uniqExact, quantile, etc.). Filter on primary/sorting keys and add a LIMIT for exploratory queries.\n3. Run it with the Query (SELECT) operation against the connection (host, port, database, credentials).\n4. Inspect the returned rows and row count.\n\n## Output\nReturn the result as a small table plus a one-sentence answer to the original question. Include the SQL you ran so it is reproducible. If the query errors, report the message and adjust the SQL rather than guessing blindly.', + }, + { + name: 'summarize-metrics', + description: + 'Run aggregation queries against ClickHouse and summarize key metrics and trends. Use for a recurring metrics digest or dashboard refresh.', + content: + '# Summarize Metrics\n\nCompute and summarize metrics from ClickHouse.\n\n## Steps\n1. Confirm the relevant table and time column with Describe Table if needed.\n2. Write aggregation queries (e.g. daily uniqExact users, counts, quantiles over a time window) using Query (SELECT).\n3. Run each query against the connection and collect the results.\n4. Compare against the prior period to spot increases, drops, or anomalies.\n\n## Output\nReturn a concise digest: the headline numbers, period-over-period change, and any notable anomalies. Keep it readable, lead with the most important metric, and note the time window covered.', + }, + { + name: 'bulk-insert-events', + description: + 'Insert a batch of rows into a ClickHouse table after mapping them to the right columns. Use to ingest event or record payloads into ClickHouse.', + content: + '# Bulk Insert Events\n\nLoad a batch of records into a ClickHouse table.\n\n## Steps\n1. Use Describe Table to confirm the target column names and types.\n2. Map each incoming payload to those columns, coercing types (e.g. timestamps to DateTime format, numbers to the right width).\n3. Build a JSON array of row objects with consistent keys, then use Insert Rows (Bulk) against the table.\n4. Verify with Count Rows or a small SELECT.\n\n## Output\nReturn the number of rows inserted and any rows that were skipped or failed validation, with the reason. Confirm the new total row count so the caller knows ingestion succeeded.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/clickhouse.ts b/apps/sim/blocks/blocks/clickhouse.ts index 2998537ddb8..712d850ba61 100644 --- a/apps/sim/blocks/blocks/clickhouse.ts +++ b/apps/sim/blocks/blocks/clickhouse.ts @@ -1,8 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { ClipboardList, File } from '@/components/emcn/icons' -import { ClickHouseIcon } from '@/components/icons' import { ClickHouseBlockDisplay } from '@/blocks/blocks/clickhouse.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { ClickHouseResponse } from '@/tools/clickhouse/types' const CLICKHOUSE_QUERY_PROMPT = `You are an expert ClickHouse database developer. Write ClickHouse SQL queries based on the user's request. @@ -455,61 +453,3 @@ export const ClickHouseBlock: BlockConfig = { }, }, } - -export const ClickHouseBlockMeta = { - tags: ['data-warehouse', 'data-analytics'], - url: 'https://clickhouse.com', - templates: [ - { - icon: ClickHouseIcon, - title: 'Natural-language ClickHouse query', - prompt: - 'Build a workflow where I ask a question in plain English, an agent writes the matching ClickHouse SQL against my events table, runs the query, and returns the results formatted as a readable answer.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['data-analytics', 'data-warehouse'], - }, - { - icon: File, - title: 'Daily ClickHouse metrics digest', - prompt: - 'Create a scheduled workflow that runs a set of ClickHouse aggregation queries each morning, summarizes the key trends and anomalies with an agent, and posts the digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['data-analytics', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ClipboardList, - title: 'Event ingestion to ClickHouse', - prompt: - 'Build a workflow that takes incoming event payloads, maps them to the right columns with an agent, and bulk-inserts the rows into a ClickHouse table for analytics.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['data-analytics', 'data-warehouse'], - }, - ], - skills: [ - { - name: 'answer-question-with-sql', - description: - 'Translate a plain-English analytics question into ClickHouse SQL, run it, and return the answer. Use for ad-hoc data questions over a ClickHouse table.', - content: - '# Answer Question With SQL\n\nTurn a natural-language question into a ClickHouse query and report the result.\n\n## Steps\n1. If you do not know the schema, use Introspect Schema or Describe Table to learn the columns and types.\n2. Write a ClickHouse SELECT using ClickHouse functions (toDate, uniqExact, quantile, etc.). Filter on primary/sorting keys and add a LIMIT for exploratory queries.\n3. Run it with the Query (SELECT) operation against the connection (host, port, database, credentials).\n4. Inspect the returned rows and row count.\n\n## Output\nReturn the result as a small table plus a one-sentence answer to the original question. Include the SQL you ran so it is reproducible. If the query errors, report the message and adjust the SQL rather than guessing blindly.', - }, - { - name: 'summarize-metrics', - description: - 'Run aggregation queries against ClickHouse and summarize key metrics and trends. Use for a recurring metrics digest or dashboard refresh.', - content: - '# Summarize Metrics\n\nCompute and summarize metrics from ClickHouse.\n\n## Steps\n1. Confirm the relevant table and time column with Describe Table if needed.\n2. Write aggregation queries (e.g. daily uniqExact users, counts, quantiles over a time window) using Query (SELECT).\n3. Run each query against the connection and collect the results.\n4. Compare against the prior period to spot increases, drops, or anomalies.\n\n## Output\nReturn a concise digest: the headline numbers, period-over-period change, and any notable anomalies. Keep it readable, lead with the most important metric, and note the time window covered.', - }, - { - name: 'bulk-insert-events', - description: - 'Insert a batch of rows into a ClickHouse table after mapping them to the right columns. Use to ingest event or record payloads into ClickHouse.', - content: - '# Bulk Insert Events\n\nLoad a batch of records into a ClickHouse table.\n\n## Steps\n1. Use Describe Table to confirm the target column names and types.\n2. Map each incoming payload to those columns, coercing types (e.g. timestamps to DateTime format, numbers to the right width).\n3. Build a JSON array of row objects with consistent keys, then use Insert Rows (Bulk) against the table.\n4. Verify with Count Rows or a small SELECT.\n\n## Output\nReturn the number of rows inserted and any rows that were skipped or failed validation, with the reason. Confirm the new total row count so the caller knows ingestion succeeded.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudflare.display.ts b/apps/sim/blocks/blocks/cloudflare.display.ts index 6a1d2d19563..51c8f815671 100644 --- a/apps/sim/blocks/blocks/cloudflare.display.ts +++ b/apps/sim/blocks/blocks/cloudflare.display.ts @@ -1,6 +1,6 @@ import { CloudflareIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CloudflareBlockDisplay = { type: 'cloudflare', @@ -14,3 +14,100 @@ export const CloudflareBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/cloudflare', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const CloudflareBlockMeta = { + tags: ['cloud', 'monitoring'], + url: 'https://www.cloudflare.com', + templates: [ + { + icon: CloudflareIcon, + title: 'Cloudflare DNS change tracker', + prompt: + 'Create a scheduled workflow that pulls every Cloudflare DNS record for my zones each hour, diffs the snapshot against the previous run, logs added, removed, and modified records to a table, and posts a Slack alert when sensitive records like MX or NS change.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: CloudflareIcon, + title: 'Cache purge on deploy', + prompt: + 'Build a workflow that fires when a Vercel deployment succeeds on production, purges the Cloudflare cache for the affected hostnames, verifies the new content is being served, and posts a confirmation message to Slack with the purged paths.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + alsoIntegrations: ['vercel', 'slack'], + }, + { + icon: CloudflareIcon, + title: 'SSL and zone health check', + prompt: + 'Create a scheduled weekly workflow that inspects every Cloudflare zone for SSL certificate status, security level, and zone settings drift, logs findings to a table, and opens Linear tickets for any zones that need attention.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'enterprise'], + alsoIntegrations: ['linear'], + }, + { + icon: CloudflareIcon, + title: 'DNS analytics digest', + prompt: + 'Build a scheduled workflow that pulls Cloudflare DNS analytics for the top zones every Monday, identifies query spikes, anomalies, and surges in particular record types, and emails a written analysis to the platform team with traffic graphs and recommendations.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting', 'analysis'], + }, + { + icon: CloudflareIcon, + title: 'Zone provisioning workflow', + prompt: + 'Create a workflow that accepts a domain name from a form, creates a new Cloudflare zone, sets opinionated default DNS records and zone settings, generates the nameserver instructions, and posts the setup summary to Slack so the team can finalize delegation.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: CloudflareIcon, + title: 'DNS record bulk importer', + prompt: + 'Build a workflow that reads a table of DNS records — name, type, content, TTL — validates each row, creates or updates the matching record in Cloudflare, and writes results back to the table so DNS changes are versioned and reviewable.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + { + icon: CloudflareIcon, + title: 'Zone settings policy enforcer', + prompt: + 'Create a scheduled workflow that reads a baseline of required Cloudflare zone settings from a knowledge base, compares it against every zone weekly, automatically reverts unauthorized changes, and emails a compliance report to security leadership.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'monitoring'], + }, + ], + skills: [ + { + name: 'audit-dns-records', + description: + 'Pull all DNS records for a Cloudflare zone and report on misconfigurations, dangling records, and sensitive record changes.', + content: + '# Audit Cloudflare DNS Records\n\nExport and review the DNS configuration for a zone to catch misconfigurations and risky records.\n\n## Steps\n1. Resolve the zone ID for the target domain.\n2. List every DNS record (A, AAAA, CNAME, MX, TXT, NS) for the zone.\n3. Flag records that point to deprovisioned hosts, wildcard CNAMEs, missing SPF/DMARC TXT records, and proxied vs. unproxied mismatches.\n4. Group findings by record type and severity.\n\n## Output\nA prioritized list of DNS issues with the record name, type, current value, and recommended fix.', + }, + { + name: 'purge-cache', + description: + 'Purge Cloudflare cache for specific URLs or an entire zone after a deploy, then confirm what was cleared.', + content: + '# Purge Cloudflare Cache\n\nClear cached content so visitors see the latest deploy.\n\n## Steps\n1. Identify the affected zone and the paths or hostnames that changed.\n2. Purge by specific files when possible; only purge everything for the zone if the change is global.\n3. Confirm the purge succeeded and note the timestamp.\n\n## Output\nA short confirmation listing the zone, the purged URLs (or "full zone"), and the purge time.', + }, + { + name: 'check-ssl-and-zone-settings', + description: + 'Inspect SSL certificate status and security settings for Cloudflare zones and report drift from a desired baseline.', + content: + '# Check SSL and Zone Settings\n\nVerify SSL/TLS posture and key security settings across zones.\n\n## Steps\n1. List the target zones.\n2. For each zone read SSL mode, certificate status/expiry, minimum TLS version, and security level.\n3. Compare against the desired baseline (e.g. Full Strict, TLS 1.2+).\n4. Flag expiring certs and any setting weaker than the baseline.\n\n## Output\nA per-zone table of SSL status, settings, and any drift that needs remediation.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudflare.ts b/apps/sim/blocks/blocks/cloudflare.ts index 0bba06aff02..b49b50e7768 100644 --- a/apps/sim/blocks/blocks/cloudflare.ts +++ b/apps/sim/blocks/blocks/cloudflare.ts @@ -1,6 +1,5 @@ -import { CloudflareIcon } from '@/components/icons' import { CloudflareBlockDisplay } from '@/blocks/blocks/cloudflare.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { CloudflareResponse } from '@/tools/cloudflare/types' export const CloudflareBlock: BlockConfig = { @@ -1089,100 +1088,3 @@ Return ONLY the comma-separated URLs - no explanations, no extra text.`, total_count: { type: 'number', description: 'Total count of results' }, }, } - -export const CloudflareBlockMeta = { - tags: ['cloud', 'monitoring'], - url: 'https://www.cloudflare.com', - templates: [ - { - icon: CloudflareIcon, - title: 'Cloudflare DNS change tracker', - prompt: - 'Create a scheduled workflow that pulls every Cloudflare DNS record for my zones each hour, diffs the snapshot against the previous run, logs added, removed, and modified records to a table, and posts a Slack alert when sensitive records like MX or NS change.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: CloudflareIcon, - title: 'Cache purge on deploy', - prompt: - 'Build a workflow that fires when a Vercel deployment succeeds on production, purges the Cloudflare cache for the affected hostnames, verifies the new content is being served, and posts a confirmation message to Slack with the purged paths.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - alsoIntegrations: ['vercel', 'slack'], - }, - { - icon: CloudflareIcon, - title: 'SSL and zone health check', - prompt: - 'Create a scheduled weekly workflow that inspects every Cloudflare zone for SSL certificate status, security level, and zone settings drift, logs findings to a table, and opens Linear tickets for any zones that need attention.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'enterprise'], - alsoIntegrations: ['linear'], - }, - { - icon: CloudflareIcon, - title: 'DNS analytics digest', - prompt: - 'Build a scheduled workflow that pulls Cloudflare DNS analytics for the top zones every Monday, identifies query spikes, anomalies, and surges in particular record types, and emails a written analysis to the platform team with traffic graphs and recommendations.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting', 'analysis'], - }, - { - icon: CloudflareIcon, - title: 'Zone provisioning workflow', - prompt: - 'Create a workflow that accepts a domain name from a form, creates a new Cloudflare zone, sets opinionated default DNS records and zone settings, generates the nameserver instructions, and posts the setup summary to Slack so the team can finalize delegation.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: CloudflareIcon, - title: 'DNS record bulk importer', - prompt: - 'Build a workflow that reads a table of DNS records — name, type, content, TTL — validates each row, creates or updates the matching record in Cloudflare, and writes results back to the table so DNS changes are versioned and reviewable.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - { - icon: CloudflareIcon, - title: 'Zone settings policy enforcer', - prompt: - 'Create a scheduled workflow that reads a baseline of required Cloudflare zone settings from a knowledge base, compares it against every zone weekly, automatically reverts unauthorized changes, and emails a compliance report to security leadership.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'monitoring'], - }, - ], - skills: [ - { - name: 'audit-dns-records', - description: - 'Pull all DNS records for a Cloudflare zone and report on misconfigurations, dangling records, and sensitive record changes.', - content: - '# Audit Cloudflare DNS Records\n\nExport and review the DNS configuration for a zone to catch misconfigurations and risky records.\n\n## Steps\n1. Resolve the zone ID for the target domain.\n2. List every DNS record (A, AAAA, CNAME, MX, TXT, NS) for the zone.\n3. Flag records that point to deprovisioned hosts, wildcard CNAMEs, missing SPF/DMARC TXT records, and proxied vs. unproxied mismatches.\n4. Group findings by record type and severity.\n\n## Output\nA prioritized list of DNS issues with the record name, type, current value, and recommended fix.', - }, - { - name: 'purge-cache', - description: - 'Purge Cloudflare cache for specific URLs or an entire zone after a deploy, then confirm what was cleared.', - content: - '# Purge Cloudflare Cache\n\nClear cached content so visitors see the latest deploy.\n\n## Steps\n1. Identify the affected zone and the paths or hostnames that changed.\n2. Purge by specific files when possible; only purge everything for the zone if the change is global.\n3. Confirm the purge succeeded and note the timestamp.\n\n## Output\nA short confirmation listing the zone, the purged URLs (or "full zone"), and the purge time.', - }, - { - name: 'check-ssl-and-zone-settings', - description: - 'Inspect SSL certificate status and security settings for Cloudflare zones and report drift from a desired baseline.', - content: - '# Check SSL and Zone Settings\n\nVerify SSL/TLS posture and key security settings across zones.\n\n## Steps\n1. List the target zones.\n2. For each zone read SSL mode, certificate status/expiry, minimum TLS version, and security level.\n3. Compare against the desired baseline (e.g. Full Strict, TLS 1.2+).\n4. Flag expiring certs and any setting weaker than the baseline.\n\n## Output\nA per-zone table of SSL status, settings, and any drift that needs remediation.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudformation.display.ts b/apps/sim/blocks/blocks/cloudformation.display.ts index 29534978c59..441f14130f7 100644 --- a/apps/sim/blocks/blocks/cloudformation.display.ts +++ b/apps/sim/blocks/blocks/cloudformation.display.ts @@ -1,6 +1,6 @@ import { CloudFormationIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CloudFormationBlockDisplay = { type: 'cloudformation', @@ -15,3 +15,100 @@ export const CloudFormationBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/cloudformation', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const CloudFormationBlockMeta = { + tags: ['cloud'], + url: 'https://aws.amazon.com/cloudformation', + templates: [ + { + icon: CloudFormationIcon, + title: 'CloudFormation drift detector', + prompt: + 'Create a scheduled daily workflow that runs drift detection on every CloudFormation stack in my AWS account, waits for detection to complete, summarizes drifted resources, logs them to a table, and posts a Slack alert when any production stack drifts.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: CloudFormationIcon, + title: 'Stack inventory builder', + prompt: + 'Build a scheduled weekly workflow that describes every CloudFormation stack, lists its resources, and writes a unified inventory of stacks, status, region, and resource counts into a tracking table so the platform team has a single source of truth.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'reporting'], + }, + { + icon: CloudFormationIcon, + title: 'Template validator gate', + prompt: + 'Create a workflow triggered when a CloudFormation template is changed in a GitHub pull request. Pull the template, validate it via the CloudFormation API, summarize any syntax or structural errors, and post the validation result as a PR comment to block merges on broken templates.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'engineering'], + alsoIntegrations: ['github'], + }, + { + icon: CloudFormationIcon, + title: 'Stack failure investigator', + prompt: + 'Build a scheduled workflow that polls CloudFormation stack events every few minutes, detects rollbacks and create-failed events, pulls the failure reason and recent events from the stack, summarizes the root cause, opens a Linear ticket with the diagnosis, and posts to the on-call Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: CloudFormationIcon, + title: 'Template archive and search', + prompt: + 'Create a scheduled workflow that retrieves the deployed template for every CloudFormation stack, stores each template as a versioned file in your files store, and updates a knowledge base so engineers can search infrastructure definitions in natural language.', + modules: ['scheduled', 'files', 'knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'research'], + }, + { + icon: CloudFormationIcon, + title: 'Resource change report', + prompt: + 'Build a scheduled weekly workflow that pulls CloudFormation stack events, summarizes resource creates, updates, and deletes across the account, classifies risky changes, and writes a written change report file for platform leadership review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting', 'enterprise'], + }, + { + icon: CloudFormationIcon, + title: 'Pre-deploy drift gate', + prompt: + 'Create a workflow that runs before a deploy, initiates drift detection on the target CloudFormation stack, polls until drift detection completes, and either approves the deploy or blocks it with a Slack alert explaining the drifted resources.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'detect-stack-drift', + description: + 'Run drift detection on CloudFormation stacks and summarize resources whose live config no longer matches the template.', + content: + '# Detect CloudFormation Stack Drift\n\nFind resources that have been changed outside of CloudFormation.\n\n## Steps\n1. List the target stacks (or accept a specific stack name).\n2. Initiate drift detection for each stack and poll until detection completes.\n3. Pull the drift results and isolate resources with status DRIFTED or DELETED.\n4. For each drifted resource, summarize the property differences.\n\n## Output\nA per-stack drift report listing each drifted resource, its type, and the specific properties that differ from the template.', + }, + { + name: 'inventory-stacks', + description: + 'List CloudFormation stacks with their status, region, and resources to build a single inventory of deployed infrastructure.', + content: + '# Inventory CloudFormation Stacks\n\nBuild a unified view of all deployed stacks.\n\n## Steps\n1. List every stack and capture name, status, creation/update time, and region.\n2. For each stack, describe its resources and count them by type.\n3. Highlight stacks in failed or rollback states.\n\n## Output\nA table of stacks with status, region, resource count, and any stacks needing attention.', + }, + { + name: 'investigate-stack-failure', + description: + 'Pull recent CloudFormation stack events to diagnose a failed create, update, or rollback and explain the root cause.', + content: + '# Investigate CloudFormation Stack Failure\n\nDiagnose why a stack operation failed.\n\n## Steps\n1. Describe the target stack and confirm its current status.\n2. Pull recent stack events, ordered newest first.\n3. Find the first FAILED event and read its resource status reason.\n4. Trace any dependent resource failures that cascaded from it.\n\n## Output\nA plain-English root-cause summary naming the failing resource, the error reason, and a suggested fix.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudformation.ts b/apps/sim/blocks/blocks/cloudformation.ts index bc4bea8e9b3..b12b410702c 100644 --- a/apps/sim/blocks/blocks/cloudformation.ts +++ b/apps/sim/blocks/blocks/cloudformation.ts @@ -1,6 +1,5 @@ -import { CloudFormationIcon } from '@/components/icons' import { CloudFormationBlockDisplay } from '@/blocks/blocks/cloudformation.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { CloudFormationDescribeStackDriftDetectionStatusResponse, CloudFormationDescribeStackEventsResponse, @@ -318,100 +317,3 @@ export const CloudFormationBlock: BlockConfig< }, }, } - -export const CloudFormationBlockMeta = { - tags: ['cloud'], - url: 'https://aws.amazon.com/cloudformation', - templates: [ - { - icon: CloudFormationIcon, - title: 'CloudFormation drift detector', - prompt: - 'Create a scheduled daily workflow that runs drift detection on every CloudFormation stack in my AWS account, waits for detection to complete, summarizes drifted resources, logs them to a table, and posts a Slack alert when any production stack drifts.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: CloudFormationIcon, - title: 'Stack inventory builder', - prompt: - 'Build a scheduled weekly workflow that describes every CloudFormation stack, lists its resources, and writes a unified inventory of stacks, status, region, and resource counts into a tracking table so the platform team has a single source of truth.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'reporting'], - }, - { - icon: CloudFormationIcon, - title: 'Template validator gate', - prompt: - 'Create a workflow triggered when a CloudFormation template is changed in a GitHub pull request. Pull the template, validate it via the CloudFormation API, summarize any syntax or structural errors, and post the validation result as a PR comment to block merges on broken templates.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'engineering'], - alsoIntegrations: ['github'], - }, - { - icon: CloudFormationIcon, - title: 'Stack failure investigator', - prompt: - 'Build a scheduled workflow that polls CloudFormation stack events every few minutes, detects rollbacks and create-failed events, pulls the failure reason and recent events from the stack, summarizes the root cause, opens a Linear ticket with the diagnosis, and posts to the on-call Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: CloudFormationIcon, - title: 'Template archive and search', - prompt: - 'Create a scheduled workflow that retrieves the deployed template for every CloudFormation stack, stores each template as a versioned file in your files store, and updates a knowledge base so engineers can search infrastructure definitions in natural language.', - modules: ['scheduled', 'files', 'knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'research'], - }, - { - icon: CloudFormationIcon, - title: 'Resource change report', - prompt: - 'Build a scheduled weekly workflow that pulls CloudFormation stack events, summarizes resource creates, updates, and deletes across the account, classifies risky changes, and writes a written change report file for platform leadership review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting', 'enterprise'], - }, - { - icon: CloudFormationIcon, - title: 'Pre-deploy drift gate', - prompt: - 'Create a workflow that runs before a deploy, initiates drift detection on the target CloudFormation stack, polls until drift detection completes, and either approves the deploy or blocks it with a Slack alert explaining the drifted resources.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'detect-stack-drift', - description: - 'Run drift detection on CloudFormation stacks and summarize resources whose live config no longer matches the template.', - content: - '# Detect CloudFormation Stack Drift\n\nFind resources that have been changed outside of CloudFormation.\n\n## Steps\n1. List the target stacks (or accept a specific stack name).\n2. Initiate drift detection for each stack and poll until detection completes.\n3. Pull the drift results and isolate resources with status DRIFTED or DELETED.\n4. For each drifted resource, summarize the property differences.\n\n## Output\nA per-stack drift report listing each drifted resource, its type, and the specific properties that differ from the template.', - }, - { - name: 'inventory-stacks', - description: - 'List CloudFormation stacks with their status, region, and resources to build a single inventory of deployed infrastructure.', - content: - '# Inventory CloudFormation Stacks\n\nBuild a unified view of all deployed stacks.\n\n## Steps\n1. List every stack and capture name, status, creation/update time, and region.\n2. For each stack, describe its resources and count them by type.\n3. Highlight stacks in failed or rollback states.\n\n## Output\nA table of stacks with status, region, resource count, and any stacks needing attention.', - }, - { - name: 'investigate-stack-failure', - description: - 'Pull recent CloudFormation stack events to diagnose a failed create, update, or rollback and explain the root cause.', - content: - '# Investigate CloudFormation Stack Failure\n\nDiagnose why a stack operation failed.\n\n## Steps\n1. Describe the target stack and confirm its current status.\n2. Pull recent stack events, ordered newest first.\n3. Find the first FAILED event and read its resource status reason.\n4. Trace any dependent resource failures that cascaded from it.\n\n## Output\nA plain-English root-cause summary naming the failing resource, the error reason, and a suggested fix.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudwatch.display.ts b/apps/sim/blocks/blocks/cloudwatch.display.ts index abf29fbaa63..0ed78b3e2b4 100644 --- a/apps/sim/blocks/blocks/cloudwatch.display.ts +++ b/apps/sim/blocks/blocks/cloudwatch.display.ts @@ -1,6 +1,6 @@ import { CloudWatchIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CloudWatchBlockDisplay = { type: 'cloudwatch', @@ -15,3 +15,102 @@ export const CloudWatchBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/cloudwatch', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const CloudWatchBlockMeta = { + tags: ['cloud', 'monitoring'], + url: 'https://aws.amazon.com/cloudwatch', + templates: [ + { + icon: CloudWatchIcon, + title: 'CloudWatch alarm digest', + prompt: + 'Create a scheduled daily workflow that summarizes the past 24 hours of CloudWatch alarms by service and severity, identifies repeat offenders, and posts a digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch log triage', + prompt: + 'Build a scheduled workflow that runs CloudWatch Logs Insights queries hourly for error patterns, clusters matches, writes top groups to a triage table, and pings the on-call engineer.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch cost-control alerts', + prompt: + 'Create a scheduled workflow that pulls CloudWatch billing alarms daily, projects month-end spend by service, and posts an alert when projection exceeds budget thresholds.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch incident scribe', + prompt: + 'Build a scheduled workflow that polls CloudWatch alarms every few minutes for any in ALARM state, captures the surrounding metrics and recent log excerpts, and writes a timeline file for the incident review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch SLO burn-rate watcher', + prompt: + 'Create a workflow that monitors CloudWatch SLO burn rate every five minutes, classifies severity, and pages the on-call team via PagerDuty when burn exceeds fast-burn thresholds.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch metric archiver', + prompt: + 'Build a scheduled workflow that exports CloudWatch metric snapshots into S3 long-term storage, preserving granularity for compliance, and writing a manifest table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['s3'], + }, + { + icon: CloudWatchIcon, + title: 'CloudWatch log error triager', + prompt: + 'Create a workflow that runs a CloudWatch Logs Insights query against application log groups every few minutes, groups recurring error signatures with an agent, opens a Linear issue for any new error pattern, and posts a Slack alert.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['linear', 'slack'], + }, + ], + skills: [ + { + name: 'investigate-error-spike', + description: + 'Run a CloudWatch Logs Insights query to find and summarize error spikes in a log group over a time window.', + content: + '# Investigate CloudWatch Error Spike\n\nFind the cause of an error spike using Logs Insights.\n\n## Steps\n1. Identify the relevant log group and the time window to investigate.\n2. Run a Logs Insights query that filters for error or exception lines and aggregates by error type.\n3. Pull representative sample log events for the top error groups.\n4. Correlate timing with any recent deploys or traffic changes.\n\n## Output\nA summary of the top error types, their counts, sample messages, and the likely cause.', + }, + { + name: 'check-metric-health', + description: + 'Pull CloudWatch metric statistics for a resource and report whether key metrics are within healthy ranges.', + content: + '# Check CloudWatch Metric Health\n\nReview key metrics for a resource against expected thresholds.\n\n## Steps\n1. Identify the namespace, metric names, and dimensions for the resource (e.g. CPUUtilization, latency, error rate).\n2. Get metric statistics over the chosen window with an appropriate period and statistic (Average, p99, Sum).\n3. Compare values against healthy thresholds.\n\n## Output\nA per-metric summary with the current value, trend, and whether it is within a healthy range.', + }, + { + name: 'review-alarm-state', + description: + 'List CloudWatch alarms, report which are in ALARM or INSUFFICIENT_DATA, and optionally mute noisy alarms.', + content: + '# Review CloudWatch Alarm State\n\nGet a snapshot of alarm health across the account.\n\n## Steps\n1. Describe alarms and group them by state (OK, ALARM, INSUFFICIENT_DATA).\n2. For alarms in ALARM, capture the metric, threshold, and reason.\n3. If asked, mute alarms that are known-noisy during a maintenance window and note them.\n\n## Output\nA list of alarms currently firing or missing data, with the metric and threshold for each.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cloudwatch.ts b/apps/sim/blocks/blocks/cloudwatch.ts index 397050f0f49..68fb081abc7 100644 --- a/apps/sim/blocks/blocks/cloudwatch.ts +++ b/apps/sim/blocks/blocks/cloudwatch.ts @@ -1,6 +1,5 @@ -import { CloudWatchIcon } from '@/components/icons' import { CloudWatchBlockDisplay } from '@/blocks/blocks/cloudwatch.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { CloudWatchDescribeAlarmsResponse, CloudWatchDescribeLogGroupsResponse, @@ -866,102 +865,3 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`, }, }, } - -export const CloudWatchBlockMeta = { - tags: ['cloud', 'monitoring'], - url: 'https://aws.amazon.com/cloudwatch', - templates: [ - { - icon: CloudWatchIcon, - title: 'CloudWatch alarm digest', - prompt: - 'Create a scheduled daily workflow that summarizes the past 24 hours of CloudWatch alarms by service and severity, identifies repeat offenders, and posts a digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch log triage', - prompt: - 'Build a scheduled workflow that runs CloudWatch Logs Insights queries hourly for error patterns, clusters matches, writes top groups to a triage table, and pings the on-call engineer.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch cost-control alerts', - prompt: - 'Create a scheduled workflow that pulls CloudWatch billing alarms daily, projects month-end spend by service, and posts an alert when projection exceeds budget thresholds.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch incident scribe', - prompt: - 'Build a scheduled workflow that polls CloudWatch alarms every few minutes for any in ALARM state, captures the surrounding metrics and recent log excerpts, and writes a timeline file for the incident review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch SLO burn-rate watcher', - prompt: - 'Create a workflow that monitors CloudWatch SLO burn rate every five minutes, classifies severity, and pages the on-call team via PagerDuty when burn exceeds fast-burn thresholds.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch metric archiver', - prompt: - 'Build a scheduled workflow that exports CloudWatch metric snapshots into S3 long-term storage, preserving granularity for compliance, and writing a manifest table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['s3'], - }, - { - icon: CloudWatchIcon, - title: 'CloudWatch log error triager', - prompt: - 'Create a workflow that runs a CloudWatch Logs Insights query against application log groups every few minutes, groups recurring error signatures with an agent, opens a Linear issue for any new error pattern, and posts a Slack alert.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['linear', 'slack'], - }, - ], - skills: [ - { - name: 'investigate-error-spike', - description: - 'Run a CloudWatch Logs Insights query to find and summarize error spikes in a log group over a time window.', - content: - '# Investigate CloudWatch Error Spike\n\nFind the cause of an error spike using Logs Insights.\n\n## Steps\n1. Identify the relevant log group and the time window to investigate.\n2. Run a Logs Insights query that filters for error or exception lines and aggregates by error type.\n3. Pull representative sample log events for the top error groups.\n4. Correlate timing with any recent deploys or traffic changes.\n\n## Output\nA summary of the top error types, their counts, sample messages, and the likely cause.', - }, - { - name: 'check-metric-health', - description: - 'Pull CloudWatch metric statistics for a resource and report whether key metrics are within healthy ranges.', - content: - '# Check CloudWatch Metric Health\n\nReview key metrics for a resource against expected thresholds.\n\n## Steps\n1. Identify the namespace, metric names, and dimensions for the resource (e.g. CPUUtilization, latency, error rate).\n2. Get metric statistics over the chosen window with an appropriate period and statistic (Average, p99, Sum).\n3. Compare values against healthy thresholds.\n\n## Output\nA per-metric summary with the current value, trend, and whether it is within a healthy range.', - }, - { - name: 'review-alarm-state', - description: - 'List CloudWatch alarms, report which are in ALARM or INSUFFICIENT_DATA, and optionally mute noisy alarms.', - content: - '# Review CloudWatch Alarm State\n\nGet a snapshot of alarm health across the account.\n\n## Steps\n1. Describe alarms and group them by state (OK, ALARM, INSUFFICIENT_DATA).\n2. For alarms in ALARM, capture the metric, threshold, and reason.\n3. If asked, mute alarms that are known-noisy during a maintenance window and note them.\n\n## Output\nA list of alarms currently firing or missing data, with the metric and threshold for each.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/codepipeline.display.ts b/apps/sim/blocks/blocks/codepipeline.display.ts index 1ef405074b7..ea43cdda10a 100644 --- a/apps/sim/blocks/blocks/codepipeline.display.ts +++ b/apps/sim/blocks/blocks/codepipeline.display.ts @@ -1,6 +1,6 @@ import { CodePipelineIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CodePipelineBlockDisplay = { type: 'codepipeline', @@ -15,3 +15,109 @@ export const CodePipelineBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/codepipeline', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const CodePipelineBlockMeta = { + tags: ['cloud', 'ci-cd'], + url: 'https://aws.amazon.com/codepipeline', + templates: [ + { + icon: CodePipelineIcon, + title: 'CodePipeline deploy approver', + prompt: + 'Build a workflow that checks a CodePipeline pipeline for pending manual approvals, posts the change summary and source revisions to Slack, and approves or rejects the deployment based on the team lead reply.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'ci-cd', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline failure triage', + prompt: + 'Create a scheduled workflow that polls CodePipeline executions every few minutes, and when one fails, pulls the pipeline state to find the failing stage and action error, opens a Linear issue, and alerts the on-call channel in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline release train', + prompt: + 'Build a scheduled workflow that starts the release CodePipeline pipeline every weekday at 9am with the release version as a pipeline variable, then posts the execution ID and a link to Slack.', + modules: ['scheduled', 'workflows'], + category: 'engineering', + tags: ['devops', 'ci-cd', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline deploy digest', + prompt: + 'Create a scheduled daily workflow that lists executions across the team CodePipeline pipelines, summarizes successes, failures, and rollbacks with their source revisions, and posts a digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline flaky-stage retrier', + prompt: + 'Build a scheduled workflow that finds failed CodePipeline executions, retries the failed stage once with failed-actions mode, and escalates to PagerDuty if the retry fails again.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline rollback brake', + prompt: + 'Create a workflow that watches CloudWatch alarms after a deployment, and when an error-rate alarm fires while a CodePipeline execution is in progress, stops the execution with a reason and notifies the release channel.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['cloudwatch', 'slack'], + }, + { + icon: CodePipelineIcon, + title: 'CodePipeline deployment audit log', + prompt: + 'Build a scheduled workflow that records every CodePipeline execution — pipeline, status, trigger, source revisions, and timing — into a table for compliance and deployment-frequency reporting.', + modules: ['scheduled', 'tables', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise', 'reporting'], + }, + ], + skills: [ + { + name: 'approve-pending-deployment', + description: + 'Find a pending CodePipeline manual approval, summarize the change, and approve or reject it.', + content: + '# Approve Pending CodePipeline Deployment\n\nHandle a manual approval gate in a pipeline.\n\n## Steps\n1. Get the pipeline state and locate the action awaiting approval (status InProgress on a manual approval action) and its approval token.\n2. Pull the execution details for the stage to summarize what is being deployed (source revisions, trigger).\n3. Submit the approval result with the token, the Approved or Rejected decision, and a summary explaining the decision.\n\n## Output\nThe decision that was submitted, the approval summary, and the pipeline/stage/action it applied to.', + }, + { + name: 'investigate-failed-pipeline', + description: + 'Find the failing stage and action of a CodePipeline execution and report the error details.', + content: + '# Investigate Failed CodePipeline Execution\n\nDiagnose why a pipeline run failed.\n\n## Steps\n1. List recent executions for the pipeline and identify the failed one (or use the provided execution ID).\n2. Get the pipeline state and find the stage and action with a Failed status.\n3. Capture the action error code, error message, and external execution URL, plus the source revisions that were being deployed.\n\n## Output\nThe failing stage and action, the error details, the commit/revision involved, and a link to the external execution.', + }, + { + name: 'trigger-pipeline-release', + description: + 'Start a CodePipeline execution, optionally with variable overrides, and report the execution ID.', + content: + '# Trigger CodePipeline Release\n\nKick off a pipeline run.\n\n## Steps\n1. Confirm the pipeline name (list pipelines if unsure).\n2. Start the execution, passing any pipeline variable overrides (e.g. version or environment) and an idempotency token if retries are possible.\n3. Optionally poll the pipeline state to confirm the execution entered the first stage.\n\n## Output\nThe pipeline execution ID that was started and the variables it ran with.', + }, + { + name: 'retry-failed-stage', + description: + 'Retry the failed actions of a CodePipeline stage and confirm the stage re-entered execution.', + content: + '# Retry Failed CodePipeline Stage\n\nRe-run a failed stage without restarting the whole pipeline.\n\n## Steps\n1. Get the pipeline state and identify the failed stage and the execution ID stuck in it.\n2. Retry the stage with FAILED_ACTIONS mode (or ALL_ACTIONS if the whole stage should re-run).\n3. Check the pipeline state again to confirm the stage is InProgress.\n\n## Output\nThe stage that was retried, the retry mode used, and the current stage status.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/codepipeline.ts b/apps/sim/blocks/blocks/codepipeline.ts index bef7936236e..7e424e027f8 100644 --- a/apps/sim/blocks/blocks/codepipeline.ts +++ b/apps/sim/blocks/blocks/codepipeline.ts @@ -1,6 +1,5 @@ -import { CodePipelineIcon } from '@/components/icons' import { CodePipelineBlockDisplay } from '@/blocks/blocks/codepipeline.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, @@ -492,109 +491,3 @@ export const CodePipelineBlock: BlockConfig< }, }, } - -export const CodePipelineBlockMeta = { - tags: ['cloud', 'ci-cd'], - url: 'https://aws.amazon.com/codepipeline', - templates: [ - { - icon: CodePipelineIcon, - title: 'CodePipeline deploy approver', - prompt: - 'Build a workflow that checks a CodePipeline pipeline for pending manual approvals, posts the change summary and source revisions to Slack, and approves or rejects the deployment based on the team lead reply.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'ci-cd', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline failure triage', - prompt: - 'Create a scheduled workflow that polls CodePipeline executions every few minutes, and when one fails, pulls the pipeline state to find the failing stage and action error, opens a Linear issue, and alerts the on-call channel in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline release train', - prompt: - 'Build a scheduled workflow that starts the release CodePipeline pipeline every weekday at 9am with the release version as a pipeline variable, then posts the execution ID and a link to Slack.', - modules: ['scheduled', 'workflows'], - category: 'engineering', - tags: ['devops', 'ci-cd', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline deploy digest', - prompt: - 'Create a scheduled daily workflow that lists executions across the team CodePipeline pipelines, summarizes successes, failures, and rollbacks with their source revisions, and posts a digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline flaky-stage retrier', - prompt: - 'Build a scheduled workflow that finds failed CodePipeline executions, retries the failed stage once with failed-actions mode, and escalates to PagerDuty if the retry fails again.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline rollback brake', - prompt: - 'Create a workflow that watches CloudWatch alarms after a deployment, and when an error-rate alarm fires while a CodePipeline execution is in progress, stops the execution with a reason and notifies the release channel.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['cloudwatch', 'slack'], - }, - { - icon: CodePipelineIcon, - title: 'CodePipeline deployment audit log', - prompt: - 'Build a scheduled workflow that records every CodePipeline execution — pipeline, status, trigger, source revisions, and timing — into a table for compliance and deployment-frequency reporting.', - modules: ['scheduled', 'tables', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise', 'reporting'], - }, - ], - skills: [ - { - name: 'approve-pending-deployment', - description: - 'Find a pending CodePipeline manual approval, summarize the change, and approve or reject it.', - content: - '# Approve Pending CodePipeline Deployment\n\nHandle a manual approval gate in a pipeline.\n\n## Steps\n1. Get the pipeline state and locate the action awaiting approval (status InProgress on a manual approval action) and its approval token.\n2. Pull the execution details for the stage to summarize what is being deployed (source revisions, trigger).\n3. Submit the approval result with the token, the Approved or Rejected decision, and a summary explaining the decision.\n\n## Output\nThe decision that was submitted, the approval summary, and the pipeline/stage/action it applied to.', - }, - { - name: 'investigate-failed-pipeline', - description: - 'Find the failing stage and action of a CodePipeline execution and report the error details.', - content: - '# Investigate Failed CodePipeline Execution\n\nDiagnose why a pipeline run failed.\n\n## Steps\n1. List recent executions for the pipeline and identify the failed one (or use the provided execution ID).\n2. Get the pipeline state and find the stage and action with a Failed status.\n3. Capture the action error code, error message, and external execution URL, plus the source revisions that were being deployed.\n\n## Output\nThe failing stage and action, the error details, the commit/revision involved, and a link to the external execution.', - }, - { - name: 'trigger-pipeline-release', - description: - 'Start a CodePipeline execution, optionally with variable overrides, and report the execution ID.', - content: - '# Trigger CodePipeline Release\n\nKick off a pipeline run.\n\n## Steps\n1. Confirm the pipeline name (list pipelines if unsure).\n2. Start the execution, passing any pipeline variable overrides (e.g. version or environment) and an idempotency token if retries are possible.\n3. Optionally poll the pipeline state to confirm the execution entered the first stage.\n\n## Output\nThe pipeline execution ID that was started and the variables it ran with.', - }, - { - name: 'retry-failed-stage', - description: - 'Retry the failed actions of a CodePipeline stage and confirm the stage re-entered execution.', - content: - '# Retry Failed CodePipeline Stage\n\nRe-run a failed stage without restarting the whole pipeline.\n\n## Steps\n1. Get the pipeline state and identify the failed stage and the execution ID stuck in it.\n2. Retry the stage with FAILED_ACTIONS mode (or ALL_ACTIONS if the whole stage should re-run).\n3. Check the pipeline state again to confirm the stage is InProgress.\n\n## Output\nThe stage that was retried, the retry mode used, and the current stage status.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/confluence.display.ts b/apps/sim/blocks/blocks/confluence.display.ts index 2d29756cf48..be6d94d04c4 100644 --- a/apps/sim/blocks/blocks/confluence.display.ts +++ b/apps/sim/blocks/blocks/confluence.display.ts @@ -1,6 +1,7 @@ -import { ConfluenceIcon } from '@/components/icons' +import { Search } from '@/components/emcn/icons' +import { ConfluenceIcon, PagerDutyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ConfluenceBlockDisplay = { type: 'confluence', @@ -22,3 +23,109 @@ export const ConfluenceV2BlockDisplay = { name: 'Confluence', hideFromToolbar: false, } satisfies BlockDisplay + +export const ConfluenceBlockMeta = { + tags: ['knowledge-base', 'content-management', 'note-taking'], + url: 'https://www.atlassian.com/software/confluence', + templates: [ + { + icon: PagerDutyIcon, + title: 'Incident response coordinator', + prompt: + 'Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'engineering', 'automation'], + alsoIntegrations: ['notion', 'pagerduty', 'datadog', 'slack'], + }, + { + icon: ConfluenceIcon, + title: 'Knowledge base sync', + prompt: + 'Create a knowledge base connected to my Confluence workspace so all wiki pages are automatically synced and searchable. Then build a scheduled workflow that identifies stale pages not updated in 90 days and sends a Slack reminder to page owners to review them.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync', 'team'], + alsoIntegrations: ['slack'], + }, + { + icon: Search, + title: 'Multi-source knowledge hub', + prompt: + 'Create a knowledge base and connect it to Confluence, Notion, and Google Drive so all my company documentation is automatically synced, chunked, and embedded. Then deploy a Q&A agent that can answer questions across all sources with citations.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'team', 'sync', 'automation'], + alsoIntegrations: ['notion', 'google_drive'], + }, + { + icon: ConfluenceIcon, + title: 'Confluence weekly contributor digest', + prompt: + 'Build a scheduled workflow that aggregates the week’s new and updated Confluence pages, identifies top contributors, and posts a digest to the team Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ConfluenceIcon, + title: 'Confluence space migration helper', + prompt: + 'Create a workflow that takes a source Confluence space, copies pages into a target space with rewritten internal links, attachments, and labels, and writes a mapping table for redirects.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + }, + { + icon: ConfluenceIcon, + title: 'Confluence question router', + prompt: + 'Build a workflow that watches a Confluence space for new questions, finds the right SME via labels, pings them on Slack, and updates the question page with a sourced answer once available.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: Search, + title: 'Confluence knowledge assistant', + prompt: + 'Create a knowledge base synced from a Confluence space, then build a Slack agent that searches Confluence pages to answer team questions, cites the source page, and offers to create a new page when an answer is missing.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'research', 'communication'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'publish-meeting-notes', + description: + 'Create a Confluence page with structured meeting notes including attendees, decisions, and action items in the right space.', + content: + '# Publish Meeting Notes to Confluence\n\nTurn raw meeting notes into a clean, structured Confluence page.\n\n## Steps\n1. Confirm the target space and any parent page.\n2. Structure the notes into sections: attendees, agenda, decisions, and action items with owners.\n3. Create the page with a clear, dated title.\n4. Return the page URL.\n\n## Output\nA confirmation with the new page title and link, plus the list of action items captured.', + }, + { + name: 'update-doc-page', + description: + 'Read an existing Confluence page, apply updates, and save it back, respecting version control to avoid conflicts.', + content: + '# Update a Confluence Page\n\nSafely edit an existing documentation page.\n\n## Steps\n1. Read the target page to get its current content and version number.\n2. Apply the requested changes to the body, preserving existing structure and formatting.\n3. Update the page, incrementing the version number by one to avoid optimistic-locking conflicts.\n4. If the update fails on a version conflict, re-read and retry.\n\n## Output\nA confirmation of the updated page with its new version number and link.', + }, + { + name: 'search-knowledge', + description: + 'Search Confluence content for a topic and summarize the most relevant pages with links for quick reference.', + content: + '# Search Confluence Knowledge\n\nFind and summarize documentation on a topic.\n\n## Steps\n1. Search content using the topic keywords, optionally scoped to a space.\n2. Read the top matching pages.\n3. Summarize what each page covers and how it relates to the question.\n\n## Output\nA short briefing answering the question, with links to the source pages cited.', + }, + { + name: 'collect-page-feedback', + description: + 'List and summarize comments on a Confluence page so you can triage feedback and open questions.', + content: + '# Collect Confluence Page Feedback\n\nGather and organize comments left on a page.\n\n## Steps\n1. Read the target page to confirm its identity.\n2. List all comments on the page.\n3. Group comments into themes: questions, corrections, and approvals.\n\n## Output\nA digest of comment themes with any unresolved questions flagged for follow-up.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/confluence.ts b/apps/sim/blocks/blocks/confluence.ts index a156491b23b..f0ad6f5590e 100644 --- a/apps/sim/blocks/blocks/confluence.ts +++ b/apps/sim/blocks/blocks/confluence.ts @@ -1,11 +1,9 @@ -import { Search } from '@/components/emcn/icons' -import { ConfluenceIcon, PagerDutyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { ConfluenceBlockDisplay, ConfluenceV2BlockDisplay, } from '@/blocks/blocks/confluence.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ConfluenceResponse } from '@/tools/confluence/types' @@ -1593,109 +1591,3 @@ export const ConfluenceV2Block: BlockConfig = { nextCursor: { type: 'string', description: 'Cursor for fetching next page of results' }, }, } - -export const ConfluenceBlockMeta = { - tags: ['knowledge-base', 'content-management', 'note-taking'], - url: 'https://www.atlassian.com/software/confluence', - templates: [ - { - icon: PagerDutyIcon, - title: 'Incident response coordinator', - prompt: - 'Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'engineering', 'automation'], - alsoIntegrations: ['notion', 'pagerduty', 'datadog', 'slack'], - }, - { - icon: ConfluenceIcon, - title: 'Knowledge base sync', - prompt: - 'Create a knowledge base connected to my Confluence workspace so all wiki pages are automatically synced and searchable. Then build a scheduled workflow that identifies stale pages not updated in 90 days and sends a Slack reminder to page owners to review them.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync', 'team'], - alsoIntegrations: ['slack'], - }, - { - icon: Search, - title: 'Multi-source knowledge hub', - prompt: - 'Create a knowledge base and connect it to Confluence, Notion, and Google Drive so all my company documentation is automatically synced, chunked, and embedded. Then deploy a Q&A agent that can answer questions across all sources with citations.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'team', 'sync', 'automation'], - alsoIntegrations: ['notion', 'google_drive'], - }, - { - icon: ConfluenceIcon, - title: 'Confluence weekly contributor digest', - prompt: - 'Build a scheduled workflow that aggregates the week’s new and updated Confluence pages, identifies top contributors, and posts a digest to the team Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ConfluenceIcon, - title: 'Confluence space migration helper', - prompt: - 'Create a workflow that takes a source Confluence space, copies pages into a target space with rewritten internal links, attachments, and labels, and writes a mapping table for redirects.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - }, - { - icon: ConfluenceIcon, - title: 'Confluence question router', - prompt: - 'Build a workflow that watches a Confluence space for new questions, finds the right SME via labels, pings them on Slack, and updates the question page with a sourced answer once available.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: Search, - title: 'Confluence knowledge assistant', - prompt: - 'Create a knowledge base synced from a Confluence space, then build a Slack agent that searches Confluence pages to answer team questions, cites the source page, and offers to create a new page when an answer is missing.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'research', 'communication'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'publish-meeting-notes', - description: - 'Create a Confluence page with structured meeting notes including attendees, decisions, and action items in the right space.', - content: - '# Publish Meeting Notes to Confluence\n\nTurn raw meeting notes into a clean, structured Confluence page.\n\n## Steps\n1. Confirm the target space and any parent page.\n2. Structure the notes into sections: attendees, agenda, decisions, and action items with owners.\n3. Create the page with a clear, dated title.\n4. Return the page URL.\n\n## Output\nA confirmation with the new page title and link, plus the list of action items captured.', - }, - { - name: 'update-doc-page', - description: - 'Read an existing Confluence page, apply updates, and save it back, respecting version control to avoid conflicts.', - content: - '# Update a Confluence Page\n\nSafely edit an existing documentation page.\n\n## Steps\n1. Read the target page to get its current content and version number.\n2. Apply the requested changes to the body, preserving existing structure and formatting.\n3. Update the page, incrementing the version number by one to avoid optimistic-locking conflicts.\n4. If the update fails on a version conflict, re-read and retry.\n\n## Output\nA confirmation of the updated page with its new version number and link.', - }, - { - name: 'search-knowledge', - description: - 'Search Confluence content for a topic and summarize the most relevant pages with links for quick reference.', - content: - '# Search Confluence Knowledge\n\nFind and summarize documentation on a topic.\n\n## Steps\n1. Search content using the topic keywords, optionally scoped to a space.\n2. Read the top matching pages.\n3. Summarize what each page covers and how it relates to the question.\n\n## Output\nA short briefing answering the question, with links to the source pages cited.', - }, - { - name: 'collect-page-feedback', - description: - 'List and summarize comments on a Confluence page so you can triage feedback and open questions.', - content: - '# Collect Confluence Page Feedback\n\nGather and organize comments left on a page.\n\n## Steps\n1. Read the target page to confirm its identity.\n2. List all comments on the page.\n3. Group comments into themes: questions, corrections, and approvals.\n\n## Output\nA digest of comment themes with any unresolved questions flagged for follow-up.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/context_dev.display.ts b/apps/sim/blocks/blocks/context_dev.display.ts index 5610df03436..f4c0572f65d 100644 --- a/apps/sim/blocks/blocks/context_dev.display.ts +++ b/apps/sim/blocks/blocks/context_dev.display.ts @@ -1,6 +1,6 @@ import { ContextDevIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ContextDevBlockDisplay = { type: 'context_dev', @@ -14,3 +14,93 @@ export const ContextDevBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/context_dev', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const ContextDevBlockMeta = { + tags: ['web-scraping', 'enrichment', 'automation'], + url: 'https://www.context.dev', + templates: [ + { + icon: ContextDevIcon, + title: 'Context.dev knowledge-base builder', + prompt: + 'Build a workflow that maps a documentation site with Context.dev, crawls each page to clean markdown, chunks and embeds the content, and upserts it into a knowledge base for an answering agent.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'sync'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev competitor monitor', + prompt: + 'Build a scheduled workflow that scrapes competitor pricing and changelog pages to markdown with Context.dev weekly, diffs against the prior snapshot, logs changes to a table, and posts notable updates to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev lead enrichment', + prompt: + 'Create a workflow that takes a work email, uses Context.dev to retrieve brand data by email and classify the company into NAICS codes, and writes the enriched firmographics to a CRM record.', + modules: ['agent', 'tables', 'workflows'], + category: 'sales', + tags: ['enrichment', 'sales'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev structured data extractor', + prompt: + 'Build a workflow that takes a website URL and a JSON schema, uses Context.dev Extract to pull structured fields across the site, and returns the validated records as JSON.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'research'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev research brief', + prompt: + 'Create an agent that runs a Context.dev web search on a topic, scrapes the top results to markdown, and synthesizes a cited research brief saved as a file.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev design-system extractor', + prompt: + 'Build a workflow that takes a domain, uses Context.dev to scrape its styleguide and fonts plus a homepage screenshot, and stores the design tokens and assets as files for a design handoff.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['design', 'research'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev transaction enrichment', + prompt: + 'Create a workflow that takes raw bank transaction descriptors, uses Context.dev to identify the merchant brand behind each one, and appends the resolved company and logo to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enrichment', 'automation'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev product catalog importer', + prompt: + "Build a workflow that takes a brand domain, uses Context.dev to extract the brand's product catalog with pricing and features, and writes each product as a row in a table.", + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enrichment', 'automation'], + }, + { + icon: ContextDevIcon, + title: 'Context.dev site change watcher', + prompt: + 'Build a scheduled workflow that maps a site sitemap with Context.dev, scrapes new or changed pages to markdown, summarizes the differences, and emails a digest.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/context_dev.ts b/apps/sim/blocks/blocks/context_dev.ts index deac2ff965a..c65157a140e 100644 --- a/apps/sim/blocks/blocks/context_dev.ts +++ b/apps/sim/blocks/blocks/context_dev.ts @@ -1,6 +1,5 @@ -import { ContextDevIcon } from '@/components/icons' import { ContextDevBlockDisplay } from '@/blocks/blocks/context_dev.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ContextDevScrapeMarkdownResponse } from '@/tools/context_dev/types' @@ -840,93 +839,3 @@ Do not include any explanations, markdown formatting, or other text outside the creditsRemaining: { type: 'number', description: 'Credits remaining on the API key' }, }, } - -export const ContextDevBlockMeta = { - tags: ['web-scraping', 'enrichment', 'automation'], - url: 'https://www.context.dev', - templates: [ - { - icon: ContextDevIcon, - title: 'Context.dev knowledge-base builder', - prompt: - 'Build a workflow that maps a documentation site with Context.dev, crawls each page to clean markdown, chunks and embeds the content, and upserts it into a knowledge base for an answering agent.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'sync'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev competitor monitor', - prompt: - 'Build a scheduled workflow that scrapes competitor pricing and changelog pages to markdown with Context.dev weekly, diffs against the prior snapshot, logs changes to a table, and posts notable updates to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev lead enrichment', - prompt: - 'Create a workflow that takes a work email, uses Context.dev to retrieve brand data by email and classify the company into NAICS codes, and writes the enriched firmographics to a CRM record.', - modules: ['agent', 'tables', 'workflows'], - category: 'sales', - tags: ['enrichment', 'sales'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev structured data extractor', - prompt: - 'Build a workflow that takes a website URL and a JSON schema, uses Context.dev Extract to pull structured fields across the site, and returns the validated records as JSON.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'research'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev research brief', - prompt: - 'Create an agent that runs a Context.dev web search on a topic, scrapes the top results to markdown, and synthesizes a cited research brief saved as a file.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev design-system extractor', - prompt: - 'Build a workflow that takes a domain, uses Context.dev to scrape its styleguide and fonts plus a homepage screenshot, and stores the design tokens and assets as files for a design handoff.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['design', 'research'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev transaction enrichment', - prompt: - 'Create a workflow that takes raw bank transaction descriptors, uses Context.dev to identify the merchant brand behind each one, and appends the resolved company and logo to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enrichment', 'automation'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev product catalog importer', - prompt: - "Build a workflow that takes a brand domain, uses Context.dev to extract the brand's product catalog with pricing and features, and writes each product as a row in a table.", - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enrichment', 'automation'], - }, - { - icon: ContextDevIcon, - title: 'Context.dev site change watcher', - prompt: - 'Build a scheduled workflow that maps a site sitemap with Context.dev, scrapes new or changed pages to markdown, summarizes the differences, and emails a digest.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/convex.display.ts b/apps/sim/blocks/blocks/convex.display.ts index dd34d64f826..a24c18783ee 100644 --- a/apps/sim/blocks/blocks/convex.display.ts +++ b/apps/sim/blocks/blocks/convex.display.ts @@ -1,6 +1,6 @@ import { ConvexIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ConvexBlockDisplay = { type: 'convex', @@ -14,3 +14,102 @@ export const ConvexBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/convex', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const ConvexBlockMeta = { + tags: ['cloud'], + url: 'https://www.convex.dev', + templates: [ + { + icon: ConvexIcon, + title: 'Convex support ticket triage', + prompt: + 'Build a workflow that runs a Convex query to fetch open support tickets, classifies each by urgency with an agent, writes the triage label back via a Convex mutation, and posts critical tickets to Slack.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['automation', 'customer-support'], + alsoIntegrations: ['slack'], + }, + { + icon: ConvexIcon, + title: 'Convex nightly backup to S3', + prompt: + 'Create a scheduled workflow that runs each night, pages through every Convex table with List Documents, writes the exported JSON to S3 with date partitions, and records the run in an audit table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: ConvexIcon, + title: 'Convex change-data alerting', + prompt: + 'Build a scheduled workflow that polls Convex Document Deltas for changed rows since the last run, filters for high-value records like fraud flags or large orders, and posts an alert with context to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: ConvexIcon, + title: 'Convex user onboarding automation', + prompt: + 'Create a workflow that receives new-signup webhooks, runs a Convex mutation to provision the user record with defaults, and sends a personalized welcome email.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'email'], + alsoIntegrations: ['gmail'], + }, + { + icon: ConvexIcon, + title: 'Convex daily metrics digest', + prompt: + 'Create a scheduled daily workflow that runs Convex queries for new signups, active users, and key feature usage, summarizes the numbers with an agent, and posts a digest to Slack with day-over-day trend.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['reporting', 'product'], + alsoIntegrations: ['slack'], + }, + { + icon: ConvexIcon, + title: 'Convex search index sync', + prompt: + 'Build a scheduled workflow that uses Convex Document Deltas to mirror changed documents into an Algolia index, removes deleted documents, and writes sync lag to a tables-based monitor.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['algolia'], + }, + { + icon: ConvexIcon, + title: 'Convex schema drift monitor', + prompt: + 'Create a scheduled workflow that runs Convex List Tables, diffs the returned table schemas against the last snapshot stored in a table, and notifies the engineering channel when fields are added, removed, or change type.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'run-convex-function', + description: + 'Run a Convex query, mutation, or action with named arguments and use its result.', + content: + '# Run a Convex Function\n\nCall a function deployed to Convex and work with its return value.\n\n## Steps\n1. Pick the operation that matches the function type: Run Query for reads, Run Mutation for writes, Run Action for side effects like calling external APIs.\n2. Provide the Deployment URL (https://your-deployment.convex.cloud) and a deploy key from the dashboard Settings page.\n3. Set Function Path in module:function form, for example messages:list or tasks/admin:reset.\n4. Pass Function Arguments as a JSON object whose keys match the argument names the function declares, for example {"limit": 10}.\n\n## Output\nThe function result is available as value, with any console output in logLines. Surface the fields downstream steps need.', + }, + { + name: 'export-convex-table', + description: + 'Page through a full Convex table snapshot with List Documents until hasMore is false.', + content: + '# Export a Convex Table\n\nRead every document in a table using snapshot pagination so the export is consistent.\n\n## Steps\n1. Use the List Documents operation with the deployment URL, deploy key, and the table name (leave empty to export all tables).\n2. On the first call leave Snapshot and Cursor empty; the response pins a snapshot timestamp.\n3. While hasMore is true, call List Documents again passing back the returned snapshot and pageCursor values.\n4. Collect the documents arrays from each page into your destination.\n\n## Output\nA complete, point-in-time set of documents for the table, each including _id and _creationTime.', + }, + { + name: 'sync-convex-changes', + description: 'Fetch only changed Convex documents since a snapshot using Document Deltas.', + content: + '# Sync Convex Changes Incrementally\n\nAfter an initial export, keep a downstream copy fresh by reading only what changed.\n\n## Steps\n1. Run an initial export with List Documents and keep the final snapshot value.\n2. On each sync run, call Document Deltas with that value as the Cursor (and optionally a table name).\n3. While hasMore is true, keep calling Document Deltas with the returned cursor; persist the last cursor for the next run.\n4. Apply each document by _id; documents with _deleted set to true should be removed downstream.\n\n## Output\nThe changed documents since the stored cursor plus a new cursor to persist, giving reliable incremental sync when documents are applied idempotently by _id.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/convex.ts b/apps/sim/blocks/blocks/convex.ts index 13636daac36..456e186cbbe 100644 --- a/apps/sim/blocks/blocks/convex.ts +++ b/apps/sim/blocks/blocks/convex.ts @@ -1,6 +1,5 @@ -import { ConvexIcon } from '@/components/icons' import { ConvexBlockDisplay } from '@/blocks/blocks/convex.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ConvexResponse } from '@/tools/convex/types' export const ConvexBlock: BlockConfig = { @@ -188,102 +187,3 @@ Return ONLY the JSON object - no explanations, no markdown, no extra text.`, }, }, } - -export const ConvexBlockMeta = { - tags: ['cloud'], - url: 'https://www.convex.dev', - templates: [ - { - icon: ConvexIcon, - title: 'Convex support ticket triage', - prompt: - 'Build a workflow that runs a Convex query to fetch open support tickets, classifies each by urgency with an agent, writes the triage label back via a Convex mutation, and posts critical tickets to Slack.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['automation', 'customer-support'], - alsoIntegrations: ['slack'], - }, - { - icon: ConvexIcon, - title: 'Convex nightly backup to S3', - prompt: - 'Create a scheduled workflow that runs each night, pages through every Convex table with List Documents, writes the exported JSON to S3 with date partitions, and records the run in an audit table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: ConvexIcon, - title: 'Convex change-data alerting', - prompt: - 'Build a scheduled workflow that polls Convex Document Deltas for changed rows since the last run, filters for high-value records like fraud flags or large orders, and posts an alert with context to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: ConvexIcon, - title: 'Convex user onboarding automation', - prompt: - 'Create a workflow that receives new-signup webhooks, runs a Convex mutation to provision the user record with defaults, and sends a personalized welcome email.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'email'], - alsoIntegrations: ['gmail'], - }, - { - icon: ConvexIcon, - title: 'Convex daily metrics digest', - prompt: - 'Create a scheduled daily workflow that runs Convex queries for new signups, active users, and key feature usage, summarizes the numbers with an agent, and posts a digest to Slack with day-over-day trend.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['reporting', 'product'], - alsoIntegrations: ['slack'], - }, - { - icon: ConvexIcon, - title: 'Convex search index sync', - prompt: - 'Build a scheduled workflow that uses Convex Document Deltas to mirror changed documents into an Algolia index, removes deleted documents, and writes sync lag to a tables-based monitor.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['algolia'], - }, - { - icon: ConvexIcon, - title: 'Convex schema drift monitor', - prompt: - 'Create a scheduled workflow that runs Convex List Tables, diffs the returned table schemas against the last snapshot stored in a table, and notifies the engineering channel when fields are added, removed, or change type.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'run-convex-function', - description: - 'Run a Convex query, mutation, or action with named arguments and use its result.', - content: - '# Run a Convex Function\n\nCall a function deployed to Convex and work with its return value.\n\n## Steps\n1. Pick the operation that matches the function type: Run Query for reads, Run Mutation for writes, Run Action for side effects like calling external APIs.\n2. Provide the Deployment URL (https://your-deployment.convex.cloud) and a deploy key from the dashboard Settings page.\n3. Set Function Path in module:function form, for example messages:list or tasks/admin:reset.\n4. Pass Function Arguments as a JSON object whose keys match the argument names the function declares, for example {"limit": 10}.\n\n## Output\nThe function result is available as value, with any console output in logLines. Surface the fields downstream steps need.', - }, - { - name: 'export-convex-table', - description: - 'Page through a full Convex table snapshot with List Documents until hasMore is false.', - content: - '# Export a Convex Table\n\nRead every document in a table using snapshot pagination so the export is consistent.\n\n## Steps\n1. Use the List Documents operation with the deployment URL, deploy key, and the table name (leave empty to export all tables).\n2. On the first call leave Snapshot and Cursor empty; the response pins a snapshot timestamp.\n3. While hasMore is true, call List Documents again passing back the returned snapshot and pageCursor values.\n4. Collect the documents arrays from each page into your destination.\n\n## Output\nA complete, point-in-time set of documents for the table, each including _id and _creationTime.', - }, - { - name: 'sync-convex-changes', - description: 'Fetch only changed Convex documents since a snapshot using Document Deltas.', - content: - '# Sync Convex Changes Incrementally\n\nAfter an initial export, keep a downstream copy fresh by reading only what changed.\n\n## Steps\n1. Run an initial export with List Documents and keep the final snapshot value.\n2. On each sync run, call Document Deltas with that value as the Cursor (and optionally a table name).\n3. While hasMore is true, keep calling Document Deltas with the returned cursor; persist the last cursor for the next run.\n4. Apply each document by _id; documents with _deleted set to true should be removed downstream.\n\n## Output\nThe changed documents since the stored cursor plus a new cursor to persist, giving reliable incremental sync when documents are applied idempotently by _id.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/crowdstrike.display.ts b/apps/sim/blocks/blocks/crowdstrike.display.ts index 9834c967fc6..561839ce2fa 100644 --- a/apps/sim/blocks/blocks/crowdstrike.display.ts +++ b/apps/sim/blocks/blocks/crowdstrike.display.ts @@ -1,6 +1,6 @@ import { CrowdStrikeIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CrowdStrikeBlockDisplay = { type: 'crowdstrike', @@ -15,3 +15,92 @@ export const CrowdStrikeBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/crowdstrike', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const CrowdStrikeBlockMeta = { + tags: ['identity', 'monitoring'], + url: 'https://www.crowdstrike.com', + templates: [ + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike sensor coverage gaps', + prompt: + 'Create a scheduled workflow that queries CrowdStrike Identity Protection sensors, identifies devices reporting an unprotected or degraded status, opens a PagerDuty incident for critical gaps, and posts the list to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty', 'slack'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike weekly sensor digest', + prompt: + 'Create a scheduled weekly workflow that runs CrowdStrike sensor aggregate queries by status and OS version, summarizes coverage and unprotected counts, and writes a digest file for security leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['enterprise', 'reporting'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike + Okta coverage check', + prompt: + 'Build a workflow that lists CrowdStrike Identity Protection sensors and cross-references them with Okta users and devices to find accounts active on endpoints that have no protected sensor, then writes the findings to a security table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + alsoIntegrations: ['okta'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike asset inventory', + prompt: + 'Create a scheduled workflow that queries CrowdStrike Identity Protection sensors per device, identifies endpoints reporting an unprotected status, and writes the gap list to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike stale sensor finder', + prompt: + 'Build a scheduled workflow that queries CrowdStrike sensors, flags devices whose last heartbeat is older than a threshold, and writes the stale-sensor list to a SOC investigation table for follow-up.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike coverage report doc', + prompt: + 'Create a scheduled workflow that aggregates CrowdStrike sensor status, OS version, and policy assignment, and generates a coverage report doc in Google Docs for the security team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'reporting'], + alsoIntegrations: ['google_docs'], + }, + { + icon: CrowdStrikeIcon, + title: 'CrowdStrike policy drift watcher', + prompt: + 'Build a scheduled workflow that queries CrowdStrike Identity Protection sensors, compares each device’s assigned IdP policy against the expected baseline, and writes mismatches to a SOC review queue.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + }, + ], + skills: [ + { + name: 'audit-identity-sensors', + description: + 'Query CrowdStrike Identity Protection sensors and report on coverage, status, and devices missing protection.', + content: + '# Audit CrowdStrike Identity Sensors\n\nReview Identity Protection sensor coverage across the fleet.\n\n## Steps\n1. Query sensors, optionally filtered by status or hostname.\n2. For sensors of interest, pull detailed attributes (version, last seen, assigned policy).\n3. Flag sensors that are offline, stale, or out of policy.\n\n## Output\nA coverage report listing healthy sensors, plus any that are offline, stale, or misconfigured for SOC review.', + }, + { + name: 'summarize-sensor-aggregates', + description: + 'Pull documented CrowdStrike sensor aggregates and summarize the fleet distribution by version, status, or platform.', + content: + '# Summarize CrowdStrike Sensor Aggregates\n\nBuild a high-level picture of the sensor fleet.\n\n## Steps\n1. Request the documented sensor aggregates (e.g. counts by version, status, or platform).\n2. Compute the distribution and identify outliers, such as a large share of outdated versions.\n3. Compare against the expected baseline.\n\n## Output\nA fleet summary with key counts and any segments that need attention (outdated, offline).', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/crowdstrike.ts b/apps/sim/blocks/blocks/crowdstrike.ts index 4657f480951..368a9299aef 100644 --- a/apps/sim/blocks/blocks/crowdstrike.ts +++ b/apps/sim/blocks/blocks/crowdstrike.ts @@ -1,6 +1,5 @@ -import { CrowdStrikeIcon } from '@/components/icons' import { CrowdStrikeBlockDisplay } from '@/blocks/blocks/crowdstrike.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { parseOptionalJsonInput, parseOptionalNumberInput } from '@/blocks/utils' import type { CrowdStrikeResponse } from '@/tools/crowdstrike/types' @@ -201,92 +200,3 @@ export const CrowdStrikeBlock: BlockConfig = { count: { type: 'number', description: 'Number of records returned by the selected operation' }, }, } - -export const CrowdStrikeBlockMeta = { - tags: ['identity', 'monitoring'], - url: 'https://www.crowdstrike.com', - templates: [ - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike sensor coverage gaps', - prompt: - 'Create a scheduled workflow that queries CrowdStrike Identity Protection sensors, identifies devices reporting an unprotected or degraded status, opens a PagerDuty incident for critical gaps, and posts the list to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty', 'slack'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike weekly sensor digest', - prompt: - 'Create a scheduled weekly workflow that runs CrowdStrike sensor aggregate queries by status and OS version, summarizes coverage and unprotected counts, and writes a digest file for security leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['enterprise', 'reporting'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike + Okta coverage check', - prompt: - 'Build a workflow that lists CrowdStrike Identity Protection sensors and cross-references them with Okta users and devices to find accounts active on endpoints that have no protected sensor, then writes the findings to a security table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - alsoIntegrations: ['okta'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike asset inventory', - prompt: - 'Create a scheduled workflow that queries CrowdStrike Identity Protection sensors per device, identifies endpoints reporting an unprotected status, and writes the gap list to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike stale sensor finder', - prompt: - 'Build a scheduled workflow that queries CrowdStrike sensors, flags devices whose last heartbeat is older than a threshold, and writes the stale-sensor list to a SOC investigation table for follow-up.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike coverage report doc', - prompt: - 'Create a scheduled workflow that aggregates CrowdStrike sensor status, OS version, and policy assignment, and generates a coverage report doc in Google Docs for the security team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'reporting'], - alsoIntegrations: ['google_docs'], - }, - { - icon: CrowdStrikeIcon, - title: 'CrowdStrike policy drift watcher', - prompt: - 'Build a scheduled workflow that queries CrowdStrike Identity Protection sensors, compares each device’s assigned IdP policy against the expected baseline, and writes mismatches to a SOC review queue.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - }, - ], - skills: [ - { - name: 'audit-identity-sensors', - description: - 'Query CrowdStrike Identity Protection sensors and report on coverage, status, and devices missing protection.', - content: - '# Audit CrowdStrike Identity Sensors\n\nReview Identity Protection sensor coverage across the fleet.\n\n## Steps\n1. Query sensors, optionally filtered by status or hostname.\n2. For sensors of interest, pull detailed attributes (version, last seen, assigned policy).\n3. Flag sensors that are offline, stale, or out of policy.\n\n## Output\nA coverage report listing healthy sensors, plus any that are offline, stale, or misconfigured for SOC review.', - }, - { - name: 'summarize-sensor-aggregates', - description: - 'Pull documented CrowdStrike sensor aggregates and summarize the fleet distribution by version, status, or platform.', - content: - '# Summarize CrowdStrike Sensor Aggregates\n\nBuild a high-level picture of the sensor fleet.\n\n## Steps\n1. Request the documented sensor aggregates (e.g. counts by version, status, or platform).\n2. Compute the distribution and identify outliers, such as a large share of outdated versions.\n3. Compare against the expected baseline.\n\n## Output\nA fleet summary with key counts and any segments that need attention (outdated, offline).', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cursor.display.ts b/apps/sim/blocks/blocks/cursor.display.ts index 7b962575ef9..de62fe7bad4 100644 --- a/apps/sim/blocks/blocks/cursor.display.ts +++ b/apps/sim/blocks/blocks/cursor.display.ts @@ -1,6 +1,6 @@ import { CursorIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const CursorBlockDisplay = { type: 'cursor', @@ -25,3 +25,102 @@ export const CursorV2BlockDisplay = { 'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.', hideFromToolbar: false, } satisfies BlockDisplay + +export const CursorBlockMeta = { + tags: ['agentic', 'automation'], + url: 'https://cursor.com', + templates: [ + { + icon: CursorIcon, + title: 'Cursor cloud agent launcher', + prompt: + 'Build a workflow that takes a feature description and a GitHub repository, launches a Cursor cloud agent with structured instructions, polls until the agent finishes, captures the generated pull request link, and posts a summary to Slack so the team can review.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: CursorIcon, + title: 'Cursor issue-to-PR pipeline', + prompt: + 'Create a workflow that fires when a GitHub issue is labeled "auto-fix", crafts a precise prompt from the issue description, launches a Cursor cloud agent on the repository, monitors progress, and comments on the issue with the resulting pull request and conversation summary.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: CursorIcon, + title: 'Cursor agent fleet monitor', + prompt: + 'Build a scheduled workflow that runs every fifteen minutes, lists all active Cursor cloud agents, logs status, runtime, and repository to a tracking table, and posts a daily Slack summary of completed, failing, and long-running agents.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring', 'agentic'], + alsoIntegrations: ['slack'], + }, + { + icon: CursorIcon, + title: 'Test fix delegator', + prompt: + 'Build a workflow triggered by a failing GitHub Actions test run that extracts the failing test name and error, launches a targeted Cursor cloud agent to fix only that test, downloads the artifact diff when ready, and replies on the failed run with the proposed patch.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: CursorIcon, + title: 'Refactor follow-up loop', + prompt: + 'Create a workflow that picks up review comments on a Cursor-authored pull request, formulates each comment as a follow-up instruction, sends them to the originating Cursor cloud agent, and waits for the updated diff before re-requesting review.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: CursorIcon, + title: 'Cursor agent conversation archiver', + prompt: + 'Build a scheduled daily workflow that lists completed Cursor cloud agents, fetches each conversation history, stores the transcripts and produced artifacts as files, and updates a tracking table with prompts, durations, and outcomes for retrospective analysis.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'analysis'], + }, + { + icon: CursorIcon, + title: 'Stuck-agent cleaner', + prompt: + 'Create a scheduled workflow that runs hourly, lists Cursor cloud agents, detects agents stuck in the same state longer than a configurable threshold, stops or deletes them based on rules, and posts a Slack report of the cleanup actions taken.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'launch-coding-agent', + description: + 'Launch a Cursor cloud agent on a GitHub repository with a clear task prompt and report the agent id and starting status.', + content: + '# Launch a Cursor Coding Agent\n\nKick off an autonomous Cursor agent to work on a repo.\n\n## Steps\n1. Confirm the target repository and the task to perform.\n2. Write a precise prompt: what to change, constraints, and acceptance criteria.\n3. Launch the agent with the chosen model and repository.\n4. Capture the agent id and initial status.\n\n## Output\nA confirmation with the agent id, repository, and the task prompt it was given.', + }, + { + name: 'track-agent-progress', + description: + 'Poll a Cursor agent for status and conversation updates and summarize what it has done so far.', + content: + '# Track Cursor Agent Progress\n\nMonitor a running Cursor agent.\n\n## Steps\n1. Get the agent status for the given agent id.\n2. Pull the conversation to see the latest actions and reasoning.\n3. If the agent is finished, list its artifacts; if blocked, identify why.\n\n## Output\nA status summary describing progress, current state, and any blockers or produced artifacts.', + }, + { + name: 'send-agent-followup', + description: + 'Send a follow-up instruction to an in-progress Cursor agent to refine or redirect its work.', + content: + '# Send a Cursor Agent Follow-up\n\nGuide an active agent with additional instructions.\n\n## Steps\n1. Confirm the agent id and review its recent conversation.\n2. Compose a clear follow-up message addressing what to change or add.\n3. Add the follow-up to the agent.\n4. Note that the agent has resumed work.\n\n## Output\nA confirmation that the follow-up was delivered, with the instruction sent.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/cursor.ts b/apps/sim/blocks/blocks/cursor.ts index 1835398318f..d556fdf0209 100644 --- a/apps/sim/blocks/blocks/cursor.ts +++ b/apps/sim/blocks/blocks/cursor.ts @@ -1,6 +1,5 @@ -import { CursorIcon } from '@/components/icons' import { CursorBlockDisplay, CursorV2BlockDisplay } from '@/blocks/blocks/cursor.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { CursorResponse } from '@/tools/cursor/types' @@ -263,102 +262,3 @@ export const CursorV2Block: BlockConfig = { userEmail: { type: 'string', description: 'Key owner email (api key info operation)' }, }, } - -export const CursorBlockMeta = { - tags: ['agentic', 'automation'], - url: 'https://cursor.com', - templates: [ - { - icon: CursorIcon, - title: 'Cursor cloud agent launcher', - prompt: - 'Build a workflow that takes a feature description and a GitHub repository, launches a Cursor cloud agent with structured instructions, polls until the agent finishes, captures the generated pull request link, and posts a summary to Slack so the team can review.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: CursorIcon, - title: 'Cursor issue-to-PR pipeline', - prompt: - 'Create a workflow that fires when a GitHub issue is labeled "auto-fix", crafts a precise prompt from the issue description, launches a Cursor cloud agent on the repository, monitors progress, and comments on the issue with the resulting pull request and conversation summary.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: CursorIcon, - title: 'Cursor agent fleet monitor', - prompt: - 'Build a scheduled workflow that runs every fifteen minutes, lists all active Cursor cloud agents, logs status, runtime, and repository to a tracking table, and posts a daily Slack summary of completed, failing, and long-running agents.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring', 'agentic'], - alsoIntegrations: ['slack'], - }, - { - icon: CursorIcon, - title: 'Test fix delegator', - prompt: - 'Build a workflow triggered by a failing GitHub Actions test run that extracts the failing test name and error, launches a targeted Cursor cloud agent to fix only that test, downloads the artifact diff when ready, and replies on the failed run with the proposed patch.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: CursorIcon, - title: 'Refactor follow-up loop', - prompt: - 'Create a workflow that picks up review comments on a Cursor-authored pull request, formulates each comment as a follow-up instruction, sends them to the originating Cursor cloud agent, and waits for the updated diff before re-requesting review.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: CursorIcon, - title: 'Cursor agent conversation archiver', - prompt: - 'Build a scheduled daily workflow that lists completed Cursor cloud agents, fetches each conversation history, stores the transcripts and produced artifacts as files, and updates a tracking table with prompts, durations, and outcomes for retrospective analysis.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'analysis'], - }, - { - icon: CursorIcon, - title: 'Stuck-agent cleaner', - prompt: - 'Create a scheduled workflow that runs hourly, lists Cursor cloud agents, detects agents stuck in the same state longer than a configurable threshold, stops or deletes them based on rules, and posts a Slack report of the cleanup actions taken.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'launch-coding-agent', - description: - 'Launch a Cursor cloud agent on a GitHub repository with a clear task prompt and report the agent id and starting status.', - content: - '# Launch a Cursor Coding Agent\n\nKick off an autonomous Cursor agent to work on a repo.\n\n## Steps\n1. Confirm the target repository and the task to perform.\n2. Write a precise prompt: what to change, constraints, and acceptance criteria.\n3. Launch the agent with the chosen model and repository.\n4. Capture the agent id and initial status.\n\n## Output\nA confirmation with the agent id, repository, and the task prompt it was given.', - }, - { - name: 'track-agent-progress', - description: - 'Poll a Cursor agent for status and conversation updates and summarize what it has done so far.', - content: - '# Track Cursor Agent Progress\n\nMonitor a running Cursor agent.\n\n## Steps\n1. Get the agent status for the given agent id.\n2. Pull the conversation to see the latest actions and reasoning.\n3. If the agent is finished, list its artifacts; if blocked, identify why.\n\n## Output\nA status summary describing progress, current state, and any blockers or produced artifacts.', - }, - { - name: 'send-agent-followup', - description: - 'Send a follow-up instruction to an in-progress Cursor agent to refine or redirect its work.', - content: - '# Send a Cursor Agent Follow-up\n\nGuide an active agent with additional instructions.\n\n## Steps\n1. Confirm the agent id and review its recent conversation.\n2. Compose a clear follow-up message addressing what to change or add.\n3. Add the follow-up to the agent.\n4. Note that the agent has resumed work.\n\n## Output\nA confirmation that the follow-up was delivered, with the instruction sent.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dagster.display.ts b/apps/sim/blocks/blocks/dagster.display.ts index 30a820f7658..36233c69b16 100644 --- a/apps/sim/blocks/blocks/dagster.display.ts +++ b/apps/sim/blocks/blocks/dagster.display.ts @@ -1,6 +1,6 @@ import { DagsterIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DagsterBlockDisplay = { type: 'dagster', @@ -14,3 +14,108 @@ export const DagsterBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/dagster', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const DagsterBlockMeta = { + tags: ['data-analytics', 'automation'], + url: 'https://dagster.io', + templates: [ + { + icon: DagsterIcon, + title: 'Dagster pipeline status digest', + prompt: + 'Create a scheduled daily workflow that pulls Dagster run statuses for the previous day, identifies failed and skipped runs, and posts a digest with links to the worst offenders in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: DagsterIcon, + title: 'Dagster asset freshness watcher', + prompt: + 'Build a scheduled workflow that polls Dagster assets, checks each critical asset’s latest materialization timestamp against a freshness threshold, alerts when an asset becomes stale, and opens a Linear ticket for the data-platform team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: DagsterIcon, + title: 'Dagster job kickoff orchestrator', + prompt: + 'Create a workflow that triggers a Dagster job with run parameters when an upstream condition is satisfied, polls until completion, and writes the run outcome to a control table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: DagsterIcon, + title: 'Dagster cost dashboard', + prompt: + 'Build a scheduled weekly workflow that pulls Dagster run durations, calculates compute cost per pipeline, and writes a weekly cost dashboard to a finance review file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + }, + { + icon: DagsterIcon, + title: 'Dagster lineage map', + prompt: + 'Create a workflow that exports Dagster asset lineage into a graph database for cross-pipeline impact analysis when an upstream source schema changes.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['neo4j'], + }, + { + icon: DagsterIcon, + title: 'Dagster sensor health watcher', + prompt: + 'Build a scheduled workflow that lists Dagster sensors, checks their tick history, and alerts Slack when a sensor stops emitting ticks unexpectedly.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: DagsterIcon, + title: 'Dagster + Databricks coordinator', + prompt: + 'Create a workflow that orchestrates a Dagster job that triggers a Databricks notebook, waits for completion, captures outputs, and writes the unified run history to a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + alsoIntegrations: ['databricks'], + }, + ], + skills: [ + { + name: 'launch-pipeline-run', + description: + 'Launch a Dagster job run with the right config and report the run id and starting status.', + content: + '# Launch a Dagster Pipeline Run\n\nKick off a data pipeline job.\n\n## Steps\n1. List jobs to confirm the target job name.\n2. Assemble the run config (partitions, tags, resources) for the run.\n3. Launch the run and capture the run id.\n4. Confirm the run entered the queue or started.\n\n## Output\nA confirmation with the run id, job name, and initial status.', + }, + { + name: 'monitor-failed-runs', + description: + 'List recent Dagster runs, surface failures, and pull logs to diagnose why a run failed.', + content: + '# Monitor Failed Dagster Runs\n\nFind and diagnose pipeline failures.\n\n## Steps\n1. List recent runs and filter to those in a failed state.\n2. For each failed run, get the run details and pull its logs.\n3. Identify the failing step/op and the error message.\n4. Decide whether a re-execute of the failed steps is appropriate.\n\n## Output\nA per-run failure summary with the failing op, error, and a recommendation (retry or investigate).', + }, + { + name: 'reexecute-failed-run', + description: + 'Re-execute a failed Dagster run from the point of failure and confirm the new run started.', + content: + '# Re-execute a Failed Dagster Run\n\nRetry a pipeline from where it broke.\n\n## Steps\n1. Get the failed run to confirm its id and failure point.\n2. Re-execute the run, scoping to the failed and downstream steps when supported.\n3. Capture the new run id and status.\n\n## Output\nA confirmation with the original run id, the new run id, and the re-execution scope.', + }, + { + name: 'manage-schedules', + description: + 'List Dagster schedules and sensors and start or stop them to control automated pipeline execution.', + content: + '# Manage Dagster Schedules\n\nControl which automated triggers are running.\n\n## Steps\n1. List schedules and sensors with their current running state.\n2. Identify the schedule or sensor to change.\n3. Start or stop it as requested.\n4. Confirm the new state.\n\n## Output\nA confirmation of which schedules/sensors were started or stopped and their resulting state.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dagster.ts b/apps/sim/blocks/blocks/dagster.ts index f06a9f55792..0c37995ccd4 100644 --- a/apps/sim/blocks/blocks/dagster.ts +++ b/apps/sim/blocks/blocks/dagster.ts @@ -1,6 +1,5 @@ -import { DagsterIcon } from '@/components/icons' import { DagsterBlockDisplay } from '@/blocks/blocks/dagster.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { DagsterResponse } from '@/tools/dagster/types' /** Coerces a subBlock value to a finite number, returning undefined for empty or non-numeric input. */ @@ -658,108 +657,3 @@ Return ONLY the comma-separated asset keys - no explanations, no extra text.`, }, }, } - -export const DagsterBlockMeta = { - tags: ['data-analytics', 'automation'], - url: 'https://dagster.io', - templates: [ - { - icon: DagsterIcon, - title: 'Dagster pipeline status digest', - prompt: - 'Create a scheduled daily workflow that pulls Dagster run statuses for the previous day, identifies failed and skipped runs, and posts a digest with links to the worst offenders in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: DagsterIcon, - title: 'Dagster asset freshness watcher', - prompt: - 'Build a scheduled workflow that polls Dagster assets, checks each critical asset’s latest materialization timestamp against a freshness threshold, alerts when an asset becomes stale, and opens a Linear ticket for the data-platform team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: DagsterIcon, - title: 'Dagster job kickoff orchestrator', - prompt: - 'Create a workflow that triggers a Dagster job with run parameters when an upstream condition is satisfied, polls until completion, and writes the run outcome to a control table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: DagsterIcon, - title: 'Dagster cost dashboard', - prompt: - 'Build a scheduled weekly workflow that pulls Dagster run durations, calculates compute cost per pipeline, and writes a weekly cost dashboard to a finance review file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - }, - { - icon: DagsterIcon, - title: 'Dagster lineage map', - prompt: - 'Create a workflow that exports Dagster asset lineage into a graph database for cross-pipeline impact analysis when an upstream source schema changes.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['neo4j'], - }, - { - icon: DagsterIcon, - title: 'Dagster sensor health watcher', - prompt: - 'Build a scheduled workflow that lists Dagster sensors, checks their tick history, and alerts Slack when a sensor stops emitting ticks unexpectedly.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: DagsterIcon, - title: 'Dagster + Databricks coordinator', - prompt: - 'Create a workflow that orchestrates a Dagster job that triggers a Databricks notebook, waits for completion, captures outputs, and writes the unified run history to a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - alsoIntegrations: ['databricks'], - }, - ], - skills: [ - { - name: 'launch-pipeline-run', - description: - 'Launch a Dagster job run with the right config and report the run id and starting status.', - content: - '# Launch a Dagster Pipeline Run\n\nKick off a data pipeline job.\n\n## Steps\n1. List jobs to confirm the target job name.\n2. Assemble the run config (partitions, tags, resources) for the run.\n3. Launch the run and capture the run id.\n4. Confirm the run entered the queue or started.\n\n## Output\nA confirmation with the run id, job name, and initial status.', - }, - { - name: 'monitor-failed-runs', - description: - 'List recent Dagster runs, surface failures, and pull logs to diagnose why a run failed.', - content: - '# Monitor Failed Dagster Runs\n\nFind and diagnose pipeline failures.\n\n## Steps\n1. List recent runs and filter to those in a failed state.\n2. For each failed run, get the run details and pull its logs.\n3. Identify the failing step/op and the error message.\n4. Decide whether a re-execute of the failed steps is appropriate.\n\n## Output\nA per-run failure summary with the failing op, error, and a recommendation (retry or investigate).', - }, - { - name: 'reexecute-failed-run', - description: - 'Re-execute a failed Dagster run from the point of failure and confirm the new run started.', - content: - '# Re-execute a Failed Dagster Run\n\nRetry a pipeline from where it broke.\n\n## Steps\n1. Get the failed run to confirm its id and failure point.\n2. Re-execute the run, scoping to the failed and downstream steps when supported.\n3. Capture the new run id and status.\n\n## Output\nA confirmation with the original run id, the new run id, and the re-execution scope.', - }, - { - name: 'manage-schedules', - description: - 'List Dagster schedules and sensors and start or stop them to control automated pipeline execution.', - content: - '# Manage Dagster Schedules\n\nControl which automated triggers are running.\n\n## Steps\n1. List schedules and sensors with their current running state.\n2. Identify the schedule or sensor to change.\n3. Start or stop it as requested.\n4. Confirm the new state.\n\n## Output\nA confirmation of which schedules/sensors were started or stopped and their resulting state.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/databricks.display.ts b/apps/sim/blocks/blocks/databricks.display.ts index 5812002a9a5..b8a75c73fcf 100644 --- a/apps/sim/blocks/blocks/databricks.display.ts +++ b/apps/sim/blocks/blocks/databricks.display.ts @@ -1,6 +1,6 @@ import { DatabricksIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DatabricksBlockDisplay = { type: 'databricks', @@ -14,3 +14,101 @@ export const DatabricksBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/databricks', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const DatabricksBlockMeta = { + tags: ['data-warehouse', 'data-analytics', 'cloud'], + url: 'https://www.databricks.com', + templates: [ + { + icon: DatabricksIcon, + title: 'Databricks job runner', + prompt: + 'Build a scheduled workflow that triggers a Databricks job daily, polls until completion, writes the run status and metrics to a control table, and pages on failure.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: DatabricksIcon, + title: 'Databricks cluster cost guard', + prompt: + 'Create a scheduled workflow that lists Databricks clusters hourly, flags clusters that are running while idle, and posts a Slack alert with the candidates to shut down so the platform team can reclaim spend.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: DatabricksIcon, + title: 'Databricks notebook scheduler', + prompt: + 'Build a workflow that runs a parameterized Databricks notebook, captures the outputs as files, and posts the result to a chosen Slack channel for review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: DatabricksIcon, + title: 'Databricks ML feature freshness', + prompt: + 'Create a scheduled workflow that runs SQL against Databricks feature tables to check the latest update timestamp per feature, alerts when a critical feature has stale data, and writes the alert details to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + }, + { + icon: DatabricksIcon, + title: 'Databricks model evaluator', + prompt: + 'Build a workflow that runs a Databricks ML model evaluation job on the latest data, captures the metrics, writes results to a model-registry table, and pings Slack on regression.', + modules: ['agent', 'tables', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: DatabricksIcon, + title: 'Databricks Delta Lake compactor', + prompt: + 'Create a scheduled workflow that runs OPTIMIZE and VACUUM on Databricks Delta Lake tables weekly, captures the size and performance delta, and writes a maintenance report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: DatabricksIcon, + title: 'Databricks job failure watcher', + prompt: + 'Build a workflow that lists recent Databricks job runs every 15 minutes, detects failed runs, pulls the run output and error for an agent to summarize the likely cause, and posts an actionable Slack alert with a link to the run.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'run-sql-query', + description: + 'Execute a SQL query against a Databricks SQL warehouse and return the results in a clean, summarized form.', + content: + '# Run a Databricks SQL Query\n\nQuery a table or view and summarize the result.\n\n## Steps\n1. Confirm the SQL warehouse and the query to run.\n2. Execute the SQL statement and wait for it to complete.\n3. Capture the returned rows and column schema.\n4. Summarize key findings (counts, totals, notable values).\n\n## Output\nThe query results plus a short plain-English summary of what they show.', + }, + { + name: 'trigger-job-run', + description: + 'Trigger a Databricks job, capture the run id, and confirm it started successfully.', + content: + '# Trigger a Databricks Job\n\nKick off a job and confirm it launched.\n\n## Steps\n1. List jobs to confirm the target job id and name.\n2. Run the job with any required parameters.\n3. Capture the run id and starting state.\n\n## Output\nA confirmation with the job name, run id, and initial status.', + }, + { + name: 'monitor-job-run', + description: + 'Check the status of a Databricks job run, pull its output, and diagnose failures.', + content: + '# Monitor a Databricks Job Run\n\nTrack a job run to completion and report results.\n\n## Steps\n1. Get the run for the given run id and read its lifecycle and result state.\n2. If still running, report progress; if finished, pull the run output.\n3. On failure, capture the error and the failing task.\n\n## Output\nA run summary with final state, key output, and (on failure) the error and failing task.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/databricks.ts b/apps/sim/blocks/blocks/databricks.ts index e7e37d07068..522e9c96f13 100644 --- a/apps/sim/blocks/blocks/databricks.ts +++ b/apps/sim/blocks/blocks/databricks.ts @@ -1,6 +1,5 @@ -import { DatabricksIcon } from '@/components/icons' import { DatabricksBlockDisplay } from '@/blocks/blocks/databricks.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { DatabricksResponse } from '@/tools/databricks/types' @@ -463,101 +462,3 @@ Return ONLY the numeric timestamp in milliseconds - no explanations, no extra te }, }, } - -export const DatabricksBlockMeta = { - tags: ['data-warehouse', 'data-analytics', 'cloud'], - url: 'https://www.databricks.com', - templates: [ - { - icon: DatabricksIcon, - title: 'Databricks job runner', - prompt: - 'Build a scheduled workflow that triggers a Databricks job daily, polls until completion, writes the run status and metrics to a control table, and pages on failure.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: DatabricksIcon, - title: 'Databricks cluster cost guard', - prompt: - 'Create a scheduled workflow that lists Databricks clusters hourly, flags clusters that are running while idle, and posts a Slack alert with the candidates to shut down so the platform team can reclaim spend.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: DatabricksIcon, - title: 'Databricks notebook scheduler', - prompt: - 'Build a workflow that runs a parameterized Databricks notebook, captures the outputs as files, and posts the result to a chosen Slack channel for review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: DatabricksIcon, - title: 'Databricks ML feature freshness', - prompt: - 'Create a scheduled workflow that runs SQL against Databricks feature tables to check the latest update timestamp per feature, alerts when a critical feature has stale data, and writes the alert details to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - }, - { - icon: DatabricksIcon, - title: 'Databricks model evaluator', - prompt: - 'Build a workflow that runs a Databricks ML model evaluation job on the latest data, captures the metrics, writes results to a model-registry table, and pings Slack on regression.', - modules: ['agent', 'tables', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: DatabricksIcon, - title: 'Databricks Delta Lake compactor', - prompt: - 'Create a scheduled workflow that runs OPTIMIZE and VACUUM on Databricks Delta Lake tables weekly, captures the size and performance delta, and writes a maintenance report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: DatabricksIcon, - title: 'Databricks job failure watcher', - prompt: - 'Build a workflow that lists recent Databricks job runs every 15 minutes, detects failed runs, pulls the run output and error for an agent to summarize the likely cause, and posts an actionable Slack alert with a link to the run.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'run-sql-query', - description: - 'Execute a SQL query against a Databricks SQL warehouse and return the results in a clean, summarized form.', - content: - '# Run a Databricks SQL Query\n\nQuery a table or view and summarize the result.\n\n## Steps\n1. Confirm the SQL warehouse and the query to run.\n2. Execute the SQL statement and wait for it to complete.\n3. Capture the returned rows and column schema.\n4. Summarize key findings (counts, totals, notable values).\n\n## Output\nThe query results plus a short plain-English summary of what they show.', - }, - { - name: 'trigger-job-run', - description: - 'Trigger a Databricks job, capture the run id, and confirm it started successfully.', - content: - '# Trigger a Databricks Job\n\nKick off a job and confirm it launched.\n\n## Steps\n1. List jobs to confirm the target job id and name.\n2. Run the job with any required parameters.\n3. Capture the run id and starting state.\n\n## Output\nA confirmation with the job name, run id, and initial status.', - }, - { - name: 'monitor-job-run', - description: - 'Check the status of a Databricks job run, pull its output, and diagnose failures.', - content: - '# Monitor a Databricks Job Run\n\nTrack a job run to completion and report results.\n\n## Steps\n1. Get the run for the given run id and read its lifecycle and result state.\n2. If still running, report progress; if finished, pull the run output.\n3. On failure, capture the error and the failing task.\n\n## Output\nA run summary with final state, key output, and (on failure) the error and failing task.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/datadog.display.ts b/apps/sim/blocks/blocks/datadog.display.ts index 5eced17bc3b..5fcba854348 100644 --- a/apps/sim/blocks/blocks/datadog.display.ts +++ b/apps/sim/blocks/blocks/datadog.display.ts @@ -1,6 +1,6 @@ import { DatadogIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DatadogBlockDisplay = { type: 'datadog', @@ -15,3 +15,109 @@ export const DatadogBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/datadog', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const DatadogBlockMeta = { + tags: ['monitoring', 'incident-management', 'error-tracking'], + url: 'https://www.datadoghq.com', + templates: [ + { + icon: DatadogIcon, + title: 'Infrastructure health report', + prompt: + 'Create a scheduled daily workflow that queries Datadog for key infrastructure metrics — error rates, latency percentiles, CPU and memory usage — logs them to a table for trend tracking, and sends a morning Slack report highlighting any anomalies or degradations.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'infrastructure', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: DatadogIcon, + title: 'Datadog alert-to-Linear bridge', + prompt: + 'Build a scheduled workflow that polls Datadog monitors for any in an alerting state, classifies severity, creates a Linear ticket for non-paging issues with full context, and posts a Slack notification linking both.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: DatadogIcon, + title: 'Datadog SLO weekly review', + prompt: + 'Create a scheduled weekly workflow that queries Datadog timeseries for the key reliability metrics behind each service SLO, computes error budget burn, and writes a narrative review file for the SRE team to discuss in the weekly meeting.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + }, + { + icon: DatadogIcon, + title: 'Datadog cost optimizer', + prompt: + 'Build a scheduled workflow that queries Datadog estimated-usage timeseries for the top custom metrics by volume, writes optimization recommendations to a finance review file, and pings the platform team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: DatadogIcon, + title: 'Datadog monitor config backup', + prompt: + 'Create a scheduled workflow that lists every Datadog monitor nightly, fetches each monitor’s full configuration, exports the definitions as JSON to S3 with version history, and writes a manifest to a tracking table for restore drills.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['s3'], + }, + { + icon: DatadogIcon, + title: 'Datadog deploy guardrail', + prompt: + 'Build a workflow triggered after a deploy that creates a Datadog event marker, queries error-rate and latency timeseries over the next few minutes, and pages the team via PagerDuty if the metrics breach the rollback threshold.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: DatadogIcon, + title: 'Datadog SLO weekly report', + prompt: + 'Create a scheduled weekly workflow that queries Datadog timeseries for key service SLOs, lists which monitors fired during the week, writes the SLO compliance numbers to a table, and emails an availability summary to the on-call leads.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'reporting', 'monitoring'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'triage-firing-monitors', + description: + 'List Datadog monitors, surface those in alert or warn state, and summarize what is firing and why.', + content: + '# Triage Firing Datadog Monitors\n\nGet a clear picture of what is alerting right now.\n\n## Steps\n1. List monitors and filter to those in Alert or Warn states.\n2. For each, get the monitor details: query, threshold, and current value.\n3. Group by service or tag to find common root causes.\n\n## Output\nA prioritized list of firing monitors with the metric, threshold, and likely affected service.', + }, + { + name: 'investigate-logs', + description: + 'Query Datadog logs for a service and time window to find errors and summarize patterns.', + content: + '# Investigate Datadog Logs\n\nSearch logs to diagnose an issue.\n\n## Steps\n1. Confirm the service, environment, and time window.\n2. Query logs filtering for error/critical status and the relevant service tag.\n3. Aggregate by error message or type to find the dominant patterns.\n4. Pull sample log lines for the top patterns.\n\n## Output\nA summary of the top error patterns with counts and sample log lines.', + }, + { + name: 'analyze-metric-trend', + description: + 'Query a Datadog timeseries metric over a window and report the trend, anomalies, and current value.', + content: + '# Analyze a Datadog Metric Trend\n\nUnderstand how a metric is behaving over time.\n\n## Steps\n1. Confirm the metric query and the time window.\n2. Query the timeseries and compute the trend (rising, flat, falling).\n3. Identify spikes, dips, or anomalies and when they occurred.\n\n## Output\nA short analysis with the current value, overall trend, and any notable anomalies with timestamps.', + }, + { + name: 'schedule-maintenance-downtime', + description: + 'Create a Datadog downtime to mute monitors during a maintenance window, then confirm the scope and timing.', + content: + '# Schedule Datadog Maintenance Downtime\n\nSuppress alerts during planned maintenance.\n\n## Steps\n1. Confirm the scope (tags/monitors) and the start and end times.\n2. Create the downtime with that scope and window.\n3. Verify it was created by listing active downtimes.\n\n## Output\nA confirmation of the downtime with its scope, start/end time, and id.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/datadog.ts b/apps/sim/blocks/blocks/datadog.ts index b79c55a2374..798ee27828a 100644 --- a/apps/sim/blocks/blocks/datadog.ts +++ b/apps/sim/blocks/blocks/datadog.ts @@ -1,6 +1,5 @@ -import { DatadogIcon } from '@/components/icons' import { DatadogBlockDisplay } from '@/blocks/blocks/datadog.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { DatadogResponse } from '@/tools/datadog/types' @@ -824,109 +823,3 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`, downtimes: { type: 'json', description: 'List of downtimes' }, }, } - -export const DatadogBlockMeta = { - tags: ['monitoring', 'incident-management', 'error-tracking'], - url: 'https://www.datadoghq.com', - templates: [ - { - icon: DatadogIcon, - title: 'Infrastructure health report', - prompt: - 'Create a scheduled daily workflow that queries Datadog for key infrastructure metrics — error rates, latency percentiles, CPU and memory usage — logs them to a table for trend tracking, and sends a morning Slack report highlighting any anomalies or degradations.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'infrastructure', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: DatadogIcon, - title: 'Datadog alert-to-Linear bridge', - prompt: - 'Build a scheduled workflow that polls Datadog monitors for any in an alerting state, classifies severity, creates a Linear ticket for non-paging issues with full context, and posts a Slack notification linking both.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: DatadogIcon, - title: 'Datadog SLO weekly review', - prompt: - 'Create a scheduled weekly workflow that queries Datadog timeseries for the key reliability metrics behind each service SLO, computes error budget burn, and writes a narrative review file for the SRE team to discuss in the weekly meeting.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - }, - { - icon: DatadogIcon, - title: 'Datadog cost optimizer', - prompt: - 'Build a scheduled workflow that queries Datadog estimated-usage timeseries for the top custom metrics by volume, writes optimization recommendations to a finance review file, and pings the platform team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: DatadogIcon, - title: 'Datadog monitor config backup', - prompt: - 'Create a scheduled workflow that lists every Datadog monitor nightly, fetches each monitor’s full configuration, exports the definitions as JSON to S3 with version history, and writes a manifest to a tracking table for restore drills.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['s3'], - }, - { - icon: DatadogIcon, - title: 'Datadog deploy guardrail', - prompt: - 'Build a workflow triggered after a deploy that creates a Datadog event marker, queries error-rate and latency timeseries over the next few minutes, and pages the team via PagerDuty if the metrics breach the rollback threshold.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: DatadogIcon, - title: 'Datadog SLO weekly report', - prompt: - 'Create a scheduled weekly workflow that queries Datadog timeseries for key service SLOs, lists which monitors fired during the week, writes the SLO compliance numbers to a table, and emails an availability summary to the on-call leads.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'reporting', 'monitoring'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'triage-firing-monitors', - description: - 'List Datadog monitors, surface those in alert or warn state, and summarize what is firing and why.', - content: - '# Triage Firing Datadog Monitors\n\nGet a clear picture of what is alerting right now.\n\n## Steps\n1. List monitors and filter to those in Alert or Warn states.\n2. For each, get the monitor details: query, threshold, and current value.\n3. Group by service or tag to find common root causes.\n\n## Output\nA prioritized list of firing monitors with the metric, threshold, and likely affected service.', - }, - { - name: 'investigate-logs', - description: - 'Query Datadog logs for a service and time window to find errors and summarize patterns.', - content: - '# Investigate Datadog Logs\n\nSearch logs to diagnose an issue.\n\n## Steps\n1. Confirm the service, environment, and time window.\n2. Query logs filtering for error/critical status and the relevant service tag.\n3. Aggregate by error message or type to find the dominant patterns.\n4. Pull sample log lines for the top patterns.\n\n## Output\nA summary of the top error patterns with counts and sample log lines.', - }, - { - name: 'analyze-metric-trend', - description: - 'Query a Datadog timeseries metric over a window and report the trend, anomalies, and current value.', - content: - '# Analyze a Datadog Metric Trend\n\nUnderstand how a metric is behaving over time.\n\n## Steps\n1. Confirm the metric query and the time window.\n2. Query the timeseries and compute the trend (rising, flat, falling).\n3. Identify spikes, dips, or anomalies and when they occurred.\n\n## Output\nA short analysis with the current value, overall trend, and any notable anomalies with timestamps.', - }, - { - name: 'schedule-maintenance-downtime', - description: - 'Create a Datadog downtime to mute monitors during a maintenance window, then confirm the scope and timing.', - content: - '# Schedule Datadog Maintenance Downtime\n\nSuppress alerts during planned maintenance.\n\n## Steps\n1. Confirm the scope (tags/monitors) and the start and end times.\n2. Create the downtime with that scope and window.\n3. Verify it was created by listing active downtimes.\n\n## Output\nA confirmation of the downtime with its scope, start/end time, and id.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/datagma.display.ts b/apps/sim/blocks/blocks/datagma.display.ts index ecb573b4923..0fdc73e817f 100644 --- a/apps/sim/blocks/blocks/datagma.display.ts +++ b/apps/sim/blocks/blocks/datagma.display.ts @@ -1,6 +1,6 @@ import { DatagmaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DatagmaBlockDisplay = { type: 'datagma', @@ -14,3 +14,8 @@ export const DatagmaBlockDisplay = { docsLink: 'https://docs.sim.ai/tools/datagma', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const DatagmaBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://datagma.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/datagma.ts b/apps/sim/blocks/blocks/datagma.ts index 3a6e0c437c7..4045979b124 100644 --- a/apps/sim/blocks/blocks/datagma.ts +++ b/apps/sim/blocks/blocks/datagma.ts @@ -1,5 +1,5 @@ import { DatagmaBlockDisplay } from '@/blocks/blocks/datagma.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { DatagmaResponse } from '@/tools/datagma/types' export const DatagmaBlock: BlockConfig = { @@ -309,8 +309,3 @@ export const DatagmaBlock: BlockConfig = { credits: { type: 'number', description: 'Remaining Datagma credits' }, }, } - -export const DatagmaBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://datagma.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/daytona.display.ts b/apps/sim/blocks/blocks/daytona.display.ts index 619e23596da..2ce4138fe4c 100644 --- a/apps/sim/blocks/blocks/daytona.display.ts +++ b/apps/sim/blocks/blocks/daytona.display.ts @@ -1,6 +1,6 @@ import { DaytonaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DaytonaBlockDisplay = { type: 'daytona', @@ -14,3 +14,117 @@ export const DaytonaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/daytona', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const DaytonaBlockMeta = { + tags: ['agentic', 'cloud', 'automation'], + url: 'https://www.daytona.io', + templates: [ + { + icon: DaytonaIcon, + title: 'Daytona code interpreter', + prompt: + 'Build a workflow where an agent answers data questions by writing Python, creating a Daytona sandbox, running the code in it, and replying with the computed result and any printed output.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'code-execution'], + }, + { + icon: DaytonaIcon, + title: 'Daytona PR test runner', + prompt: + 'Create a workflow triggered by a GitHub pull request that creates a Daytona sandbox, clones the repository at the PR branch, runs the test suite with an execute command, and posts the pass/fail summary back to the PR.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['ci', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: DaytonaIcon, + title: 'Daytona CSV analysis', + prompt: + 'Build a workflow that takes an uploaded CSV file, uploads it into a Daytona sandbox, runs a Python analysis script over it, downloads the generated report file, and shares the findings in Slack.', + modules: ['files', 'agent', 'workflows'], + category: 'engineering', + tags: ['data', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DaytonaIcon, + title: 'Daytona scheduled script runner', + prompt: + 'Create a scheduled daily workflow that spins up a Daytona sandbox, runs a maintenance script with an execute command, writes the output to a results table, and deletes the sandbox when finished.', + modules: ['scheduled', 'tables', 'workflows'], + category: 'operations', + tags: ['automation', 'maintenance'], + }, + { + icon: DaytonaIcon, + title: 'Daytona sandbox janitor', + prompt: + 'Build a scheduled weekly workflow that lists all Daytona sandboxes, stops any that have been running longer than expected, deletes sandboxes labeled as temporary, and posts a cleanup summary to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'cost-control'], + alsoIntegrations: ['slack'], + }, + { + icon: DaytonaIcon, + title: 'Daytona generated-code validator', + prompt: + 'Create a workflow where an agent generates code from a user request, runs it in a Daytona sandbox, inspects the exit code and output, fixes errors and reruns until the code passes, then returns the validated code.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'code-execution'], + }, + { + icon: DaytonaIcon, + title: 'Daytona repo health check', + prompt: + 'Build a scheduled workflow that creates a Daytona sandbox, clones the main branch of a repository, runs install and build commands, records any failures in a table, and alerts the engineering channel when the build breaks.', + modules: ['scheduled', 'tables', 'workflows'], + category: 'engineering', + tags: ['ci', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: DaytonaIcon, + title: 'Daytona file transformer', + prompt: + 'Create a workflow that receives a document from a form, uploads it to a Daytona sandbox, runs a conversion script on it, downloads the transformed file, and emails it back to the requester.', + modules: ['files', 'workflows'], + category: 'operations', + tags: ['automation', 'documents'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'run-code-in-sandbox', + description: + 'Run Python, JavaScript, or TypeScript in an isolated Daytona sandbox and return the output. Use as a safe code interpreter for computation, parsing, or data wrangling.', + content: + '# Run Code In Sandbox\n\nExecute code safely in an isolated Daytona sandbox.\n\n## Steps\n1. Create a sandbox with the Create Sandbox operation (or reuse an existing sandbox ID), setting an auto-stop interval so it cleans up after itself.\n2. Use Run Code with the language set to python, javascript, or typescript. Print the values you need to stdout — the printed output is what comes back.\n3. Check the exit code: 0 means success; on failure, read the result output for the error, fix the code, and rerun.\n4. Delete the sandbox with Delete Sandbox when the work is finished if it was created just for this task.\n\n## Output\nReturn the printed result and the exit code. If the run produced chart artifacts, mention them. On repeated failures, return the last error output instead of fabricating a result.', + }, + { + name: 'analyze-data-file', + description: + 'Upload a data file into a Daytona sandbox, analyze it with Python, and download any generated results. Use for CSV/JSON analysis that needs real computation.', + content: + '# Analyze Data File\n\nProcess a workflow file with real code in a sandbox.\n\n## Steps\n1. Create a sandbox (or reuse one) and note its ID.\n2. Use Upload File to place the data file at a known path, e.g. /home/daytona/data.csv. A trailing slash on the destination uploads into that directory under the original file name.\n3. Use Run Code with Python to read the file from that path, compute the analysis, print a summary, and write any derived files (reports, charts) to known paths.\n4. Use Download File to pull each derived file back into the workflow, and List Files to discover outputs if paths are dynamic.\n5. Delete the sandbox when finished.\n\n## Output\nReturn the printed analysis summary and the downloaded result files. Name the exact sandbox paths used so the run can be reproduced.', + }, + { + name: 'clone-repo-and-run-checks', + description: + 'Clone a Git repository into a Daytona sandbox and run install, build, or test commands. Use for CI-style checks, repo health monitoring, or validating changes.', + content: + '# Clone Repo And Run Checks\n\nRun repository checks in an isolated environment.\n\n## Steps\n1. Create a sandbox sized for the job (set CPU and memory in advanced options for heavy builds).\n2. Use Git Clone with the repository URL and a clone path like /home/daytona/repo. Pass a branch for non-default branches, and a username plus token for private repositories.\n3. Use Execute Command from the clone path (set the working directory) to run installs, builds, or tests. Raise the timeout for long commands — the default is 10 seconds.\n4. Inspect each exit code and capture the output of failing commands.\n5. Delete the sandbox when the checks complete.\n\n## Output\nReturn pass/fail per command with exit codes, and include the failing output verbatim when something breaks.', + }, + { + name: 'manage-sandbox-fleet', + description: + 'List, stop, and delete Daytona sandboxes to control cost and tidy up environments. Use for scheduled cleanup or auditing what is currently running.', + content: + '# Manage Sandbox Fleet\n\nAudit and clean up sandboxes in the organization.\n\n## Steps\n1. Use List Sandboxes to enumerate sandboxes; filter by name prefix or labels, and page with the cursor when there are many.\n2. Inspect each sandbox state and timestamps to find ones idle or running longer than expected.\n3. Stop Sandbox for environments worth keeping but not actively used; Delete Sandbox for disposable ones (e.g. labeled temporary).\n4. When creating sandboxes elsewhere, set auto-stop and auto-delete intervals so cleanup happens automatically.\n\n## Output\nReturn a summary of sandboxes found, which were stopped or deleted and why, and any that were left running with their states.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/daytona.ts b/apps/sim/blocks/blocks/daytona.ts index 90059078ad2..a9105c1f374 100644 --- a/apps/sim/blocks/blocks/daytona.ts +++ b/apps/sim/blocks/blocks/daytona.ts @@ -1,6 +1,5 @@ -import { DaytonaIcon } from '@/components/icons' import { DaytonaBlockDisplay } from '@/blocks/blocks/daytona.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' @@ -554,117 +553,3 @@ export const DaytonaBlock: BlockConfig = { clonePath: { type: 'string', description: 'Clone destination path (git clone operation)' }, }, } - -export const DaytonaBlockMeta = { - tags: ['agentic', 'cloud', 'automation'], - url: 'https://www.daytona.io', - templates: [ - { - icon: DaytonaIcon, - title: 'Daytona code interpreter', - prompt: - 'Build a workflow where an agent answers data questions by writing Python, creating a Daytona sandbox, running the code in it, and replying with the computed result and any printed output.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'code-execution'], - }, - { - icon: DaytonaIcon, - title: 'Daytona PR test runner', - prompt: - 'Create a workflow triggered by a GitHub pull request that creates a Daytona sandbox, clones the repository at the PR branch, runs the test suite with an execute command, and posts the pass/fail summary back to the PR.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['ci', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: DaytonaIcon, - title: 'Daytona CSV analysis', - prompt: - 'Build a workflow that takes an uploaded CSV file, uploads it into a Daytona sandbox, runs a Python analysis script over it, downloads the generated report file, and shares the findings in Slack.', - modules: ['files', 'agent', 'workflows'], - category: 'engineering', - tags: ['data', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DaytonaIcon, - title: 'Daytona scheduled script runner', - prompt: - 'Create a scheduled daily workflow that spins up a Daytona sandbox, runs a maintenance script with an execute command, writes the output to a results table, and deletes the sandbox when finished.', - modules: ['scheduled', 'tables', 'workflows'], - category: 'operations', - tags: ['automation', 'maintenance'], - }, - { - icon: DaytonaIcon, - title: 'Daytona sandbox janitor', - prompt: - 'Build a scheduled weekly workflow that lists all Daytona sandboxes, stops any that have been running longer than expected, deletes sandboxes labeled as temporary, and posts a cleanup summary to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'cost-control'], - alsoIntegrations: ['slack'], - }, - { - icon: DaytonaIcon, - title: 'Daytona generated-code validator', - prompt: - 'Create a workflow where an agent generates code from a user request, runs it in a Daytona sandbox, inspects the exit code and output, fixes errors and reruns until the code passes, then returns the validated code.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'code-execution'], - }, - { - icon: DaytonaIcon, - title: 'Daytona repo health check', - prompt: - 'Build a scheduled workflow that creates a Daytona sandbox, clones the main branch of a repository, runs install and build commands, records any failures in a table, and alerts the engineering channel when the build breaks.', - modules: ['scheduled', 'tables', 'workflows'], - category: 'engineering', - tags: ['ci', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: DaytonaIcon, - title: 'Daytona file transformer', - prompt: - 'Create a workflow that receives a document from a form, uploads it to a Daytona sandbox, runs a conversion script on it, downloads the transformed file, and emails it back to the requester.', - modules: ['files', 'workflows'], - category: 'operations', - tags: ['automation', 'documents'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'run-code-in-sandbox', - description: - 'Run Python, JavaScript, or TypeScript in an isolated Daytona sandbox and return the output. Use as a safe code interpreter for computation, parsing, or data wrangling.', - content: - '# Run Code In Sandbox\n\nExecute code safely in an isolated Daytona sandbox.\n\n## Steps\n1. Create a sandbox with the Create Sandbox operation (or reuse an existing sandbox ID), setting an auto-stop interval so it cleans up after itself.\n2. Use Run Code with the language set to python, javascript, or typescript. Print the values you need to stdout — the printed output is what comes back.\n3. Check the exit code: 0 means success; on failure, read the result output for the error, fix the code, and rerun.\n4. Delete the sandbox with Delete Sandbox when the work is finished if it was created just for this task.\n\n## Output\nReturn the printed result and the exit code. If the run produced chart artifacts, mention them. On repeated failures, return the last error output instead of fabricating a result.', - }, - { - name: 'analyze-data-file', - description: - 'Upload a data file into a Daytona sandbox, analyze it with Python, and download any generated results. Use for CSV/JSON analysis that needs real computation.', - content: - '# Analyze Data File\n\nProcess a workflow file with real code in a sandbox.\n\n## Steps\n1. Create a sandbox (or reuse one) and note its ID.\n2. Use Upload File to place the data file at a known path, e.g. /home/daytona/data.csv. A trailing slash on the destination uploads into that directory under the original file name.\n3. Use Run Code with Python to read the file from that path, compute the analysis, print a summary, and write any derived files (reports, charts) to known paths.\n4. Use Download File to pull each derived file back into the workflow, and List Files to discover outputs if paths are dynamic.\n5. Delete the sandbox when finished.\n\n## Output\nReturn the printed analysis summary and the downloaded result files. Name the exact sandbox paths used so the run can be reproduced.', - }, - { - name: 'clone-repo-and-run-checks', - description: - 'Clone a Git repository into a Daytona sandbox and run install, build, or test commands. Use for CI-style checks, repo health monitoring, or validating changes.', - content: - '# Clone Repo And Run Checks\n\nRun repository checks in an isolated environment.\n\n## Steps\n1. Create a sandbox sized for the job (set CPU and memory in advanced options for heavy builds).\n2. Use Git Clone with the repository URL and a clone path like /home/daytona/repo. Pass a branch for non-default branches, and a username plus token for private repositories.\n3. Use Execute Command from the clone path (set the working directory) to run installs, builds, or tests. Raise the timeout for long commands — the default is 10 seconds.\n4. Inspect each exit code and capture the output of failing commands.\n5. Delete the sandbox when the checks complete.\n\n## Output\nReturn pass/fail per command with exit codes, and include the failing output verbatim when something breaks.', - }, - { - name: 'manage-sandbox-fleet', - description: - 'List, stop, and delete Daytona sandboxes to control cost and tidy up environments. Use for scheduled cleanup or auditing what is currently running.', - content: - '# Manage Sandbox Fleet\n\nAudit and clean up sandboxes in the organization.\n\n## Steps\n1. Use List Sandboxes to enumerate sandboxes; filter by name prefix or labels, and page with the cursor when there are many.\n2. Inspect each sandbox state and timestamps to find ones idle or running longer than expected.\n3. Stop Sandbox for environments worth keeping but not actively used; Delete Sandbox for disposable ones (e.g. labeled temporary).\n4. When creating sandboxes elsewhere, set auto-stop and auto-delete intervals so cleanup happens automatically.\n\n## Output\nReturn a summary of sandboxes found, which were stopped or deleted and why, and any that were left running with their states.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/devin.display.ts b/apps/sim/blocks/blocks/devin.display.ts index 6a84c8f671d..7ba70123965 100644 --- a/apps/sim/blocks/blocks/devin.display.ts +++ b/apps/sim/blocks/blocks/devin.display.ts @@ -1,6 +1,6 @@ import { DevinIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DevinBlockDisplay = { type: 'devin', @@ -14,3 +14,101 @@ export const DevinBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/devin', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const DevinBlockMeta = { + tags: ['agentic', 'automation'], + url: 'https://devin.ai', + templates: [ + { + icon: DevinIcon, + title: 'Devin session launcher', + prompt: + 'Build a workflow that accepts a coding task description, creates a new Devin session with rich context, polls the session until it produces a pull request or hits a blocker, and posts the session link and status to Slack.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DevinIcon, + title: 'Devin bug-fix dispatcher', + prompt: + 'Create a workflow that watches for new critical errors, packages the stack trace and reproduction steps into a Devin prompt, creates a session, and updates a Linear ticket with the Devin session link and any pull requests it opens.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'devops'], + alsoIntegrations: ['linear'], + }, + { + icon: DevinIcon, + title: 'Devin session monitor', + prompt: + 'Build a scheduled workflow that runs every ten minutes, lists Devin sessions for your organization, tracks status changes, logs sessions, pull requests, and tags to a table, and sends a Slack alert when any session has been stuck for more than two hours.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring', 'agentic'], + alsoIntegrations: ['slack'], + }, + { + icon: DevinIcon, + title: 'Devin progress nudger', + prompt: + 'Build a workflow that runs every hour against active Devin sessions, detects sessions that are suspended or awaiting input, sends a targeted follow-up message via the Devin API to unblock progress, and notifies the requester if a session needs human intervention.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DevinIcon, + title: 'Documentation gap closer', + prompt: + 'Create a workflow that scans a knowledge base of docs against the latest repo state, finds undocumented public APIs, opens a Devin session for each gap with a prompt to write documentation, and stores the produced markdown back into the knowledge base.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'content', 'agentic'], + }, + { + icon: DevinIcon, + title: 'Devin retrospective report', + prompt: + 'Build a scheduled weekly workflow that lists Devin sessions completed in the past week, summarizes outcomes, pull requests merged, time-to-completion, and recurring failure modes, and writes a retrospective report file shared with engineering leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'reporting', 'analysis'], + }, + { + icon: DevinIcon, + title: 'Devin issue-to-PR runner', + prompt: + 'Create a workflow triggered when a Linear issue is labeled ready-for-devin that creates a Devin session with the issue context, monitors the session to completion, and comments the resulting pull request link back on the Linear issue.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation', 'agentic'], + alsoIntegrations: ['linear'], + }, + ], + skills: [ + { + name: 'start-engineering-session', + description: + 'Create a Devin session with a clear engineering task prompt and report the session id and link.', + content: + '# Start a Devin Engineering Session\n\nKick off an autonomous engineering task with Devin.\n\n## Steps\n1. Confirm the repository and the task to perform.\n2. Write a precise prompt: the goal, constraints, and acceptance criteria.\n3. Create the session, optionally tagging it for tracking.\n4. Capture the session id and URL.\n\n## Output\nA confirmation with the session id, link, and the task prompt Devin was given.', + }, + { + name: 'check-session-progress', + description: + 'Get a Devin session status and recent messages and summarize what it has accomplished or where it is blocked.', + content: + '# Check Devin Session Progress\n\nMonitor a running Devin session.\n\n## Steps\n1. Get the session for the given session id and read its status.\n2. List recent session messages to see Devin actions and reasoning.\n3. Determine whether it is making progress, finished, or blocked needing input.\n\n## Output\nA status summary describing progress, current state, and any questions Devin is waiting on.', + }, + { + name: 'guide-session', + description: + 'Send a message to an active Devin session to answer a question or redirect its work.', + content: + '# Guide a Devin Session\n\nUnblock or steer an active session.\n\n## Steps\n1. Confirm the session id and review the latest messages.\n2. Compose a clear reply: answer the open question or give new direction.\n3. Send the message to the session.\n4. Confirm Devin has resumed.\n\n## Output\nA confirmation that the message was sent, with the guidance provided.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/devin.ts b/apps/sim/blocks/blocks/devin.ts index 704162e448f..c7cd093c7f8 100644 --- a/apps/sim/blocks/blocks/devin.ts +++ b/apps/sim/blocks/blocks/devin.ts @@ -1,6 +1,5 @@ -import { DevinIcon } from '@/components/icons' import { DevinBlockDisplay } from '@/blocks/blocks/devin.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' const SESSION_OBJECT_OPERATIONS = [ @@ -308,101 +307,3 @@ RULES: }, }, } - -export const DevinBlockMeta = { - tags: ['agentic', 'automation'], - url: 'https://devin.ai', - templates: [ - { - icon: DevinIcon, - title: 'Devin session launcher', - prompt: - 'Build a workflow that accepts a coding task description, creates a new Devin session with rich context, polls the session until it produces a pull request or hits a blocker, and posts the session link and status to Slack.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DevinIcon, - title: 'Devin bug-fix dispatcher', - prompt: - 'Create a workflow that watches for new critical errors, packages the stack trace and reproduction steps into a Devin prompt, creates a session, and updates a Linear ticket with the Devin session link and any pull requests it opens.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'devops'], - alsoIntegrations: ['linear'], - }, - { - icon: DevinIcon, - title: 'Devin session monitor', - prompt: - 'Build a scheduled workflow that runs every ten minutes, lists Devin sessions for your organization, tracks status changes, logs sessions, pull requests, and tags to a table, and sends a Slack alert when any session has been stuck for more than two hours.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring', 'agentic'], - alsoIntegrations: ['slack'], - }, - { - icon: DevinIcon, - title: 'Devin progress nudger', - prompt: - 'Build a workflow that runs every hour against active Devin sessions, detects sessions that are suspended or awaiting input, sends a targeted follow-up message via the Devin API to unblock progress, and notifies the requester if a session needs human intervention.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DevinIcon, - title: 'Documentation gap closer', - prompt: - 'Create a workflow that scans a knowledge base of docs against the latest repo state, finds undocumented public APIs, opens a Devin session for each gap with a prompt to write documentation, and stores the produced markdown back into the knowledge base.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'content', 'agentic'], - }, - { - icon: DevinIcon, - title: 'Devin retrospective report', - prompt: - 'Build a scheduled weekly workflow that lists Devin sessions completed in the past week, summarizes outcomes, pull requests merged, time-to-completion, and recurring failure modes, and writes a retrospective report file shared with engineering leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'reporting', 'analysis'], - }, - { - icon: DevinIcon, - title: 'Devin issue-to-PR runner', - prompt: - 'Create a workflow triggered when a Linear issue is labeled ready-for-devin that creates a Devin session with the issue context, monitors the session to completion, and comments the resulting pull request link back on the Linear issue.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation', 'agentic'], - alsoIntegrations: ['linear'], - }, - ], - skills: [ - { - name: 'start-engineering-session', - description: - 'Create a Devin session with a clear engineering task prompt and report the session id and link.', - content: - '# Start a Devin Engineering Session\n\nKick off an autonomous engineering task with Devin.\n\n## Steps\n1. Confirm the repository and the task to perform.\n2. Write a precise prompt: the goal, constraints, and acceptance criteria.\n3. Create the session, optionally tagging it for tracking.\n4. Capture the session id and URL.\n\n## Output\nA confirmation with the session id, link, and the task prompt Devin was given.', - }, - { - name: 'check-session-progress', - description: - 'Get a Devin session status and recent messages and summarize what it has accomplished or where it is blocked.', - content: - '# Check Devin Session Progress\n\nMonitor a running Devin session.\n\n## Steps\n1. Get the session for the given session id and read its status.\n2. List recent session messages to see Devin actions and reasoning.\n3. Determine whether it is making progress, finished, or blocked needing input.\n\n## Output\nA status summary describing progress, current state, and any questions Devin is waiting on.', - }, - { - name: 'guide-session', - description: - 'Send a message to an active Devin session to answer a question or redirect its work.', - content: - '# Guide a Devin Session\n\nUnblock or steer an active session.\n\n## Steps\n1. Confirm the session id and review the latest messages.\n2. Compose a clear reply: answer the open question or give new direction.\n3. Send the message to the session.\n4. Confirm Devin has resumed.\n\n## Output\nA confirmation that the message was sent, with the guidance provided.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/discord.display.ts b/apps/sim/blocks/blocks/discord.display.ts index adc90ef76f6..513f8a94123 100644 --- a/apps/sim/blocks/blocks/discord.display.ts +++ b/apps/sim/blocks/blocks/discord.display.ts @@ -1,6 +1,6 @@ import { DiscordIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DiscordBlockDisplay = { type: 'discord', @@ -15,3 +15,107 @@ export const DiscordBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/discord', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const DiscordBlockMeta = { + tags: ['messaging', 'webhooks', 'automation'], + url: 'https://discord.com', + templates: [ + { + icon: DiscordIcon, + title: 'Discord community manager', + prompt: + 'Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.', + modules: ['knowledge-base', 'tables', 'agent', 'scheduled', 'workflows'], + category: 'support', + tags: ['community', 'support', 'communication'], + alsoIntegrations: ['google_docs', 'notion', 'slack'], + }, + { + icon: DiscordIcon, + title: 'Discord support deflector', + prompt: + 'Build a scheduled workflow that polls help channels in Discord for new questions, searches a knowledge base for an answer, and posts a sourced reply in-thread; escalates to a human when confidence is low.', + modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['community', 'support'], + }, + { + icon: DiscordIcon, + title: 'Discord weekly community digest', + prompt: + 'Create a scheduled weekly workflow that summarizes Discord activity — top threads, helpful members, new questions — and posts the digest to the announcements channel and Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['community', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: DiscordIcon, + title: 'Discord onboarding tracker', + prompt: + 'Build a scheduled workflow that polls a Discord server for recently joined members, opens a private onboarding thread for each new member with relevant links, and tracks completion of starter tasks in a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'support', + tags: ['community', 'automation'], + }, + { + icon: DiscordIcon, + title: 'Discord moderation triage', + prompt: + 'Create a scheduled workflow that polls Discord channels for new messages, classifies community-guideline violations with an agent, auto-warns the user on minor issues, and pings moderators in a private channel for severe cases.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['community', 'automation'], + }, + { + icon: DiscordIcon, + title: 'Discord feature request collector', + prompt: + 'Build a scheduled workflow that polls a Discord feedback channel for new posts, classifies them as bugs vs feature requests, opens Linear tickets for actionable items, and replies in-thread with the ticket link.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['community', 'product'], + alsoIntegrations: ['linear'], + }, + { + icon: DiscordIcon, + title: 'Discord event reminder', + prompt: + 'Create a scheduled workflow that reads upcoming Luma or Google Calendar events, posts a reminder in the matching Discord channel 24 hours before, and pings RSVP attendees by role.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['community', 'communication'], + alsoIntegrations: ['luma', 'google_calendar'], + }, + ], + skills: [ + { + name: 'post-announcement', + description: + 'Post a formatted announcement message to a Discord channel and optionally pin it.', + content: + '# Post a Discord Announcement\n\nShare an announcement with a community channel.\n\n## Steps\n1. Confirm the target channel and the announcement content.\n2. Format the message clearly, using mentions or roles only if requested.\n3. Send the message to the channel.\n4. If it is important, pin the message.\n\n## Output\nA confirmation with the channel, message link or id, and whether it was pinned.', + }, + { + name: 'summarize-channel-activity', + description: + 'Read recent Discord channel messages and produce a summary of discussions, questions, and decisions.', + content: + '# Summarize Discord Channel Activity\n\nCatch up on what happened in a channel.\n\n## Steps\n1. Confirm the channel and how many recent messages to review.\n2. Get the channel messages.\n3. Group the conversation into themes: announcements, questions, and decisions.\n4. Flag unanswered questions that need a reply.\n\n## Output\nA concise digest of the discussion with unanswered questions called out.', + }, + { + name: 'open-discussion-thread', + description: + 'Create a Discord thread for a topic and post a kickoff message to organize community discussion.', + content: + '# Open a Discord Discussion Thread\n\nSpin up a focused thread for a topic.\n\n## Steps\n1. Confirm the parent channel and the thread topic.\n2. Create the thread with a clear name.\n3. Post a kickoff message framing the discussion and any prompts.\n\n## Output\nA confirmation with the thread name, link or id, and the kickoff message posted.', + }, + { + name: 'collect-reactions-feedback', + description: + 'Post a poll-style message in Discord, add reaction options, and read back the tally as feedback.', + content: + '# Collect Discord Reaction Feedback\n\nRun a lightweight reaction poll.\n\n## Steps\n1. Confirm the channel, the question, and the reaction options.\n2. Send the poll message.\n3. Add each reaction option to the message.\n4. After the polling window, read the message to tally the reaction counts.\n\n## Output\nThe poll question with the reaction tally and which option leads.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/discord.ts b/apps/sim/blocks/blocks/discord.ts index cae933b1179..bc99295ffc0 100644 --- a/apps/sim/blocks/blocks/discord.ts +++ b/apps/sim/blocks/blocks/discord.ts @@ -1,6 +1,5 @@ -import { DiscordIcon } from '@/components/icons' import { DiscordBlockDisplay } from '@/blocks/blocks/discord.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DiscordResponse } from '@/tools/discord/types' @@ -787,107 +786,3 @@ export const DiscordBlock: BlockConfig = { data: { type: 'json', description: 'Response data' }, }, } - -export const DiscordBlockMeta = { - tags: ['messaging', 'webhooks', 'automation'], - url: 'https://discord.com', - templates: [ - { - icon: DiscordIcon, - title: 'Discord community manager', - prompt: - 'Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.', - modules: ['knowledge-base', 'tables', 'agent', 'scheduled', 'workflows'], - category: 'support', - tags: ['community', 'support', 'communication'], - alsoIntegrations: ['google_docs', 'notion', 'slack'], - }, - { - icon: DiscordIcon, - title: 'Discord support deflector', - prompt: - 'Build a scheduled workflow that polls help channels in Discord for new questions, searches a knowledge base for an answer, and posts a sourced reply in-thread; escalates to a human when confidence is low.', - modules: ['knowledge-base', 'scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['community', 'support'], - }, - { - icon: DiscordIcon, - title: 'Discord weekly community digest', - prompt: - 'Create a scheduled weekly workflow that summarizes Discord activity — top threads, helpful members, new questions — and posts the digest to the announcements channel and Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['community', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: DiscordIcon, - title: 'Discord onboarding tracker', - prompt: - 'Build a scheduled workflow that polls a Discord server for recently joined members, opens a private onboarding thread for each new member with relevant links, and tracks completion of starter tasks in a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'support', - tags: ['community', 'automation'], - }, - { - icon: DiscordIcon, - title: 'Discord moderation triage', - prompt: - 'Create a scheduled workflow that polls Discord channels for new messages, classifies community-guideline violations with an agent, auto-warns the user on minor issues, and pings moderators in a private channel for severe cases.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['community', 'automation'], - }, - { - icon: DiscordIcon, - title: 'Discord feature request collector', - prompt: - 'Build a scheduled workflow that polls a Discord feedback channel for new posts, classifies them as bugs vs feature requests, opens Linear tickets for actionable items, and replies in-thread with the ticket link.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['community', 'product'], - alsoIntegrations: ['linear'], - }, - { - icon: DiscordIcon, - title: 'Discord event reminder', - prompt: - 'Create a scheduled workflow that reads upcoming Luma or Google Calendar events, posts a reminder in the matching Discord channel 24 hours before, and pings RSVP attendees by role.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['community', 'communication'], - alsoIntegrations: ['luma', 'google_calendar'], - }, - ], - skills: [ - { - name: 'post-announcement', - description: - 'Post a formatted announcement message to a Discord channel and optionally pin it.', - content: - '# Post a Discord Announcement\n\nShare an announcement with a community channel.\n\n## Steps\n1. Confirm the target channel and the announcement content.\n2. Format the message clearly, using mentions or roles only if requested.\n3. Send the message to the channel.\n4. If it is important, pin the message.\n\n## Output\nA confirmation with the channel, message link or id, and whether it was pinned.', - }, - { - name: 'summarize-channel-activity', - description: - 'Read recent Discord channel messages and produce a summary of discussions, questions, and decisions.', - content: - '# Summarize Discord Channel Activity\n\nCatch up on what happened in a channel.\n\n## Steps\n1. Confirm the channel and how many recent messages to review.\n2. Get the channel messages.\n3. Group the conversation into themes: announcements, questions, and decisions.\n4. Flag unanswered questions that need a reply.\n\n## Output\nA concise digest of the discussion with unanswered questions called out.', - }, - { - name: 'open-discussion-thread', - description: - 'Create a Discord thread for a topic and post a kickoff message to organize community discussion.', - content: - '# Open a Discord Discussion Thread\n\nSpin up a focused thread for a topic.\n\n## Steps\n1. Confirm the parent channel and the thread topic.\n2. Create the thread with a clear name.\n3. Post a kickoff message framing the discussion and any prompts.\n\n## Output\nA confirmation with the thread name, link or id, and the kickoff message posted.', - }, - { - name: 'collect-reactions-feedback', - description: - 'Post a poll-style message in Discord, add reaction options, and read back the tally as feedback.', - content: - '# Collect Discord Reaction Feedback\n\nRun a lightweight reaction poll.\n\n## Steps\n1. Confirm the channel, the question, and the reaction options.\n2. Send the poll message.\n3. Add each reaction option to the message.\n4. After the polling window, read the message to tally the reaction counts.\n\n## Output\nThe poll question with the reaction tally and which option leads.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/docusign.display.ts b/apps/sim/blocks/blocks/docusign.display.ts index 4c04324eeb3..c2e566e9f31 100644 --- a/apps/sim/blocks/blocks/docusign.display.ts +++ b/apps/sim/blocks/blocks/docusign.display.ts @@ -1,6 +1,6 @@ import { DocuSignIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DocuSignBlockDisplay = { type: 'docusign', @@ -14,3 +14,108 @@ export const DocuSignBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/docusign', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const DocuSignBlockMeta = { + tags: ['e-signatures', 'document-processing'], + url: 'https://www.docusign.com', + templates: [ + { + icon: DocuSignIcon, + title: 'DocuSign envelope sender', + prompt: + 'Build a workflow that takes a deal from Salesforce above a threshold, pre-fills a DocuSign envelope from a template, sends it, and writes the envelope ID back to the opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + alsoIntegrations: ['salesforce'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign chase reminder', + prompt: + 'Create a scheduled workflow that lists DocuSign envelopes pending signature for over 48 hours, notifies the owning rep in Slack to nudge each signer, and escalates with a flagged message after 7 days.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign completed contract archiver', + prompt: + 'Build a scheduled workflow that polls DocuSign for completed envelopes, downloads the signed PDF, saves it to a Google Drive contracts folder, and writes the metadata into a contracts table.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'sync'], + alsoIntegrations: ['google_drive'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign clause analyzer', + prompt: + 'Create a workflow that processes signed DocuSign contracts, extracts payment terms, liability caps, and renewal dates, writes them to a table, and flags non-standard clauses for legal review.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'analysis'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign renewal tracker', + prompt: + 'Build a scheduled workflow that reads a DocuSign contracts table, finds renewals due in the next 60 days, and creates a renewal-prep task in Salesforce for each.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign stalled envelope resolver', + prompt: + 'Create a scheduled workflow that lists in-flight DocuSign envelopes, checks each envelope’s recipients for signers who have left the company, voids the affected envelopes, and posts the list to Slack so a rep can resend from the right template.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DocuSignIcon, + title: 'DocuSign signature analytics digest', + prompt: + 'Build a scheduled weekly workflow that pulls DocuSign envelope analytics — time-to-sign, completion rate, drop-off — and posts a digest to the sales ops Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'send-contract-for-signature', + description: + 'Send a document to one or more signers for e-signature, using a DocuSign template or an uploaded file.', + content: + '# Send Contract for Signature\n\nSend a document out for e-signature through DocuSign and confirm it was delivered.\n\n## Steps\n1. Determine whether to send from a template (preferred for standard agreements) or from an uploaded document. If a template is named, use List Templates to resolve its ID.\n2. For a template, call Send from Template with the template ID and a template-roles JSON array mapping each role name to a signer name and email. For an ad-hoc document, call Send Envelope with the email subject, signer name, signer email, and the document file.\n3. Add any CC recipients and set the email subject to something the signer will recognize.\n4. Send immediately unless asked to save as a draft.\n\n## Output\nReport the envelope ID and status. List each signer and CC recipient with their email so the requester can confirm the right people were addressed.', + }, + { + name: 'track-pending-envelopes', + description: + 'List envelopes awaiting signature, identify ones stalled past a threshold, and surface who still needs to sign.', + content: + '# Track Pending Envelopes\n\nFind DocuSign envelopes that are sent but not yet completed so stalled signatures can be chased.\n\n## Steps\n1. Call List Envelopes filtered to sent and delivered status over a recent date window.\n2. For each envelope, use List Recipients to see which signers have signed and which are still outstanding.\n3. Compute how long each envelope has been waiting and flag any past the requested threshold (default 48 hours).\n\n## Output\nReturn a table of stalled envelopes: envelope ID, subject, days waiting, and the outstanding signer name and email. Sort by longest waiting first.', + }, + { + name: 'archive-completed-documents', + description: + 'Find completed envelopes, download the signed PDFs, and extract key metadata for archiving.', + content: + '# Archive Completed Documents\n\nCollect signed documents once an envelope is complete and capture their metadata.\n\n## Steps\n1. Call List Envelopes filtered to completed status over the requested date window.\n2. For each completed envelope, call Download Document with "combined" to get the full signed PDF.\n3. Record the envelope ID, subject, completed date, and signer list for each document.\n\n## Output\nReturn each completed envelope with its downloaded file, signers, and completed date. Note any envelope where the download failed so it can be retried.', + }, + { + name: 'void-stale-envelope', + description: 'Void an envelope that should no longer be signed and record the reason.', + content: + '# Void Stale Envelope\n\nCancel a DocuSign envelope that is no longer valid — wrong recipient, superseded terms, or expired offer.\n\n## Steps\n1. Confirm the envelope ID. If only a subject or signer is known, use List Envelopes to resolve it, and verify it is not already completed.\n2. Call Get Envelope to confirm the current status is still voidable (created, sent, or delivered).\n3. Call Void Envelope with a clear void reason describing why it is being cancelled.\n\n## Output\nConfirm the envelope ID, its new voided status, and the recorded reason. If the envelope was already completed or voided, report that instead of attempting to void it.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/docusign.ts b/apps/sim/blocks/blocks/docusign.ts index 29b5e1ceb0c..ca601a11a64 100644 --- a/apps/sim/blocks/blocks/docusign.ts +++ b/apps/sim/blocks/blocks/docusign.ts @@ -1,7 +1,6 @@ -import { DocuSignIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { DocuSignBlockDisplay } from '@/blocks/blocks/docusign.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DocuSignResponse } from '@/tools/docusign/types' @@ -364,108 +363,3 @@ export const DocuSignBlock: BlockConfig = { resultSetSize: { type: 'number', description: 'Results returned in this response' }, }, } - -export const DocuSignBlockMeta = { - tags: ['e-signatures', 'document-processing'], - url: 'https://www.docusign.com', - templates: [ - { - icon: DocuSignIcon, - title: 'DocuSign envelope sender', - prompt: - 'Build a workflow that takes a deal from Salesforce above a threshold, pre-fills a DocuSign envelope from a template, sends it, and writes the envelope ID back to the opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - alsoIntegrations: ['salesforce'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign chase reminder', - prompt: - 'Create a scheduled workflow that lists DocuSign envelopes pending signature for over 48 hours, notifies the owning rep in Slack to nudge each signer, and escalates with a flagged message after 7 days.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign completed contract archiver', - prompt: - 'Build a scheduled workflow that polls DocuSign for completed envelopes, downloads the signed PDF, saves it to a Google Drive contracts folder, and writes the metadata into a contracts table.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'sync'], - alsoIntegrations: ['google_drive'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign clause analyzer', - prompt: - 'Create a workflow that processes signed DocuSign contracts, extracts payment terms, liability caps, and renewal dates, writes them to a table, and flags non-standard clauses for legal review.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'analysis'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign renewal tracker', - prompt: - 'Build a scheduled workflow that reads a DocuSign contracts table, finds renewals due in the next 60 days, and creates a renewal-prep task in Salesforce for each.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign stalled envelope resolver', - prompt: - 'Create a scheduled workflow that lists in-flight DocuSign envelopes, checks each envelope’s recipients for signers who have left the company, voids the affected envelopes, and posts the list to Slack so a rep can resend from the right template.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DocuSignIcon, - title: 'DocuSign signature analytics digest', - prompt: - 'Build a scheduled weekly workflow that pulls DocuSign envelope analytics — time-to-sign, completion rate, drop-off — and posts a digest to the sales ops Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'send-contract-for-signature', - description: - 'Send a document to one or more signers for e-signature, using a DocuSign template or an uploaded file.', - content: - '# Send Contract for Signature\n\nSend a document out for e-signature through DocuSign and confirm it was delivered.\n\n## Steps\n1. Determine whether to send from a template (preferred for standard agreements) or from an uploaded document. If a template is named, use List Templates to resolve its ID.\n2. For a template, call Send from Template with the template ID and a template-roles JSON array mapping each role name to a signer name and email. For an ad-hoc document, call Send Envelope with the email subject, signer name, signer email, and the document file.\n3. Add any CC recipients and set the email subject to something the signer will recognize.\n4. Send immediately unless asked to save as a draft.\n\n## Output\nReport the envelope ID and status. List each signer and CC recipient with their email so the requester can confirm the right people were addressed.', - }, - { - name: 'track-pending-envelopes', - description: - 'List envelopes awaiting signature, identify ones stalled past a threshold, and surface who still needs to sign.', - content: - '# Track Pending Envelopes\n\nFind DocuSign envelopes that are sent but not yet completed so stalled signatures can be chased.\n\n## Steps\n1. Call List Envelopes filtered to sent and delivered status over a recent date window.\n2. For each envelope, use List Recipients to see which signers have signed and which are still outstanding.\n3. Compute how long each envelope has been waiting and flag any past the requested threshold (default 48 hours).\n\n## Output\nReturn a table of stalled envelopes: envelope ID, subject, days waiting, and the outstanding signer name and email. Sort by longest waiting first.', - }, - { - name: 'archive-completed-documents', - description: - 'Find completed envelopes, download the signed PDFs, and extract key metadata for archiving.', - content: - '# Archive Completed Documents\n\nCollect signed documents once an envelope is complete and capture their metadata.\n\n## Steps\n1. Call List Envelopes filtered to completed status over the requested date window.\n2. For each completed envelope, call Download Document with "combined" to get the full signed PDF.\n3. Record the envelope ID, subject, completed date, and signer list for each document.\n\n## Output\nReturn each completed envelope with its downloaded file, signers, and completed date. Note any envelope where the download failed so it can be retried.', - }, - { - name: 'void-stale-envelope', - description: 'Void an envelope that should no longer be signed and record the reason.', - content: - '# Void Stale Envelope\n\nCancel a DocuSign envelope that is no longer valid — wrong recipient, superseded terms, or expired offer.\n\n## Steps\n1. Confirm the envelope ID. If only a subject or signer is known, use List Envelopes to resolve it, and verify it is not already completed.\n2. Call Get Envelope to confirm the current status is still voidable (created, sent, or delivered).\n3. Call Void Envelope with a clear void reason describing why it is being cancelled.\n\n## Output\nConfirm the envelope ID, its new voided status, and the recorded reason. If the envelope was already completed or voided, report that instead of attempting to void it.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dropbox.display.ts b/apps/sim/blocks/blocks/dropbox.display.ts index 8330ef981c7..35279f9217f 100644 --- a/apps/sim/blocks/blocks/dropbox.display.ts +++ b/apps/sim/blocks/blocks/dropbox.display.ts @@ -1,6 +1,6 @@ import { DropboxIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DropboxBlockDisplay = { type: 'dropbox', @@ -15,3 +15,105 @@ export const DropboxBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/dropbox', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const DropboxBlockMeta = { + tags: ['cloud', 'document-processing'], + url: 'https://www.dropbox.com', + templates: [ + { + icon: DropboxIcon, + title: 'Dropbox to knowledge base', + prompt: + 'Build a scheduled workflow that lists a Dropbox folder, downloads documents added since the last run, extracts and chunks their text, and upserts the chunks into a knowledge base for agent retrieval.', + modules: ['scheduled', 'knowledge-base', 'files', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: DropboxIcon, + title: 'Dropbox shared-link auditor', + prompt: + 'Create a scheduled workflow that lists Dropbox shared links, identifies links shared with external users or marked public, and writes a security review report to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: DropboxIcon, + title: 'Dropbox vendor-invoice intake', + prompt: + 'Build a scheduled workflow that lists a Dropbox vendor folder for invoice PDFs added since the last run, extracts vendor and amount with an agent, writes the row to a payables table, and pings finance on Slack.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DropboxIcon, + title: 'Dropbox creative asset organizer', + prompt: + 'Create a scheduled workflow that lists a Dropbox creative-assets folder, classifies files added since the last run by campaign and type, moves them into the right subfolder, and updates a tables-based asset index.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: DropboxIcon, + title: 'Dropbox retention sweeper', + prompt: + 'Build a scheduled workflow that finds Dropbox files older than the retention policy, archives them to long-term storage, and writes the cleanup record to an audit table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: DropboxIcon, + title: 'Dropbox to Notion publisher', + prompt: + 'Create a scheduled workflow that lists Dropbox markdown files added since the last run, converts each to a Notion page in the right database, and writes a link back to the source file metadata.', + modules: ['scheduled', 'files', 'agent', 'workflows'], + category: 'productivity', + tags: ['content', 'sync'], + alsoIntegrations: ['notion'], + }, + { + icon: DropboxIcon, + title: 'Dropbox + DocuSign signed-doc archiver', + prompt: + 'Build a scheduled workflow that polls DocuSign for completed envelopes, downloads each signed PDF, saves it to a Dropbox compliance folder, and writes the audit record to a contracts table.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'sync'], + alsoIntegrations: ['docusign'], + }, + ], + skills: [ + { + name: 'upload-file-to-dropbox', + description: + 'Upload a file to a specific Dropbox path and optionally generate a shareable link.', + content: + '# Upload File to Dropbox\n\nSave a file into Dropbox at a chosen location and optionally share it.\n\n## Steps\n1. Determine the destination path, including the filename and extension (e.g., /reports/q3-summary.pdf).\n2. Call Upload File with the file and destination path. Use overwrite mode only if replacing an existing file; otherwise use add and enable auto-rename to avoid clobbering.\n3. If a shareable link is requested, call Create Shared Link on the uploaded path with the requested visibility (public, team-only, or password-protected).\n\n## Output\nReport the final stored path (after any auto-rename) and, if created, the shared link URL.', + }, + { + name: 'find-files-in-dropbox', + description: + 'Search Dropbox for files by query, extension, or folder, and return matching paths.', + content: + '# Find Files in Dropbox\n\nLocate files in Dropbox matching a search term or filter.\n\n## Steps\n1. Use Search Files with the query term. Scope to a folder path when the location is known, and pass file extensions (e.g., pdf,xlsx) to narrow results.\n2. If browsing a known folder instead of searching, use List Folder with the folder path; enable recursive listing to include subfolders.\n3. For any candidate match, use Get Metadata to confirm size, type, and last-modified time before acting on it.\n\n## Output\nReturn the matching files as a list of path, name, size, and last-modified. If nothing matches, say so and suggest a broader query.', + }, + { + name: 'organize-dropbox-folder', + description: 'List a folder and move, copy, or delete files to reorganize Dropbox contents.', + content: + '# Organize Dropbox Folder\n\nReorganize files in Dropbox by moving them into the right folders.\n\n## Steps\n1. Call List Folder on the source path to enumerate the files to process.\n2. Decide each file destination based on the requested rules (by type, date, campaign, or naming pattern). Create target folders with Create Folder if they do not exist.\n3. Use Move File/Folder to relocate each file, or Copy File/Folder when the original must stay in place. Enable auto-rename to avoid conflicts.\n\n## Output\nReturn a summary of every file moved or copied with its old and new path, and flag any operation that failed.', + }, + { + name: 'share-dropbox-link', + description: + 'Create a shared link for a Dropbox file or folder with controlled visibility and expiration.', + content: + '# Share Dropbox Link\n\nGenerate a shareable link for an existing Dropbox item with the right access controls.\n\n## Steps\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\n3. Set an expiration date if the link should not be permanent.\n\n## Output\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dropbox.ts b/apps/sim/blocks/blocks/dropbox.ts index d19d5318fc7..e0de386dd56 100644 --- a/apps/sim/blocks/blocks/dropbox.ts +++ b/apps/sim/blocks/blocks/dropbox.ts @@ -1,7 +1,6 @@ -import { DropboxIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { DropboxBlockDisplay } from '@/blocks/blocks/dropbox.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DropboxResponse } from '@/tools/dropbox/types' @@ -392,105 +391,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, matches: { type: 'json', description: 'Search results' }, }, } - -export const DropboxBlockMeta = { - tags: ['cloud', 'document-processing'], - url: 'https://www.dropbox.com', - templates: [ - { - icon: DropboxIcon, - title: 'Dropbox to knowledge base', - prompt: - 'Build a scheduled workflow that lists a Dropbox folder, downloads documents added since the last run, extracts and chunks their text, and upserts the chunks into a knowledge base for agent retrieval.', - modules: ['scheduled', 'knowledge-base', 'files', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: DropboxIcon, - title: 'Dropbox shared-link auditor', - prompt: - 'Create a scheduled workflow that lists Dropbox shared links, identifies links shared with external users or marked public, and writes a security review report to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: DropboxIcon, - title: 'Dropbox vendor-invoice intake', - prompt: - 'Build a scheduled workflow that lists a Dropbox vendor folder for invoice PDFs added since the last run, extracts vendor and amount with an agent, writes the row to a payables table, and pings finance on Slack.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DropboxIcon, - title: 'Dropbox creative asset organizer', - prompt: - 'Create a scheduled workflow that lists a Dropbox creative-assets folder, classifies files added since the last run by campaign and type, moves them into the right subfolder, and updates a tables-based asset index.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: DropboxIcon, - title: 'Dropbox retention sweeper', - prompt: - 'Build a scheduled workflow that finds Dropbox files older than the retention policy, archives them to long-term storage, and writes the cleanup record to an audit table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: DropboxIcon, - title: 'Dropbox to Notion publisher', - prompt: - 'Create a scheduled workflow that lists Dropbox markdown files added since the last run, converts each to a Notion page in the right database, and writes a link back to the source file metadata.', - modules: ['scheduled', 'files', 'agent', 'workflows'], - category: 'productivity', - tags: ['content', 'sync'], - alsoIntegrations: ['notion'], - }, - { - icon: DropboxIcon, - title: 'Dropbox + DocuSign signed-doc archiver', - prompt: - 'Build a scheduled workflow that polls DocuSign for completed envelopes, downloads each signed PDF, saves it to a Dropbox compliance folder, and writes the audit record to a contracts table.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'sync'], - alsoIntegrations: ['docusign'], - }, - ], - skills: [ - { - name: 'upload-file-to-dropbox', - description: - 'Upload a file to a specific Dropbox path and optionally generate a shareable link.', - content: - '# Upload File to Dropbox\n\nSave a file into Dropbox at a chosen location and optionally share it.\n\n## Steps\n1. Determine the destination path, including the filename and extension (e.g., /reports/q3-summary.pdf).\n2. Call Upload File with the file and destination path. Use overwrite mode only if replacing an existing file; otherwise use add and enable auto-rename to avoid clobbering.\n3. If a shareable link is requested, call Create Shared Link on the uploaded path with the requested visibility (public, team-only, or password-protected).\n\n## Output\nReport the final stored path (after any auto-rename) and, if created, the shared link URL.', - }, - { - name: 'find-files-in-dropbox', - description: - 'Search Dropbox for files by query, extension, or folder, and return matching paths.', - content: - '# Find Files in Dropbox\n\nLocate files in Dropbox matching a search term or filter.\n\n## Steps\n1. Use Search Files with the query term. Scope to a folder path when the location is known, and pass file extensions (e.g., pdf,xlsx) to narrow results.\n2. If browsing a known folder instead of searching, use List Folder with the folder path; enable recursive listing to include subfolders.\n3. For any candidate match, use Get Metadata to confirm size, type, and last-modified time before acting on it.\n\n## Output\nReturn the matching files as a list of path, name, size, and last-modified. If nothing matches, say so and suggest a broader query.', - }, - { - name: 'organize-dropbox-folder', - description: 'List a folder and move, copy, or delete files to reorganize Dropbox contents.', - content: - '# Organize Dropbox Folder\n\nReorganize files in Dropbox by moving them into the right folders.\n\n## Steps\n1. Call List Folder on the source path to enumerate the files to process.\n2. Decide each file destination based on the requested rules (by type, date, campaign, or naming pattern). Create target folders with Create Folder if they do not exist.\n3. Use Move File/Folder to relocate each file, or Copy File/Folder when the original must stay in place. Enable auto-rename to avoid conflicts.\n\n## Output\nReturn a summary of every file moved or copied with its old and new path, and flag any operation that failed.', - }, - { - name: 'share-dropbox-link', - description: - 'Create a shared link for a Dropbox file or folder with controlled visibility and expiration.', - content: - '# Share Dropbox Link\n\nGenerate a shareable link for an existing Dropbox item with the right access controls.\n\n## Steps\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\n3. Set an expiration date if the link should not be permanent.\n\n## Output\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dropcontact.display.ts b/apps/sim/blocks/blocks/dropcontact.display.ts index a4b3e8661eb..833f8f55355 100644 --- a/apps/sim/blocks/blocks/dropcontact.display.ts +++ b/apps/sim/blocks/blocks/dropcontact.display.ts @@ -1,6 +1,6 @@ import { DropcontactIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DropcontactBlockDisplay = { type: 'dropcontact', @@ -14,3 +14,8 @@ export const DropcontactBlockDisplay = { docsLink: 'https://docs.sim.ai/tools/dropcontact', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const DropcontactBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.dropcontact.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dropcontact.ts b/apps/sim/blocks/blocks/dropcontact.ts index a0214812b7b..1927d4db5e9 100644 --- a/apps/sim/blocks/blocks/dropcontact.ts +++ b/apps/sim/blocks/blocks/dropcontact.ts @@ -1,5 +1,5 @@ import { DropcontactBlockDisplay } from '@/blocks/blocks/dropcontact.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { DropcontactResponse } from '@/tools/dropcontact/types' export const DropcontactBlock: BlockConfig = { @@ -208,8 +208,3 @@ export const DropcontactBlock: BlockConfig = { company_results: { type: 'string', description: 'Company net results' }, }, } - -export const DropcontactBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.dropcontact.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dspy.display.ts b/apps/sim/blocks/blocks/dspy.display.ts index 2db143d1277..80527b5568c 100644 --- a/apps/sim/blocks/blocks/dspy.display.ts +++ b/apps/sim/blocks/blocks/dspy.display.ts @@ -1,6 +1,6 @@ import { DsPyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DSPyBlockDisplay = { type: 'dspy', @@ -14,3 +14,97 @@ export const DSPyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/dspy', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const DSPyBlockMeta = { + tags: ['llm', 'agentic', 'automation'], + url: 'https://dspy.ai', + templates: [ + { + icon: DsPyIcon, + title: 'DSPy structured extraction', + prompt: + 'Build a workflow that reads raw records from a table, runs a DSPy predict program on your self-hosted server to extract structured fields from each, and writes the typed results back to the table.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: DsPyIcon, + title: 'DSPy evaluation harness', + prompt: + 'Create a workflow that runs a DSPy program against a labeled evals table, computes accuracy, F1, and per-class breakdowns, and writes the metrics to a reporting table for tracking over iterations.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: DsPyIcon, + title: 'DSPy A/B program selector', + prompt: + 'Create a scheduled workflow that runs two DSPy program endpoints against the same eval set nightly, scores each on accuracy, and writes the head-to-head comparison and recommended winner to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: DsPyIcon, + title: 'DSPy production traffic replay', + prompt: + 'Build a workflow that periodically replays sample production traces through a DSPy program, captures divergences, and writes regression analysis to a tracking file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: DsPyIcon, + title: 'DSPy + LangSmith trace harness', + prompt: + 'Create a workflow that runs a DSPy program over an eval set, logs each prediction as a LangSmith trace for evaluation, captures the quality delta against the previous run, and writes the comparison to engineering Slack.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['langsmith', 'slack'], + }, + { + icon: DsPyIcon, + title: 'DSPy ticket classifier', + prompt: + 'Build a workflow that runs new support tickets through a DSPy predict signature to classify category, urgency, and sentiment with structured outputs, then routes each ticket to the right queue and writes the labels back to the ticket.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'llm'], + }, + { + icon: DsPyIcon, + title: 'DSPy reasoning research agent', + prompt: + 'Create a workflow that takes a research question, uses DSPy chain-of-thought to break it into sub-questions, runs DSPy ReAct with web search to gather evidence, and writes a structured, cited answer to a file.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['research', 'llm', 'agentic'], + }, + ], + skills: [ + { + name: 'run-dspy-prediction', + description: + 'Call a self-hosted DSPy Predict program to get a structured output from an input.', + content: + '# Run DSPy Prediction\n\nSend input to a self-hosted DSPy Predict program and return its structured answer.\n\n## Steps\n1. Confirm the DSPy server base URL and, if required, the API key.\n2. Choose the Predict operation and supply the input text. Set the input field name only if the program signature expects something other than the default.\n3. Pass any extra signature fields as an additional-inputs JSON object.\n\n## Output\nReturn the program answer and any structured fields it produced. If the server returns a non-success status, surface the status and the raw output for debugging.', + }, + { + name: 'reason-with-chain-of-thought', + description: + 'Use a DSPy Chain of Thought program to answer a question with explicit reasoning.', + content: + '# Reason with Chain of Thought\n\nAnswer a question through a self-hosted DSPy Chain of Thought program that exposes its reasoning.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the Chain of Thought operation and supply the question. Add any background as context.\n3. Run the program and capture both the answer and the reasoning trace.\n\n## Output\nReturn the final answer plus the reasoning rationale so the requester can audit how the conclusion was reached.', + }, + { + name: 'run-dspy-react-agent', + description: + 'Run a DSPy ReAct agent on a task that requires multi-step tool use, and capture its trajectory.', + content: + '# Run DSPy ReAct Agent\n\nExecute a task with a self-hosted DSPy ReAct agent that interleaves reasoning and actions.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the ReAct operation and describe the task clearly. Set a max-iterations cap to bound how many reasoning-action cycles run.\n3. Provide any needed context, then execute the agent.\n\n## Output\nReturn the final answer and the step-by-step trajectory (thoughts, actions, observations). If the agent hit the iteration cap without finishing, note that and summarize the last state.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dspy.ts b/apps/sim/blocks/blocks/dspy.ts index 550c7c0a687..4fa3c4b26d9 100644 --- a/apps/sim/blocks/blocks/dspy.ts +++ b/apps/sim/blocks/blocks/dspy.ts @@ -1,6 +1,5 @@ -import { DsPyIcon } from '@/components/icons' import { DSPyBlockDisplay } from '@/blocks/blocks/dspy.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' export const DSPyBlock: BlockConfig = { ...DSPyBlockDisplay, @@ -166,97 +165,3 @@ export const DSPyBlock: BlockConfig = { rawOutput: { type: 'json', description: 'Complete raw output from the DSPy program' }, }, } - -export const DSPyBlockMeta = { - tags: ['llm', 'agentic', 'automation'], - url: 'https://dspy.ai', - templates: [ - { - icon: DsPyIcon, - title: 'DSPy structured extraction', - prompt: - 'Build a workflow that reads raw records from a table, runs a DSPy predict program on your self-hosted server to extract structured fields from each, and writes the typed results back to the table.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: DsPyIcon, - title: 'DSPy evaluation harness', - prompt: - 'Create a workflow that runs a DSPy program against a labeled evals table, computes accuracy, F1, and per-class breakdowns, and writes the metrics to a reporting table for tracking over iterations.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: DsPyIcon, - title: 'DSPy A/B program selector', - prompt: - 'Create a scheduled workflow that runs two DSPy program endpoints against the same eval set nightly, scores each on accuracy, and writes the head-to-head comparison and recommended winner to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: DsPyIcon, - title: 'DSPy production traffic replay', - prompt: - 'Build a workflow that periodically replays sample production traces through a DSPy program, captures divergences, and writes regression analysis to a tracking file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: DsPyIcon, - title: 'DSPy + LangSmith trace harness', - prompt: - 'Create a workflow that runs a DSPy program over an eval set, logs each prediction as a LangSmith trace for evaluation, captures the quality delta against the previous run, and writes the comparison to engineering Slack.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['langsmith', 'slack'], - }, - { - icon: DsPyIcon, - title: 'DSPy ticket classifier', - prompt: - 'Build a workflow that runs new support tickets through a DSPy predict signature to classify category, urgency, and sentiment with structured outputs, then routes each ticket to the right queue and writes the labels back to the ticket.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'llm'], - }, - { - icon: DsPyIcon, - title: 'DSPy reasoning research agent', - prompt: - 'Create a workflow that takes a research question, uses DSPy chain-of-thought to break it into sub-questions, runs DSPy ReAct with web search to gather evidence, and writes a structured, cited answer to a file.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['research', 'llm', 'agentic'], - }, - ], - skills: [ - { - name: 'run-dspy-prediction', - description: - 'Call a self-hosted DSPy Predict program to get a structured output from an input.', - content: - '# Run DSPy Prediction\n\nSend input to a self-hosted DSPy Predict program and return its structured answer.\n\n## Steps\n1. Confirm the DSPy server base URL and, if required, the API key.\n2. Choose the Predict operation and supply the input text. Set the input field name only if the program signature expects something other than the default.\n3. Pass any extra signature fields as an additional-inputs JSON object.\n\n## Output\nReturn the program answer and any structured fields it produced. If the server returns a non-success status, surface the status and the raw output for debugging.', - }, - { - name: 'reason-with-chain-of-thought', - description: - 'Use a DSPy Chain of Thought program to answer a question with explicit reasoning.', - content: - '# Reason with Chain of Thought\n\nAnswer a question through a self-hosted DSPy Chain of Thought program that exposes its reasoning.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the Chain of Thought operation and supply the question. Add any background as context.\n3. Run the program and capture both the answer and the reasoning trace.\n\n## Output\nReturn the final answer plus the reasoning rationale so the requester can audit how the conclusion was reached.', - }, - { - name: 'run-dspy-react-agent', - description: - 'Run a DSPy ReAct agent on a task that requires multi-step tool use, and capture its trajectory.', - content: - '# Run DSPy ReAct Agent\n\nExecute a task with a self-hosted DSPy ReAct agent that interleaves reasoning and actions.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the ReAct operation and describe the task clearly. Set a max-iterations cap to bound how many reasoning-action cycles run.\n3. Provide any needed context, then execute the agent.\n\n## Output\nReturn the final answer and the step-by-step trajectory (thoughts, actions, observations). If the agent hit the iteration cap without finishing, note that and summarize the last state.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dub.display.ts b/apps/sim/blocks/blocks/dub.display.ts index 7762d09caf9..4c3bceb1a48 100644 --- a/apps/sim/blocks/blocks/dub.display.ts +++ b/apps/sim/blocks/blocks/dub.display.ts @@ -1,6 +1,6 @@ import { DubIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DubBlockDisplay = { type: 'dub', @@ -14,3 +14,107 @@ export const DubBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/dub', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const DubBlockMeta = { + tags: ['link-management', 'marketing', 'data-analytics'], + url: 'https://dub.co', + templates: [ + { + icon: DubIcon, + title: 'Dub short link factory', + prompt: + 'Build a workflow that takes a destination URL and campaign metadata, creates a tracked short link in Dub with UTM parameters and a custom slug, stores the link in a table, and returns it to the caller for use in outreach and marketing.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: DubIcon, + title: 'Campaign link batcher', + prompt: + 'Create a workflow that reads a table of campaign destinations, upserts a Dub short link for each row with consistent UTM tags, writes the resulting short URL back into the table, and posts a Slack confirmation summarizing how many links were created or refreshed.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: DubIcon, + title: 'Dub analytics digest', + prompt: + 'Build a scheduled weekly workflow that pulls Dub link analytics — clicks, leads, sales, and top referrers — for active campaigns, writes a narrative summary highlighting winners and decliners, and delivers the digest to Slack with deep links into the Dub dashboard.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: DubIcon, + title: 'Short link hygiene auditor', + prompt: + 'Create a scheduled monthly workflow that lists all Dub links, checks each destination for 4xx and 5xx responses, flags broken links in a table, and emails the marketing team a remediation list so dead campaign links never go live.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: DubIcon, + title: 'Outbound link personalizer', + prompt: + 'Build a workflow that reads a leads table, generates a per-lead Dub short link with the lead identifier in UTM and metadata, attaches the personalized link to the outreach email body, and tracks delivery in the table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'marketing', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: DubIcon, + title: 'Release announcement linker', + prompt: + 'Create a workflow triggered by a GitHub release that creates a Dub short link for the release notes URL, posts the short link to the marketing Slack channel, and stores the mapping of release tag to short link in a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'devops', 'automation'], + alsoIntegrations: ['github', 'slack'], + }, + { + icon: DubIcon, + title: 'Top-converting links report', + prompt: + 'Build a scheduled monthly workflow that pulls Dub analytics grouped by link, ranks top performers by leads and sales, identifies underperformers, writes a narrative report file with recommendations, and shares it with marketing leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis', 'reporting'], + }, + ], + skills: [ + { + name: 'create-tracked-short-link', + description: + 'Create a Dub short link for a destination URL with UTM parameters and an optional custom slug.', + content: + '# Create Tracked Short Link\n\nTurn a long destination URL into a branded, trackable Dub short link.\n\n## Steps\n1. Take the destination URL and any campaign metadata (source, medium, campaign name).\n2. Call Create Link with the URL. Set the UTM source, medium, and campaign fields so clicks attribute correctly, and set a custom slug when a memorable link is wanted.\n3. Add a custom domain, title, or tag IDs if the request specifies them.\n\n## Output\nReturn the full short link URL, its slug, the destination, and the QR code URL. Confirm which UTM parameters were applied.', + }, + { + name: 'report-link-analytics', + description: + 'Pull Dub click, lead, and sales analytics for a link or campaign over a time window.', + content: + '# Report Link Analytics\n\nSummarize how a Dub short link or campaign is performing.\n\n## Steps\n1. Choose the Get Analytics operation. Set the event type (clicks, leads, sales, or composite) the request cares about.\n2. Scope to a specific link via link ID or external ID, or to a domain for a whole campaign. Set the interval (e.g., 7d, 30d) or explicit start and end dates.\n3. Set group-by to break results down by country, device, referrer, or top links when a breakdown is asked for; otherwise use count for totals.\n\n## Output\nReport the headline metrics (clicks, leads, sales, revenue) and, when grouped, the top segments. Call out notable winners and decliners versus the prior period when comparison data is available.', + }, + { + name: 'batch-create-campaign-links', + description: + 'Upsert a Dub short link for each row in a list of destinations with consistent UTM tagging.', + content: + '# Batch Create Campaign Links\n\nGenerate consistent tracked links for many destinations at once.\n\n## Steps\n1. For each destination URL in the list, build the UTM parameters and slug from the row data so tagging is uniform across the batch.\n2. Use Upsert Link (keyed on external ID or slug) so re-runs refresh rather than duplicate existing links.\n3. Collect the resulting short link for each row.\n\n## Output\nReturn a table mapping each destination to its short link and external ID. Report how many links were created versus refreshed, and flag any rows that failed.', + }, + { + name: 'audit-existing-links', + description: + 'List Dub links and check each destination for broken or stale URLs to flag for cleanup.', + content: + '# Audit Existing Links\n\nReview existing Dub links to catch broken or outdated destinations.\n\n## Steps\n1. Call List Links, optionally filtered by domain or tag IDs, paginating until all links are retrieved.\n2. For each link, inspect the destination URL and check it for 4xx or 5xx responses or obviously stale targets.\n3. Note links with low or zero clicks over a long period as candidates for archiving.\n\n## Output\nReturn a remediation list: short link, destination, detected issue (broken, redirecting, stale), and a suggested action. Sort broken links first.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dub.ts b/apps/sim/blocks/blocks/dub.ts index 20657cf7874..911a16a1fda 100644 --- a/apps/sim/blocks/blocks/dub.ts +++ b/apps/sim/blocks/blocks/dub.ts @@ -1,6 +1,5 @@ -import { DubIcon } from '@/components/icons' import { DubBlockDisplay } from '@/blocks/blocks/dub.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { DubResponse } from '@/tools/dub/types' @@ -879,107 +878,3 @@ export const DubBlock: BlockConfig = { content: { type: 'string', description: 'QR code as base64-encoded PNG data' }, }, } - -export const DubBlockMeta = { - tags: ['link-management', 'marketing', 'data-analytics'], - url: 'https://dub.co', - templates: [ - { - icon: DubIcon, - title: 'Dub short link factory', - prompt: - 'Build a workflow that takes a destination URL and campaign metadata, creates a tracked short link in Dub with UTM parameters and a custom slug, stores the link in a table, and returns it to the caller for use in outreach and marketing.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: DubIcon, - title: 'Campaign link batcher', - prompt: - 'Create a workflow that reads a table of campaign destinations, upserts a Dub short link for each row with consistent UTM tags, writes the resulting short URL back into the table, and posts a Slack confirmation summarizing how many links were created or refreshed.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: DubIcon, - title: 'Dub analytics digest', - prompt: - 'Build a scheduled weekly workflow that pulls Dub link analytics — clicks, leads, sales, and top referrers — for active campaigns, writes a narrative summary highlighting winners and decliners, and delivers the digest to Slack with deep links into the Dub dashboard.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: DubIcon, - title: 'Short link hygiene auditor', - prompt: - 'Create a scheduled monthly workflow that lists all Dub links, checks each destination for 4xx and 5xx responses, flags broken links in a table, and emails the marketing team a remediation list so dead campaign links never go live.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: DubIcon, - title: 'Outbound link personalizer', - prompt: - 'Build a workflow that reads a leads table, generates a per-lead Dub short link with the lead identifier in UTM and metadata, attaches the personalized link to the outreach email body, and tracks delivery in the table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'marketing', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: DubIcon, - title: 'Release announcement linker', - prompt: - 'Create a workflow triggered by a GitHub release that creates a Dub short link for the release notes URL, posts the short link to the marketing Slack channel, and stores the mapping of release tag to short link in a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'devops', 'automation'], - alsoIntegrations: ['github', 'slack'], - }, - { - icon: DubIcon, - title: 'Top-converting links report', - prompt: - 'Build a scheduled monthly workflow that pulls Dub analytics grouped by link, ranks top performers by leads and sales, identifies underperformers, writes a narrative report file with recommendations, and shares it with marketing leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis', 'reporting'], - }, - ], - skills: [ - { - name: 'create-tracked-short-link', - description: - 'Create a Dub short link for a destination URL with UTM parameters and an optional custom slug.', - content: - '# Create Tracked Short Link\n\nTurn a long destination URL into a branded, trackable Dub short link.\n\n## Steps\n1. Take the destination URL and any campaign metadata (source, medium, campaign name).\n2. Call Create Link with the URL. Set the UTM source, medium, and campaign fields so clicks attribute correctly, and set a custom slug when a memorable link is wanted.\n3. Add a custom domain, title, or tag IDs if the request specifies them.\n\n## Output\nReturn the full short link URL, its slug, the destination, and the QR code URL. Confirm which UTM parameters were applied.', - }, - { - name: 'report-link-analytics', - description: - 'Pull Dub click, lead, and sales analytics for a link or campaign over a time window.', - content: - '# Report Link Analytics\n\nSummarize how a Dub short link or campaign is performing.\n\n## Steps\n1. Choose the Get Analytics operation. Set the event type (clicks, leads, sales, or composite) the request cares about.\n2. Scope to a specific link via link ID or external ID, or to a domain for a whole campaign. Set the interval (e.g., 7d, 30d) or explicit start and end dates.\n3. Set group-by to break results down by country, device, referrer, or top links when a breakdown is asked for; otherwise use count for totals.\n\n## Output\nReport the headline metrics (clicks, leads, sales, revenue) and, when grouped, the top segments. Call out notable winners and decliners versus the prior period when comparison data is available.', - }, - { - name: 'batch-create-campaign-links', - description: - 'Upsert a Dub short link for each row in a list of destinations with consistent UTM tagging.', - content: - '# Batch Create Campaign Links\n\nGenerate consistent tracked links for many destinations at once.\n\n## Steps\n1. For each destination URL in the list, build the UTM parameters and slug from the row data so tagging is uniform across the batch.\n2. Use Upsert Link (keyed on external ID or slug) so re-runs refresh rather than duplicate existing links.\n3. Collect the resulting short link for each row.\n\n## Output\nReturn a table mapping each destination to its short link and external ID. Report how many links were created versus refreshed, and flag any rows that failed.', - }, - { - name: 'audit-existing-links', - description: - 'List Dub links and check each destination for broken or stale URLs to flag for cleanup.', - content: - '# Audit Existing Links\n\nReview existing Dub links to catch broken or outdated destinations.\n\n## Steps\n1. Call List Links, optionally filtered by domain or tag IDs, paginating until all links are retrieved.\n2. For each link, inspect the destination URL and check it for 4xx or 5xx responses or obviously stale targets.\n3. Note links with low or zero clicks over a long period as candidates for archiving.\n\n## Output\nReturn a remediation list: short link, destination, detected issue (broken, redirecting, stale), and a suggested action. Sort broken links first.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/duckduckgo.display.ts b/apps/sim/blocks/blocks/duckduckgo.display.ts index 9d0eac0c9f9..0eb8155c772 100644 --- a/apps/sim/blocks/blocks/duckduckgo.display.ts +++ b/apps/sim/blocks/blocks/duckduckgo.display.ts @@ -1,6 +1,6 @@ import { DuckDuckGoIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DuckDuckGoBlockDisplay = { type: 'duckduckgo', @@ -14,3 +14,99 @@ export const DuckDuckGoBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/duckduckgo', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const DuckDuckGoBlockMeta = { + tags: ['web-scraping'], + url: 'https://duckduckgo.com', + templates: [ + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo private research agent', + prompt: + 'Build an agent that runs DuckDuckGo searches for queries that need privacy preservation, returns answers with citations, and saves the findings to a knowledge base.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo daily digest', + prompt: + 'Create a scheduled daily workflow that queries DuckDuckGo for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo competitor watcher', + prompt: + 'Build a scheduled workflow that runs DuckDuckGo searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo agent fallback', + prompt: + 'Create an agent that uses Perplexity for primary search and falls back to DuckDuckGo on rate-limit errors so research workflows remain reliable.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research'], + alsoIntegrations: ['perplexity'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo legal-research helper', + prompt: + 'Build a workflow that uses DuckDuckGo to find precedents and analyses for legal questions, summarizes with citations, and writes a research file for review.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'research'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo open-web validator', + prompt: + 'Create a workflow that validates claims in an agent draft by searching DuckDuckGo for supporting sources, flagging claims without strong citations.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'analysis'], + }, + { + icon: DuckDuckGoIcon, + title: 'DuckDuckGo enrichment researcher', + prompt: + 'Build a workflow that uses DuckDuckGo to research prospect or company context where standard enrichment is missing, and writes the findings back to the CRM record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'answer-with-duckduckgo', + description: + 'Search DuckDuckGo for a quick instant answer or abstract on a topic and return it with its source.', + content: + '# Answer with DuckDuckGo\n\nGet a fast, privacy-preserving answer to a factual question using DuckDuckGo Instant Answers.\n\n## Steps\n1. Form a concise query from the question. Enable Remove HTML so returned text is clean.\n2. Run the search and read the instant answer, abstract, and abstract source.\n3. If the result is a disambiguation page rather than a direct answer, refine the query to be more specific and search again.\n\n## Output\nReturn the answer or abstract text along with the source name and URL so the claim is attributable. If no instant answer exists, say so and surface the related topics instead.', + }, + { + name: 'gather-related-topics', + description: + 'Use DuckDuckGo to collect related topics and external links around a subject for research.', + content: + '# Gather Related Topics\n\nBuild a quick research starting point on a subject using DuckDuckGo.\n\n## Steps\n1. Search the subject with Remove HTML enabled.\n2. Collect the heading, abstract, related topics, and any external link results.\n3. Group the related topics into themes and pick the most authoritative links to explore further.\n\n## Output\nReturn the abstract summary plus a list of related topics and external links, each with its URL, organized by theme.', + }, + { + name: 'validate-claim-online', + description: + 'Check a stated claim against DuckDuckGo results to confirm or flag it as unsupported.', + content: + '# Validate Claim Online\n\nVerify whether a claim is supported by public web sources via DuckDuckGo.\n\n## Steps\n1. Turn the claim into a focused search query and run it with Remove HTML enabled.\n2. Compare the instant answer, abstract, and source against the claim.\n3. Decide whether the result supports, contradicts, or is silent on the claim.\n\n## Output\nReturn a verdict — supported, contradicted, or unverified — with the source name and URL. If unverified, recommend a more targeted query or a dedicated source.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/duckduckgo.ts b/apps/sim/blocks/blocks/duckduckgo.ts index 119cd3507eb..40e4f33194d 100644 --- a/apps/sim/blocks/blocks/duckduckgo.ts +++ b/apps/sim/blocks/blocks/duckduckgo.ts @@ -1,6 +1,5 @@ -import { DuckDuckGoIcon } from '@/components/icons' import { DuckDuckGoBlockDisplay } from '@/blocks/blocks/duckduckgo.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { DuckDuckGoResponse } from '@/tools/duckduckgo/types' export const DuckDuckGoBlock: BlockConfig = { @@ -59,99 +58,3 @@ export const DuckDuckGoBlock: BlockConfig = { results: { type: 'json', description: 'Array of external link results' }, }, } - -export const DuckDuckGoBlockMeta = { - tags: ['web-scraping'], - url: 'https://duckduckgo.com', - templates: [ - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo private research agent', - prompt: - 'Build an agent that runs DuckDuckGo searches for queries that need privacy preservation, returns answers with citations, and saves the findings to a knowledge base.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo daily digest', - prompt: - 'Create a scheduled daily workflow that queries DuckDuckGo for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo competitor watcher', - prompt: - 'Build a scheduled workflow that runs DuckDuckGo searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo agent fallback', - prompt: - 'Create an agent that uses Perplexity for primary search and falls back to DuckDuckGo on rate-limit errors so research workflows remain reliable.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research'], - alsoIntegrations: ['perplexity'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo legal-research helper', - prompt: - 'Build a workflow that uses DuckDuckGo to find precedents and analyses for legal questions, summarizes with citations, and writes a research file for review.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'research'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo open-web validator', - prompt: - 'Create a workflow that validates claims in an agent draft by searching DuckDuckGo for supporting sources, flagging claims without strong citations.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'analysis'], - }, - { - icon: DuckDuckGoIcon, - title: 'DuckDuckGo enrichment researcher', - prompt: - 'Build a workflow that uses DuckDuckGo to research prospect or company context where standard enrichment is missing, and writes the findings back to the CRM record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'answer-with-duckduckgo', - description: - 'Search DuckDuckGo for a quick instant answer or abstract on a topic and return it with its source.', - content: - '# Answer with DuckDuckGo\n\nGet a fast, privacy-preserving answer to a factual question using DuckDuckGo Instant Answers.\n\n## Steps\n1. Form a concise query from the question. Enable Remove HTML so returned text is clean.\n2. Run the search and read the instant answer, abstract, and abstract source.\n3. If the result is a disambiguation page rather than a direct answer, refine the query to be more specific and search again.\n\n## Output\nReturn the answer or abstract text along with the source name and URL so the claim is attributable. If no instant answer exists, say so and surface the related topics instead.', - }, - { - name: 'gather-related-topics', - description: - 'Use DuckDuckGo to collect related topics and external links around a subject for research.', - content: - '# Gather Related Topics\n\nBuild a quick research starting point on a subject using DuckDuckGo.\n\n## Steps\n1. Search the subject with Remove HTML enabled.\n2. Collect the heading, abstract, related topics, and any external link results.\n3. Group the related topics into themes and pick the most authoritative links to explore further.\n\n## Output\nReturn the abstract summary plus a list of related topics and external links, each with its URL, organized by theme.', - }, - { - name: 'validate-claim-online', - description: - 'Check a stated claim against DuckDuckGo results to confirm or flag it as unsupported.', - content: - '# Validate Claim Online\n\nVerify whether a claim is supported by public web sources via DuckDuckGo.\n\n## Steps\n1. Turn the claim into a focused search query and run it with Remove HTML enabled.\n2. Compare the instant answer, abstract, and source against the claim.\n3. Decide whether the result supports, contradicts, or is silent on the claim.\n\n## Output\nReturn a verdict — supported, contradicted, or unverified — with the source name and URL. If unverified, recommend a more targeted query or a dedicated source.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dynamodb.display.ts b/apps/sim/blocks/blocks/dynamodb.display.ts index c22d08235af..68a0a18d3bc 100644 --- a/apps/sim/blocks/blocks/dynamodb.display.ts +++ b/apps/sim/blocks/blocks/dynamodb.display.ts @@ -1,6 +1,6 @@ import { DynamoDBIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const DynamoDBBlockDisplay = { type: 'dynamodb', @@ -15,3 +15,100 @@ export const DynamoDBBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/dynamodb', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const DynamoDBBlockMeta = { + tags: ['cloud', 'data-analytics'], + url: 'https://aws.amazon.com/dynamodb', + templates: [ + { + icon: DynamoDBIcon, + title: 'DynamoDB hot-partition watcher', + prompt: + 'Build a scheduled workflow that pulls DynamoDB CloudWatch metrics, identifies hot partitions and throttled requests, and writes the report to a Slack channel with mitigation suggestions.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['cloudwatch', 'slack'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB TTL backfill', + prompt: + 'Create a workflow that scans a DynamoDB table for items missing the TTL attribute, computes the correct TTL based on creation time, and updates in batches with throttling.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB to S3 archive', + prompt: + 'Build a scheduled workflow that exports DynamoDB items older than the retention horizon to S3 with Parquet partitioning and removes the rows from the table, writing the archive manifest.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB change publisher', + prompt: + 'Create a scheduled workflow that scans a DynamoDB table for items changed since the last run, transforms each into a typed event, and publishes it to an SQS queue for downstream processing.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['sqs'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB capacity recommender', + prompt: + 'Build a scheduled weekly workflow that analyzes DynamoDB capacity consumption, recommends switches between provisioned and on-demand per table, and writes the savings projection to a finance review file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'devops'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB GSI health audit', + prompt: + 'Create a scheduled workflow that scans DynamoDB GSIs for skew, low projection efficiency, and unused indexes, and writes a remediation plan to engineering Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: DynamoDBIcon, + title: 'DynamoDB + Athena unified analytics', + prompt: + 'Create a workflow that exports DynamoDB tables nightly into Athena-queryable Parquet, registers the schema, and writes a sample query for analyst use.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + alsoIntegrations: ['athena'], + }, + ], + skills: [ + { + name: 'lookup-item-by-key', + description: + 'Get a single DynamoDB item by its primary key and return the requested attributes.', + content: + '# Lookup Item by Key\n\nRetrieve one record from a DynamoDB table by its key.\n\n## Steps\n1. Identify the table and the partition key (and sort key if the table uses one).\n2. Get the item by its key.\n3. Return the requested attributes, or report that no item exists for that key.\n\n## Output\nThe item attributes if found, or a clear "not found" result. Do not fabricate values for missing attributes.', + }, + { + name: 'query-table-records', + description: + 'Query a DynamoDB table or index by partition key with optional filters and return the matching items.', + content: + '# Query Table Records\n\nFetch a set of related items from DynamoDB using a query.\n\n## Steps\n1. Determine the table or secondary index and the partition key value to query.\n2. Add a sort-key condition or filter expression if needed to narrow results.\n3. Run the query and collect the items, paginating if there are more.\n\n## Output\nThe matching items and a count. Note if results were truncated by a limit or pagination boundary.', + }, + { + name: 'upsert-item', + description: 'Create or update a DynamoDB item, setting attributes from provided values.', + content: + '# Upsert Item\n\nWrite a record into a DynamoDB table.\n\n## Steps\n1. Build the item with its primary key and the attributes to set.\n2. Put the item, or use an update expression to modify only specific attributes.\n3. Confirm the write succeeded.\n\n## Output\nConfirm the item key written and which attributes were set or updated.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dynamodb.ts b/apps/sim/blocks/blocks/dynamodb.ts index 632707d9267..7100c4b2996 100644 --- a/apps/sim/blocks/blocks/dynamodb.ts +++ b/apps/sim/blocks/blocks/dynamodb.ts @@ -1,7 +1,6 @@ import { toError } from '@sim/utils/errors' -import { DynamoDBIcon } from '@/components/icons' import { DynamoDBBlockDisplay } from '@/blocks/blocks/dynamodb.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { DynamoDBIntrospectResponse, DynamoDBResponse } from '@/tools/dynamodb/types' @@ -819,100 +818,3 @@ Return ONLY the expression - no explanations.`, }, }, } - -export const DynamoDBBlockMeta = { - tags: ['cloud', 'data-analytics'], - url: 'https://aws.amazon.com/dynamodb', - templates: [ - { - icon: DynamoDBIcon, - title: 'DynamoDB hot-partition watcher', - prompt: - 'Build a scheduled workflow that pulls DynamoDB CloudWatch metrics, identifies hot partitions and throttled requests, and writes the report to a Slack channel with mitigation suggestions.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['cloudwatch', 'slack'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB TTL backfill', - prompt: - 'Create a workflow that scans a DynamoDB table for items missing the TTL attribute, computes the correct TTL based on creation time, and updates in batches with throttling.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB to S3 archive', - prompt: - 'Build a scheduled workflow that exports DynamoDB items older than the retention horizon to S3 with Parquet partitioning and removes the rows from the table, writing the archive manifest.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB change publisher', - prompt: - 'Create a scheduled workflow that scans a DynamoDB table for items changed since the last run, transforms each into a typed event, and publishes it to an SQS queue for downstream processing.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['sqs'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB capacity recommender', - prompt: - 'Build a scheduled weekly workflow that analyzes DynamoDB capacity consumption, recommends switches between provisioned and on-demand per table, and writes the savings projection to a finance review file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'devops'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB GSI health audit', - prompt: - 'Create a scheduled workflow that scans DynamoDB GSIs for skew, low projection efficiency, and unused indexes, and writes a remediation plan to engineering Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: DynamoDBIcon, - title: 'DynamoDB + Athena unified analytics', - prompt: - 'Create a workflow that exports DynamoDB tables nightly into Athena-queryable Parquet, registers the schema, and writes a sample query for analyst use.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - alsoIntegrations: ['athena'], - }, - ], - skills: [ - { - name: 'lookup-item-by-key', - description: - 'Get a single DynamoDB item by its primary key and return the requested attributes.', - content: - '# Lookup Item by Key\n\nRetrieve one record from a DynamoDB table by its key.\n\n## Steps\n1. Identify the table and the partition key (and sort key if the table uses one).\n2. Get the item by its key.\n3. Return the requested attributes, or report that no item exists for that key.\n\n## Output\nThe item attributes if found, or a clear "not found" result. Do not fabricate values for missing attributes.', - }, - { - name: 'query-table-records', - description: - 'Query a DynamoDB table or index by partition key with optional filters and return the matching items.', - content: - '# Query Table Records\n\nFetch a set of related items from DynamoDB using a query.\n\n## Steps\n1. Determine the table or secondary index and the partition key value to query.\n2. Add a sort-key condition or filter expression if needed to narrow results.\n3. Run the query and collect the items, paginating if there are more.\n\n## Output\nThe matching items and a count. Note if results were truncated by a limit or pagination boundary.', - }, - { - name: 'upsert-item', - description: 'Create or update a DynamoDB item, setting attributes from provided values.', - content: - '# Upsert Item\n\nWrite a record into a DynamoDB table.\n\n## Steps\n1. Build the item with its primary key and the attributes to set.\n2. Put the item, or use an update expression to modify only specific attributes.\n3. Confirm the write succeeded.\n\n## Output\nConfirm the item key written and which attributes were set or updated.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/elasticsearch.display.ts b/apps/sim/blocks/blocks/elasticsearch.display.ts index 64266d486d7..381486f669b 100644 --- a/apps/sim/blocks/blocks/elasticsearch.display.ts +++ b/apps/sim/blocks/blocks/elasticsearch.display.ts @@ -1,6 +1,6 @@ import { ElasticsearchIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ElasticsearchBlockDisplay = { type: 'elasticsearch', @@ -14,3 +14,105 @@ export const ElasticsearchBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/elasticsearch', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const ElasticsearchBlockMeta = { + tags: ['vector-search', 'data-analytics'], + url: 'https://www.elastic.co/elasticsearch', + templates: [ + { + icon: ElasticsearchIcon, + title: 'Elasticsearch log triage', + prompt: + 'Build a scheduled workflow that runs saved Elasticsearch queries hourly for error patterns, clusters the matches, writes the top groups to a triage table, and pings on-call.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch security event correlator', + prompt: + 'Create a workflow that pulls Elasticsearch security events, correlates them across sources, and opens a CrowdStrike or PagerDuty incident on a confirmed pattern.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['crowdstrike', 'pagerduty'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch index lifecycle audit', + prompt: + 'Build a scheduled weekly workflow that audits Elasticsearch indices against retention policies, identifies over-retained data, and writes the cleanup plan to a Slack approval thread.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch search-as-a-service connector', + prompt: + 'Create a workflow that exposes a saved Elasticsearch query as an internal search endpoint, normalizes results into a standard shape, and writes usage telemetry to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch + knowledge base hybrid', + prompt: + 'Build a workflow that combines Elasticsearch keyword search with a vector knowledge base, fuses results with reciprocal-rank fusion, and answers user questions with grounded citations.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'research'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch slow-query digest', + prompt: + 'Create a scheduled daily workflow that aggregates Elasticsearch slow-log entries, clusters the top offenders, and posts a digest to the platform Slack channel with recommended fixes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: ElasticsearchIcon, + title: 'Elasticsearch + LangSmith retrieval evaluator', + prompt: + 'Create a workflow that uses LangSmith to evaluate retrieval quality from Elasticsearch versus a vector knowledge base, writes the head-to-head scores to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['langsmith'], + }, + ], + skills: [ + { + name: 'search-elasticsearch-index', + description: 'Run a query against an Elasticsearch index and return the matching documents.', + content: + '# Search Elasticsearch Index\n\nQuery an index and return the relevant documents.\n\n## Steps\n1. Confirm the connection details (host or cloud ID and auth) and the target index name.\n2. Choose the Search operation and build the query DSL — match for full-text, term for exact values, range for numeric or date bounds, and bool to combine clauses.\n3. Set size and offset for paging, add a sort spec when ordering matters, and use source includes/excludes to trim returned fields.\n\n## Output\nReturn the matching hits with their _id, _score, and relevant _source fields, plus the total count and query time. If nothing matched, report zero hits and suggest loosening the query.', + }, + { + name: 'index-document', + description: 'Add or update a document in an Elasticsearch index.', + content: + '# Index Document\n\nWrite a document into an Elasticsearch index so it becomes searchable.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Build the document as a JSON object with appropriate field types. Choose the Index Document operation; supply a document ID to upsert a known record, or omit it to let Elasticsearch auto-generate one.\n3. To change only specific fields of an existing document, use Update Document with a partial document and the document ID instead.\n4. Set the refresh policy to immediate or wait-for when the write must be searchable right away.\n\n## Output\nReturn the resulting _id, _version, and the operation result (created or updated).', + }, + { + name: 'bulk-load-documents', + description: + 'Index, update, or delete many Elasticsearch documents in a single bulk request.', + content: + '# Bulk Load Documents\n\nApply many document operations to Elasticsearch efficiently in one call.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Assemble the operations as NDJSON: an action line (index, create, update, or delete) followed by the document line where required.\n3. Run the Bulk Operations call and set a refresh policy if the data must be immediately searchable.\n\n## Output\nReport whether any errors occurred and summarize the per-item results — how many succeeded versus failed and the reason for any failures.', + }, + { + name: 'check-cluster-health', + description: 'Report Elasticsearch cluster health and key index statistics.', + content: + '# Check Cluster Health\n\nAssess the health of an Elasticsearch deployment.\n\n## Steps\n1. Confirm the connection details.\n2. Call Cluster Health to get the overall status (green, yellow, red) and node count. Optionally wait for a target status.\n3. Use List Indices and Get Index Info to spot oversized, unassigned, or unhealthy indices, and Cluster Stats for storage and shard totals.\n\n## Output\nReport the cluster status, number of nodes, and any indices that look problematic. If status is yellow or red, explain the likely cause (e.g., unassigned replicas) and what to check next.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/elasticsearch.ts b/apps/sim/blocks/blocks/elasticsearch.ts index 498d9810888..89072a5e14b 100644 --- a/apps/sim/blocks/blocks/elasticsearch.ts +++ b/apps/sim/blocks/blocks/elasticsearch.ts @@ -1,6 +1,5 @@ -import { ElasticsearchIcon } from '@/components/icons' import { ElasticsearchBlockDisplay } from '@/blocks/blocks/elasticsearch.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ElasticsearchResponse } from '@/tools/elasticsearch/types' @@ -526,105 +525,3 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, nodes: { type: 'json', description: 'Node statistics' }, }, } - -export const ElasticsearchBlockMeta = { - tags: ['vector-search', 'data-analytics'], - url: 'https://www.elastic.co/elasticsearch', - templates: [ - { - icon: ElasticsearchIcon, - title: 'Elasticsearch log triage', - prompt: - 'Build a scheduled workflow that runs saved Elasticsearch queries hourly for error patterns, clusters the matches, writes the top groups to a triage table, and pings on-call.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch security event correlator', - prompt: - 'Create a workflow that pulls Elasticsearch security events, correlates them across sources, and opens a CrowdStrike or PagerDuty incident on a confirmed pattern.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['crowdstrike', 'pagerduty'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch index lifecycle audit', - prompt: - 'Build a scheduled weekly workflow that audits Elasticsearch indices against retention policies, identifies over-retained data, and writes the cleanup plan to a Slack approval thread.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch search-as-a-service connector', - prompt: - 'Create a workflow that exposes a saved Elasticsearch query as an internal search endpoint, normalizes results into a standard shape, and writes usage telemetry to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch + knowledge base hybrid', - prompt: - 'Build a workflow that combines Elasticsearch keyword search with a vector knowledge base, fuses results with reciprocal-rank fusion, and answers user questions with grounded citations.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'research'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch slow-query digest', - prompt: - 'Create a scheduled daily workflow that aggregates Elasticsearch slow-log entries, clusters the top offenders, and posts a digest to the platform Slack channel with recommended fixes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: ElasticsearchIcon, - title: 'Elasticsearch + LangSmith retrieval evaluator', - prompt: - 'Create a workflow that uses LangSmith to evaluate retrieval quality from Elasticsearch versus a vector knowledge base, writes the head-to-head scores to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['langsmith'], - }, - ], - skills: [ - { - name: 'search-elasticsearch-index', - description: 'Run a query against an Elasticsearch index and return the matching documents.', - content: - '# Search Elasticsearch Index\n\nQuery an index and return the relevant documents.\n\n## Steps\n1. Confirm the connection details (host or cloud ID and auth) and the target index name.\n2. Choose the Search operation and build the query DSL — match for full-text, term for exact values, range for numeric or date bounds, and bool to combine clauses.\n3. Set size and offset for paging, add a sort spec when ordering matters, and use source includes/excludes to trim returned fields.\n\n## Output\nReturn the matching hits with their _id, _score, and relevant _source fields, plus the total count and query time. If nothing matched, report zero hits and suggest loosening the query.', - }, - { - name: 'index-document', - description: 'Add or update a document in an Elasticsearch index.', - content: - '# Index Document\n\nWrite a document into an Elasticsearch index so it becomes searchable.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Build the document as a JSON object with appropriate field types. Choose the Index Document operation; supply a document ID to upsert a known record, or omit it to let Elasticsearch auto-generate one.\n3. To change only specific fields of an existing document, use Update Document with a partial document and the document ID instead.\n4. Set the refresh policy to immediate or wait-for when the write must be searchable right away.\n\n## Output\nReturn the resulting _id, _version, and the operation result (created or updated).', - }, - { - name: 'bulk-load-documents', - description: - 'Index, update, or delete many Elasticsearch documents in a single bulk request.', - content: - '# Bulk Load Documents\n\nApply many document operations to Elasticsearch efficiently in one call.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Assemble the operations as NDJSON: an action line (index, create, update, or delete) followed by the document line where required.\n3. Run the Bulk Operations call and set a refresh policy if the data must be immediately searchable.\n\n## Output\nReport whether any errors occurred and summarize the per-item results — how many succeeded versus failed and the reason for any failures.', - }, - { - name: 'check-cluster-health', - description: 'Report Elasticsearch cluster health and key index statistics.', - content: - '# Check Cluster Health\n\nAssess the health of an Elasticsearch deployment.\n\n## Steps\n1. Confirm the connection details.\n2. Call Cluster Health to get the overall status (green, yellow, red) and node count. Optionally wait for a target status.\n3. Use List Indices and Get Index Info to spot oversized, unassigned, or unhealthy indices, and Cluster Stats for storage and shard totals.\n\n## Output\nReport the cluster status, number of nodes, and any indices that look problematic. If status is yellow or red, explain the likely cause (e.g., unassigned replicas) and what to check next.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/elevenlabs.display.ts b/apps/sim/blocks/blocks/elevenlabs.display.ts index 0654a15a46c..a9a9b520f1b 100644 --- a/apps/sim/blocks/blocks/elevenlabs.display.ts +++ b/apps/sim/blocks/blocks/elevenlabs.display.ts @@ -1,6 +1,6 @@ import { ElevenLabsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ElevenLabsBlockDisplay = { type: 'elevenlabs', @@ -13,3 +13,99 @@ export const ElevenLabsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/elevenlabs', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const ElevenLabsBlockMeta = { + tags: ['text-to-speech'], + url: 'https://elevenlabs.io', + templates: [ + { + icon: ElevenLabsIcon, + title: 'ElevenLabs blog-to-podcast', + prompt: + 'Build a workflow that takes a blog post, narrates it with an ElevenLabs voice, saves the audio file, and posts a player-ready link to the marketing Slack channel.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['slack'], + }, + { + icon: ElevenLabsIcon, + title: 'Customer voice greeting generator', + prompt: + 'Create a workflow that reads a table of new enterprise customers, generates a personalized ElevenLabs voice greeting with their account manager voice, and emails the audio file to the customer on day one.', + modules: ['tables', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: ElevenLabsIcon, + title: 'ElevenLabs IVR builder', + prompt: + 'Build a workflow that generates branded ElevenLabs voice prompts from a tables-driven script, saves each clip as a file, and lists the bundle so it can be wired into the phone tree.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: ElevenLabsIcon, + title: 'ElevenLabs + Pulse meeting voice digest', + prompt: + 'Build a workflow that takes Pulse meeting insights, narrates them with an ElevenLabs voice, and emails the audio digest to the team for asynchronous review.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['pulse', 'gmail'], + }, + { + icon: ElevenLabsIcon, + title: 'ElevenLabs daily voice digest', + prompt: + 'Build a scheduled daily workflow that generates an ElevenLabs voice digest of the day’s key metrics, saves the audio, and Slacks the player link to leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['founder', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ElevenLabsIcon, + title: 'ElevenLabs release-notes narrator', + prompt: + "Create a workflow that takes new product release notes, rewrites them into a natural spoken script with an agent, generates narration with ElevenLabs text-to-speech, and saves the audio file ready to share as a what's-new update.", + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: ElevenLabsIcon, + title: 'ElevenLabs voicemail responder', + prompt: + 'Build a workflow that on a new inbound message drafts a short personalized reply with an agent, converts it to speech with ElevenLabs in a chosen voice, and saves the audio so it can be sent as a voice note to the customer.', + modules: ['agent', 'files', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + }, + ], + skills: [ + { + name: 'narrate-text-to-speech', + description: + 'Convert a block of text into natural-sounding speech audio with a chosen ElevenLabs voice.', + content: + '# Narrate Text to Speech\n\nGenerate spoken audio from text using ElevenLabs.\n\n## Steps\n1. Take the text to narrate and confirm the target voice ID (ask for one if not provided).\n2. Pick a model — use a multilingual model for non-English or mixed-language text, or a turbo/flash model when low latency matters.\n3. For consistent delivery, set stability higher; for more expressive variation, set it lower. Raise similarity boost to stay closer to the reference voice.\n\n## Output\nReturn the generated audio file and its URL. Confirm the voice and model used so the requester can adjust if the delivery is not right.', + }, + { + name: 'narrate-article-as-audio', + description: 'Turn a long article or blog post into a podcast-style audio narration.', + content: + '# Narrate Article as Audio\n\nProduce a listenable audio version of written content.\n\n## Steps\n1. Clean the source text — strip markdown, navigation, and boilerplate so only the readable prose remains. Expand abbreviations the voice should speak in full.\n2. Choose a voice ID suited to the content and a high-quality multilingual model for natural delivery.\n3. Convert the cleaned text to speech, keeping stability moderate so the narration sounds engaging but consistent.\n\n## Output\nReturn the audio file and a player-ready URL, along with the voice used. If the text is very long, note any truncation and suggest splitting it into parts.', + }, + { + name: 'generate-voice-prompt', + description: + 'Generate a short branded voice clip such as an IVR prompt, greeting, or notification.', + content: + '# Generate Voice Prompt\n\nCreate a short, polished voice clip for things like phone menus, greetings, or alerts.\n\n## Steps\n1. Take the exact script for the prompt. Keep it concise and confirm pronunciation of any names or numbers.\n2. Select a consistent brand voice ID so every prompt sounds the same.\n3. Set stability high for a steady, professional delivery and convert the script to speech.\n\n## Output\nReturn the audio file and its URL. When generating a set of prompts, list each clip with its script so they can be wired into the phone tree or app.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/elevenlabs.ts b/apps/sim/blocks/blocks/elevenlabs.ts index 20fb583fc3a..4b949e1670c 100644 --- a/apps/sim/blocks/blocks/elevenlabs.ts +++ b/apps/sim/blocks/blocks/elevenlabs.ts @@ -1,6 +1,5 @@ -import { ElevenLabsIcon } from '@/components/icons' import { ElevenLabsBlockDisplay } from '@/blocks/blocks/elevenlabs.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ElevenLabsBlockResponse } from '@/tools/elevenlabs/types' export const ElevenLabsBlock: BlockConfig = { @@ -96,99 +95,3 @@ export const ElevenLabsBlock: BlockConfig = { audioFile: { type: 'file', description: 'Generated audio file' }, }, } - -export const ElevenLabsBlockMeta = { - tags: ['text-to-speech'], - url: 'https://elevenlabs.io', - templates: [ - { - icon: ElevenLabsIcon, - title: 'ElevenLabs blog-to-podcast', - prompt: - 'Build a workflow that takes a blog post, narrates it with an ElevenLabs voice, saves the audio file, and posts a player-ready link to the marketing Slack channel.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['slack'], - }, - { - icon: ElevenLabsIcon, - title: 'Customer voice greeting generator', - prompt: - 'Create a workflow that reads a table of new enterprise customers, generates a personalized ElevenLabs voice greeting with their account manager voice, and emails the audio file to the customer on day one.', - modules: ['tables', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: ElevenLabsIcon, - title: 'ElevenLabs IVR builder', - prompt: - 'Build a workflow that generates branded ElevenLabs voice prompts from a tables-driven script, saves each clip as a file, and lists the bundle so it can be wired into the phone tree.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: ElevenLabsIcon, - title: 'ElevenLabs + Pulse meeting voice digest', - prompt: - 'Build a workflow that takes Pulse meeting insights, narrates them with an ElevenLabs voice, and emails the audio digest to the team for asynchronous review.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['pulse', 'gmail'], - }, - { - icon: ElevenLabsIcon, - title: 'ElevenLabs daily voice digest', - prompt: - 'Build a scheduled daily workflow that generates an ElevenLabs voice digest of the day’s key metrics, saves the audio, and Slacks the player link to leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['founder', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ElevenLabsIcon, - title: 'ElevenLabs release-notes narrator', - prompt: - "Create a workflow that takes new product release notes, rewrites them into a natural spoken script with an agent, generates narration with ElevenLabs text-to-speech, and saves the audio file ready to share as a what's-new update.", - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: ElevenLabsIcon, - title: 'ElevenLabs voicemail responder', - prompt: - 'Build a workflow that on a new inbound message drafts a short personalized reply with an agent, converts it to speech with ElevenLabs in a chosen voice, and saves the audio so it can be sent as a voice note to the customer.', - modules: ['agent', 'files', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - }, - ], - skills: [ - { - name: 'narrate-text-to-speech', - description: - 'Convert a block of text into natural-sounding speech audio with a chosen ElevenLabs voice.', - content: - '# Narrate Text to Speech\n\nGenerate spoken audio from text using ElevenLabs.\n\n## Steps\n1. Take the text to narrate and confirm the target voice ID (ask for one if not provided).\n2. Pick a model — use a multilingual model for non-English or mixed-language text, or a turbo/flash model when low latency matters.\n3. For consistent delivery, set stability higher; for more expressive variation, set it lower. Raise similarity boost to stay closer to the reference voice.\n\n## Output\nReturn the generated audio file and its URL. Confirm the voice and model used so the requester can adjust if the delivery is not right.', - }, - { - name: 'narrate-article-as-audio', - description: 'Turn a long article or blog post into a podcast-style audio narration.', - content: - '# Narrate Article as Audio\n\nProduce a listenable audio version of written content.\n\n## Steps\n1. Clean the source text — strip markdown, navigation, and boilerplate so only the readable prose remains. Expand abbreviations the voice should speak in full.\n2. Choose a voice ID suited to the content and a high-quality multilingual model for natural delivery.\n3. Convert the cleaned text to speech, keeping stability moderate so the narration sounds engaging but consistent.\n\n## Output\nReturn the audio file and a player-ready URL, along with the voice used. If the text is very long, note any truncation and suggest splitting it into parts.', - }, - { - name: 'generate-voice-prompt', - description: - 'Generate a short branded voice clip such as an IVR prompt, greeting, or notification.', - content: - '# Generate Voice Prompt\n\nCreate a short, polished voice clip for things like phone menus, greetings, or alerts.\n\n## Steps\n1. Take the exact script for the prompt. Keep it concise and confirm pronunciation of any names or numbers.\n2. Select a consistent brand voice ID so every prompt sounds the same.\n3. Set stability high for a steady, professional delivery and convert the script to speech.\n\n## Output\nReturn the audio file and its URL. When generating a set of prompts, list each clip with its script so they can be wired into the phone tree or app.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/emailbison.display.ts b/apps/sim/blocks/blocks/emailbison.display.ts index 481f914b23d..7ad7df4012b 100644 --- a/apps/sim/blocks/blocks/emailbison.display.ts +++ b/apps/sim/blocks/blocks/emailbison.display.ts @@ -1,6 +1,6 @@ import { EmailBisonIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const EmailBisonBlockDisplay = { type: 'emailbison', @@ -15,3 +15,107 @@ export const EmailBisonBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/emailbison', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const EmailBisonBlockMeta = { + tags: ['sales-engagement', 'email-marketing', 'automation'], + url: 'https://emailbison.com', + templates: [ + { + icon: EmailBisonIcon, + title: 'Email Bison campaign launcher', + prompt: + 'Build a workflow that takes a target persona and offer, drafts a multi-step Email Bison campaign with personalized variables, creates the campaign and attaches the matching leads, and launches it once a human approves.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'communication'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison reply triage', + prompt: + 'Create a workflow that pulls new Email Bison replies on a schedule, classifies each as interested, not interested, objection, or out-of-office, applies the matching tag to the lead, and pings the rep in Slack for hot replies.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison + Apollo lead feeder', + prompt: + 'Build a workflow that runs an Apollo search for an ICP, enriches each prospect, creates the lead in Email Bison with personalization variables, and attaches the leads to the matching active campaign.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['apollo'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison tag automator', + prompt: + 'Create a workflow that reads Email Bison replies and activity, and applies tags to leads based on engagement signals — opened, clicked, replied positively, bounced — so segmentation stays current for follow-up campaigns.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'analysis'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison weekly outbound digest', + prompt: + 'Build a scheduled weekly workflow that pulls Email Bison campaign performance — sends, opens, replies, positive reply rate — generates a digest with the top campaigns and bottom performers, and posts it to a Slack sales channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison + HubSpot sync', + prompt: + 'Create a workflow that mirrors Email Bison lead status and reply outcomes into the matching HubSpot contact, logs each campaign step as an engagement, and creates a HubSpot task for sales when a lead replies positively.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'sync'], + alsoIntegrations: ['hubspot'], + }, + { + icon: EmailBisonIcon, + title: 'Email Bison bounce cleanup', + prompt: + 'Build a scheduled workflow that finds Email Bison leads with hard bounces, tags them for suppression, updates the lead in Email Bison, and writes a cleanup report so deliverability stays healthy.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'analysis'], + }, + ], + skills: [ + { + name: 'add-leads-to-campaign', + description: + 'Create leads in Email Bison and attach them to an outbound campaign with personalization variables.', + content: + '# Add Leads to Campaign\n\nLoad prospects into Email Bison and enroll them in a campaign.\n\n## Steps\n1. Confirm the instance URL and target campaign. If only a campaign name is known, use List Campaigns to resolve its ID.\n2. For each prospect, call Create Lead with first name, last name, email, and any title or company. Pass personalization fields as a custom-variables JSON array (e.g., linkedin_url, first_line).\n3. Collect the new lead IDs and call Attach Leads to Campaign with the campaign ID and those IDs.\n\n## Output\nReport how many leads were created and attached, list any duplicates or invalid emails that were skipped, and confirm the campaign they were added to.', + }, + { + name: 'triage-campaign-replies', + description: + 'Pull recent Email Bison replies, classify each by intent, and tag the lead accordingly.', + content: + '# Triage Campaign Replies\n\nProcess inbound replies to outbound campaigns and route them.\n\n## Steps\n1. Call List Replies, optionally scoped to a campaign, sender email, or the inbox folder, and filter to unread when only new replies matter.\n2. Classify each reply as interested, not interested, objection, out-of-office, or auto-reply based on its content.\n3. Resolve or create the matching tag with List Tags / Create Tag, then call Attach Tags to Leads to label the lead by intent.\n\n## Output\nReturn each reply with its lead, classification, and the tag applied. Highlight interested replies so a rep can follow up first.', + }, + { + name: 'manage-campaign-status', + description: + 'Pause, resume, or archive an Email Bison campaign and adjust its sending settings.', + content: + '# Manage Campaign Status\n\nControl whether an Email Bison campaign is actively sending and tune its limits.\n\n## Steps\n1. Confirm the campaign ID (resolve via List Campaigns if only a name is given).\n2. Call Update Campaign Status with pause, resume, or archive as requested.\n3. To adjust throughput or behavior, call Update Campaign to change max emails per day, max new leads per day, sequence prioritization, or tracking settings.\n\n## Output\nConfirm the campaign new status and any sending settings that changed. Note the prior values so the change can be reverted if needed.', + }, + { + name: 'report-campaign-performance', + description: + 'Summarize Email Bison campaign performance — sends, opens, replies, and positive reply rate.', + content: + '# Report Campaign Performance\n\nProduce a performance snapshot across Email Bison campaigns.\n\n## Steps\n1. Call List Campaigns to get the active campaigns and their stats.\n2. For reply-level detail, call List Replies per campaign and tally interested versus total to compute positive reply rate.\n3. Rank campaigns by reply rate and identify top and bottom performers.\n\n## Output\nReturn a digest: per-campaign sends, opens, replies, and positive reply rate, with the best and worst performers called out and a one-line takeaway for each.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/emailbison.ts b/apps/sim/blocks/blocks/emailbison.ts index d3880880d4f..ad84928ed90 100644 --- a/apps/sim/blocks/blocks/emailbison.ts +++ b/apps/sim/blocks/blocks/emailbison.ts @@ -1,6 +1,5 @@ -import { EmailBisonIcon } from '@/components/icons' import { EmailBisonBlockDisplay } from '@/blocks/blocks/emailbison.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { EmailBisonResponse } from '@/tools/emailbison/types' import { getTrigger } from '@/triggers' @@ -616,107 +615,3 @@ function toBooleanParam(value: unknown): boolean | undefined { function emptyToUndefined(value: unknown): unknown { return value === '' ? undefined : value } - -export const EmailBisonBlockMeta = { - tags: ['sales-engagement', 'email-marketing', 'automation'], - url: 'https://emailbison.com', - templates: [ - { - icon: EmailBisonIcon, - title: 'Email Bison campaign launcher', - prompt: - 'Build a workflow that takes a target persona and offer, drafts a multi-step Email Bison campaign with personalized variables, creates the campaign and attaches the matching leads, and launches it once a human approves.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'communication'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison reply triage', - prompt: - 'Create a workflow that pulls new Email Bison replies on a schedule, classifies each as interested, not interested, objection, or out-of-office, applies the matching tag to the lead, and pings the rep in Slack for hot replies.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison + Apollo lead feeder', - prompt: - 'Build a workflow that runs an Apollo search for an ICP, enriches each prospect, creates the lead in Email Bison with personalization variables, and attaches the leads to the matching active campaign.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['apollo'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison tag automator', - prompt: - 'Create a workflow that reads Email Bison replies and activity, and applies tags to leads based on engagement signals — opened, clicked, replied positively, bounced — so segmentation stays current for follow-up campaigns.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'analysis'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison weekly outbound digest', - prompt: - 'Build a scheduled weekly workflow that pulls Email Bison campaign performance — sends, opens, replies, positive reply rate — generates a digest with the top campaigns and bottom performers, and posts it to a Slack sales channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison + HubSpot sync', - prompt: - 'Create a workflow that mirrors Email Bison lead status and reply outcomes into the matching HubSpot contact, logs each campaign step as an engagement, and creates a HubSpot task for sales when a lead replies positively.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'sync'], - alsoIntegrations: ['hubspot'], - }, - { - icon: EmailBisonIcon, - title: 'Email Bison bounce cleanup', - prompt: - 'Build a scheduled workflow that finds Email Bison leads with hard bounces, tags them for suppression, updates the lead in Email Bison, and writes a cleanup report so deliverability stays healthy.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'analysis'], - }, - ], - skills: [ - { - name: 'add-leads-to-campaign', - description: - 'Create leads in Email Bison and attach them to an outbound campaign with personalization variables.', - content: - '# Add Leads to Campaign\n\nLoad prospects into Email Bison and enroll them in a campaign.\n\n## Steps\n1. Confirm the instance URL and target campaign. If only a campaign name is known, use List Campaigns to resolve its ID.\n2. For each prospect, call Create Lead with first name, last name, email, and any title or company. Pass personalization fields as a custom-variables JSON array (e.g., linkedin_url, first_line).\n3. Collect the new lead IDs and call Attach Leads to Campaign with the campaign ID and those IDs.\n\n## Output\nReport how many leads were created and attached, list any duplicates or invalid emails that were skipped, and confirm the campaign they were added to.', - }, - { - name: 'triage-campaign-replies', - description: - 'Pull recent Email Bison replies, classify each by intent, and tag the lead accordingly.', - content: - '# Triage Campaign Replies\n\nProcess inbound replies to outbound campaigns and route them.\n\n## Steps\n1. Call List Replies, optionally scoped to a campaign, sender email, or the inbox folder, and filter to unread when only new replies matter.\n2. Classify each reply as interested, not interested, objection, out-of-office, or auto-reply based on its content.\n3. Resolve or create the matching tag with List Tags / Create Tag, then call Attach Tags to Leads to label the lead by intent.\n\n## Output\nReturn each reply with its lead, classification, and the tag applied. Highlight interested replies so a rep can follow up first.', - }, - { - name: 'manage-campaign-status', - description: - 'Pause, resume, or archive an Email Bison campaign and adjust its sending settings.', - content: - '# Manage Campaign Status\n\nControl whether an Email Bison campaign is actively sending and tune its limits.\n\n## Steps\n1. Confirm the campaign ID (resolve via List Campaigns if only a name is given).\n2. Call Update Campaign Status with pause, resume, or archive as requested.\n3. To adjust throughput or behavior, call Update Campaign to change max emails per day, max new leads per day, sequence prioritization, or tracking settings.\n\n## Output\nConfirm the campaign new status and any sending settings that changed. Note the prior values so the change can be reverted if needed.', - }, - { - name: 'report-campaign-performance', - description: - 'Summarize Email Bison campaign performance — sends, opens, replies, and positive reply rate.', - content: - '# Report Campaign Performance\n\nProduce a performance snapshot across Email Bison campaigns.\n\n## Steps\n1. Call List Campaigns to get the active campaigns and their stats.\n2. For reply-level detail, call List Replies per campaign and tally interested versus total to compute positive reply rate.\n3. Rank campaigns by reply rate and identify top and bottom performers.\n\n## Output\nReturn a digest: per-campaign sends, opens, replies, and positive reply rate, with the best and worst performers called out and a one-line takeaway for each.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrich.display.ts b/apps/sim/blocks/blocks/enrich.display.ts index b1490530b8d..685a442abfc 100644 --- a/apps/sim/blocks/blocks/enrich.display.ts +++ b/apps/sim/blocks/blocks/enrich.display.ts @@ -1,6 +1,6 @@ import { EnrichSoIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const EnrichBlockDisplay = { type: 'enrich', @@ -14,3 +14,108 @@ export const EnrichBlockDisplay = { docsLink: 'https://docs.enrich.so/', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const EnrichBlockMeta = { + tags: ['enrichment'], + url: 'https://www.enrich.so', + templates: [ + { + icon: EnrichSoIcon, + title: 'Enrich CRM hydrator', + prompt: + 'Build a workflow that watches new Salesforce leads, enriches each with Enrich.so contact data, and writes role, company size, and email to the lead record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich list cleaner', + prompt: + 'Create a workflow that runs an outreach list through Enrich, removes invalid emails and disqualified roles, and writes the clean list to a sender table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich bulk-account researcher', + prompt: + 'Build a workflow that takes a list of target accounts, enriches each with Enrich firmographic data, and writes a tables-based account brief for the sales team.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich + Email Bison sender', + prompt: + 'Create a workflow that runs Enrich on prospects then drafts and sends a personalized Email Bison sequence based on the enriched fields.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich event-attendee researcher', + prompt: + 'Build a workflow that takes the Luma event attendee list, enriches each via Enrich, and writes a per-attendee research brief for the sales team.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['luma'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich CRM gap-filler', + prompt: + 'Create a scheduled workflow that finds HubSpot contacts missing key fields, runs Enrich, and fills in the gaps so reporting is complete.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: EnrichSoIcon, + title: 'Enrich LinkedIn role validator', + prompt: + 'Build a scheduled workflow that reads HubSpot contacts with a LinkedIn profile URL, re-enriches each with Enrich, flags outdated roles, and updates the contact record with the current title.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'enrich-contact-from-email', + description: + 'Enrich a person from their email address — name, role, company, social profiles, and more.', + content: + '# Enrich Contact from Email\n\nTurn an email address into a full contact profile using Enrich.so.\n\n## Steps\n1. Take the email address. Choose Email to Profile for a full enrichment, or Email to Person (Lite) for a fast, cheaper lookup.\n2. Enable fresh-data fetch when up-to-date info matters more than speed.\n3. Read back name, current title, company, location, and any LinkedIn or social URLs.\n\n## Output\nReturn the enriched fields in a clean object. Note which fields could not be resolved so downstream steps know what is missing, and report remaining credits if relevant.', + }, + { + name: 'find-and-verify-work-email', + description: + 'Find a prospect work email from a name and company or LinkedIn URL, then verify deliverability.', + content: + '# Find and Verify Work Email\n\nLocate a reliable work email for a prospect and confirm it is safe to send to.\n\n## Steps\n1. If you have a name and company domain, use Find Email. If you have a LinkedIn profile URL, use LinkedIn to Work Email instead.\n2. Run Verify Email on the returned address to check deliverability, and Disposable Email Check to rule out throwaway domains.\n3. If the work email cannot be found, optionally fall back to LinkedIn to Personal Email when appropriate.\n\n## Output\nReturn the discovered email, its verification status (valid, risky, invalid), and whether it is disposable. Recommend whether the address is safe to add to outreach.', + }, + { + name: 'enrich-company-firmographics', + description: + 'Look up firmographic data for a company — size, industry, funding, revenue, and traffic.', + content: + '# Enrich Company Firmographics\n\nBuild a firmographic profile for a target account using Enrich.so.\n\n## Steps\n1. Identify the company by name or domain. Use Company Lookup for core firmographics.\n2. Add Company Funding & Traffic and Company Revenue for deeper financial signals when account scoring needs them.\n3. If you only have a visitor IP, use IP to Company first to resolve the organization.\n\n## Output\nReturn a consolidated account brief: company name, domain, industry, employee count, funding, revenue, and traffic. Flag any data points that could not be resolved.', + }, + { + name: 'search-prospects', + description: + 'Search Enrich.so for people or companies matching an ideal-customer-profile filter.', + content: + '# Search Prospects\n\nFind people or companies that match a target profile.\n\n## Steps\n1. For people, use Search People with filters like job title, industry, location, and skills. For companies, use Search Company with industry, location, and employee-size bounds.\n2. To pull contacts at known accounts, use Search Company Employees with the company IDs and target job titles.\n3. Page through results using the page and page-size parameters until you have enough matches.\n\n## Output\nReturn the matching people or companies with their key identifying fields and any profile URLs, plus a count of total matches. Suggest tighter filters if too many or too few results come back.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrich.ts b/apps/sim/blocks/blocks/enrich.ts index 9e78222a4b8..edc6a4d40f4 100644 --- a/apps/sim/blocks/blocks/enrich.ts +++ b/apps/sim/blocks/blocks/enrich.ts @@ -1,6 +1,5 @@ -import { EnrichSoIcon } from '@/components/icons' import { EnrichBlockDisplay } from '@/blocks/blocks/enrich.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const EnrichBlock: BlockConfig = { @@ -729,108 +728,3 @@ export const EnrichBlock: BlockConfig = { output: { type: 'json', description: 'Output data from the Enrich operation' }, }, } - -export const EnrichBlockMeta = { - tags: ['enrichment'], - url: 'https://www.enrich.so', - templates: [ - { - icon: EnrichSoIcon, - title: 'Enrich CRM hydrator', - prompt: - 'Build a workflow that watches new Salesforce leads, enriches each with Enrich.so contact data, and writes role, company size, and email to the lead record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich list cleaner', - prompt: - 'Create a workflow that runs an outreach list through Enrich, removes invalid emails and disqualified roles, and writes the clean list to a sender table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich bulk-account researcher', - prompt: - 'Build a workflow that takes a list of target accounts, enriches each with Enrich firmographic data, and writes a tables-based account brief for the sales team.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich + Email Bison sender', - prompt: - 'Create a workflow that runs Enrich on prospects then drafts and sends a personalized Email Bison sequence based on the enriched fields.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich event-attendee researcher', - prompt: - 'Build a workflow that takes the Luma event attendee list, enriches each via Enrich, and writes a per-attendee research brief for the sales team.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['luma'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich CRM gap-filler', - prompt: - 'Create a scheduled workflow that finds HubSpot contacts missing key fields, runs Enrich, and fills in the gaps so reporting is complete.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: EnrichSoIcon, - title: 'Enrich LinkedIn role validator', - prompt: - 'Build a scheduled workflow that reads HubSpot contacts with a LinkedIn profile URL, re-enriches each with Enrich, flags outdated roles, and updates the contact record with the current title.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'enrich-contact-from-email', - description: - 'Enrich a person from their email address — name, role, company, social profiles, and more.', - content: - '# Enrich Contact from Email\n\nTurn an email address into a full contact profile using Enrich.so.\n\n## Steps\n1. Take the email address. Choose Email to Profile for a full enrichment, or Email to Person (Lite) for a fast, cheaper lookup.\n2. Enable fresh-data fetch when up-to-date info matters more than speed.\n3. Read back name, current title, company, location, and any LinkedIn or social URLs.\n\n## Output\nReturn the enriched fields in a clean object. Note which fields could not be resolved so downstream steps know what is missing, and report remaining credits if relevant.', - }, - { - name: 'find-and-verify-work-email', - description: - 'Find a prospect work email from a name and company or LinkedIn URL, then verify deliverability.', - content: - '# Find and Verify Work Email\n\nLocate a reliable work email for a prospect and confirm it is safe to send to.\n\n## Steps\n1. If you have a name and company domain, use Find Email. If you have a LinkedIn profile URL, use LinkedIn to Work Email instead.\n2. Run Verify Email on the returned address to check deliverability, and Disposable Email Check to rule out throwaway domains.\n3. If the work email cannot be found, optionally fall back to LinkedIn to Personal Email when appropriate.\n\n## Output\nReturn the discovered email, its verification status (valid, risky, invalid), and whether it is disposable. Recommend whether the address is safe to add to outreach.', - }, - { - name: 'enrich-company-firmographics', - description: - 'Look up firmographic data for a company — size, industry, funding, revenue, and traffic.', - content: - '# Enrich Company Firmographics\n\nBuild a firmographic profile for a target account using Enrich.so.\n\n## Steps\n1. Identify the company by name or domain. Use Company Lookup for core firmographics.\n2. Add Company Funding & Traffic and Company Revenue for deeper financial signals when account scoring needs them.\n3. If you only have a visitor IP, use IP to Company first to resolve the organization.\n\n## Output\nReturn a consolidated account brief: company name, domain, industry, employee count, funding, revenue, and traffic. Flag any data points that could not be resolved.', - }, - { - name: 'search-prospects', - description: - 'Search Enrich.so for people or companies matching an ideal-customer-profile filter.', - content: - '# Search Prospects\n\nFind people or companies that match a target profile.\n\n## Steps\n1. For people, use Search People with filters like job title, industry, location, and skills. For companies, use Search Company with industry, location, and employee-size bounds.\n2. To pull contacts at known accounts, use Search Company Employees with the company IDs and target job titles.\n3. Page through results using the page and page-size parameters until you have enough matches.\n\n## Output\nReturn the matching people or companies with their key identifying fields and any profile URLs, plus a count of total matches. Suggest tighter filters if too many or too few results come back.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrichment.display.ts b/apps/sim/blocks/blocks/enrichment.display.ts index a4d8efdabc1..0cc8c9d09e4 100644 --- a/apps/sim/blocks/blocks/enrichment.display.ts +++ b/apps/sim/blocks/blocks/enrichment.display.ts @@ -1,6 +1,6 @@ import { EnrichmentIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const EnrichmentBlockDisplay = { type: 'enrichment', @@ -14,3 +14,106 @@ export const EnrichmentBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/enrichment', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const EnrichmentBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + templates: [ + { + icon: EnrichmentIcon, + title: 'Work email finder', + prompt: + 'Build a workflow that reads prospect rows with a full name and company domain from a table, runs the Work Email enrichment to find each verified work email, and writes the result back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: EnrichmentIcon, + title: 'Phone number lookup', + prompt: + "Create a workflow that takes a contact's full name and company domain, runs the Phone Number enrichment to find their direct phone, and appends the number to a call-list table for the SDR team.", + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: EnrichmentIcon, + title: 'Company domain resolver', + prompt: + 'Build a workflow that reads a list of company names from a table, runs the Company Domain enrichment to resolve each website domain, and writes the matched domains back so later steps can enrich against them.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: EnrichmentIcon, + title: 'Company profile enricher', + prompt: + 'Create a workflow that takes a company domain, runs the Company Info enrichment to pull industry, employee count, founded year, and description, and writes the firmographics into an accounts table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: EnrichmentIcon, + title: 'Name to full contact pipeline', + prompt: + 'Build a workflow that takes a prospect name and company name, first runs the Company Domain enrichment to resolve the domain, then runs Work Email and Phone Number enrichments to find the verified email and phone, and writes a complete contact row to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: EnrichmentIcon, + title: 'Inbound lead qualifier', + prompt: + 'Create a workflow that on a new inbound signup runs the Company Info enrichment on the email domain to pull industry and headcount, scores fit against my ICP with an agent, and routes qualified leads to the sales Slack channel.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'enrichment'], + alsoIntegrations: ['slack'], + }, + { + icon: EnrichmentIcon, + title: 'CRM enrichment sweep', + prompt: + 'Build a scheduled workflow that pulls HubSpot contacts missing a work email or phone, runs the Work Email and Phone Number enrichments to fill the gaps, and updates each record so the database stays ready for outbound.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'enrichment'], + alsoIntegrations: ['hubspot'], + }, + { + icon: EnrichmentIcon, + title: 'Target account researcher', + prompt: + 'Create a workflow that takes a company name, resolves its domain with the Company Domain enrichment, pulls firmographics with Company Info, and compiles an account brief into a file for reps to review before outreach.', + modules: ['files', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + ], + skills: [ + { + name: 'find-work-email', + description: + 'Find a verified work email for a contact given their full name and company domain using the Work Email enrichment.', + content: + '# Find a Work Email\n\nResolve a verified work email for a prospect.\n\n## Steps\n1. Confirm you have the contact full name and the company domain (resolve the domain first if only a company name is given).\n2. Run the Work Email enrichment with name and domain.\n3. Capture the email and its verification confidence.\n\n## Output\nThe verified work email with its confidence level, or a clear note that no match was found.', + }, + { + name: 'enrich-company-profile', + description: + 'Pull firmographics (industry, headcount, founded year, description) for a company domain using the Company Info enrichment.', + content: + '# Enrich a Company Profile\n\nBuild a firmographic profile for an account.\n\n## Steps\n1. Confirm the company domain (resolve it with the Company Domain enrichment if you only have a name).\n2. Run the Company Info enrichment on the domain.\n3. Capture industry, employee count, founded year, and description.\n\n## Output\nA structured company profile with the key firmographics, ready to write into an accounts record.', + }, + { + name: 'build-full-contact', + description: + 'Take a prospect name and company, resolve the domain, then find the work email and phone to assemble a complete contact.', + content: + '# Build a Full Contact\n\nGo from a name and company to a complete, enriched contact.\n\n## Steps\n1. Run the Company Domain enrichment to resolve the company website domain.\n2. Run the Work Email enrichment using the name and resolved domain.\n3. Run the Phone Number enrichment for a direct phone.\n4. Assemble the results into one contact record.\n\n## Output\nA complete contact with name, company, domain, verified email, and phone, plus confidence for each field.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrichment.ts b/apps/sim/blocks/blocks/enrichment.ts index a6905ebbf1f..1dec4bacfc9 100644 --- a/apps/sim/blocks/blocks/enrichment.ts +++ b/apps/sim/blocks/blocks/enrichment.ts @@ -1,6 +1,5 @@ -import { EnrichmentIcon } from '@/components/icons' import { EnrichmentBlockDisplay } from '@/blocks/blocks/enrichment.display' -import type { BlockConfig, BlockMeta, OutputFieldDefinition, ParamType } from '@/blocks/types' +import type { BlockConfig, OutputFieldDefinition, ParamType } from '@/blocks/types' import { ALL_ENRICHMENTS, getEnrichment } from '@/enrichments' import { mapFieldType } from '@/enrichments/providers' import type { EnrichmentOutputField } from '@/enrichments/types' @@ -104,106 +103,3 @@ export const EnrichmentBlock: BlockConfig = { inputs: blockInputs, outputs: blockOutputs, } - -export const EnrichmentBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - templates: [ - { - icon: EnrichmentIcon, - title: 'Work email finder', - prompt: - 'Build a workflow that reads prospect rows with a full name and company domain from a table, runs the Work Email enrichment to find each verified work email, and writes the result back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: EnrichmentIcon, - title: 'Phone number lookup', - prompt: - "Create a workflow that takes a contact's full name and company domain, runs the Phone Number enrichment to find their direct phone, and appends the number to a call-list table for the SDR team.", - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: EnrichmentIcon, - title: 'Company domain resolver', - prompt: - 'Build a workflow that reads a list of company names from a table, runs the Company Domain enrichment to resolve each website domain, and writes the matched domains back so later steps can enrich against them.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: EnrichmentIcon, - title: 'Company profile enricher', - prompt: - 'Create a workflow that takes a company domain, runs the Company Info enrichment to pull industry, employee count, founded year, and description, and writes the firmographics into an accounts table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: EnrichmentIcon, - title: 'Name to full contact pipeline', - prompt: - 'Build a workflow that takes a prospect name and company name, first runs the Company Domain enrichment to resolve the domain, then runs Work Email and Phone Number enrichments to find the verified email and phone, and writes a complete contact row to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: EnrichmentIcon, - title: 'Inbound lead qualifier', - prompt: - 'Create a workflow that on a new inbound signup runs the Company Info enrichment on the email domain to pull industry and headcount, scores fit against my ICP with an agent, and routes qualified leads to the sales Slack channel.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'enrichment'], - alsoIntegrations: ['slack'], - }, - { - icon: EnrichmentIcon, - title: 'CRM enrichment sweep', - prompt: - 'Build a scheduled workflow that pulls HubSpot contacts missing a work email or phone, runs the Work Email and Phone Number enrichments to fill the gaps, and updates each record so the database stays ready for outbound.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'enrichment'], - alsoIntegrations: ['hubspot'], - }, - { - icon: EnrichmentIcon, - title: 'Target account researcher', - prompt: - 'Create a workflow that takes a company name, resolves its domain with the Company Domain enrichment, pulls firmographics with Company Info, and compiles an account brief into a file for reps to review before outreach.', - modules: ['files', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - ], - skills: [ - { - name: 'find-work-email', - description: - 'Find a verified work email for a contact given their full name and company domain using the Work Email enrichment.', - content: - '# Find a Work Email\n\nResolve a verified work email for a prospect.\n\n## Steps\n1. Confirm you have the contact full name and the company domain (resolve the domain first if only a company name is given).\n2. Run the Work Email enrichment with name and domain.\n3. Capture the email and its verification confidence.\n\n## Output\nThe verified work email with its confidence level, or a clear note that no match was found.', - }, - { - name: 'enrich-company-profile', - description: - 'Pull firmographics (industry, headcount, founded year, description) for a company domain using the Company Info enrichment.', - content: - '# Enrich a Company Profile\n\nBuild a firmographic profile for an account.\n\n## Steps\n1. Confirm the company domain (resolve it with the Company Domain enrichment if you only have a name).\n2. Run the Company Info enrichment on the domain.\n3. Capture industry, employee count, founded year, and description.\n\n## Output\nA structured company profile with the key firmographics, ready to write into an accounts record.', - }, - { - name: 'build-full-contact', - description: - 'Take a prospect name and company, resolve the domain, then find the work email and phone to assemble a complete contact.', - content: - '# Build a Full Contact\n\nGo from a name and company to a complete, enriched contact.\n\n## Steps\n1. Run the Company Domain enrichment to resolve the company website domain.\n2. Run the Work Email enrichment using the name and resolved domain.\n3. Run the Phone Number enrichment for a direct phone.\n4. Assemble the results into one contact record.\n\n## Output\nA complete contact with name, company, domain, verified email, and phone, plus confidence for each field.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrow.display.ts b/apps/sim/blocks/blocks/enrow.display.ts index 17df4ecd77a..2b1d3426568 100644 --- a/apps/sim/blocks/blocks/enrow.display.ts +++ b/apps/sim/blocks/blocks/enrow.display.ts @@ -1,6 +1,6 @@ import { EnrowIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const EnrowBlockDisplay = { type: 'enrow', @@ -14,3 +14,8 @@ export const EnrowBlockDisplay = { docsLink: 'https://enrow.readme.io', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const EnrowBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://enrow.io', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/enrow.ts b/apps/sim/blocks/blocks/enrow.ts index 7e210218d55..106aa4886f3 100644 --- a/apps/sim/blocks/blocks/enrow.ts +++ b/apps/sim/blocks/blocks/enrow.ts @@ -1,5 +1,5 @@ import { EnrowBlockDisplay } from '@/blocks/blocks/enrow.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { EnrowResponse } from '@/tools/enrow/types' export const EnrowBlock: BlockConfig = { @@ -112,8 +112,3 @@ export const EnrowBlock: BlockConfig = { linkedin_url: { type: 'string', description: 'LinkedIn URL of the person (find only)' }, }, } - -export const EnrowBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://enrow.io', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/evernote.display.ts b/apps/sim/blocks/blocks/evernote.display.ts index 1746dd99830..7ba4432626a 100644 --- a/apps/sim/blocks/blocks/evernote.display.ts +++ b/apps/sim/blocks/blocks/evernote.display.ts @@ -1,6 +1,6 @@ import { EvernoteIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const EvernoteBlockDisplay = { type: 'evernote', @@ -14,3 +14,103 @@ export const EvernoteBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/evernote', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const EvernoteBlockMeta = { + tags: ['note-taking', 'knowledge-base'], + url: 'https://evernote.com', + templates: [ + { + icon: EvernoteIcon, + title: 'Evernote to knowledge base sync', + prompt: + 'Build a workflow that syncs Evernote notebooks into a knowledge base on a schedule so all notes and clipped web pages become searchable by an agent.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + }, + { + icon: EvernoteIcon, + title: 'Evernote weekly summary', + prompt: + 'Create a scheduled weekly workflow that summarizes new Evernote notes by tag, writes the summary as a Markdown file, and emails it to the user as a knowledge digest.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: EvernoteIcon, + title: 'Evernote action-item extractor', + prompt: + 'Build a workflow that searches Evernote for recently created notes, extracts action items and due dates with an agent, and creates a matching task in Asana for each.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['asana'], + }, + { + icon: EvernoteIcon, + title: 'Evernote research collector', + prompt: + 'Create a workflow that takes web clippings saved to Evernote, classifies by topic, and writes structured rows to a research table for downstream analysis.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + }, + { + icon: EvernoteIcon, + title: 'Evernote tag auto-organizer', + prompt: + 'Build a workflow that scans new Evernote notes, suggests and applies tags based on content, and writes the tag changes to an audit log for review.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: EvernoteIcon, + title: 'Evernote to Notion migrator', + prompt: + 'Create a workflow that imports an Evernote notebook into Notion as pages in a chosen database, preserving formatting, attachments, and tags.', + modules: ['files', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'sync'], + alsoIntegrations: ['notion'], + }, + { + icon: EvernoteIcon, + title: 'Evernote research-assistant agent', + prompt: + 'Build an agent that searches across the user’s Evernote notebooks for grounded answers with citations, and saves the answer plus sources back as a new Evernote note.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + }, + ], + skills: [ + { + name: 'create-evernote-note', + description: 'Create a new Evernote note with a title, content, tags, and target notebook.', + content: + '# Create Evernote Note\n\nSave new content as a note in Evernote.\n\n## Steps\n1. Confirm the note title and content. Plain text is fine; the content is stored as ENML.\n2. Choose the Create Note operation. To file it in a specific notebook, resolve the notebook GUID with List Notebooks and pass it.\n3. Add comma-separated tag names so the note is findable later.\n\n## Output\nReturn the new note GUID, its title, and the notebook and tags it was saved under.', + }, + { + name: 'search-evernote-notes', + description: + 'Search Evernote for notes matching a query and return their titles and metadata.', + content: + '# Search Evernote Notes\n\nFind notes across Evernote using its search grammar.\n\n## Steps\n1. Build a query using Evernote search syntax — e.g., tag:work, intitle:meeting, notebook scoping, or plain keywords.\n2. Run Search Notes. Scope to a notebook GUID when the location is known, and set max results and offset to page through matches.\n3. For any note you need the body of, call Get Note with its GUID and include content.\n\n## Output\nReturn the matching notes with title, GUID, and notebook, plus the total match count. If a note body is needed, include its retrieved content.', + }, + { + name: 'extract-note-action-items', + description: 'Read recent Evernote notes and extract action items, owners, and due dates.', + content: + '# Extract Note Action Items\n\nPull tasks out of meeting notes or research notes in Evernote.\n\n## Steps\n1. Use Search Notes to find the relevant recent notes (e.g., by tag or notebook).\n2. For each match, call Get Note with content to read the full body.\n3. Identify action items, the responsible owner, and any due dates mentioned in the text.\n\n## Output\nReturn a structured list of action items, each with its owner, due date if stated, and a link back to the source note GUID. Flag items with no clear owner.', + }, + { + name: 'organize-notes-with-tags', + description: 'Create tags and apply them to Evernote notes to keep them organized.', + content: + '# Organize Notes with Tags\n\nKeep Evernote notes structured by tagging them consistently.\n\n## Steps\n1. Call List Tags to see existing tags and avoid duplicates. Create any missing tag with Create Tag (optionally nested under a parent tag).\n2. For each note to organize, read it with Get Note if needed, decide the right tags from its content, and apply them via Update Note with the tag names.\n3. Keep tag names consistent in casing and wording across notes.\n\n## Output\nReturn each note GUID with the tags applied and note any new tags that were created.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/evernote.ts b/apps/sim/blocks/blocks/evernote.ts index 67ae534343c..a79a733b936 100644 --- a/apps/sim/blocks/blocks/evernote.ts +++ b/apps/sim/blocks/blocks/evernote.ts @@ -1,6 +1,5 @@ -import { EvernoteIcon } from '@/components/icons' import { EvernoteBlockDisplay } from '@/blocks/blocks/evernote.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const EvernoteBlock: BlockConfig = { @@ -299,103 +298,3 @@ export const EvernoteBlock: BlockConfig = { noteGuid: { type: 'string', description: 'GUID of the affected note' }, }, } - -export const EvernoteBlockMeta = { - tags: ['note-taking', 'knowledge-base'], - url: 'https://evernote.com', - templates: [ - { - icon: EvernoteIcon, - title: 'Evernote to knowledge base sync', - prompt: - 'Build a workflow that syncs Evernote notebooks into a knowledge base on a schedule so all notes and clipped web pages become searchable by an agent.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - }, - { - icon: EvernoteIcon, - title: 'Evernote weekly summary', - prompt: - 'Create a scheduled weekly workflow that summarizes new Evernote notes by tag, writes the summary as a Markdown file, and emails it to the user as a knowledge digest.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: EvernoteIcon, - title: 'Evernote action-item extractor', - prompt: - 'Build a workflow that searches Evernote for recently created notes, extracts action items and due dates with an agent, and creates a matching task in Asana for each.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['asana'], - }, - { - icon: EvernoteIcon, - title: 'Evernote research collector', - prompt: - 'Create a workflow that takes web clippings saved to Evernote, classifies by topic, and writes structured rows to a research table for downstream analysis.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - }, - { - icon: EvernoteIcon, - title: 'Evernote tag auto-organizer', - prompt: - 'Build a workflow that scans new Evernote notes, suggests and applies tags based on content, and writes the tag changes to an audit log for review.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: EvernoteIcon, - title: 'Evernote to Notion migrator', - prompt: - 'Create a workflow that imports an Evernote notebook into Notion as pages in a chosen database, preserving formatting, attachments, and tags.', - modules: ['files', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'sync'], - alsoIntegrations: ['notion'], - }, - { - icon: EvernoteIcon, - title: 'Evernote research-assistant agent', - prompt: - 'Build an agent that searches across the user’s Evernote notebooks for grounded answers with citations, and saves the answer plus sources back as a new Evernote note.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - }, - ], - skills: [ - { - name: 'create-evernote-note', - description: 'Create a new Evernote note with a title, content, tags, and target notebook.', - content: - '# Create Evernote Note\n\nSave new content as a note in Evernote.\n\n## Steps\n1. Confirm the note title and content. Plain text is fine; the content is stored as ENML.\n2. Choose the Create Note operation. To file it in a specific notebook, resolve the notebook GUID with List Notebooks and pass it.\n3. Add comma-separated tag names so the note is findable later.\n\n## Output\nReturn the new note GUID, its title, and the notebook and tags it was saved under.', - }, - { - name: 'search-evernote-notes', - description: - 'Search Evernote for notes matching a query and return their titles and metadata.', - content: - '# Search Evernote Notes\n\nFind notes across Evernote using its search grammar.\n\n## Steps\n1. Build a query using Evernote search syntax — e.g., tag:work, intitle:meeting, notebook scoping, or plain keywords.\n2. Run Search Notes. Scope to a notebook GUID when the location is known, and set max results and offset to page through matches.\n3. For any note you need the body of, call Get Note with its GUID and include content.\n\n## Output\nReturn the matching notes with title, GUID, and notebook, plus the total match count. If a note body is needed, include its retrieved content.', - }, - { - name: 'extract-note-action-items', - description: 'Read recent Evernote notes and extract action items, owners, and due dates.', - content: - '# Extract Note Action Items\n\nPull tasks out of meeting notes or research notes in Evernote.\n\n## Steps\n1. Use Search Notes to find the relevant recent notes (e.g., by tag or notebook).\n2. For each match, call Get Note with content to read the full body.\n3. Identify action items, the responsible owner, and any due dates mentioned in the text.\n\n## Output\nReturn a structured list of action items, each with its owner, due date if stated, and a link back to the source note GUID. Flag items with no clear owner.', - }, - { - name: 'organize-notes-with-tags', - description: 'Create tags and apply them to Evernote notes to keep them organized.', - content: - '# Organize Notes with Tags\n\nKeep Evernote notes structured by tagging them consistently.\n\n## Steps\n1. Call List Tags to see existing tags and avoid duplicates. Create any missing tag with Create Tag (optionally nested under a parent tag).\n2. For each note to organize, read it with Get Note if needed, decide the right tags from its content, and apply them via Update Note with the tag names.\n3. Keep tag names consistent in casing and wording across notes.\n\n## Output\nReturn each note GUID with the tags applied and note any new tags that were created.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/exa.display.ts b/apps/sim/blocks/blocks/exa.display.ts index 1d03c892ab2..21f2afbe1a0 100644 --- a/apps/sim/blocks/blocks/exa.display.ts +++ b/apps/sim/blocks/blocks/exa.display.ts @@ -1,6 +1,6 @@ import { ExaAIIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ExaBlockDisplay = { type: 'exa', @@ -15,3 +15,102 @@ export const ExaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/exa', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const ExaBlockMeta = { + tags: ['web-scraping'], + url: 'https://exa.ai', + templates: [ + { + icon: ExaAIIcon, + title: 'Exa company intel agent', + prompt: + 'Build an agent that takes a company name, uses Exa neural search to find recent product updates, funding news, and competitor mentions, and writes a one-page intel brief.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ExaAIIcon, + title: 'Exa knowledge crawler', + prompt: + 'Build a workflow that uses Exa to find authoritative URLs on a topic, scrapes each one, chunks the content, and upserts it into a knowledge base so the agent can answer with citations.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: ExaAIIcon, + title: 'Exa neural research agent', + prompt: + 'Build an agent that uses Exa neural search to find authoritative sources on a topic, scrapes them, and produces a structured research brief with citations.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: ExaAIIcon, + title: 'Exa similar-page finder', + prompt: + 'Create a workflow that takes a URL, runs Exa similar-page search to find related authoritative sources, and writes the discovery list to a research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: ExaAIIcon, + title: 'Exa daily research digest', + prompt: + 'Build a scheduled workflow that runs Exa searches on tracked topics each morning, summarizes top hits with citations, and emails the user a research digest.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: ExaAIIcon, + title: 'Exa investment research helper', + prompt: + 'Create an agent that uses Exa to deep-research a ticker, finds recent material developments, summarizes with citations, and writes the brief to a finance research file.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'research'], + }, + { + icon: ExaAIIcon, + title: 'Exa competitor news monitor', + prompt: + 'Build a scheduled daily workflow that runs Exa search for fresh news about my competitors, gets the page contents and finds similar coverage, summarizes the notable moves with citations, and posts a digest to the team Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'search-the-web-with-exa', + description: + 'Run an Exa neural or keyword search to find high-quality web sources on a topic.', + content: + '# Search the Web with Exa\n\nFind authoritative web pages on a topic using Exa AI search.\n\n## Steps\n1. Use the Search operation with a clear query. Pick the search type — neural for meaning-based discovery, keyword for exact terms, or auto to let Exa decide.\n2. Narrow results with include/exclude domains, a category filter (research paper, news article, company, GitHub), and published-date bounds for recency.\n3. Enable include-text or include-summary so each result comes back with usable content rather than just a link.\n\n## Output\nReturn the top results with title, URL, published date, and the text or summary. Note which filters were applied so the search can be tightened or broadened.', + }, + { + name: 'answer-question-with-citations', + description: 'Use Exa Answer to get a direct, sourced answer to a factual question.', + content: + '# Answer Question with Citations\n\nGet a grounded answer to a question with supporting sources via Exa.\n\n## Steps\n1. Use the Answer operation and pass the question in natural language.\n2. Enable include-text when you want the supporting passages, not just the citation URLs.\n3. Review the citations to confirm the answer is well-supported before relying on it.\n\n## Output\nReturn the answer text plus its citations (titles and URLs). If the citations are weak or conflicting, say so and recommend a follow-up search.', + }, + { + name: 'extract-page-contents', + description: 'Use Exa Get Contents to pull clean text and summaries from a set of URLs.', + content: + '# Extract Page Contents\n\nRetrieve readable content from specific web pages using Exa.\n\n## Steps\n1. Use the Get Contents operation with the target URLs (comma-separated).\n2. Enable include-text for full content, and supply a summary query to get a focused summary tailored to what you need.\n3. To pull deeper context from a site, set a subpage count and target keywords (e.g., docs, pricing, about).\n\n## Output\nReturn each URL with its extracted text or summary and any highlights. Flag any URL that could not be crawled.', + }, + { + name: 'find-similar-pages', + description: 'Use Exa Find Similar Links to discover pages related to a known URL.', + content: + '# Find Similar Pages\n\nDiscover sources similar to a reference page using Exa.\n\n## Steps\n1. Use the Find Similar Links operation with the source URL.\n2. Set the number of results and enable exclude-source-domain so you get genuinely new sources, not more pages from the same site.\n3. Apply a category filter or include/exclude domains to keep the discovery on-target, and enable include-text or include-summary for context.\n\n## Output\nReturn the similar pages with title, URL, and a snippet or summary, ordered by relevance. Note the filters used.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/exa.ts b/apps/sim/blocks/blocks/exa.ts index 79bb3d12b81..0db8591e4a4 100644 --- a/apps/sim/blocks/blocks/exa.ts +++ b/apps/sim/blocks/blocks/exa.ts @@ -1,6 +1,5 @@ -import { ExaAIIcon } from '@/components/icons' import { ExaBlockDisplay } from '@/blocks/blocks/exa.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ExaResponse } from '@/tools/exa/types' @@ -435,102 +434,3 @@ export const ExaBlock: BlockConfig = { research: { type: 'json', description: 'Research findings' }, }, } - -export const ExaBlockMeta = { - tags: ['web-scraping'], - url: 'https://exa.ai', - templates: [ - { - icon: ExaAIIcon, - title: 'Exa company intel agent', - prompt: - 'Build an agent that takes a company name, uses Exa neural search to find recent product updates, funding news, and competitor mentions, and writes a one-page intel brief.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ExaAIIcon, - title: 'Exa knowledge crawler', - prompt: - 'Build a workflow that uses Exa to find authoritative URLs on a topic, scrapes each one, chunks the content, and upserts it into a knowledge base so the agent can answer with citations.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: ExaAIIcon, - title: 'Exa neural research agent', - prompt: - 'Build an agent that uses Exa neural search to find authoritative sources on a topic, scrapes them, and produces a structured research brief with citations.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: ExaAIIcon, - title: 'Exa similar-page finder', - prompt: - 'Create a workflow that takes a URL, runs Exa similar-page search to find related authoritative sources, and writes the discovery list to a research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: ExaAIIcon, - title: 'Exa daily research digest', - prompt: - 'Build a scheduled workflow that runs Exa searches on tracked topics each morning, summarizes top hits with citations, and emails the user a research digest.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: ExaAIIcon, - title: 'Exa investment research helper', - prompt: - 'Create an agent that uses Exa to deep-research a ticker, finds recent material developments, summarizes with citations, and writes the brief to a finance research file.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'research'], - }, - { - icon: ExaAIIcon, - title: 'Exa competitor news monitor', - prompt: - 'Build a scheduled daily workflow that runs Exa search for fresh news about my competitors, gets the page contents and finds similar coverage, summarizes the notable moves with citations, and posts a digest to the team Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'search-the-web-with-exa', - description: - 'Run an Exa neural or keyword search to find high-quality web sources on a topic.', - content: - '# Search the Web with Exa\n\nFind authoritative web pages on a topic using Exa AI search.\n\n## Steps\n1. Use the Search operation with a clear query. Pick the search type — neural for meaning-based discovery, keyword for exact terms, or auto to let Exa decide.\n2. Narrow results with include/exclude domains, a category filter (research paper, news article, company, GitHub), and published-date bounds for recency.\n3. Enable include-text or include-summary so each result comes back with usable content rather than just a link.\n\n## Output\nReturn the top results with title, URL, published date, and the text or summary. Note which filters were applied so the search can be tightened or broadened.', - }, - { - name: 'answer-question-with-citations', - description: 'Use Exa Answer to get a direct, sourced answer to a factual question.', - content: - '# Answer Question with Citations\n\nGet a grounded answer to a question with supporting sources via Exa.\n\n## Steps\n1. Use the Answer operation and pass the question in natural language.\n2. Enable include-text when you want the supporting passages, not just the citation URLs.\n3. Review the citations to confirm the answer is well-supported before relying on it.\n\n## Output\nReturn the answer text plus its citations (titles and URLs). If the citations are weak or conflicting, say so and recommend a follow-up search.', - }, - { - name: 'extract-page-contents', - description: 'Use Exa Get Contents to pull clean text and summaries from a set of URLs.', - content: - '# Extract Page Contents\n\nRetrieve readable content from specific web pages using Exa.\n\n## Steps\n1. Use the Get Contents operation with the target URLs (comma-separated).\n2. Enable include-text for full content, and supply a summary query to get a focused summary tailored to what you need.\n3. To pull deeper context from a site, set a subpage count and target keywords (e.g., docs, pricing, about).\n\n## Output\nReturn each URL with its extracted text or summary and any highlights. Flag any URL that could not be crawled.', - }, - { - name: 'find-similar-pages', - description: 'Use Exa Find Similar Links to discover pages related to a known URL.', - content: - '# Find Similar Pages\n\nDiscover sources similar to a reference page using Exa.\n\n## Steps\n1. Use the Find Similar Links operation with the source URL.\n2. Set the number of results and enable exclude-source-domain so you get genuinely new sources, not more pages from the same site.\n3. Apply a category filter or include/exclude domains to keep the discovery on-target, and enable include-text or include-summary for context.\n\n## Output\nReturn the similar pages with title, URL, and a snippet or summary, ordered by relevance. Note the filters used.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/extend.display.ts b/apps/sim/blocks/blocks/extend.display.ts index 3c057678c3f..5108729f0f9 100644 --- a/apps/sim/blocks/blocks/extend.display.ts +++ b/apps/sim/blocks/blocks/extend.display.ts @@ -1,6 +1,6 @@ import { ExtendIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ExtendBlockDisplay = { type: 'extend', @@ -24,3 +24,100 @@ export const ExtendV2BlockDisplay = { 'Integrate Extend AI into the workflow. Parse and extract structured content from documents or file references.', hideFromToolbar: false, } satisfies BlockDisplay + +export const ExtendBlockMeta = { + tags: ['document-processing', 'ocr'], + url: 'https://www.extend.ai', + templates: [ + { + icon: ExtendIcon, + title: 'Extend structured-data extractor', + prompt: + 'Build a workflow that runs uploaded forms through Extend to pull labelled fields, writes the structured rows to a table, and notifies Slack on missing required fields.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: ExtendIcon, + title: 'Extend insurance claim ingester', + prompt: + 'Create a workflow that uses Extend to ingest claim forms, extracts policy number, claim amount, and incident details to structured rows, and routes high-value claims to a Slack adjuster channel.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: ExtendIcon, + title: 'Extend purchase-order extractor', + prompt: + 'Create a workflow that processes inbound PO PDFs with Extend, writes vendor, SKU, quantity, and total to an orders table, and pings Slack when a PO exceeds the approval threshold.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: ExtendIcon, + title: 'Extend + ElevenLabs spoken-summary', + prompt: + 'Build a workflow that uses Extend to pull structured data from a document, then narrates the summary with ElevenLabs, producing an audio briefing for stakeholders.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['enterprise', 'communication'], + alsoIntegrations: ['elevenlabs'], + }, + { + icon: ExtendIcon, + title: 'Extend KYC pipeline', + prompt: + 'Build a workflow that runs Extend on uploaded KYC documents, validates extracted fields against a compliance rule set, and writes outcomes to a verification table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + }, + { + icon: ExtendIcon, + title: 'Extend invoice processor', + prompt: + 'Create a workflow that parses uploaded vendor invoices with Extend, extracts line items, totals, and due dates, validates against the matching purchase order, and writes approved invoices to an accounts-payable table for payment.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation', 'document-processing'], + }, + { + icon: ExtendIcon, + title: 'Extend contract data extractor', + prompt: + 'Build a workflow that runs Extend on uploaded contracts to pull parties, term dates, renewal clauses, and obligations, summarizes the key risks with an agent, and logs the structured fields to a contracts table for the legal team.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'document-processing', 'automation'], + }, + ], + skills: [ + { + name: 'extract-invoice-fields', + description: + 'Parse an uploaded invoice with Extend and return structured vendor, line item, and total fields.', + content: + '# Extract Invoice Fields\n\nUse Extend to turn an invoice PDF or image into structured, validated data.\n\n## Steps\n1. Take the uploaded invoice document (file upload or URL).\n2. Run the Extend parser to produce structured chunks and blocks.\n3. Pull the key fields: vendor name, invoice number, invoice date, due date, line items (description, quantity, unit price), subtotal, tax, and total.\n4. Validate that totals add up and that required fields are present; flag any that are missing or inconsistent.\n\n## Output\nReturn a clean JSON object with the extracted fields plus a list of any validation warnings. Note the page count and credits used so cost can be tracked.', + }, + { + name: 'parse-document-to-markdown', + description: + 'Convert a scanned or complex document into clean, LLM-ready markdown using Extend.', + content: + '# Parse Document to Markdown\n\nUse Extend to convert any supported document (PDF, image, or Office file) into clean markdown an agent can reason over.\n\n## Steps\n1. Take the source document and choose a chunking strategy (page, section, or document) based on how the content will be consumed.\n2. Run the Extend parser with markdown output.\n3. Stitch the returned chunks into a single ordered markdown document, preserving headings, tables, and lists.\n\n## Output\nReturn the full markdown text plus the page count. If the document was chunked, also return the per-chunk markdown so downstream steps can process sections independently.', + }, + { + name: 'classify-and-route-document', + description: + 'Parse an uploaded document with Extend, identify its type, and route it to the right downstream handler.', + content: + '# Classify and Route Document\n\nUse Extend to read an incoming document and decide where it should go.\n\n## Steps\n1. Run the Extend parser on the uploaded document to get its text content.\n2. Inspect the parsed content to classify the document type (e.g. invoice, contract, claim form, purchase order, KYC document).\n3. Pull the few identifying fields needed for routing (such as document type, reference number, and amount).\n4. Decide the destination queue, table, or channel based on the classification and any thresholds.\n\n## Output\nReturn the detected document type, the routing decision, and the extracted routing fields. Note any document that could not be confidently classified for manual review.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/extend.ts b/apps/sim/blocks/blocks/extend.ts index 3c302461b5f..6505e42bd64 100644 --- a/apps/sim/blocks/blocks/extend.ts +++ b/apps/sim/blocks/blocks/extend.ts @@ -1,6 +1,5 @@ -import { ExtendIcon } from '@/components/icons' import { ExtendBlockDisplay, ExtendV2BlockDisplay } from '@/blocks/blocks/extend.display' -import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' +import { AuthMode, type BlockConfig, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { ExtendParserOutput } from '@/tools/extend/types' @@ -189,100 +188,3 @@ export const ExtendV2Block: BlockConfig = { }, inputs: extendV2Inputs, } - -export const ExtendBlockMeta = { - tags: ['document-processing', 'ocr'], - url: 'https://www.extend.ai', - templates: [ - { - icon: ExtendIcon, - title: 'Extend structured-data extractor', - prompt: - 'Build a workflow that runs uploaded forms through Extend to pull labelled fields, writes the structured rows to a table, and notifies Slack on missing required fields.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: ExtendIcon, - title: 'Extend insurance claim ingester', - prompt: - 'Create a workflow that uses Extend to ingest claim forms, extracts policy number, claim amount, and incident details to structured rows, and routes high-value claims to a Slack adjuster channel.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: ExtendIcon, - title: 'Extend purchase-order extractor', - prompt: - 'Create a workflow that processes inbound PO PDFs with Extend, writes vendor, SKU, quantity, and total to an orders table, and pings Slack when a PO exceeds the approval threshold.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: ExtendIcon, - title: 'Extend + ElevenLabs spoken-summary', - prompt: - 'Build a workflow that uses Extend to pull structured data from a document, then narrates the summary with ElevenLabs, producing an audio briefing for stakeholders.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['enterprise', 'communication'], - alsoIntegrations: ['elevenlabs'], - }, - { - icon: ExtendIcon, - title: 'Extend KYC pipeline', - prompt: - 'Build a workflow that runs Extend on uploaded KYC documents, validates extracted fields against a compliance rule set, and writes outcomes to a verification table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - }, - { - icon: ExtendIcon, - title: 'Extend invoice processor', - prompt: - 'Create a workflow that parses uploaded vendor invoices with Extend, extracts line items, totals, and due dates, validates against the matching purchase order, and writes approved invoices to an accounts-payable table for payment.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation', 'document-processing'], - }, - { - icon: ExtendIcon, - title: 'Extend contract data extractor', - prompt: - 'Build a workflow that runs Extend on uploaded contracts to pull parties, term dates, renewal clauses, and obligations, summarizes the key risks with an agent, and logs the structured fields to a contracts table for the legal team.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'document-processing', 'automation'], - }, - ], - skills: [ - { - name: 'extract-invoice-fields', - description: - 'Parse an uploaded invoice with Extend and return structured vendor, line item, and total fields.', - content: - '# Extract Invoice Fields\n\nUse Extend to turn an invoice PDF or image into structured, validated data.\n\n## Steps\n1. Take the uploaded invoice document (file upload or URL).\n2. Run the Extend parser to produce structured chunks and blocks.\n3. Pull the key fields: vendor name, invoice number, invoice date, due date, line items (description, quantity, unit price), subtotal, tax, and total.\n4. Validate that totals add up and that required fields are present; flag any that are missing or inconsistent.\n\n## Output\nReturn a clean JSON object with the extracted fields plus a list of any validation warnings. Note the page count and credits used so cost can be tracked.', - }, - { - name: 'parse-document-to-markdown', - description: - 'Convert a scanned or complex document into clean, LLM-ready markdown using Extend.', - content: - '# Parse Document to Markdown\n\nUse Extend to convert any supported document (PDF, image, or Office file) into clean markdown an agent can reason over.\n\n## Steps\n1. Take the source document and choose a chunking strategy (page, section, or document) based on how the content will be consumed.\n2. Run the Extend parser with markdown output.\n3. Stitch the returned chunks into a single ordered markdown document, preserving headings, tables, and lists.\n\n## Output\nReturn the full markdown text plus the page count. If the document was chunked, also return the per-chunk markdown so downstream steps can process sections independently.', - }, - { - name: 'classify-and-route-document', - description: - 'Parse an uploaded document with Extend, identify its type, and route it to the right downstream handler.', - content: - '# Classify and Route Document\n\nUse Extend to read an incoming document and decide where it should go.\n\n## Steps\n1. Run the Extend parser on the uploaded document to get its text content.\n2. Inspect the parsed content to classify the document type (e.g. invoice, contract, claim form, purchase order, KYC document).\n3. Pull the few identifying fields needed for routing (such as document type, reference number, and amount).\n4. Decide the destination queue, table, or channel based on the classification and any thresholds.\n\n## Output\nReturn the detected document type, the routing decision, and the extracted routing fields. Note any document that could not be confidently classified for manual review.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/fathom.display.ts b/apps/sim/blocks/blocks/fathom.display.ts index 01b11ab44d7..76e5761aaa1 100644 --- a/apps/sim/blocks/blocks/fathom.display.ts +++ b/apps/sim/blocks/blocks/fathom.display.ts @@ -1,6 +1,6 @@ import { FathomIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const FathomBlockDisplay = { type: 'fathom', @@ -15,3 +15,101 @@ export const FathomBlockDisplay = { integrationType: IntegrationType.Analytics, triggerAllowed: true, } satisfies BlockDisplay + +export const FathomBlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://fathom.ai', + templates: [ + { + icon: FathomIcon, + title: 'Fathom meeting recap to Slack', + prompt: + 'Build a workflow that triggers when a Fathom meeting completes, pulls the summary and action items, and posts a recap to the relevant Slack channel.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: FathomIcon, + title: 'Fathom transcript to Notion notes', + prompt: + 'Create a workflow that triggers on a new Fathom meeting, pulls the transcript and summary, and writes a structured meeting note to Notion with attendees and next steps.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'note-taking'], + alsoIntegrations: ['notion'], + }, + { + icon: FathomIcon, + title: 'Fathom weekly meeting digest', + prompt: + 'Build a scheduled weekly workflow that lists Fathom meetings from the past week, summarizes the key decisions and commitments across calls with an agent, and emails the digest to the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: FathomIcon, + title: 'Fathom CRM call logger', + prompt: + 'Build a workflow that triggers when a Fathom meeting ends, pulls the summary and CRM matches, and logs the call notes and next steps to the matched HubSpot contact.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['meeting', 'sales'], + alsoIntegrations: ['hubspot'], + }, + { + icon: FathomIcon, + title: 'Fathom action-item tracker', + prompt: + 'Create a workflow that triggers on a new Fathom meeting, extracts action items from the summary with an agent, and writes each one to a tasks table with owner and due date.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'automation'], + }, + { + icon: FathomIcon, + title: 'Fathom meeting archive', + prompt: + 'Build a workflow that triggers on a completed Fathom meeting, pulls the full transcript and summary, and saves a formatted recap file to the shared meeting archive.', + modules: ['files', 'agent', 'workflows'], + category: 'productivity', + tags: ['meeting', 'note-taking'], + }, + { + icon: FathomIcon, + title: 'Fathom sales-call action items', + prompt: + 'Create a workflow that after a Fathom meeting pulls the summary and transcript, extracts the customer commitments and next steps with an agent, creates follow-up tasks in the CRM, and emails a recap to the attendees.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'meeting', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'summarize-recent-meetings', + description: + 'List recent Fathom meetings and produce a concise digest of decisions, owners, and action items.', + content: + '# Summarize Recent Meetings\n\nUse Fathom to pull recent meetings and turn them into a readable digest.\n\n## Steps\n1. List Fathom meetings, filtering by a date range (createdAfter / createdBefore) and optionally by team or recorder.\n2. Request summaries and action items in the response so each meeting comes back with its recap.\n3. Across the meetings, group the key decisions, commitments, and open action items by topic or owner.\n\n## Output\nReturn a digest with one short section per meeting (title, date, attendees, key points) followed by a consolidated action-item list with owners. Use the pagination cursor to cover the full range if there are many meetings.', + }, + { + name: 'extract-meeting-action-items', + description: + 'Pull a specific Fathom meeting summary and extract a clean list of action items with owners.', + content: + '# Extract Meeting Action Items\n\nUse Fathom to turn a single meeting into a tracked task list.\n\n## Steps\n1. Get the meeting summary for the given recording ID.\n2. Identify every commitment or next step mentioned, with the responsible owner and any stated due date.\n3. If owners are unclear, fall back to the transcript to find who made each commitment.\n\n## Output\nReturn a structured list of action items, each with the task description, owner, and due date (or null). Include a one-line meeting recap at the top for context.', + }, + { + name: 'log-sales-call-to-crm', + description: + 'Pull a Fathom call summary and CRM matches, then format a CRM-ready note with next steps.', + content: + '# Log Sales Call to CRM\n\nUse Fathom to capture a sales call and prepare it for the CRM.\n\n## Steps\n1. Get the summary for the meeting recording ID, including CRM matches so the linked contact or deal is known.\n2. Extract the customer pain points, objections, commitments, and agreed next steps.\n3. Format a concise call note suitable for logging against the matched CRM record.\n\n## Output\nReturn the matched CRM contact or deal identifier, a formatted call note, and a list of follow-up next steps with owners and dates so they can be written into the CRM.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/fathom.ts b/apps/sim/blocks/blocks/fathom.ts index 7d8ee9ee046..cc5438c277d 100644 --- a/apps/sim/blocks/blocks/fathom.ts +++ b/apps/sim/blocks/blocks/fathom.ts @@ -1,6 +1,5 @@ -import { FathomIcon } from '@/components/icons' import { FathomBlockDisplay } from '@/blocks/blocks/fathom.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { FathomResponse } from '@/tools/fathom/types' import { getTrigger } from '@/triggers' import { fathomTriggerOptions } from '@/triggers/fathom/utils' @@ -201,101 +200,3 @@ export const FathomBlock: BlockConfig = { available: ['fathom_new_meeting', 'fathom_webhook'], }, } - -export const FathomBlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://fathom.ai', - templates: [ - { - icon: FathomIcon, - title: 'Fathom meeting recap to Slack', - prompt: - 'Build a workflow that triggers when a Fathom meeting completes, pulls the summary and action items, and posts a recap to the relevant Slack channel.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: FathomIcon, - title: 'Fathom transcript to Notion notes', - prompt: - 'Create a workflow that triggers on a new Fathom meeting, pulls the transcript and summary, and writes a structured meeting note to Notion with attendees and next steps.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'note-taking'], - alsoIntegrations: ['notion'], - }, - { - icon: FathomIcon, - title: 'Fathom weekly meeting digest', - prompt: - 'Build a scheduled weekly workflow that lists Fathom meetings from the past week, summarizes the key decisions and commitments across calls with an agent, and emails the digest to the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: FathomIcon, - title: 'Fathom CRM call logger', - prompt: - 'Build a workflow that triggers when a Fathom meeting ends, pulls the summary and CRM matches, and logs the call notes and next steps to the matched HubSpot contact.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['meeting', 'sales'], - alsoIntegrations: ['hubspot'], - }, - { - icon: FathomIcon, - title: 'Fathom action-item tracker', - prompt: - 'Create a workflow that triggers on a new Fathom meeting, extracts action items from the summary with an agent, and writes each one to a tasks table with owner and due date.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'automation'], - }, - { - icon: FathomIcon, - title: 'Fathom meeting archive', - prompt: - 'Build a workflow that triggers on a completed Fathom meeting, pulls the full transcript and summary, and saves a formatted recap file to the shared meeting archive.', - modules: ['files', 'agent', 'workflows'], - category: 'productivity', - tags: ['meeting', 'note-taking'], - }, - { - icon: FathomIcon, - title: 'Fathom sales-call action items', - prompt: - 'Create a workflow that after a Fathom meeting pulls the summary and transcript, extracts the customer commitments and next steps with an agent, creates follow-up tasks in the CRM, and emails a recap to the attendees.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'meeting', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'summarize-recent-meetings', - description: - 'List recent Fathom meetings and produce a concise digest of decisions, owners, and action items.', - content: - '# Summarize Recent Meetings\n\nUse Fathom to pull recent meetings and turn them into a readable digest.\n\n## Steps\n1. List Fathom meetings, filtering by a date range (createdAfter / createdBefore) and optionally by team or recorder.\n2. Request summaries and action items in the response so each meeting comes back with its recap.\n3. Across the meetings, group the key decisions, commitments, and open action items by topic or owner.\n\n## Output\nReturn a digest with one short section per meeting (title, date, attendees, key points) followed by a consolidated action-item list with owners. Use the pagination cursor to cover the full range if there are many meetings.', - }, - { - name: 'extract-meeting-action-items', - description: - 'Pull a specific Fathom meeting summary and extract a clean list of action items with owners.', - content: - '# Extract Meeting Action Items\n\nUse Fathom to turn a single meeting into a tracked task list.\n\n## Steps\n1. Get the meeting summary for the given recording ID.\n2. Identify every commitment or next step mentioned, with the responsible owner and any stated due date.\n3. If owners are unclear, fall back to the transcript to find who made each commitment.\n\n## Output\nReturn a structured list of action items, each with the task description, owner, and due date (or null). Include a one-line meeting recap at the top for context.', - }, - { - name: 'log-sales-call-to-crm', - description: - 'Pull a Fathom call summary and CRM matches, then format a CRM-ready note with next steps.', - content: - '# Log Sales Call to CRM\n\nUse Fathom to capture a sales call and prepare it for the CRM.\n\n## Steps\n1. Get the summary for the meeting recording ID, including CRM matches so the linked contact or deal is known.\n2. Extract the customer pain points, objections, commitments, and agreed next steps.\n3. Format a concise call note suitable for logging against the matched CRM record.\n\n## Output\nReturn the matched CRM contact or deal identifier, a formatted call note, and a list of follow-up next steps with owners and dates so they can be written into the CRM.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/findymail.display.ts b/apps/sim/blocks/blocks/findymail.display.ts index 23915151231..d5741280da4 100644 --- a/apps/sim/blocks/blocks/findymail.display.ts +++ b/apps/sim/blocks/blocks/findymail.display.ts @@ -1,6 +1,6 @@ import { FindymailIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const FindymailBlockDisplay = { type: 'findymail', @@ -14,3 +14,104 @@ export const FindymailBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/findymail', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const FindymailBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.findymail.com', + templates: [ + { + icon: FindymailIcon, + title: 'Findymail email finder', + prompt: + 'Build a workflow that takes a prospect name and company domain from a table, runs Findymail to find the verified work email, and writes the deliverable contact back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: FindymailIcon, + title: 'Findymail LinkedIn enricher', + prompt: + 'Create a workflow that takes a list of LinkedIn profile URLs, finds the matching verified work email via Findymail, and writes the enriched contacts into a research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: FindymailIcon, + title: 'Findymail email verifier', + prompt: + 'Build a workflow that runs a list of email addresses through Findymail verification, removes undeliverable addresses, and writes a clean list for outbound sends.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: FindymailIcon, + title: 'Findymail company team mapper', + prompt: + 'Create a workflow that takes a target company domain, uses Findymail to find employees by job title and enrich company data, and writes the org map into a tables-based account base.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: FindymailIcon, + title: 'Findymail CRM gap-filler', + prompt: + 'Build a scheduled workflow that finds HubSpot contacts missing verified emails, looks them up with Findymail, verifies each, and updates the contact record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: FindymailIcon, + title: 'Findymail LinkedIn list builder', + prompt: + "Create a workflow that reads a list of LinkedIn profile URLs from a table, finds and verifies each prospect's work email and phone with Findymail, enriches their company, and writes a clean, ready-to-contact prospect table.", + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: FindymailIcon, + title: 'Findymail domain prospecting', + prompt: + 'Build a workflow that takes a target company domain, uses Findymail to find employees and their verified emails by role, validates each address, and pushes the qualified contacts into the outbound sequence.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + ], + skills: [ + { + name: 'find-verified-email', + description: + 'Find a prospect verified work email from their name and company, or from a LinkedIn URL.', + content: + '# Find Verified Email\n\nUse Findymail to discover a deliverable work email for a prospect.\n\n## Steps\n1. If you have a name plus company domain, use Find Email From Name. If you have a LinkedIn profile URL, use Find Email From LinkedIn.\n2. Findymail verifies the email at discovery time, so the returned address is already checked for deliverability.\n3. Capture the contact name, email, and domain from the response.\n\n## Output\nReturn the verified email, the matched contact name, and the source company domain. If no email was found, say so clearly rather than guessing an address.', + }, + { + name: 'verify-email-list', + description: + 'Run a list of email addresses through Findymail verification and split into deliverable and undeliverable.', + content: + '# Verify Email List\n\nUse Findymail to clean an email list before an outbound send.\n\n## Steps\n1. For each email address, run Verify Email.\n2. Read the verified flag and the detected provider for each result.\n3. Partition the list into deliverable addresses and undeliverable ones.\n\n## Output\nReturn two lists: deliverable emails (with provider) and undeliverable emails. Include a short summary count so the caller knows how many were removed.', + }, + { + name: 'map-company-team', + description: + 'Given a company domain, find employees by job title and enrich the company profile into a team map.', + content: + '# Map Company Team\n\nUse Findymail to build an org map for a target account.\n\n## Steps\n1. Use Get Company Info on the domain to pull industry, size, and description.\n2. Use Find Employees with the company website and a list of target job titles to pull matching people.\n3. Optionally find each contact verified email or phone for the highest-priority roles.\n\n## Output\nReturn the company profile plus a list of employees (name, job title, LinkedIn URL, and email where available), grouped by function so the account team can see the buying committee.', + }, + { + name: 'enrich-from-email', + description: + 'Reverse-lookup an email address with Findymail to recover the full LinkedIn profile and current company.', + content: + '# Enrich From Email\n\nUse Findymail to turn a bare email address into a full contact record.\n\n## Steps\n1. Run Reverse Email Lookup on the email, requesting the full profile.\n2. Pull the full name, headline, job title, location, current company, and profile details.\n3. Optionally call Get Company Info on the recovered company domain for firmographics.\n\n## Output\nReturn a structured contact record: name, title, company, location, LinkedIn URL, and the original email. Note any fields the lookup could not resolve.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/findymail.ts b/apps/sim/blocks/blocks/findymail.ts index 38a88bff6f3..c5c755a8cd3 100644 --- a/apps/sim/blocks/blocks/findymail.ts +++ b/apps/sim/blocks/blocks/findymail.ts @@ -1,6 +1,5 @@ -import { FindymailIcon } from '@/components/icons' import { FindymailBlockDisplay } from '@/blocks/blocks/findymail.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { FindymailResponse } from '@/tools/findymail/types' export const FindymailBlock: BlockConfig = { @@ -424,104 +423,3 @@ export const FindymailBlock: BlockConfig = { email: { type: 'string', description: 'Email address' }, }, } - -export const FindymailBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.findymail.com', - templates: [ - { - icon: FindymailIcon, - title: 'Findymail email finder', - prompt: - 'Build a workflow that takes a prospect name and company domain from a table, runs Findymail to find the verified work email, and writes the deliverable contact back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: FindymailIcon, - title: 'Findymail LinkedIn enricher', - prompt: - 'Create a workflow that takes a list of LinkedIn profile URLs, finds the matching verified work email via Findymail, and writes the enriched contacts into a research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: FindymailIcon, - title: 'Findymail email verifier', - prompt: - 'Build a workflow that runs a list of email addresses through Findymail verification, removes undeliverable addresses, and writes a clean list for outbound sends.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: FindymailIcon, - title: 'Findymail company team mapper', - prompt: - 'Create a workflow that takes a target company domain, uses Findymail to find employees by job title and enrich company data, and writes the org map into a tables-based account base.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: FindymailIcon, - title: 'Findymail CRM gap-filler', - prompt: - 'Build a scheduled workflow that finds HubSpot contacts missing verified emails, looks them up with Findymail, verifies each, and updates the contact record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: FindymailIcon, - title: 'Findymail LinkedIn list builder', - prompt: - "Create a workflow that reads a list of LinkedIn profile URLs from a table, finds and verifies each prospect's work email and phone with Findymail, enriches their company, and writes a clean, ready-to-contact prospect table.", - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: FindymailIcon, - title: 'Findymail domain prospecting', - prompt: - 'Build a workflow that takes a target company domain, uses Findymail to find employees and their verified emails by role, validates each address, and pushes the qualified contacts into the outbound sequence.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - ], - skills: [ - { - name: 'find-verified-email', - description: - 'Find a prospect verified work email from their name and company, or from a LinkedIn URL.', - content: - '# Find Verified Email\n\nUse Findymail to discover a deliverable work email for a prospect.\n\n## Steps\n1. If you have a name plus company domain, use Find Email From Name. If you have a LinkedIn profile URL, use Find Email From LinkedIn.\n2. Findymail verifies the email at discovery time, so the returned address is already checked for deliverability.\n3. Capture the contact name, email, and domain from the response.\n\n## Output\nReturn the verified email, the matched contact name, and the source company domain. If no email was found, say so clearly rather than guessing an address.', - }, - { - name: 'verify-email-list', - description: - 'Run a list of email addresses through Findymail verification and split into deliverable and undeliverable.', - content: - '# Verify Email List\n\nUse Findymail to clean an email list before an outbound send.\n\n## Steps\n1. For each email address, run Verify Email.\n2. Read the verified flag and the detected provider for each result.\n3. Partition the list into deliverable addresses and undeliverable ones.\n\n## Output\nReturn two lists: deliverable emails (with provider) and undeliverable emails. Include a short summary count so the caller knows how many were removed.', - }, - { - name: 'map-company-team', - description: - 'Given a company domain, find employees by job title and enrich the company profile into a team map.', - content: - '# Map Company Team\n\nUse Findymail to build an org map for a target account.\n\n## Steps\n1. Use Get Company Info on the domain to pull industry, size, and description.\n2. Use Find Employees with the company website and a list of target job titles to pull matching people.\n3. Optionally find each contact verified email or phone for the highest-priority roles.\n\n## Output\nReturn the company profile plus a list of employees (name, job title, LinkedIn URL, and email where available), grouped by function so the account team can see the buying committee.', - }, - { - name: 'enrich-from-email', - description: - 'Reverse-lookup an email address with Findymail to recover the full LinkedIn profile and current company.', - content: - '# Enrich From Email\n\nUse Findymail to turn a bare email address into a full contact record.\n\n## Steps\n1. Run Reverse Email Lookup on the email, requesting the full profile.\n2. Pull the full name, headline, job title, location, current company, and profile details.\n3. Optionally call Get Company Info on the recovered company domain for firmographics.\n\n## Output\nReturn a structured contact record: name, title, company, location, LinkedIn URL, and the original email. Note any fields the lookup could not resolve.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/firecrawl.display.ts b/apps/sim/blocks/blocks/firecrawl.display.ts index 51f7b947290..6b8bf29454b 100644 --- a/apps/sim/blocks/blocks/firecrawl.display.ts +++ b/apps/sim/blocks/blocks/firecrawl.display.ts @@ -1,6 +1,6 @@ import { FirecrawlIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const FirecrawlBlockDisplay = { type: 'firecrawl', @@ -14,3 +14,107 @@ export const FirecrawlBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/firecrawl', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const FirecrawlBlockMeta = { + tags: ['web-scraping', 'automation'], + url: 'https://www.firecrawl.dev', + templates: [ + { + icon: FirecrawlIcon, + title: 'SEO content brief generator', + prompt: + 'Build a workflow that takes a target keyword, uses Firecrawl to scrape the top 10 ranking pages, analyzes their content structure and subtopics, then generates a detailed content brief with outline, word count target, questions to answer, and internal linking suggestions.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'research'], + }, + { + icon: FirecrawlIcon, + title: 'Competitive intel monitor', + prompt: + 'Build a scheduled workflow that scrapes competitor websites, pricing pages, and changelog pages weekly using Firecrawl, compares against previous snapshots, summarizes any changes, logs them to a tracking table, and sends a Slack alert for major updates.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['founder', 'product', 'monitoring', 'research'], + alsoIntegrations: ['slack'], + }, + { + icon: FirecrawlIcon, + title: 'Firecrawl competitor site monitor', + prompt: + 'Build a scheduled workflow that uses Firecrawl to scrape competitor pricing, product, and changelog pages weekly, diffs against the prior snapshot, and posts changes to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: FirecrawlIcon, + title: 'Firecrawl SEO content brief', + prompt: + 'Create a workflow that takes a target keyword, scrapes the top-10 ranking pages with Firecrawl, analyzes structure and subtopics, and writes a content brief file.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: FirecrawlIcon, + title: 'Firecrawl knowledge-base builder', + prompt: + 'Build a workflow that crawls a documentation site with Firecrawl, chunks and embeds the pages, and upserts them into a knowledge base for an answering agent.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'sync'], + }, + { + icon: FirecrawlIcon, + title: 'Firecrawl + Exa research stack', + prompt: + 'Create an agent that uses Exa to find authoritative URLs on a topic, scrapes each with Firecrawl, and produces a structured research brief with citations.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + alsoIntegrations: ['exa'], + }, + { + icon: FirecrawlIcon, + title: 'Firecrawl product-launch detector', + prompt: + 'Build a scheduled workflow that crawls competitor blogs and product pages with Firecrawl daily, classifies posts as product launches, and posts notable launches to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'scrape-page-to-markdown', + description: + 'Scrape a single URL with Firecrawl and return clean main-content markdown for an agent to read.', + content: + '# Scrape Page to Markdown\n\nUse Firecrawl to fetch a web page as clean, LLM-ready markdown.\n\n## Steps\n1. Use the Scrape operation on the target URL.\n2. Enable Only Main Content to strip navigation, ads, and footers; set a Wait For delay if the page renders content with JavaScript.\n3. Return the markdown output and capture page metadata (title, description).\n\n## Output\nReturn the page markdown plus key metadata. If the page failed to load or returned empty content, report that instead of fabricating text.', + }, + { + name: 'extract-structured-data', + description: + 'Pull structured fields from one or more URLs using Firecrawl Extract with a prompt or schema.', + content: + '# Extract Structured Data\n\nUse Firecrawl to extract specific fields from web pages.\n\n## Steps\n1. Use the Extract operation with the list of target URLs.\n2. Provide a clear extraction prompt describing exactly what to pull (for example product name, price, and description).\n3. Run the extraction and read the structured data from the response.\n\n## Output\nReturn the extracted records as structured JSON. List the source URLs and flag any URL that yielded no data.', + }, + { + name: 'crawl-site', + description: + 'Crawl an entire site or section with Firecrawl and return the page content for indexing or analysis.', + content: + '# Crawl Site\n\nUse Firecrawl to traverse a site and collect its pages.\n\n## Steps\n1. Use the Crawl operation on the root URL, setting a sensible page Limit to control cost.\n2. Enable Only Main Content so each page comes back as clean markdown.\n3. Collect the crawled pages and their URLs from the response.\n\n## Output\nReturn the list of crawled pages with their URL and markdown content, plus the total page count. This output is ready to chunk and embed into a knowledge base.', + }, + { + name: 'research-with-search', + description: + 'Run a web search with Firecrawl, then scrape the top results into a cited research brief.', + content: + '# Research With Search\n\nUse Firecrawl to gather and synthesize web sources on a topic.\n\n## Steps\n1. Use the Search operation with the research query and a result Limit.\n2. For the most relevant results, use Scrape to pull the full page markdown.\n3. Synthesize the findings into a brief, attributing each claim to its source URL.\n\n## Output\nReturn a structured research brief with key findings and a Sources list of the URLs used. Keep claims grounded in the scraped content.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/firecrawl.ts b/apps/sim/blocks/blocks/firecrawl.ts index fc928c6c34b..8b9eb499709 100644 --- a/apps/sim/blocks/blocks/firecrawl.ts +++ b/apps/sim/blocks/blocks/firecrawl.ts @@ -1,6 +1,5 @@ -import { FirecrawlIcon } from '@/components/icons' import { FirecrawlBlockDisplay } from '@/blocks/blocks/firecrawl.display' -import type { BlockConfig, BlockMeta, SubBlockType } from '@/blocks/types' +import type { BlockConfig, SubBlockType } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { FirecrawlResponse } from '@/tools/firecrawl/types' @@ -649,107 +648,3 @@ Example 2 - Product Data: screenshot: { type: 'string', description: 'Screenshot URL or base64 (when requested)' }, }, } - -export const FirecrawlBlockMeta = { - tags: ['web-scraping', 'automation'], - url: 'https://www.firecrawl.dev', - templates: [ - { - icon: FirecrawlIcon, - title: 'SEO content brief generator', - prompt: - 'Build a workflow that takes a target keyword, uses Firecrawl to scrape the top 10 ranking pages, analyzes their content structure and subtopics, then generates a detailed content brief with outline, word count target, questions to answer, and internal linking suggestions.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'research'], - }, - { - icon: FirecrawlIcon, - title: 'Competitive intel monitor', - prompt: - 'Build a scheduled workflow that scrapes competitor websites, pricing pages, and changelog pages weekly using Firecrawl, compares against previous snapshots, summarizes any changes, logs them to a tracking table, and sends a Slack alert for major updates.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['founder', 'product', 'monitoring', 'research'], - alsoIntegrations: ['slack'], - }, - { - icon: FirecrawlIcon, - title: 'Firecrawl competitor site monitor', - prompt: - 'Build a scheduled workflow that uses Firecrawl to scrape competitor pricing, product, and changelog pages weekly, diffs against the prior snapshot, and posts changes to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: FirecrawlIcon, - title: 'Firecrawl SEO content brief', - prompt: - 'Create a workflow that takes a target keyword, scrapes the top-10 ranking pages with Firecrawl, analyzes structure and subtopics, and writes a content brief file.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: FirecrawlIcon, - title: 'Firecrawl knowledge-base builder', - prompt: - 'Build a workflow that crawls a documentation site with Firecrawl, chunks and embeds the pages, and upserts them into a knowledge base for an answering agent.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'sync'], - }, - { - icon: FirecrawlIcon, - title: 'Firecrawl + Exa research stack', - prompt: - 'Create an agent that uses Exa to find authoritative URLs on a topic, scrapes each with Firecrawl, and produces a structured research brief with citations.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - alsoIntegrations: ['exa'], - }, - { - icon: FirecrawlIcon, - title: 'Firecrawl product-launch detector', - prompt: - 'Build a scheduled workflow that crawls competitor blogs and product pages with Firecrawl daily, classifies posts as product launches, and posts notable launches to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'scrape-page-to-markdown', - description: - 'Scrape a single URL with Firecrawl and return clean main-content markdown for an agent to read.', - content: - '# Scrape Page to Markdown\n\nUse Firecrawl to fetch a web page as clean, LLM-ready markdown.\n\n## Steps\n1. Use the Scrape operation on the target URL.\n2. Enable Only Main Content to strip navigation, ads, and footers; set a Wait For delay if the page renders content with JavaScript.\n3. Return the markdown output and capture page metadata (title, description).\n\n## Output\nReturn the page markdown plus key metadata. If the page failed to load or returned empty content, report that instead of fabricating text.', - }, - { - name: 'extract-structured-data', - description: - 'Pull structured fields from one or more URLs using Firecrawl Extract with a prompt or schema.', - content: - '# Extract Structured Data\n\nUse Firecrawl to extract specific fields from web pages.\n\n## Steps\n1. Use the Extract operation with the list of target URLs.\n2. Provide a clear extraction prompt describing exactly what to pull (for example product name, price, and description).\n3. Run the extraction and read the structured data from the response.\n\n## Output\nReturn the extracted records as structured JSON. List the source URLs and flag any URL that yielded no data.', - }, - { - name: 'crawl-site', - description: - 'Crawl an entire site or section with Firecrawl and return the page content for indexing or analysis.', - content: - '# Crawl Site\n\nUse Firecrawl to traverse a site and collect its pages.\n\n## Steps\n1. Use the Crawl operation on the root URL, setting a sensible page Limit to control cost.\n2. Enable Only Main Content so each page comes back as clean markdown.\n3. Collect the crawled pages and their URLs from the response.\n\n## Output\nReturn the list of crawled pages with their URL and markdown content, plus the total page count. This output is ready to chunk and embed into a knowledge base.', - }, - { - name: 'research-with-search', - description: - 'Run a web search with Firecrawl, then scrape the top results into a cited research brief.', - content: - '# Research With Search\n\nUse Firecrawl to gather and synthesize web sources on a topic.\n\n## Steps\n1. Use the Search operation with the research query and a result Limit.\n2. For the most relevant results, use Scrape to pull the full page markdown.\n3. Synthesize the findings into a brief, attributing each claim to its source URL.\n\n## Output\nReturn a structured research brief with key findings and a Sources list of the URLs used. Keep claims grounded in the scraped content.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/fireflies.display.ts b/apps/sim/blocks/blocks/fireflies.display.ts index d3391d3751f..d059ad6f496 100644 --- a/apps/sim/blocks/blocks/fireflies.display.ts +++ b/apps/sim/blocks/blocks/fireflies.display.ts @@ -1,6 +1,6 @@ import { FirefliesIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const FirefliesBlockDisplay = { type: 'fireflies', @@ -25,3 +25,107 @@ export const FirefliesV2BlockDisplay = { integrationType: IntegrationType.Productivity, hideFromToolbar: false, } satisfies BlockDisplay + +export const FirefliesBlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://fireflies.ai', + templates: [ + { + icon: FirefliesIcon, + title: 'Fireflies meeting recap to Slack', + prompt: + 'Build a workflow that runs when a Fireflies recording finishes, pulls the transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies CRM updater', + prompt: + 'Create a workflow that runs after a Fireflies sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies action-item ticket creator', + prompt: + 'Build a workflow that extracts action items from a Fireflies meeting transcript, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['linear', 'asana'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies customer-quote miner', + prompt: + 'Create a workflow that processes Fireflies transcripts for customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies talk-ratio coach', + prompt: + 'Build a scheduled weekly workflow that pulls Fireflies sales-call analytics per rep — talk ratio, longest monologue, question rate — and posts a coaching digest to managers.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies + Notion meeting notes', + prompt: + 'Create a workflow that watches Fireflies recordings, generates a polished meeting-notes page in Notion under the right team space, and links the recording.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: FirefliesIcon, + title: 'Fireflies competitor-mention tracker', + prompt: + 'Build a workflow that scans Fireflies sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts notable patterns to Slack weekly.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'summarize-meeting-transcript', + description: + 'Fetch a Fireflies transcript and produce a structured recap with decisions, action items, and owners.', + content: + '# Summarize Meeting Transcript\n\nUse Fireflies to turn a recorded meeting into a clean recap.\n\n## Steps\n1. Get the transcript for the given transcript ID (or pick the latest from List Transcripts).\n2. Read the sentences and any provided summary to identify the main topics discussed.\n3. Extract key decisions, action items with owners, and notable questions or risks.\n\n## Output\nReturn a structured recap: a short overview, a bulleted list of decisions, and an action-item table (task, owner, due date). Keep it grounded in the transcript content.', + }, + { + name: 'extract-action-items', + description: + 'Pull a Fireflies transcript and extract a clean list of action items with owners and due dates.', + content: + '# Extract Action Items\n\nUse Fireflies to capture follow-ups from a meeting.\n\n## Steps\n1. Get the transcript for the meeting by its transcript ID.\n2. Scan the sentences for commitments, assignments, and next steps.\n3. Attribute each item to the speaker who owns it and capture any stated deadline.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date (or null). Add a one-line meeting summary at the top for context.', + }, + { + name: 'create-meeting-soundbite', + description: + 'Create a Fireflies soundbite (bite) clipping a key moment from a transcript for sharing.', + content: + '# Create Meeting Soundbite\n\nUse Fireflies to clip and share a highlight from a recorded meeting.\n\n## Steps\n1. Get the transcript and find the start and end timestamps of the moment to clip.\n2. Use Create Bite with the transcript ID and the chosen time range.\n3. Confirm the bite was created and capture its identifier or link.\n\n## Output\nReturn the soundbite identifier or shareable link plus a short caption describing the clipped moment.', + }, + ], +} as const satisfies BlockMeta + +export const FirefliesV2BlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://fireflies.ai', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/fireflies.ts b/apps/sim/blocks/blocks/fireflies.ts index feaed4aa934..e757d705383 100644 --- a/apps/sim/blocks/blocks/fireflies.ts +++ b/apps/sim/blocks/blocks/fireflies.ts @@ -1,7 +1,6 @@ -import { FirefliesIcon } from '@/components/icons' import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils' import { FirefliesBlockDisplay, FirefliesV2BlockDisplay } from '@/blocks/blocks/fireflies.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { FirefliesResponse } from '@/tools/fireflies/types' @@ -676,107 +675,3 @@ export const FirefliesV2Block: BlockConfig = { }, inputs: firefliesV2Inputs, } - -export const FirefliesBlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://fireflies.ai', - templates: [ - { - icon: FirefliesIcon, - title: 'Fireflies meeting recap to Slack', - prompt: - 'Build a workflow that runs when a Fireflies recording finishes, pulls the transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies CRM updater', - prompt: - 'Create a workflow that runs after a Fireflies sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies action-item ticket creator', - prompt: - 'Build a workflow that extracts action items from a Fireflies meeting transcript, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['linear', 'asana'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies customer-quote miner', - prompt: - 'Create a workflow that processes Fireflies transcripts for customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies talk-ratio coach', - prompt: - 'Build a scheduled weekly workflow that pulls Fireflies sales-call analytics per rep — talk ratio, longest monologue, question rate — and posts a coaching digest to managers.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies + Notion meeting notes', - prompt: - 'Create a workflow that watches Fireflies recordings, generates a polished meeting-notes page in Notion under the right team space, and links the recording.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: FirefliesIcon, - title: 'Fireflies competitor-mention tracker', - prompt: - 'Build a workflow that scans Fireflies sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts notable patterns to Slack weekly.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'summarize-meeting-transcript', - description: - 'Fetch a Fireflies transcript and produce a structured recap with decisions, action items, and owners.', - content: - '# Summarize Meeting Transcript\n\nUse Fireflies to turn a recorded meeting into a clean recap.\n\n## Steps\n1. Get the transcript for the given transcript ID (or pick the latest from List Transcripts).\n2. Read the sentences and any provided summary to identify the main topics discussed.\n3. Extract key decisions, action items with owners, and notable questions or risks.\n\n## Output\nReturn a structured recap: a short overview, a bulleted list of decisions, and an action-item table (task, owner, due date). Keep it grounded in the transcript content.', - }, - { - name: 'extract-action-items', - description: - 'Pull a Fireflies transcript and extract a clean list of action items with owners and due dates.', - content: - '# Extract Action Items\n\nUse Fireflies to capture follow-ups from a meeting.\n\n## Steps\n1. Get the transcript for the meeting by its transcript ID.\n2. Scan the sentences for commitments, assignments, and next steps.\n3. Attribute each item to the speaker who owns it and capture any stated deadline.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date (or null). Add a one-line meeting summary at the top for context.', - }, - { - name: 'create-meeting-soundbite', - description: - 'Create a Fireflies soundbite (bite) clipping a key moment from a transcript for sharing.', - content: - '# Create Meeting Soundbite\n\nUse Fireflies to clip and share a highlight from a recorded meeting.\n\n## Steps\n1. Get the transcript and find the start and end timestamps of the moment to clip.\n2. Use Create Bite with the transcript ID and the chosen time range.\n3. Confirm the bite was created and capture its identifier or link.\n\n## Output\nReturn the soundbite identifier or shareable link plus a short caption describing the clipped moment.', - }, - ], -} as const satisfies BlockMeta - -export const FirefliesV2BlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://fireflies.ai', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gamma.display.ts b/apps/sim/blocks/blocks/gamma.display.ts index daa1ff45b4f..74f730e4424 100644 --- a/apps/sim/blocks/blocks/gamma.display.ts +++ b/apps/sim/blocks/blocks/gamma.display.ts @@ -1,6 +1,6 @@ import { GammaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GammaBlockDisplay = { type: 'gamma', @@ -14,3 +14,107 @@ export const GammaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/gamma', integrationType: IntegrationType.Marketing, } satisfies BlockDisplay + +export const GammaBlockMeta = { + tags: ['document-processing', 'content-management'], + url: 'https://gamma.app', + templates: [ + { + icon: GammaIcon, + title: 'Gamma deck from doc', + prompt: + 'Build a workflow that takes a Google Docs source, generates a Gamma deck from the structure and bullet points, and emails the deck link to the author for polish.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'marketing'], + alsoIntegrations: ['google_docs', 'gmail'], + }, + { + icon: GammaIcon, + title: 'Gamma customer-story builder', + prompt: + 'Create a workflow that takes a customer-story brief, generates a Gamma deck with the challenge, solution, results, and pull quote, and shares the link with the marketing team in Slack.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['slack'], + }, + { + icon: GammaIcon, + title: 'Gamma weekly all-hands deck', + prompt: + 'Build a scheduled weekly workflow that pulls KPIs from tables, generates a Gamma all-hands deck with the latest numbers, and posts the link to the leadership Slack channel.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GammaIcon, + title: 'Gamma onboarding training', + prompt: + 'Create a workflow that generates a Gamma onboarding training deck from a knowledge base topic, including interactive quizzes at the end, and shares it with the new hire.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'content'], + }, + { + icon: GammaIcon, + title: 'Gamma sales pitch personalizer', + prompt: + 'Build a workflow triggered by a Salesforce opportunity that generates a Gamma sales pitch deck personalized to the account, embeds the deck link in the opportunity, and notifies the rep.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'content'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GammaIcon, + title: 'Gamma weekly content carousel', + prompt: + 'Create a scheduled workflow that turns the week’s top blog posts into a multi-slide Gamma carousel, then queues the export for X and LinkedIn posting.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['x', 'linkedin'], + }, + { + icon: GammaIcon, + title: 'Gamma RFP responder', + prompt: + 'Build a workflow that takes an inbound RFP, generates a Gamma response deck using a knowledge base of past proposals, and attaches the deck link to the linked HubSpot deal.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'content'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'generate-presentation', + description: 'Generate a polished presentation deck from a topic or outline using Gamma.', + content: + '# Generate Presentation\n\nUse Gamma to turn a topic or outline into a finished presentation.\n\n## Steps\n1. Gather the source content: a topic, a brief, or a structured outline of the points to cover.\n2. Call Gamma to generate a presentation, choosing the number of cards and a theme that fits the audience.\n3. Request an export format (such as PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the link to the generated Gamma and, if requested, the export file URL. Summarize the deck structure (titles per card) so the requester can review before sharing.', + }, + { + name: 'generate-document', + description: 'Generate a structured document or webpage from input text using Gamma.', + content: + '# Generate Document\n\nUse Gamma to produce a formatted document or webpage from raw input.\n\n## Steps\n1. Provide the input text and choose the output format (document or webpage).\n2. Call Gamma to generate the content, setting a theme and the desired length or number of cards.\n3. Capture the resulting Gamma URL and any export URL.\n\n## Output\nReturn the generated Gamma link plus a short outline of the sections it produced. Include the export file URL if one was requested.', + }, + { + name: 'personalize-deck-from-template', + description: + 'Adapt an existing Gamma template into a prospect or client-specific deck with Generate from Template.', + content: + '# Personalize Deck From Template\n\nUse Gamma to scale on-brand, personalized decks from a proven template.\n\n## Steps\n1. Identify the template gamma ID to adapt (a master pitch or proposal deck) and collect the recipient details and the angle to tailor for.\n2. Use Generate from Template with that template gamma ID and a prompt that retargets the audience, swaps in the recipient name and use case, and adjusts emphasis (for example highlight compliance for a healthcare buyer). The template structure is preserved by default.\n3. Request an export (PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the generated Gamma link and any export URL. Note the recipient it was generated for so it can be attached to the right CRM record or email.', + }, + { + name: 'check-generation-status', + description: + 'Poll a Gamma generation job by its generation ID and return the final deck link once ready.', + content: + '# Check Generation Status\n\nGamma generation is asynchronous, so use this to wait for a deck to finish.\n\n## Steps\n1. Take the generation ID returned when the deck was requested.\n2. Use Check Status to read the current status of the job.\n3. Repeat until the status is completed (or failed), respecting a sensible polling interval.\n\n## Output\nReturn the final status and, on success, the Gamma URL and any export URL. On failure, return the error details so the caller can retry or adjust the request.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gamma.ts b/apps/sim/blocks/blocks/gamma.ts index ff49a54c2d0..c43ed71d0ec 100644 --- a/apps/sim/blocks/blocks/gamma.ts +++ b/apps/sim/blocks/blocks/gamma.ts @@ -1,6 +1,5 @@ -import { GammaIcon } from '@/components/icons' import { GammaBlockDisplay } from '@/blocks/blocks/gamma.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { GammaResponse } from '@/tools/gamma/types' export const GammaBlock: BlockConfig = { @@ -331,107 +330,3 @@ Example: "folder_abc123, folder_def456"`, nextCursor: { type: 'string', description: 'Pagination cursor for next page' }, }, } - -export const GammaBlockMeta = { - tags: ['document-processing', 'content-management'], - url: 'https://gamma.app', - templates: [ - { - icon: GammaIcon, - title: 'Gamma deck from doc', - prompt: - 'Build a workflow that takes a Google Docs source, generates a Gamma deck from the structure and bullet points, and emails the deck link to the author for polish.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'marketing'], - alsoIntegrations: ['google_docs', 'gmail'], - }, - { - icon: GammaIcon, - title: 'Gamma customer-story builder', - prompt: - 'Create a workflow that takes a customer-story brief, generates a Gamma deck with the challenge, solution, results, and pull quote, and shares the link with the marketing team in Slack.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['slack'], - }, - { - icon: GammaIcon, - title: 'Gamma weekly all-hands deck', - prompt: - 'Build a scheduled weekly workflow that pulls KPIs from tables, generates a Gamma all-hands deck with the latest numbers, and posts the link to the leadership Slack channel.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GammaIcon, - title: 'Gamma onboarding training', - prompt: - 'Create a workflow that generates a Gamma onboarding training deck from a knowledge base topic, including interactive quizzes at the end, and shares it with the new hire.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'content'], - }, - { - icon: GammaIcon, - title: 'Gamma sales pitch personalizer', - prompt: - 'Build a workflow triggered by a Salesforce opportunity that generates a Gamma sales pitch deck personalized to the account, embeds the deck link in the opportunity, and notifies the rep.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'content'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GammaIcon, - title: 'Gamma weekly content carousel', - prompt: - 'Create a scheduled workflow that turns the week’s top blog posts into a multi-slide Gamma carousel, then queues the export for X and LinkedIn posting.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['x', 'linkedin'], - }, - { - icon: GammaIcon, - title: 'Gamma RFP responder', - prompt: - 'Build a workflow that takes an inbound RFP, generates a Gamma response deck using a knowledge base of past proposals, and attaches the deck link to the linked HubSpot deal.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'content'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'generate-presentation', - description: 'Generate a polished presentation deck from a topic or outline using Gamma.', - content: - '# Generate Presentation\n\nUse Gamma to turn a topic or outline into a finished presentation.\n\n## Steps\n1. Gather the source content: a topic, a brief, or a structured outline of the points to cover.\n2. Call Gamma to generate a presentation, choosing the number of cards and a theme that fits the audience.\n3. Request an export format (such as PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the link to the generated Gamma and, if requested, the export file URL. Summarize the deck structure (titles per card) so the requester can review before sharing.', - }, - { - name: 'generate-document', - description: 'Generate a structured document or webpage from input text using Gamma.', - content: - '# Generate Document\n\nUse Gamma to produce a formatted document or webpage from raw input.\n\n## Steps\n1. Provide the input text and choose the output format (document or webpage).\n2. Call Gamma to generate the content, setting a theme and the desired length or number of cards.\n3. Capture the resulting Gamma URL and any export URL.\n\n## Output\nReturn the generated Gamma link plus a short outline of the sections it produced. Include the export file URL if one was requested.', - }, - { - name: 'personalize-deck-from-template', - description: - 'Adapt an existing Gamma template into a prospect or client-specific deck with Generate from Template.', - content: - '# Personalize Deck From Template\n\nUse Gamma to scale on-brand, personalized decks from a proven template.\n\n## Steps\n1. Identify the template gamma ID to adapt (a master pitch or proposal deck) and collect the recipient details and the angle to tailor for.\n2. Use Generate from Template with that template gamma ID and a prompt that retargets the audience, swaps in the recipient name and use case, and adjusts emphasis (for example highlight compliance for a healthcare buyer). The template structure is preserved by default.\n3. Request an export (PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the generated Gamma link and any export URL. Note the recipient it was generated for so it can be attached to the right CRM record or email.', - }, - { - name: 'check-generation-status', - description: - 'Poll a Gamma generation job by its generation ID and return the final deck link once ready.', - content: - '# Check Generation Status\n\nGamma generation is asynchronous, so use this to wait for a deck to finish.\n\n## Steps\n1. Take the generation ID returned when the deck was requested.\n2. Use Check Status to read the current status of the job.\n3. Repeat until the status is completed (or failed), respecting a sensible polling interval.\n\n## Output\nReturn the final status and, on success, the Gamma URL and any export URL. On failure, return the error details so the caller can retry or adjust the request.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/github.display.ts b/apps/sim/blocks/blocks/github.display.ts index 1da5145d082..cd222a31dc5 100644 --- a/apps/sim/blocks/blocks/github.display.ts +++ b/apps/sim/blocks/blocks/github.display.ts @@ -1,6 +1,7 @@ -import { GithubIcon } from '@/components/icons' +import { Calendar } from '@/components/emcn/icons' +import { GithubIcon, NotionIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GitHubBlockDisplay = { type: 'github', @@ -24,3 +25,135 @@ export const GitHubV2BlockDisplay = { integrationType: IntegrationType.DevOps, hideFromToolbar: false, } satisfies BlockDisplay + +export const GitHubBlockMeta = { + tags: ['version-control', 'ci-cd'], + url: 'https://github.com', + templates: [ + { + icon: GithubIcon, + title: 'PR review assistant', + prompt: + 'Create a knowledge base connected to my GitHub repo so it stays synced with my style guide and coding standards. Then build a workflow that reviews new pull requests against it, checks for common issues and security vulnerabilities, and posts a review comment with specific suggestions.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: GithubIcon, + title: 'Changelog generator', + prompt: + 'Build a scheduled workflow that runs every Friday, pulls all merged PRs from GitHub for the week, categorizes changes as features, fixes, or improvements, and generates a user-facing changelog document with clear descriptions.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'product', 'reporting', 'content'], + }, + { + icon: NotionIcon, + title: 'Documentation auto-updater', + prompt: + 'Create a knowledge base connected to my GitHub repository so code and docs stay synced. Then build a scheduled weekly workflow that detects API changes, compares them against the knowledge base to find outdated documentation, and either updates Notion pages directly or creates Linear tickets for the needed changes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync', 'automation'], + alsoIntegrations: ['notion', 'linear'], + }, + { + icon: GithubIcon, + title: 'GitHub repository search', + prompt: + 'Create a knowledge base connected to my GitHub repository so all source files, READMEs, and pull request descriptions are automatically synced and searchable. Then build an agent I can ask things like "where do we handle Stripe webhooks?" or "what changed in the auth module last month?" and get answers with file and PR citations.', + modules: ['knowledge-base', 'agent'], + category: 'engineering', + tags: ['engineering', 'research', 'devops'], + }, + { + icon: GithubIcon, + title: 'Release notes drafter', + prompt: + 'Build a workflow triggered when a GitHub release tag is created. Pull every merged pull request and commit since the previous tag, group them by feature, fix, and chore, draft customer-facing release notes, and post the draft as a comment on the release for final approval.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'content', 'devops'], + }, + { + icon: Calendar, + title: 'Weekly team digest', + prompt: + "Build a scheduled workflow that runs every Friday, pulls the week's GitHub commits, closed Linear issues, and key Slack conversations, then emails a formatted weekly summary to the team.", + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['engineering', 'team', 'reporting'], + alsoIntegrations: ['linear', 'slack'], + }, + + { + icon: GithubIcon, + title: 'Link GitHub pull requests to Jira tickets', + prompt: + 'Build a workflow that monitors GitHub pull requests and automatically transitions linked Jira issues when PRs are opened or merged, keeping your project board accurate without any manual updates.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['jira'], + }, + { + icon: GithubIcon, + title: 'Sync GitHub events with Linear issues', + prompt: + 'Build a workflow that creates Linear issues from GitHub pull requests and commits, and automatically updates their status when a PR is merged.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['linear'], + }, + { + icon: GithubIcon, + title: 'Get GitHub activity alerts in Slack', + prompt: + 'Create an agent that watches GitHub for new pull requests, commits, issues, or deployments and posts formatted Slack notifications so your engineering team never misses a critical event.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'review-pull-request', + description: + 'Fetch a GitHub PR, its changed files, and diff, then post a structured review comment.', + content: + '# Review Pull Request\n\nUse GitHub to read a pull request and leave a useful review.\n\n## Steps\n1. Get PR details for the given owner, repo, and PR number to read the title, description, and status.\n2. Get the PR files to see the changed paths and diffs.\n3. Assess the changes for correctness, missing tests, and risky edits.\n4. Post a PR comment summarizing the review with specific, actionable feedback.\n\n## Output\nConfirm the comment was posted and return a short summary of the findings: what looks good, what needs changes, and any blocking concerns.', + }, + { + name: 'triage-new-issue', + description: + 'Read a GitHub issue, classify it, apply labels, and assign it to the right owner.', + content: + '# Triage New Issue\n\nUse GitHub to triage an incoming issue.\n\n## Steps\n1. Get the issue by owner, repo, and issue number to read its title and body.\n2. Classify it (bug, feature, question, docs) and judge its severity.\n3. Add the appropriate labels with Add issue labels.\n4. Assign the issue to the relevant owner with Add issue assignees.\n\n## Output\nReturn the applied labels, the assignee, and a one-line triage summary. If the issue lacks reproduction details, note what information is missing.', + }, + { + name: 'summarize-repo-activity', + description: + 'Pull recent GitHub PRs, commits, and issues for a repo and produce a concise activity digest.', + content: + '# Summarize Repo Activity\n\nUse GitHub to build a status digest for a repository.\n\n## Steps\n1. List open pull requests and recent issues for the owner and repo.\n2. Get the latest commit to anchor the digest in time.\n3. Group activity into in-progress work, newly opened items, and anything stalled or awaiting review.\n\n## Output\nReturn a digest with three sections: open PRs (title, author, status), notable issues, and the latest commit. Keep it short enough to drop into a standup or Slack channel.', + }, + { + name: 'open-pull-request-with-changes', + description: + 'Create a branch, commit a file change, and open a GitHub pull request for review.', + content: + '# Open Pull Request With Changes\n\nUse GitHub to land a change as a reviewable PR.\n\n## Steps\n1. Create a new branch off the default branch with Create branch.\n2. Create or update the target file on that branch with Create file or Update file, including a clear commit message.\n3. Open a pull request from the new branch with Create pull request, writing a descriptive title and body.\n4. Optionally request reviewers with Request PR reviewers.\n\n## Output\nReturn the new PR number and URL, the branch name, and the files changed so the requester can track it to merge.', + }, + ], +} as const satisfies BlockMeta + +export const GitHubV2BlockMeta = { + tags: ['version-control', 'ci-cd'], + url: 'https://github.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/github.ts b/apps/sim/blocks/blocks/github.ts index 0574948d868..ce027c996ff 100644 --- a/apps/sim/blocks/blocks/github.ts +++ b/apps/sim/blocks/blocks/github.ts @@ -1,7 +1,5 @@ -import { Calendar } from '@/components/emcn/icons' -import { GithubIcon, NotionIcon } from '@/components/icons' import { GitHubBlockDisplay, GitHubV2BlockDisplay } from '@/blocks/blocks/github.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { GitHubResponse } from '@/tools/github/types' @@ -2049,135 +2047,3 @@ export const GitHubV2Block: BlockConfig = { commit_author: { type: 'string', description: 'Author of the latest commit' }, }, } - -export const GitHubBlockMeta = { - tags: ['version-control', 'ci-cd'], - url: 'https://github.com', - templates: [ - { - icon: GithubIcon, - title: 'PR review assistant', - prompt: - 'Create a knowledge base connected to my GitHub repo so it stays synced with my style guide and coding standards. Then build a workflow that reviews new pull requests against it, checks for common issues and security vulnerabilities, and posts a review comment with specific suggestions.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: GithubIcon, - title: 'Changelog generator', - prompt: - 'Build a scheduled workflow that runs every Friday, pulls all merged PRs from GitHub for the week, categorizes changes as features, fixes, or improvements, and generates a user-facing changelog document with clear descriptions.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'product', 'reporting', 'content'], - }, - { - icon: NotionIcon, - title: 'Documentation auto-updater', - prompt: - 'Create a knowledge base connected to my GitHub repository so code and docs stay synced. Then build a scheduled weekly workflow that detects API changes, compares them against the knowledge base to find outdated documentation, and either updates Notion pages directly or creates Linear tickets for the needed changes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync', 'automation'], - alsoIntegrations: ['notion', 'linear'], - }, - { - icon: GithubIcon, - title: 'GitHub repository search', - prompt: - 'Create a knowledge base connected to my GitHub repository so all source files, READMEs, and pull request descriptions are automatically synced and searchable. Then build an agent I can ask things like "where do we handle Stripe webhooks?" or "what changed in the auth module last month?" and get answers with file and PR citations.', - modules: ['knowledge-base', 'agent'], - category: 'engineering', - tags: ['engineering', 'research', 'devops'], - }, - { - icon: GithubIcon, - title: 'Release notes drafter', - prompt: - 'Build a workflow triggered when a GitHub release tag is created. Pull every merged pull request and commit since the previous tag, group them by feature, fix, and chore, draft customer-facing release notes, and post the draft as a comment on the release for final approval.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'content', 'devops'], - }, - { - icon: Calendar, - title: 'Weekly team digest', - prompt: - "Build a scheduled workflow that runs every Friday, pulls the week's GitHub commits, closed Linear issues, and key Slack conversations, then emails a formatted weekly summary to the team.", - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['engineering', 'team', 'reporting'], - alsoIntegrations: ['linear', 'slack'], - }, - - { - icon: GithubIcon, - title: 'Link GitHub pull requests to Jira tickets', - prompt: - 'Build a workflow that monitors GitHub pull requests and automatically transitions linked Jira issues when PRs are opened or merged, keeping your project board accurate without any manual updates.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['jira'], - }, - { - icon: GithubIcon, - title: 'Sync GitHub events with Linear issues', - prompt: - 'Build a workflow that creates Linear issues from GitHub pull requests and commits, and automatically updates their status when a PR is merged.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['linear'], - }, - { - icon: GithubIcon, - title: 'Get GitHub activity alerts in Slack', - prompt: - 'Create an agent that watches GitHub for new pull requests, commits, issues, or deployments and posts formatted Slack notifications so your engineering team never misses a critical event.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'review-pull-request', - description: - 'Fetch a GitHub PR, its changed files, and diff, then post a structured review comment.', - content: - '# Review Pull Request\n\nUse GitHub to read a pull request and leave a useful review.\n\n## Steps\n1. Get PR details for the given owner, repo, and PR number to read the title, description, and status.\n2. Get the PR files to see the changed paths and diffs.\n3. Assess the changes for correctness, missing tests, and risky edits.\n4. Post a PR comment summarizing the review with specific, actionable feedback.\n\n## Output\nConfirm the comment was posted and return a short summary of the findings: what looks good, what needs changes, and any blocking concerns.', - }, - { - name: 'triage-new-issue', - description: - 'Read a GitHub issue, classify it, apply labels, and assign it to the right owner.', - content: - '# Triage New Issue\n\nUse GitHub to triage an incoming issue.\n\n## Steps\n1. Get the issue by owner, repo, and issue number to read its title and body.\n2. Classify it (bug, feature, question, docs) and judge its severity.\n3. Add the appropriate labels with Add issue labels.\n4. Assign the issue to the relevant owner with Add issue assignees.\n\n## Output\nReturn the applied labels, the assignee, and a one-line triage summary. If the issue lacks reproduction details, note what information is missing.', - }, - { - name: 'summarize-repo-activity', - description: - 'Pull recent GitHub PRs, commits, and issues for a repo and produce a concise activity digest.', - content: - '# Summarize Repo Activity\n\nUse GitHub to build a status digest for a repository.\n\n## Steps\n1. List open pull requests and recent issues for the owner and repo.\n2. Get the latest commit to anchor the digest in time.\n3. Group activity into in-progress work, newly opened items, and anything stalled or awaiting review.\n\n## Output\nReturn a digest with three sections: open PRs (title, author, status), notable issues, and the latest commit. Keep it short enough to drop into a standup or Slack channel.', - }, - { - name: 'open-pull-request-with-changes', - description: - 'Create a branch, commit a file change, and open a GitHub pull request for review.', - content: - '# Open Pull Request With Changes\n\nUse GitHub to land a change as a reviewable PR.\n\n## Steps\n1. Create a new branch off the default branch with Create branch.\n2. Create or update the target file on that branch with Create file or Update file, including a clear commit message.\n3. Open a pull request from the new branch with Create pull request, writing a descriptive title and body.\n4. Optionally request reviewers with Request PR reviewers.\n\n## Output\nReturn the new PR number and URL, the branch name, and the files changed so the requester can track it to merge.', - }, - ], -} as const satisfies BlockMeta - -export const GitHubV2BlockMeta = { - tags: ['version-control', 'ci-cd'], - url: 'https://github.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gitlab.display.ts b/apps/sim/blocks/blocks/gitlab.display.ts index eff1b5c4411..372d9624a60 100644 --- a/apps/sim/blocks/blocks/gitlab.display.ts +++ b/apps/sim/blocks/blocks/gitlab.display.ts @@ -1,6 +1,6 @@ import { GitLabIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GitLabBlockDisplay = { type: 'gitlab', @@ -15,3 +15,100 @@ export const GitLabBlockDisplay = { integrationType: IntegrationType.DevOps, triggerAllowed: true, } satisfies BlockDisplay + +export const GitLabBlockMeta = { + tags: ['version-control', 'ci-cd'], + url: 'https://about.gitlab.com', + templates: [ + { + icon: GitLabIcon, + title: 'GitLab merge request reviewer', + prompt: + 'Create a knowledge base from my coding standards and architecture docs. Build a scheduled workflow that lists open GitLab merge requests, fetches each diff, runs an agent that checks the code against the knowledge base and flags security issues, performance concerns, and style violations, then posts a structured review as an MR comment.', + modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'automation'], + }, + { + icon: GitLabIcon, + title: 'GitLab pipeline failure responder', + prompt: + 'Build a scheduled workflow that lists recent GitLab pipelines on the main branch, finds newly failed runs, summarizes the root cause from the job logs, identifies the most likely owner from recent commits, opens a GitLab issue with the diagnosis, and posts an alert to Slack with a link to the failing pipeline.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GitLabIcon, + title: 'GitLab issue triager', + prompt: + 'Create a scheduled workflow that runs every hour, pulls new GitLab issues, classifies each by component, severity, and effort, applies labels and assigns the right owner, and posts a daily Slack digest of unassigned and stale issues so nothing slips through.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GitLabIcon, + title: 'GitLab release publisher', + prompt: + 'Build a scheduled workflow that detects new GitLab release tags, gathers merged merge requests since the previous tag, groups changes by component, drafts release notes as a file, and posts the formatted summary back as a comment on the release.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'content'], + }, + { + icon: GitLabIcon, + title: 'GitLab project health digest', + prompt: + 'Create a scheduled weekly workflow that pulls open issues, stale merge requests, recent pipeline failures, and contributor activity for every GitLab project, logs metrics to a tracking table, and sends a Slack health digest to engineering leadership.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GitLabIcon, + title: 'GitLab merge request unblocker', + prompt: + 'Build a scheduled daily workflow that lists open GitLab merge requests, identifies those blocked on review for more than two days, sends targeted Slack DMs to the assigned reviewers with the MR link, and updates a table tracking unblock actions.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'team'], + alsoIntegrations: ['slack'], + }, + { + icon: GitLabIcon, + title: 'GitLab repository knowledge base', + prompt: + 'Create a knowledge base that ingests GitLab project files, merge request descriptions, and issue threads, then build an agent I can ask things like "how does the billing module handle proration?" or "which MR introduced the rate limiter?" and get answers with GitLab citations.', + modules: ['knowledge-base', 'agent'], + category: 'engineering', + tags: ['engineering', 'research', 'devops'], + }, + ], + skills: [ + { + name: 'review-merge-request', + description: + 'Fetch a GitLab merge request and post a structured review comment with actionable feedback.', + content: + '# Review Merge Request\n\nUse GitLab to read a merge request and leave a useful review.\n\n## Steps\n1. Get the merge request by project ID and MR IID to read its title, description, and changes.\n2. Assess the change for correctness, missing tests, and risky edits.\n3. Post a review note on the MR with Add MR Comment, summarizing the feedback.\n\n## Output\nConfirm the comment was posted and return a short summary: what looks good, what needs changes, and any blocking concerns.', + }, + { + name: 'triage-gitlab-issue', + description: + 'Read a GitLab issue, classify it, and post a triage comment or update its fields.', + content: + '# Triage GitLab Issue\n\nUse GitLab to triage an incoming issue.\n\n## Steps\n1. Get the issue by project ID and issue IID to read its title and description.\n2. Classify it (bug, feature, question) and judge severity.\n3. Update the issue with the right labels and assignee using Update Issue, and add a triage note with Add Issue Comment.\n\n## Output\nReturn the classification, applied labels, assignee, and a one-line triage summary. Note any missing reproduction details.', + }, + { + name: 'monitor-pipeline-status', + description: + 'Check GitLab pipeline status for a project and report failures, optionally retrying a failed pipeline.', + content: + '# Monitor Pipeline Status\n\nUse GitLab to keep an eye on CI pipelines.\n\n## Steps\n1. List pipelines for the project and identify the most recent runs.\n2. Get the pipeline details for any that failed to read the status and reason.\n3. If a failure looks transient, use Retry Pipeline to re-run it.\n\n## Output\nReturn a summary of recent pipeline runs (ref, status, when) and call out any failures. If a retry was triggered, include the retried pipeline ID.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gitlab.ts b/apps/sim/blocks/blocks/gitlab.ts index df26c5c2cbd..99e4744896b 100644 --- a/apps/sim/blocks/blocks/gitlab.ts +++ b/apps/sim/blocks/blocks/gitlab.ts @@ -1,6 +1,5 @@ -import { GitLabIcon } from '@/components/icons' import { GitLabBlockDisplay } from '@/blocks/blocks/gitlab.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { GitLabResponse } from '@/tools/gitlab/types' import { getTrigger } from '@/triggers' @@ -1109,100 +1108,3 @@ Return ONLY the commit message - no explanations, no extra text.`, ], }, } - -export const GitLabBlockMeta = { - tags: ['version-control', 'ci-cd'], - url: 'https://about.gitlab.com', - templates: [ - { - icon: GitLabIcon, - title: 'GitLab merge request reviewer', - prompt: - 'Create a knowledge base from my coding standards and architecture docs. Build a scheduled workflow that lists open GitLab merge requests, fetches each diff, runs an agent that checks the code against the knowledge base and flags security issues, performance concerns, and style violations, then posts a structured review as an MR comment.', - modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'automation'], - }, - { - icon: GitLabIcon, - title: 'GitLab pipeline failure responder', - prompt: - 'Build a scheduled workflow that lists recent GitLab pipelines on the main branch, finds newly failed runs, summarizes the root cause from the job logs, identifies the most likely owner from recent commits, opens a GitLab issue with the diagnosis, and posts an alert to Slack with a link to the failing pipeline.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GitLabIcon, - title: 'GitLab issue triager', - prompt: - 'Create a scheduled workflow that runs every hour, pulls new GitLab issues, classifies each by component, severity, and effort, applies labels and assigns the right owner, and posts a daily Slack digest of unassigned and stale issues so nothing slips through.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GitLabIcon, - title: 'GitLab release publisher', - prompt: - 'Build a scheduled workflow that detects new GitLab release tags, gathers merged merge requests since the previous tag, groups changes by component, drafts release notes as a file, and posts the formatted summary back as a comment on the release.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'content'], - }, - { - icon: GitLabIcon, - title: 'GitLab project health digest', - prompt: - 'Create a scheduled weekly workflow that pulls open issues, stale merge requests, recent pipeline failures, and contributor activity for every GitLab project, logs metrics to a tracking table, and sends a Slack health digest to engineering leadership.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GitLabIcon, - title: 'GitLab merge request unblocker', - prompt: - 'Build a scheduled daily workflow that lists open GitLab merge requests, identifies those blocked on review for more than two days, sends targeted Slack DMs to the assigned reviewers with the MR link, and updates a table tracking unblock actions.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'team'], - alsoIntegrations: ['slack'], - }, - { - icon: GitLabIcon, - title: 'GitLab repository knowledge base', - prompt: - 'Create a knowledge base that ingests GitLab project files, merge request descriptions, and issue threads, then build an agent I can ask things like "how does the billing module handle proration?" or "which MR introduced the rate limiter?" and get answers with GitLab citations.', - modules: ['knowledge-base', 'agent'], - category: 'engineering', - tags: ['engineering', 'research', 'devops'], - }, - ], - skills: [ - { - name: 'review-merge-request', - description: - 'Fetch a GitLab merge request and post a structured review comment with actionable feedback.', - content: - '# Review Merge Request\n\nUse GitLab to read a merge request and leave a useful review.\n\n## Steps\n1. Get the merge request by project ID and MR IID to read its title, description, and changes.\n2. Assess the change for correctness, missing tests, and risky edits.\n3. Post a review note on the MR with Add MR Comment, summarizing the feedback.\n\n## Output\nConfirm the comment was posted and return a short summary: what looks good, what needs changes, and any blocking concerns.', - }, - { - name: 'triage-gitlab-issue', - description: - 'Read a GitLab issue, classify it, and post a triage comment or update its fields.', - content: - '# Triage GitLab Issue\n\nUse GitLab to triage an incoming issue.\n\n## Steps\n1. Get the issue by project ID and issue IID to read its title and description.\n2. Classify it (bug, feature, question) and judge severity.\n3. Update the issue with the right labels and assignee using Update Issue, and add a triage note with Add Issue Comment.\n\n## Output\nReturn the classification, applied labels, assignee, and a one-line triage summary. Note any missing reproduction details.', - }, - { - name: 'monitor-pipeline-status', - description: - 'Check GitLab pipeline status for a project and report failures, optionally retrying a failed pipeline.', - content: - '# Monitor Pipeline Status\n\nUse GitLab to keep an eye on CI pipelines.\n\n## Steps\n1. List pipelines for the project and identify the most recent runs.\n2. Get the pipeline details for any that failed to read the status and reason.\n3. If a failure looks transient, use Retry Pipeline to re-run it.\n\n## Output\nReturn a summary of recent pipeline runs (ref, status, when) and call out any failures. If a retry was triggered, include the retried pipeline ID.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gmail.display.ts b/apps/sim/blocks/blocks/gmail.display.ts index 54d180b3f60..b2625a050bf 100644 --- a/apps/sim/blocks/blocks/gmail.display.ts +++ b/apps/sim/blocks/blocks/gmail.display.ts @@ -1,6 +1,7 @@ -import { GmailIcon } from '@/components/icons' +import { Card } from '@/components/emcn/icons' +import { GmailIcon, LemlistIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GmailBlockDisplay = { type: 'gmail', @@ -24,3 +25,123 @@ export const GmailV2BlockDisplay = { integrationType: IntegrationType.Email, hideFromToolbar: false, } satisfies BlockDisplay + +export const GmailBlockMeta = { + tags: ['google-workspace', 'messaging'], + url: 'https://www.google.com/gmail/about', + templates: [ + { + icon: GmailIcon, + title: 'Auto-reply agent', + prompt: + 'Create a workflow that reads my Gmail inbox, identifies emails that need a response, and drafts contextual replies for each one. Schedule it to run every hour.', + image: '/templates/gmail-agent-dark.png', + modules: ['agent', 'workflows'], + category: 'popular', + tags: ['individual', 'communication', 'automation'], + featured: true, + }, + { + icon: LemlistIcon, + title: 'Outbound sequence builder', + prompt: + 'Build a workflow that reads leads from my table, researches each prospect and their company on the web, writes a personalized cold email tailored to their role and pain points, and sends it via Gmail. Schedule it to run daily to process new leads automatically.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication', 'automation'], + }, + { + icon: GmailIcon, + title: 'Email knowledge search', + prompt: + 'Create a knowledge base connected to my Gmail so all my emails are automatically synced, chunked, and searchable. Then build an agent I can ask things like "what did Sarah say about the pricing proposal?" or "find the contract John sent last month" and get instant answers with the original email cited.', + modules: ['knowledge-base', 'agent'], + category: 'support', + tags: ['individual', 'research', 'communication'], + }, + { + icon: GmailIcon, + title: 'Email triage assistant', + prompt: + 'Build a workflow that scans my Gmail inbox every hour, categorizes emails by urgency and type (action needed, FYI, follow-up), drafts replies for routine messages, and sends me a prioritized summary in Slack so I only open what matters. Schedule it to run hourly.', + modules: ['agent', 'scheduled', 'workflows'], + category: 'productivity', + tags: ['individual', 'communication', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: Card, + title: 'Invoice processor', + prompt: + 'Build a workflow that processes invoice PDFs from Gmail, extracts vendor name, amount, due date, and line items, then logs everything to a tracking table and sends a Slack alert for invoices due within 7 days.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GmailIcon, + title: 'Gmail to CRM activity logger', + prompt: + 'Build a workflow that reads new Gmail threads with customers, extracts the contact, deal context, and key points discussed, and logs a timestamped activity to the matching HubSpot contact or deal so every conversation stays attached to the record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'communication', 'automation'], + alsoIntegrations: ['hubspot'], + }, + { + icon: GmailIcon, + title: 'Gmail attachment vault', + prompt: + 'Create a workflow that watches Gmail for new emails with attachments, saves each attachment into a categorized folder in Google Drive based on sender and subject, and logs a row to a tracking table with the file link and source email.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation', 'sync'], + alsoIntegrations: ['google_drive'], + }, + + { + icon: GmailIcon, + title: 'Save incoming emails to Notion databases', + prompt: + 'Build a workflow that monitors Gmail for incoming emails, extracts structured data from each one, and stores it as a Notion database entry — useful for lead capture, support tickets, and meeting scheduling.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'triage-inbox', + description: + 'Sort unread email by urgency and draft replies for the most important messages.', + content: + '# Triage Inbox\n\nReview unread Gmail messages and bring order to the inbox.\n\n## Steps\n1. Read unread messages from the relevant time window.\n2. Classify each as Urgent, Today, This week, or FYI based on sender, subject, and content.\n3. For Urgent and Today items, draft a concise reply.\n4. Flag anything that needs a meeting or a decision from someone else.\n\n## Output\nReturn a prioritized list: each message with its sender, a one-line summary, the assigned priority, and the draft reply where one was written. Do not send anything without confirmation.', + }, + { + name: 'summarize-email-thread', + description: 'Condense a long email thread into the key points, decisions, and action items.', + content: + '# Summarize Email Thread\n\nGiven a Gmail thread, produce a tight summary.\n\n## Steps\n1. Read every message in the thread in order.\n2. Identify the core topic, what was decided, and what is still open.\n3. Pull out action items and who owns each.\n\n## Output\n- A one-sentence TL;DR.\n- Key decisions as bullets.\n- Action items with owners.\n- Open questions that still need an answer.', + }, + { + name: 'draft-reply-from-context', + description: 'Draft a contextual reply to an email in the right tone, ready for review.', + content: + '# Draft Reply From Context\n\nWrite a reply to an incoming email that is ready to send after a quick review.\n\n## Steps\n1. Read the email and any prior thread context.\n2. Determine what the sender is asking for and the appropriate tone (formal, friendly, brief).\n3. Draft a reply that answers every question and proposes clear next steps.\n\n## Output\nA complete draft reply with subject and body. Keep it concise, match the sender style, and leave placeholders in brackets for any detail you cannot infer. Do not send without confirmation.', + }, + { + name: 'find-and-extract-emails', + description: 'Search Gmail for messages matching a query and extract the details you need.', + content: + '# Find And Extract Emails\n\nLocate specific emails and pull structured information from them.\n\n## Steps\n1. Build a Gmail search query from the request (sender, subject keywords, date range, label, has attachment).\n2. Retrieve matching messages.\n3. Extract the requested fields from each, for example invoice amounts, order numbers, contact details, or attachment names.\n\n## Output\nA structured list of the matching emails with the extracted fields, plus a link or message id for each so the source can be opened.', + }, + ], +} as const satisfies BlockMeta + +export const GmailV2BlockMeta = { + tags: ['google-workspace', 'messaging'], + url: 'https://www.google.com/gmail/about', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gmail.ts b/apps/sim/blocks/blocks/gmail.ts index 4dbaea9bf48..ab527ad9c6f 100644 --- a/apps/sim/blocks/blocks/gmail.ts +++ b/apps/sim/blocks/blocks/gmail.ts @@ -1,8 +1,6 @@ -import { Card } from '@/components/emcn/icons' -import { GmailIcon, LemlistIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GmailBlockDisplay, GmailV2BlockDisplay } from '@/blocks/blocks/gmail.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, @@ -629,123 +627,3 @@ export const GmailV2Block: BlockConfig = { timestamp: { type: 'string', description: 'Event timestamp' }, }, } - -export const GmailBlockMeta = { - tags: ['google-workspace', 'messaging'], - url: 'https://www.google.com/gmail/about', - templates: [ - { - icon: GmailIcon, - title: 'Auto-reply agent', - prompt: - 'Create a workflow that reads my Gmail inbox, identifies emails that need a response, and drafts contextual replies for each one. Schedule it to run every hour.', - image: '/templates/gmail-agent-dark.png', - modules: ['agent', 'workflows'], - category: 'popular', - tags: ['individual', 'communication', 'automation'], - featured: true, - }, - { - icon: LemlistIcon, - title: 'Outbound sequence builder', - prompt: - 'Build a workflow that reads leads from my table, researches each prospect and their company on the web, writes a personalized cold email tailored to their role and pain points, and sends it via Gmail. Schedule it to run daily to process new leads automatically.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication', 'automation'], - }, - { - icon: GmailIcon, - title: 'Email knowledge search', - prompt: - 'Create a knowledge base connected to my Gmail so all my emails are automatically synced, chunked, and searchable. Then build an agent I can ask things like "what did Sarah say about the pricing proposal?" or "find the contract John sent last month" and get instant answers with the original email cited.', - modules: ['knowledge-base', 'agent'], - category: 'support', - tags: ['individual', 'research', 'communication'], - }, - { - icon: GmailIcon, - title: 'Email triage assistant', - prompt: - 'Build a workflow that scans my Gmail inbox every hour, categorizes emails by urgency and type (action needed, FYI, follow-up), drafts replies for routine messages, and sends me a prioritized summary in Slack so I only open what matters. Schedule it to run hourly.', - modules: ['agent', 'scheduled', 'workflows'], - category: 'productivity', - tags: ['individual', 'communication', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: Card, - title: 'Invoice processor', - prompt: - 'Build a workflow that processes invoice PDFs from Gmail, extracts vendor name, amount, due date, and line items, then logs everything to a tracking table and sends a Slack alert for invoices due within 7 days.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GmailIcon, - title: 'Gmail to CRM activity logger', - prompt: - 'Build a workflow that reads new Gmail threads with customers, extracts the contact, deal context, and key points discussed, and logs a timestamped activity to the matching HubSpot contact or deal so every conversation stays attached to the record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'communication', 'automation'], - alsoIntegrations: ['hubspot'], - }, - { - icon: GmailIcon, - title: 'Gmail attachment vault', - prompt: - 'Create a workflow that watches Gmail for new emails with attachments, saves each attachment into a categorized folder in Google Drive based on sender and subject, and logs a row to a tracking table with the file link and source email.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation', 'sync'], - alsoIntegrations: ['google_drive'], - }, - - { - icon: GmailIcon, - title: 'Save incoming emails to Notion databases', - prompt: - 'Build a workflow that monitors Gmail for incoming emails, extracts structured data from each one, and stores it as a Notion database entry — useful for lead capture, support tickets, and meeting scheduling.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'triage-inbox', - description: - 'Sort unread email by urgency and draft replies for the most important messages.', - content: - '# Triage Inbox\n\nReview unread Gmail messages and bring order to the inbox.\n\n## Steps\n1. Read unread messages from the relevant time window.\n2. Classify each as Urgent, Today, This week, or FYI based on sender, subject, and content.\n3. For Urgent and Today items, draft a concise reply.\n4. Flag anything that needs a meeting or a decision from someone else.\n\n## Output\nReturn a prioritized list: each message with its sender, a one-line summary, the assigned priority, and the draft reply where one was written. Do not send anything without confirmation.', - }, - { - name: 'summarize-email-thread', - description: 'Condense a long email thread into the key points, decisions, and action items.', - content: - '# Summarize Email Thread\n\nGiven a Gmail thread, produce a tight summary.\n\n## Steps\n1. Read every message in the thread in order.\n2. Identify the core topic, what was decided, and what is still open.\n3. Pull out action items and who owns each.\n\n## Output\n- A one-sentence TL;DR.\n- Key decisions as bullets.\n- Action items with owners.\n- Open questions that still need an answer.', - }, - { - name: 'draft-reply-from-context', - description: 'Draft a contextual reply to an email in the right tone, ready for review.', - content: - '# Draft Reply From Context\n\nWrite a reply to an incoming email that is ready to send after a quick review.\n\n## Steps\n1. Read the email and any prior thread context.\n2. Determine what the sender is asking for and the appropriate tone (formal, friendly, brief).\n3. Draft a reply that answers every question and proposes clear next steps.\n\n## Output\nA complete draft reply with subject and body. Keep it concise, match the sender style, and leave placeholders in brackets for any detail you cannot infer. Do not send without confirmation.', - }, - { - name: 'find-and-extract-emails', - description: 'Search Gmail for messages matching a query and extract the details you need.', - content: - '# Find And Extract Emails\n\nLocate specific emails and pull structured information from them.\n\n## Steps\n1. Build a Gmail search query from the request (sender, subject keywords, date range, label, has attachment).\n2. Retrieve matching messages.\n3. Extract the requested fields from each, for example invoice amounts, order numbers, contact details, or attachment names.\n\n## Output\nA structured list of the matching emails with the extracted fields, plus a link or message id for each so the source can be opened.', - }, - ], -} as const satisfies BlockMeta - -export const GmailV2BlockMeta = { - tags: ['google-workspace', 'messaging'], - url: 'https://www.google.com/gmail/about', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gong.display.ts b/apps/sim/blocks/blocks/gong.display.ts index e5ad9ee1707..b38f66e75b8 100644 --- a/apps/sim/blocks/blocks/gong.display.ts +++ b/apps/sim/blocks/blocks/gong.display.ts @@ -1,6 +1,6 @@ import { GongIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GongBlockDisplay = { type: 'gong', @@ -16,3 +16,100 @@ export const GongBlockDisplay = { integrationType: IntegrationType.Sales, triggerAllowed: true, } satisfies BlockDisplay + +export const GongBlockMeta = { + tags: ['meeting', 'sales-engagement', 'speech-to-text'], + url: 'https://www.gong.io', + templates: [ + { + icon: GongIcon, + title: 'Sales call analyzer', + prompt: + 'Build a workflow that pulls call transcripts from Gong after each sales call, identifies key objections raised, action items promised, and competitor mentions, updates the deal record in my CRM, and posts a call summary with next steps to the Slack deal channel.', + modules: ['agent', 'tables', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: GongIcon, + title: 'Gong objection tracker', + prompt: + 'Build a scheduled weekly workflow that scans Gong sales calls for recurring objections, scores frequency and stage, and writes a competitive-intel digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: GongIcon, + title: 'Gong deal-risk surfacer', + prompt: + 'Create a workflow that monitors Gong conversation intelligence signals, identifies deals at risk based on talk patterns, and posts a Slack alert to the AE and manager.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GongIcon, + title: 'Gong coaching dashboard', + prompt: + 'Build a scheduled weekly workflow that pulls Gong per-rep metrics — talk ratio, longest monologue, question rate — and writes a coaching table for managers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + }, + { + icon: GongIcon, + title: 'Gong customer-quote miner', + prompt: + 'Create a workflow that processes Gong customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: GongIcon, + title: 'Gong CRM auto-updater', + prompt: + 'Build a workflow that runs after a Gong sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity with notes.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: GongIcon, + title: 'Gong competitor-mention tracker', + prompt: + 'Create a workflow that scans Gong calls for competitor mentions, captures context and outcome, and writes the competitive intel to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + ], + skills: [ + { + name: 'summarize-call', + description: + 'Pull a Gong call transcript and produce a structured recap with topics, objections, and next steps.', + content: + '# Summarize Call\n\nUse Gong to turn a recorded call into a clean recap.\n\n## Steps\n1. Get the call by its call ID to read the metadata (participants, duration, account).\n2. Get the call transcript for the same call ID.\n3. Identify the main topics, customer objections, and agreed next steps from the transcript.\n\n## Output\nReturn a recap: a short overview, key topics discussed, objections raised, and a list of next steps with owners. Keep it grounded in the transcript.', + }, + { + name: 'extract-deal-signals', + description: + 'Read a Gong call transcript and extract CRM-ready deal signals like decision-maker, competitor, and next step.', + content: + '# Extract Deal Signals\n\nUse Gong to turn conversation content into structured deal attributes.\n\n## Steps\n1. Get the call transcript for the given call ID.\n2. Scan for high-value signals: decision-maker, budget, timeline, competitor mentions, use case, and the agreed next step with its date.\n3. Normalize each signal into a structured field.\n\n## Output\nReturn a structured object of deal attributes (decision_maker, competitor, next_step, next_step_date, use_case, and any others found). Leave fields null when not mentioned rather than guessing, so they can be written to CRM.', + }, + { + name: 'review-recent-calls', + description: + 'List recent Gong calls in a date range and produce a digest of themes and follow-ups across them.', + content: + '# Review Recent Calls\n\nUse Gong to summarize a batch of recent calls.\n\n## Steps\n1. List calls (or use Get Extensive Calls) filtered by a date range and optionally by user or workspace.\n2. For the most relevant calls, get the transcript to pull themes and outcomes.\n3. Roll the findings up into recurring themes, common objections, and open follow-ups across the calls.\n\n## Output\nReturn a digest: a per-call one-liner, the cross-call themes, and a consolidated follow-up list. Note any call missing a clear next step.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index 540fa514beb..a7018d08918 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -1,6 +1,5 @@ -import { GongIcon } from '@/components/icons' import { GongBlockDisplay } from '@/blocks/blocks/gong.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { GongResponse } from '@/tools/gong/types' import { getTrigger } from '@/triggers' @@ -911,100 +910,3 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes available: ['gong_webhook', 'gong_call_completed'], }, } - -export const GongBlockMeta = { - tags: ['meeting', 'sales-engagement', 'speech-to-text'], - url: 'https://www.gong.io', - templates: [ - { - icon: GongIcon, - title: 'Sales call analyzer', - prompt: - 'Build a workflow that pulls call transcripts from Gong after each sales call, identifies key objections raised, action items promised, and competitor mentions, updates the deal record in my CRM, and posts a call summary with next steps to the Slack deal channel.', - modules: ['agent', 'tables', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: GongIcon, - title: 'Gong objection tracker', - prompt: - 'Build a scheduled weekly workflow that scans Gong sales calls for recurring objections, scores frequency and stage, and writes a competitive-intel digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: GongIcon, - title: 'Gong deal-risk surfacer', - prompt: - 'Create a workflow that monitors Gong conversation intelligence signals, identifies deals at risk based on talk patterns, and posts a Slack alert to the AE and manager.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GongIcon, - title: 'Gong coaching dashboard', - prompt: - 'Build a scheduled weekly workflow that pulls Gong per-rep metrics — talk ratio, longest monologue, question rate — and writes a coaching table for managers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - }, - { - icon: GongIcon, - title: 'Gong customer-quote miner', - prompt: - 'Create a workflow that processes Gong customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: GongIcon, - title: 'Gong CRM auto-updater', - prompt: - 'Build a workflow that runs after a Gong sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity with notes.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: GongIcon, - title: 'Gong competitor-mention tracker', - prompt: - 'Create a workflow that scans Gong calls for competitor mentions, captures context and outcome, and writes the competitive intel to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - ], - skills: [ - { - name: 'summarize-call', - description: - 'Pull a Gong call transcript and produce a structured recap with topics, objections, and next steps.', - content: - '# Summarize Call\n\nUse Gong to turn a recorded call into a clean recap.\n\n## Steps\n1. Get the call by its call ID to read the metadata (participants, duration, account).\n2. Get the call transcript for the same call ID.\n3. Identify the main topics, customer objections, and agreed next steps from the transcript.\n\n## Output\nReturn a recap: a short overview, key topics discussed, objections raised, and a list of next steps with owners. Keep it grounded in the transcript.', - }, - { - name: 'extract-deal-signals', - description: - 'Read a Gong call transcript and extract CRM-ready deal signals like decision-maker, competitor, and next step.', - content: - '# Extract Deal Signals\n\nUse Gong to turn conversation content into structured deal attributes.\n\n## Steps\n1. Get the call transcript for the given call ID.\n2. Scan for high-value signals: decision-maker, budget, timeline, competitor mentions, use case, and the agreed next step with its date.\n3. Normalize each signal into a structured field.\n\n## Output\nReturn a structured object of deal attributes (decision_maker, competitor, next_step, next_step_date, use_case, and any others found). Leave fields null when not mentioned rather than guessing, so they can be written to CRM.', - }, - { - name: 'review-recent-calls', - description: - 'List recent Gong calls in a date range and produce a digest of themes and follow-ups across them.', - content: - '# Review Recent Calls\n\nUse Gong to summarize a batch of recent calls.\n\n## Steps\n1. List calls (or use Get Extensive Calls) filtered by a date range and optionally by user or workspace.\n2. For the most relevant calls, get the transcript to pull themes and outcomes.\n3. Roll the findings up into recurring themes, common objections, and open follow-ups across the calls.\n\n## Output\nReturn a digest: a per-call one-liner, the cross-call themes, and a consolidated follow-up list. Note any call missing a clear next step.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google.display.ts b/apps/sim/blocks/blocks/google.display.ts index 343336266d5..faa6707db47 100644 --- a/apps/sim/blocks/blocks/google.display.ts +++ b/apps/sim/blocks/blocks/google.display.ts @@ -1,6 +1,6 @@ import { GoogleIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleSearchBlockDisplay = { type: 'google_search', @@ -13,3 +13,99 @@ export const GoogleSearchBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_search', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const GoogleSearchBlockMeta = { + tags: ['web-scraping', 'seo'], + url: 'https://developers.google.com/custom-search', + templates: [ + { + icon: GoogleIcon, + title: 'Daily news digest', + prompt: + 'Create a scheduled daily workflow that runs Google searches for the topics and competitors I care about, picks the most relevant fresh results, summarizes each in a sentence, and emails me a curated digest every morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research', 'content'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleIcon, + title: 'Lead company researcher', + prompt: + "Build a workflow that watches my leads table for new rows, runs Google searches for each company's recent news, funding, and leadership, summarizes the findings with an agent, and writes a research brief back to the row.", + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'automation'], + }, + { + icon: GoogleIcon, + title: 'SERP rank tracker', + prompt: + 'Create a scheduled weekly workflow that runs Google searches for my target keywords, records where my domain appears in the results, logs positions to a tables-based scorecard, and posts a Slack summary of gainers and losers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'seo', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleIcon, + title: 'Brand mention monitor', + prompt: + 'Build a scheduled workflow that searches Google for new mentions of my brand and key executives, filters out noise with an agent, and posts notable mentions with links to a Slack channel for the comms team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring', 'research'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleIcon, + title: 'Research-backed answer agent', + prompt: + 'Create an agent that takes any question, runs targeted Google searches to gather current sources, synthesizes a concise answer with citations, and returns it so the team gets sourced answers instead of guesses.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'team'], + }, + { + icon: GoogleIcon, + title: 'Content gap explorer', + prompt: + 'Build a workflow that runs Google searches for a seed topic and its related queries, extracts the recurring subtopics and questions competitors rank for, and writes a prioritized content brief to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'seo', 'research'], + }, + { + icon: GoogleIcon, + title: 'Support answer finder', + prompt: + 'Create a workflow that on a new support ticket runs Google searches scoped to our docs and trusted sources, finds the most relevant pages, and drafts a sourced reply for the agent to review before sending.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'research', 'automation'], + }, + ], + skills: [ + { + name: 'search-the-web', + description: + 'Run a Google web search and return the most relevant results with titles and links.', + content: + '# Search the Web\n\nFind current information with Google Custom Search.\n\n## Steps\n1. Turn the request into an effective query. Use operators when helpful: "exact phrase", `site:domain.com`, `-exclude`, `OR`, `filetype:pdf`.\n2. Set Number of Results to a sensible value (e.g., 10).\n3. Run the search with the API key and Custom Search Engine ID.\n4. Read the result items: title, link, and snippet.\n\n## Output\nA ranked list of results, each with title, URL, and a one-line snippet. Drop low-relevance hits and note if the query returned little so it can be broadened.', + }, + { + name: 'research-and-summarize', + description: + 'Search Google for a topic, gather the best sources, and synthesize a cited answer.', + content: + '# Research and Summarize\n\nAnswer a question from fresh web sources.\n\n## Steps\n1. Break the question into 1-3 focused search queries.\n2. Run each search and collect the most relevant result items (title, link, snippet).\n3. Synthesize a concise answer grounded in the snippets; do not assert facts the sources do not support.\n4. Attribute each claim to its source link.\n\n## Output\nA short, sourced answer followed by a list of the sources used (title + URL). If sources conflict, say so rather than guessing.', + }, + { + name: 'monitor-mentions', + description: + 'Search Google for recent mentions of a brand, person, or keyword and surface notable hits.', + content: + '# Monitor Mentions\n\nFind recent web mentions of a target term.\n\n## Steps\n1. Build queries for the brand/person/keyword, optionally scoped with `site:` for specific outlets or quotes for exact names.\n2. Run the searches and collect result items.\n3. Filter out irrelevant or stale hits and dedupe near-identical results.\n4. Classify each remaining mention (e.g., news, review, social) and gauge tone where possible.\n\n## Output\nA list of notable mentions: title, source URL, a one-line summary, and a tone tag. Lead with the most significant items.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google.ts b/apps/sim/blocks/blocks/google.ts index f5ec8a42b03..72a3805e013 100644 --- a/apps/sim/blocks/blocks/google.ts +++ b/apps/sim/blocks/blocks/google.ts @@ -1,6 +1,5 @@ -import { GoogleIcon } from '@/components/icons' import { GoogleSearchBlockDisplay } from '@/blocks/blocks/google.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { GoogleSearchResponse } from '@/tools/google/types' @@ -185,99 +184,3 @@ Return ONLY the search query - no explanations, no quotes around the whole thing nextPageStartIndex: { type: 'number', description: 'Start index for the next page of results' }, }, } - -export const GoogleSearchBlockMeta = { - tags: ['web-scraping', 'seo'], - url: 'https://developers.google.com/custom-search', - templates: [ - { - icon: GoogleIcon, - title: 'Daily news digest', - prompt: - 'Create a scheduled daily workflow that runs Google searches for the topics and competitors I care about, picks the most relevant fresh results, summarizes each in a sentence, and emails me a curated digest every morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research', 'content'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleIcon, - title: 'Lead company researcher', - prompt: - "Build a workflow that watches my leads table for new rows, runs Google searches for each company's recent news, funding, and leadership, summarizes the findings with an agent, and writes a research brief back to the row.", - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'automation'], - }, - { - icon: GoogleIcon, - title: 'SERP rank tracker', - prompt: - 'Create a scheduled weekly workflow that runs Google searches for my target keywords, records where my domain appears in the results, logs positions to a tables-based scorecard, and posts a Slack summary of gainers and losers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'seo', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleIcon, - title: 'Brand mention monitor', - prompt: - 'Build a scheduled workflow that searches Google for new mentions of my brand and key executives, filters out noise with an agent, and posts notable mentions with links to a Slack channel for the comms team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring', 'research'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleIcon, - title: 'Research-backed answer agent', - prompt: - 'Create an agent that takes any question, runs targeted Google searches to gather current sources, synthesizes a concise answer with citations, and returns it so the team gets sourced answers instead of guesses.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'team'], - }, - { - icon: GoogleIcon, - title: 'Content gap explorer', - prompt: - 'Build a workflow that runs Google searches for a seed topic and its related queries, extracts the recurring subtopics and questions competitors rank for, and writes a prioritized content brief to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'seo', 'research'], - }, - { - icon: GoogleIcon, - title: 'Support answer finder', - prompt: - 'Create a workflow that on a new support ticket runs Google searches scoped to our docs and trusted sources, finds the most relevant pages, and drafts a sourced reply for the agent to review before sending.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'research', 'automation'], - }, - ], - skills: [ - { - name: 'search-the-web', - description: - 'Run a Google web search and return the most relevant results with titles and links.', - content: - '# Search the Web\n\nFind current information with Google Custom Search.\n\n## Steps\n1. Turn the request into an effective query. Use operators when helpful: "exact phrase", `site:domain.com`, `-exclude`, `OR`, `filetype:pdf`.\n2. Set Number of Results to a sensible value (e.g., 10).\n3. Run the search with the API key and Custom Search Engine ID.\n4. Read the result items: title, link, and snippet.\n\n## Output\nA ranked list of results, each with title, URL, and a one-line snippet. Drop low-relevance hits and note if the query returned little so it can be broadened.', - }, - { - name: 'research-and-summarize', - description: - 'Search Google for a topic, gather the best sources, and synthesize a cited answer.', - content: - '# Research and Summarize\n\nAnswer a question from fresh web sources.\n\n## Steps\n1. Break the question into 1-3 focused search queries.\n2. Run each search and collect the most relevant result items (title, link, snippet).\n3. Synthesize a concise answer grounded in the snippets; do not assert facts the sources do not support.\n4. Attribute each claim to its source link.\n\n## Output\nA short, sourced answer followed by a list of the sources used (title + URL). If sources conflict, say so rather than guessing.', - }, - { - name: 'monitor-mentions', - description: - 'Search Google for recent mentions of a brand, person, or keyword and surface notable hits.', - content: - '# Monitor Mentions\n\nFind recent web mentions of a target term.\n\n## Steps\n1. Build queries for the brand/person/keyword, optionally scoped with `site:` for specific outlets or quotes for exact names.\n2. Run the searches and collect result items.\n3. Filter out irrelevant or stale hits and dedupe near-identical results.\n4. Classify each remaining mention (e.g., news, review, social) and gauge tone where possible.\n\n## Output\nA list of notable mentions: title, source URL, a one-line summary, and a tone tag. Lead with the most significant items.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_ads.display.ts b/apps/sim/blocks/blocks/google_ads.display.ts index 3c9558c7857..1a15ca8680b 100644 --- a/apps/sim/blocks/blocks/google_ads.display.ts +++ b/apps/sim/blocks/blocks/google_ads.display.ts @@ -1,6 +1,6 @@ import { GoogleAdsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleAdsBlockDisplay = { type: 'google_ads', @@ -14,3 +14,100 @@ export const GoogleAdsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_ads', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const GoogleAdsBlockMeta = { + tags: ['marketing', 'google-workspace', 'data-analytics'], + url: 'https://ads.google.com', + templates: [ + { + icon: GoogleAdsIcon, + title: 'Google Ads spend pacing', + prompt: + 'Build a scheduled daily workflow that pulls Google Ads campaign spend, compares against monthly budget, and posts a Slack alert when any campaign is pacing more than 15% over.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads keyword performance report', + prompt: + 'Create a scheduled weekly workflow that pulls Google Ads keyword performance, flags keywords with rising CPCs or dropping CTRs, and writes a recommendation list to a file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads negative-keyword finder', + prompt: + 'Build a scheduled workflow that scans Google Ads search-term performance weekly, identifies irrelevant terms wasting spend, and writes a recommended negative-keyword list to a file for the team to review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads + Stripe ROAS tracker', + prompt: + 'Create a scheduled workflow that joins Google Ads spend with Stripe revenue per campaign UTM, calculates true ROAS, and posts the per-channel breakdown to Slack each morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'finance', 'reporting'], + alsoIntegrations: ['stripe', 'slack'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads + PageSpeed landing audit', + prompt: + 'Create a scheduled workflow that for active Google Ads campaigns runs Google PageSpeed on the landing pages weekly, flags slow LPs, and pings the marketing team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['google_pagespeed', 'slack'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads + Profound AI brand attribution', + prompt: + 'Build a scheduled workflow that joins Google Ads spend per campaign with Profound AI brand-visibility scores, writes a true-attribution table, and posts findings to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + alsoIntegrations: ['profound', 'slack'], + }, + { + icon: GoogleAdsIcon, + title: 'Google Ads creative auditor', + prompt: + 'Create a scheduled workflow that pulls Google Ads creatives, scores ad copy quality with an agent, and writes a per-campaign creative review file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + ], + skills: [ + { + name: 'report-campaign-performance', + description: + 'Pull Google Ads campaign performance for a date range and produce a clear metrics report.', + content: + '# Report Campaign Performance\n\nUse Google Ads to summarize how campaigns are performing.\n\n## Steps\n1. List campaigns for the customer to know what is active.\n2. Use Campaign Performance over the chosen date range to pull impressions, clicks, cost, conversions, CTR, CPC, and ROAS.\n3. Rank campaigns by spend and by efficiency to surface what is working and what is not.\n\n## Output\nReturn a per-campaign metrics table plus a short narrative: top performers, underperformers, and where spend is being wasted. Note the date range used.', + }, + { + name: 'analyze-ad-performance', + description: + 'Pull ad-level Google Ads performance and identify the best and worst creatives in each ad group.', + content: + '# Analyze Ad Performance\n\nUse Google Ads to compare creatives within campaigns.\n\n## Steps\n1. List ad groups for the target campaign or customer.\n2. Use Ad Performance over the date range to pull per-ad clicks, conversions, CTR, and cost.\n3. Within each ad group, identify the strongest and weakest ads.\n\n## Output\nReturn, per ad group, the best and worst performing ads with their key metrics, plus a recommendation (scale, pause, or rewrite). Keep recommendations tied to the data.', + }, + { + name: 'run-gaql-query', + description: + 'Run a custom GAQL query against Google Ads to answer a specific reporting question.', + content: + '# Run GAQL Query\n\nUse Google Ads to answer an ad-hoc reporting question with GAQL.\n\n## Steps\n1. Clarify the metrics, dimensions, and segments the question needs.\n2. Write a valid GAQL query (SELECT fields FROM resource WHERE conditions) scoped to the customer and date range.\n3. Use the Custom Query operation to run it and read the rows.\n\n## Output\nReturn the result rows as a clean table along with the GAQL query that produced them, so the analysis is reproducible.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_ads.ts b/apps/sim/blocks/blocks/google_ads.ts index 01ecde790ce..91b139c2c18 100644 --- a/apps/sim/blocks/blocks/google_ads.ts +++ b/apps/sim/blocks/blocks/google_ads.ts @@ -1,7 +1,6 @@ -import { GoogleAdsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleAdsBlockDisplay } from '@/blocks/blocks/google_ads.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const GoogleAdsBlock: BlockConfig = { @@ -284,100 +283,3 @@ Return ONLY the GAQL query - no explanations, no quotes, no extra text.`, }, }, } - -export const GoogleAdsBlockMeta = { - tags: ['marketing', 'google-workspace', 'data-analytics'], - url: 'https://ads.google.com', - templates: [ - { - icon: GoogleAdsIcon, - title: 'Google Ads spend pacing', - prompt: - 'Build a scheduled daily workflow that pulls Google Ads campaign spend, compares against monthly budget, and posts a Slack alert when any campaign is pacing more than 15% over.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads keyword performance report', - prompt: - 'Create a scheduled weekly workflow that pulls Google Ads keyword performance, flags keywords with rising CPCs or dropping CTRs, and writes a recommendation list to a file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads negative-keyword finder', - prompt: - 'Build a scheduled workflow that scans Google Ads search-term performance weekly, identifies irrelevant terms wasting spend, and writes a recommended negative-keyword list to a file for the team to review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads + Stripe ROAS tracker', - prompt: - 'Create a scheduled workflow that joins Google Ads spend with Stripe revenue per campaign UTM, calculates true ROAS, and posts the per-channel breakdown to Slack each morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'finance', 'reporting'], - alsoIntegrations: ['stripe', 'slack'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads + PageSpeed landing audit', - prompt: - 'Create a scheduled workflow that for active Google Ads campaigns runs Google PageSpeed on the landing pages weekly, flags slow LPs, and pings the marketing team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['google_pagespeed', 'slack'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads + Profound AI brand attribution', - prompt: - 'Build a scheduled workflow that joins Google Ads spend per campaign with Profound AI brand-visibility scores, writes a true-attribution table, and posts findings to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - alsoIntegrations: ['profound', 'slack'], - }, - { - icon: GoogleAdsIcon, - title: 'Google Ads creative auditor', - prompt: - 'Create a scheduled workflow that pulls Google Ads creatives, scores ad copy quality with an agent, and writes a per-campaign creative review file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - ], - skills: [ - { - name: 'report-campaign-performance', - description: - 'Pull Google Ads campaign performance for a date range and produce a clear metrics report.', - content: - '# Report Campaign Performance\n\nUse Google Ads to summarize how campaigns are performing.\n\n## Steps\n1. List campaigns for the customer to know what is active.\n2. Use Campaign Performance over the chosen date range to pull impressions, clicks, cost, conversions, CTR, CPC, and ROAS.\n3. Rank campaigns by spend and by efficiency to surface what is working and what is not.\n\n## Output\nReturn a per-campaign metrics table plus a short narrative: top performers, underperformers, and where spend is being wasted. Note the date range used.', - }, - { - name: 'analyze-ad-performance', - description: - 'Pull ad-level Google Ads performance and identify the best and worst creatives in each ad group.', - content: - '# Analyze Ad Performance\n\nUse Google Ads to compare creatives within campaigns.\n\n## Steps\n1. List ad groups for the target campaign or customer.\n2. Use Ad Performance over the date range to pull per-ad clicks, conversions, CTR, and cost.\n3. Within each ad group, identify the strongest and weakest ads.\n\n## Output\nReturn, per ad group, the best and worst performing ads with their key metrics, plus a recommendation (scale, pause, or rewrite). Keep recommendations tied to the data.', - }, - { - name: 'run-gaql-query', - description: - 'Run a custom GAQL query against Google Ads to answer a specific reporting question.', - content: - '# Run GAQL Query\n\nUse Google Ads to answer an ad-hoc reporting question with GAQL.\n\n## Steps\n1. Clarify the metrics, dimensions, and segments the question needs.\n2. Write a valid GAQL query (SELECT fields FROM resource WHERE conditions) scoped to the customer and date range.\n3. Use the Custom Query operation to run it and read the rows.\n\n## Output\nReturn the result rows as a clean table along with the GAQL query that produced them, so the analysis is reproducible.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_bigquery.display.ts b/apps/sim/blocks/blocks/google_bigquery.display.ts index c53470ce7bc..fabdaf43941 100644 --- a/apps/sim/blocks/blocks/google_bigquery.display.ts +++ b/apps/sim/blocks/blocks/google_bigquery.display.ts @@ -1,6 +1,6 @@ import { GoogleBigQueryIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleBigQueryBlockDisplay = { type: 'google_bigquery', @@ -14,3 +14,101 @@ export const GoogleBigQueryBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_bigquery', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const GoogleBigQueryBlockMeta = { + tags: ['data-warehouse', 'google-workspace', 'data-analytics'], + url: 'https://cloud.google.com/bigquery', + templates: [ + { + icon: GoogleBigQueryIcon, + title: 'BigQuery scheduled report runner', + prompt: + 'Build a scheduled workflow that runs a saved BigQuery query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery customer 360 builder', + prompt: + 'Create a scheduled workflow that joins BigQuery sources — Stripe, product events, support tickets — into a single per-customer profile table refreshed daily.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery cost-tracking alerts', + prompt: + 'Build a scheduled daily workflow that pulls BigQuery slot and storage usage, projects month-end spend, and posts a Slack alert when projection exceeds budget.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery anomaly notifier', + prompt: + 'Create a workflow that runs BigQuery anomaly-detection queries on key metrics hourly, writes any anomalies to a tracking table, and pages the on-call data team on severe deltas.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'analysis'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery + Sheets exec dashboard', + prompt: + 'Build a scheduled workflow that pulls a BigQuery executive dashboard query weekly, writes the result into a chosen Google Sheet, and notifies leadership the new snapshot is ready.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + alsoIntegrations: ['google_sheets', 'gmail'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery schema drift detector', + prompt: + 'Create a scheduled workflow that snapshots BigQuery dataset schemas, diffs against the prior snapshot, and opens a Linear ticket on unexpected schema changes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: GoogleBigQueryIcon, + title: 'BigQuery NL analytics agent', + prompt: + "Build a Slack agent that lists BigQuery datasets and tables to understand the schema, translates a teammate's natural-language question into a safe BigQuery SQL query, runs it, and replies with the result table plus the query used.", + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'engineering'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'answer-question-with-sql', + description: + 'Inspect BigQuery schema, translate a natural-language question into safe SQL, run it, and return results.', + content: + '# Answer Question With SQL\n\nUse BigQuery to answer a data question from plain English.\n\n## Steps\n1. List datasets and tables, and Get Table on the relevant ones to understand the schema and column types.\n2. Translate the question into a single read-only BigQuery Standard SQL query, scoping it with filters and a LIMIT to control cost.\n3. Use Run Query to execute it.\n\n## Output\nReturn the result rows as a table plus the exact SQL query used, so the answer is verifiable. If the schema cannot support the question, say what is missing.', + }, + { + name: 'explore-dataset-schema', + description: + 'List BigQuery datasets and tables and summarize the schema of a dataset for an analyst.', + content: + '# Explore Dataset Schema\n\nUse BigQuery to map out what data is available.\n\n## Steps\n1. List datasets in the project.\n2. List tables in the target dataset.\n3. Get Table on each relevant table to read its columns, types, and descriptions.\n\n## Output\nReturn a structured schema summary: each table with its columns, types, and a one-line purpose. Highlight likely join keys so an analyst can plan queries.', + }, + { + name: 'load-rows-to-table', + description: 'Insert structured rows into a BigQuery table for logging or pipeline output.', + content: + '# Load Rows to Table\n\nUse BigQuery to write structured records into a table.\n\n## Steps\n1. Confirm the target dataset and table, and Get Table to verify the expected columns and types.\n2. Shape the incoming records to match the table schema exactly.\n3. Use Insert Rows to write the batch.\n\n## Output\nReturn the count of rows inserted and any rows rejected with their error. If types did not match the schema, report which fields failed rather than silently dropping data.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_bigquery.ts b/apps/sim/blocks/blocks/google_bigquery.ts index c2ad98b3326..7953ca0b00b 100644 --- a/apps/sim/blocks/blocks/google_bigquery.ts +++ b/apps/sim/blocks/blocks/google_bigquery.ts @@ -1,7 +1,6 @@ -import { GoogleBigQueryIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleBigQueryBlockDisplay } from '@/blocks/blocks/google_bigquery.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const GoogleBigQueryBlock: BlockConfig = { @@ -277,101 +276,3 @@ Return ONLY the JSON array - no explanations, no wrapping, no extra text.`, nextPageToken: { type: 'string', description: 'Token for next page of results' }, }, } - -export const GoogleBigQueryBlockMeta = { - tags: ['data-warehouse', 'google-workspace', 'data-analytics'], - url: 'https://cloud.google.com/bigquery', - templates: [ - { - icon: GoogleBigQueryIcon, - title: 'BigQuery scheduled report runner', - prompt: - 'Build a scheduled workflow that runs a saved BigQuery query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery customer 360 builder', - prompt: - 'Create a scheduled workflow that joins BigQuery sources — Stripe, product events, support tickets — into a single per-customer profile table refreshed daily.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery cost-tracking alerts', - prompt: - 'Build a scheduled daily workflow that pulls BigQuery slot and storage usage, projects month-end spend, and posts a Slack alert when projection exceeds budget.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery anomaly notifier', - prompt: - 'Create a workflow that runs BigQuery anomaly-detection queries on key metrics hourly, writes any anomalies to a tracking table, and pages the on-call data team on severe deltas.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'analysis'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery + Sheets exec dashboard', - prompt: - 'Build a scheduled workflow that pulls a BigQuery executive dashboard query weekly, writes the result into a chosen Google Sheet, and notifies leadership the new snapshot is ready.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - alsoIntegrations: ['google_sheets', 'gmail'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery schema drift detector', - prompt: - 'Create a scheduled workflow that snapshots BigQuery dataset schemas, diffs against the prior snapshot, and opens a Linear ticket on unexpected schema changes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: GoogleBigQueryIcon, - title: 'BigQuery NL analytics agent', - prompt: - "Build a Slack agent that lists BigQuery datasets and tables to understand the schema, translates a teammate's natural-language question into a safe BigQuery SQL query, runs it, and replies with the result table plus the query used.", - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'engineering'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'answer-question-with-sql', - description: - 'Inspect BigQuery schema, translate a natural-language question into safe SQL, run it, and return results.', - content: - '# Answer Question With SQL\n\nUse BigQuery to answer a data question from plain English.\n\n## Steps\n1. List datasets and tables, and Get Table on the relevant ones to understand the schema and column types.\n2. Translate the question into a single read-only BigQuery Standard SQL query, scoping it with filters and a LIMIT to control cost.\n3. Use Run Query to execute it.\n\n## Output\nReturn the result rows as a table plus the exact SQL query used, so the answer is verifiable. If the schema cannot support the question, say what is missing.', - }, - { - name: 'explore-dataset-schema', - description: - 'List BigQuery datasets and tables and summarize the schema of a dataset for an analyst.', - content: - '# Explore Dataset Schema\n\nUse BigQuery to map out what data is available.\n\n## Steps\n1. List datasets in the project.\n2. List tables in the target dataset.\n3. Get Table on each relevant table to read its columns, types, and descriptions.\n\n## Output\nReturn a structured schema summary: each table with its columns, types, and a one-line purpose. Highlight likely join keys so an analyst can plan queries.', - }, - { - name: 'load-rows-to-table', - description: 'Insert structured rows into a BigQuery table for logging or pipeline output.', - content: - '# Load Rows to Table\n\nUse BigQuery to write structured records into a table.\n\n## Steps\n1. Confirm the target dataset and table, and Get Table to verify the expected columns and types.\n2. Shape the incoming records to match the table schema exactly.\n3. Use Insert Rows to write the batch.\n\n## Output\nReturn the count of rows inserted and any rows rejected with their error. If types did not match the schema, report which fields failed rather than silently dropping data.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_books.display.ts b/apps/sim/blocks/blocks/google_books.display.ts index 107c24718d2..4c355353fd8 100644 --- a/apps/sim/blocks/blocks/google_books.display.ts +++ b/apps/sim/blocks/blocks/google_books.display.ts @@ -1,6 +1,6 @@ import { GoogleBooksIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleBooksBlockDisplay = { type: 'google_books', @@ -14,3 +14,98 @@ export const GoogleBooksBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_books', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const GoogleBooksBlockMeta = { + tags: ['google-workspace', 'knowledge-base', 'content-management'], + url: 'https://books.google.com', + templates: [ + { + icon: GoogleBooksIcon, + title: 'Google Books citation finder', + prompt: + 'Build a workflow that takes a topic, queries Google Books for relevant titles and quotes, and writes a citations bibliography file for research papers.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books reading list builder', + prompt: + 'Create a workflow that takes a topic, finds top-rated Google Books titles, writes a curated reading-list file with summaries, and emails it to the user.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books research enricher', + prompt: + 'Build a workflow that for each topic in a research table queries Google Books for foundational works, captures the key passages, and writes them to a knowledge base.', + modules: ['knowledge-base', 'tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books quote miner', + prompt: + 'Create a workflow that searches Google Books for quotes on a topic, scores by relevance, and writes the top quotes to a marketing content table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books bibliographic agent', + prompt: + 'Build a research agent that uses Google Books as one of its tools to find canonical sources and properly cite them in answers with ISBN and page references.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books due-diligence helper', + prompt: + 'Create a workflow that for a tracked person or company searches Google Books for prior publications and citations, and writes the findings to a CRM intel record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleBooksIcon, + title: 'Google Books topic explorer', + prompt: + 'Build an agent that explores a topic across Google Books, identifies adjacent themes from book metadata, and writes a topic map to a research file.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + ], + skills: [ + { + name: 'find-books-on-topic', + description: + 'Search Google Books for the most relevant titles on a topic and return a ranked, summarized list.', + content: + '# Find Books on a Topic\n\nUse Google Books to discover authoritative titles for a subject and present a clean shortlist.\n\n## Steps\n1. Take the topic or question from the request.\n2. Run a Search Volumes operation with a focused query. Use field operators when helpful: `intitle:`, `inauthor:`, `subject:`. Set Order By to `relevance` (or `newest` for recent works).\n3. Set Max Results (1-40) and optionally filter by Print Type (books) or eBook availability.\n4. For the top hits, read title, authors, publisher, published date, average rating, and a short description.\n5. Rank by relevance and rating; drop clearly off-topic results.\n\n## Output\nA numbered list of up to 10 books, each with title, author(s), year, rating (if present), one-line summary, and the preview/info link. Note if a result set is thin so the requester can broaden the query.', + }, + { + name: 'lookup-book-by-isbn', + description: + 'Resolve an ISBN or title into a single canonical book record with full metadata.', + content: + '# Look Up a Book by ISBN or Title\n\nResolve a specific book to its canonical Google Books record.\n\n## Steps\n1. If you have an ISBN, run Search Volumes with query `isbn:`. Otherwise search by `intitle:` plus `inauthor:` to disambiguate.\n2. Pick the best-matching volume and capture its volume ID.\n3. Run Get Volume Details on that volume ID for the fullest metadata.\n4. Collect title, subtitle, authors, publisher, published date, page count, categories, language, ISBN-10/13, and description.\n\n## Output\nA single structured record: title, authors, publisher, year, ISBNs, page count, categories, and the info link. If multiple editions match, list them and flag which is most likely intended.', + }, + { + name: 'build-reading-list', + description: + 'Assemble a curated, themed reading list with summaries from Google Books search results.', + content: + '# Build a Reading List\n\nTurn a topic into a curated reading list a person can act on.\n\n## Steps\n1. Identify the theme and any constraints (level, recency, language) from the request.\n2. Run one or more Search Volumes queries covering the main subtopics; use `langRestrict` and `orderBy` as needed.\n3. For each candidate, capture authors, year, rating, and description.\n4. Deduplicate editions of the same work and keep the best edition.\n5. Group the final picks into 2-4 logical sections (e.g., foundational, advanced, recent).\n\n## Output\nA grouped reading list. Each entry: title, author(s), year, a one-sentence reason it is included, and the preview link. Keep it to 8-15 titles unless asked otherwise.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_books.ts b/apps/sim/blocks/blocks/google_books.ts index caeedcbfe27..08f6f0a5f4c 100644 --- a/apps/sim/blocks/blocks/google_books.ts +++ b/apps/sim/blocks/blocks/google_books.ts @@ -1,6 +1,5 @@ -import { GoogleBooksIcon } from '@/components/icons' import { GoogleBooksBlockDisplay } from '@/blocks/blocks/google_books.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const GoogleBooksBlock: BlockConfig = { @@ -193,98 +192,3 @@ export const GoogleBooksBlock: BlockConfig = { isbn13: { type: 'string', description: 'ISBN-13 identifier' }, }, } - -export const GoogleBooksBlockMeta = { - tags: ['google-workspace', 'knowledge-base', 'content-management'], - url: 'https://books.google.com', - templates: [ - { - icon: GoogleBooksIcon, - title: 'Google Books citation finder', - prompt: - 'Build a workflow that takes a topic, queries Google Books for relevant titles and quotes, and writes a citations bibliography file for research papers.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books reading list builder', - prompt: - 'Create a workflow that takes a topic, finds top-rated Google Books titles, writes a curated reading-list file with summaries, and emails it to the user.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books research enricher', - prompt: - 'Build a workflow that for each topic in a research table queries Google Books for foundational works, captures the key passages, and writes them to a knowledge base.', - modules: ['knowledge-base', 'tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books quote miner', - prompt: - 'Create a workflow that searches Google Books for quotes on a topic, scores by relevance, and writes the top quotes to a marketing content table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books bibliographic agent', - prompt: - 'Build a research agent that uses Google Books as one of its tools to find canonical sources and properly cite them in answers with ISBN and page references.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books due-diligence helper', - prompt: - 'Create a workflow that for a tracked person or company searches Google Books for prior publications and citations, and writes the findings to a CRM intel record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleBooksIcon, - title: 'Google Books topic explorer', - prompt: - 'Build an agent that explores a topic across Google Books, identifies adjacent themes from book metadata, and writes a topic map to a research file.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - ], - skills: [ - { - name: 'find-books-on-topic', - description: - 'Search Google Books for the most relevant titles on a topic and return a ranked, summarized list.', - content: - '# Find Books on a Topic\n\nUse Google Books to discover authoritative titles for a subject and present a clean shortlist.\n\n## Steps\n1. Take the topic or question from the request.\n2. Run a Search Volumes operation with a focused query. Use field operators when helpful: `intitle:`, `inauthor:`, `subject:`. Set Order By to `relevance` (or `newest` for recent works).\n3. Set Max Results (1-40) and optionally filter by Print Type (books) or eBook availability.\n4. For the top hits, read title, authors, publisher, published date, average rating, and a short description.\n5. Rank by relevance and rating; drop clearly off-topic results.\n\n## Output\nA numbered list of up to 10 books, each with title, author(s), year, rating (if present), one-line summary, and the preview/info link. Note if a result set is thin so the requester can broaden the query.', - }, - { - name: 'lookup-book-by-isbn', - description: - 'Resolve an ISBN or title into a single canonical book record with full metadata.', - content: - '# Look Up a Book by ISBN or Title\n\nResolve a specific book to its canonical Google Books record.\n\n## Steps\n1. If you have an ISBN, run Search Volumes with query `isbn:`. Otherwise search by `intitle:` plus `inauthor:` to disambiguate.\n2. Pick the best-matching volume and capture its volume ID.\n3. Run Get Volume Details on that volume ID for the fullest metadata.\n4. Collect title, subtitle, authors, publisher, published date, page count, categories, language, ISBN-10/13, and description.\n\n## Output\nA single structured record: title, authors, publisher, year, ISBNs, page count, categories, and the info link. If multiple editions match, list them and flag which is most likely intended.', - }, - { - name: 'build-reading-list', - description: - 'Assemble a curated, themed reading list with summaries from Google Books search results.', - content: - '# Build a Reading List\n\nTurn a topic into a curated reading list a person can act on.\n\n## Steps\n1. Identify the theme and any constraints (level, recency, language) from the request.\n2. Run one or more Search Volumes queries covering the main subtopics; use `langRestrict` and `orderBy` as needed.\n3. For each candidate, capture authors, year, rating, and description.\n4. Deduplicate editions of the same work and keep the best edition.\n5. Group the final picks into 2-4 logical sections (e.g., foundational, advanced, recent).\n\n## Output\nA grouped reading list. Each entry: title, author(s), year, a one-sentence reason it is included, and the preview link. Keep it to 8-15 titles unless asked otherwise.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_calendar.display.ts b/apps/sim/blocks/blocks/google_calendar.display.ts index 9701ccaeec1..7834977a1c1 100644 --- a/apps/sim/blocks/blocks/google_calendar.display.ts +++ b/apps/sim/blocks/blocks/google_calendar.display.ts @@ -1,6 +1,6 @@ -import { GoogleCalendarIcon } from '@/components/icons' +import { GoogleCalendarIcon, TwilioIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleCalendarBlockDisplay = { type: 'google_calendar', @@ -23,3 +23,112 @@ export const GoogleCalendarV2BlockDisplay = { integrationType: IntegrationType.Productivity, hideFromToolbar: false, } satisfies BlockDisplay + +export const GoogleCalendarBlockMeta = { + tags: ['calendar', 'scheduling', 'google-workspace'], + url: 'https://workspace.google.com/products/calendar', + templates: [ + { + icon: GoogleCalendarIcon, + title: 'Meeting prep agent', + prompt: + 'Create an agent that checks my Google Calendar each morning, researches every attendee and topic on the web, and prepares a brief for each meeting so I walk in fully prepared. Schedule it to run every weekday morning.', + image: '/templates/meeting-prep-dark.png', + modules: ['agent', 'scheduled', 'workflows'], + category: 'popular', + tags: ['founder', 'sales', 'research', 'automation'], + featured: true, + }, + { + icon: TwilioIcon, + title: 'SMS appointment reminders', + prompt: + 'Create a scheduled workflow that checks Google Calendar each morning for appointments in the next 24 hours, and sends an SMS reminder to each attendee via Twilio with the meeting time, location, and any prep notes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'communication', 'automation'], + alsoIntegrations: ['twilio_sms'], + }, + { + icon: GoogleCalendarIcon, + title: 'Booking-to-calendar scheduler', + prompt: + 'Build a workflow that on a new Calendly booking creates the matching Google Calendar event, invites the attendees, attaches the meeting agenda, and writes the event link back so both systems stay in sync.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'scheduling', 'automation'], + alsoIntegrations: ['calendly'], + }, + { + icon: GoogleCalendarIcon, + title: 'Daily agenda digest', + prompt: + 'Create a scheduled weekday workflow that lists my Google Calendar events for the day, summarizes them with attendee context and prep notes, and posts a clean morning agenda to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'reporting', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleCalendarIcon, + title: 'Interview scheduling coordinator', + prompt: + "Build a workflow that when a candidate reaches the interview stage finds open slots across the panel's Google Calendars, creates the interview event with the video link, invites everyone, and emails the candidate the confirmation.", + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'scheduling', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleCalendarIcon, + title: 'Meeting-load weekly report', + prompt: + 'Create a scheduled weekly workflow that lists Google Calendar events for the team, computes total meeting hours and recurring-meeting load per person, writes the breakdown to a table, and flags anyone over the focus-time threshold.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['team', 'reporting', 'analysis'], + }, + { + icon: GoogleCalendarIcon, + title: 'Calendar event note-taker prep', + prompt: + 'Build a workflow that scans upcoming Google Calendar events for external meetings, researches each company and attendee, drafts talking points, and updates the event description so the notes travel with the invite.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'automation'], + }, + ], + skills: [ + { + name: 'schedule-meeting', + description: + 'Create a Google Calendar event with the right time, attendees, and details, sending invites.', + content: + '# Schedule a Meeting\n\nCreate a calendar event and invite attendees.\n\n## Steps\n1. Determine the calendar (default to `primary`), title, start and end times, location, and description from the request.\n2. Convert times to ISO 8601 with the correct timezone offset (e.g., `2025-06-03T10:00:00-08:00`).\n3. If the request is conversational (e.g., "lunch with John tomorrow at noon"), use Quick Add instead of building each field by hand.\n4. Run Create Event (or Quick Add) with the attendee emails as a comma-separated list.\n5. Set Send Email Notifications to `all` so attendees are invited.\n\n## Output\nConfirm the created event: title, start/end in a readable format, attendees, and the event link (htmlLink). If a conflict is likely, note it.', + }, + { + name: 'summarize-daily-agenda', + description: + "List today's Google Calendar events and produce a clean, ordered agenda summary.", + content: + '# Summarize the Daily Agenda\n\nProduce a readable agenda for a day or window.\n\n## Steps\n1. Resolve the target window into UTC ISO timestamps for Start Time Filter (timeMin) and End Time Filter (timeMax). For "today", use 00:00:00Z to 23:59:59Z.\n2. Run List Events on the chosen calendar with those filters and a reasonable Max Results.\n3. Sort events chronologically and read summary, start/end, location, and attendees for each.\n4. Flag back-to-back meetings and any event with no agenda or description.\n\n## Output\nA chronological agenda. Each line: time range, title, location (if any), and attendee count. Add a short header with total meetings and total meeting hours.', + }, + { + name: 'find-and-reschedule-event', + description: 'Locate an existing event and update its time, attendees, or details.', + content: + '# Find and Reschedule an Event\n\nUpdate an existing calendar event.\n\n## Steps\n1. If you do not have the event ID, run List Events over a suitable window and match by title/attendees to find the event ID.\n2. Run Get Event to read the current details and confirm it is the right one.\n3. Run Update Event with only the changed fields (new start/end in ISO 8601 with offset, new attendees, new location, or title).\n4. Set Send Email Notifications to `all` so attendees see the change.\n\n## Output\nConfirm what changed (old vs new time/attendees) and return the event link. If multiple events matched, list them and ask which to update before changing anything destructive.', + }, + { + name: 'invite-attendees-to-event', + description: 'Add attendees to an existing Google Calendar event and notify them.', + content: + '# Invite Attendees to an Event\n\nAdd people to an event without recreating it.\n\n## Steps\n1. Obtain the event ID (use List Events to find it if needed).\n2. Collect the attendee emails to add as a comma-separated list.\n3. Run Invite Attendees with Replace Existing set to `Add to existing attendees` (unless asked to replace the whole list).\n4. Set Send Email Notifications to `all`.\n\n## Output\nConfirm the added attendees and the resulting full attendee list, with the event link.', + }, + ], +} as const satisfies BlockMeta + +export const GoogleCalendarV2BlockMeta = { + tags: ['calendar', 'scheduling', 'google-workspace'], + url: 'https://workspace.google.com/products/calendar', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_calendar.ts b/apps/sim/blocks/blocks/google_calendar.ts index 9f7baae93fd..391bee34794 100644 --- a/apps/sim/blocks/blocks/google_calendar.ts +++ b/apps/sim/blocks/blocks/google_calendar.ts @@ -1,10 +1,9 @@ -import { GoogleCalendarIcon, TwilioIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleCalendarBlockDisplay, GoogleCalendarV2BlockDisplay, } from '@/blocks/blocks/google_calendar.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleCalendarResponse } from '@/tools/google_calendar/types' @@ -941,112 +940,3 @@ export const GoogleCalendarV2Block: BlockConfig = { timeZone: { type: 'string', description: 'Calendar time zone' }, }, } - -export const GoogleCalendarBlockMeta = { - tags: ['calendar', 'scheduling', 'google-workspace'], - url: 'https://workspace.google.com/products/calendar', - templates: [ - { - icon: GoogleCalendarIcon, - title: 'Meeting prep agent', - prompt: - 'Create an agent that checks my Google Calendar each morning, researches every attendee and topic on the web, and prepares a brief for each meeting so I walk in fully prepared. Schedule it to run every weekday morning.', - image: '/templates/meeting-prep-dark.png', - modules: ['agent', 'scheduled', 'workflows'], - category: 'popular', - tags: ['founder', 'sales', 'research', 'automation'], - featured: true, - }, - { - icon: TwilioIcon, - title: 'SMS appointment reminders', - prompt: - 'Create a scheduled workflow that checks Google Calendar each morning for appointments in the next 24 hours, and sends an SMS reminder to each attendee via Twilio with the meeting time, location, and any prep notes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'communication', 'automation'], - alsoIntegrations: ['twilio_sms'], - }, - { - icon: GoogleCalendarIcon, - title: 'Booking-to-calendar scheduler', - prompt: - 'Build a workflow that on a new Calendly booking creates the matching Google Calendar event, invites the attendees, attaches the meeting agenda, and writes the event link back so both systems stay in sync.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'scheduling', 'automation'], - alsoIntegrations: ['calendly'], - }, - { - icon: GoogleCalendarIcon, - title: 'Daily agenda digest', - prompt: - 'Create a scheduled weekday workflow that lists my Google Calendar events for the day, summarizes them with attendee context and prep notes, and posts a clean morning agenda to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'reporting', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleCalendarIcon, - title: 'Interview scheduling coordinator', - prompt: - "Build a workflow that when a candidate reaches the interview stage finds open slots across the panel's Google Calendars, creates the interview event with the video link, invites everyone, and emails the candidate the confirmation.", - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'scheduling', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleCalendarIcon, - title: 'Meeting-load weekly report', - prompt: - 'Create a scheduled weekly workflow that lists Google Calendar events for the team, computes total meeting hours and recurring-meeting load per person, writes the breakdown to a table, and flags anyone over the focus-time threshold.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['team', 'reporting', 'analysis'], - }, - { - icon: GoogleCalendarIcon, - title: 'Calendar event note-taker prep', - prompt: - 'Build a workflow that scans upcoming Google Calendar events for external meetings, researches each company and attendee, drafts talking points, and updates the event description so the notes travel with the invite.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'automation'], - }, - ], - skills: [ - { - name: 'schedule-meeting', - description: - 'Create a Google Calendar event with the right time, attendees, and details, sending invites.', - content: - '# Schedule a Meeting\n\nCreate a calendar event and invite attendees.\n\n## Steps\n1. Determine the calendar (default to `primary`), title, start and end times, location, and description from the request.\n2. Convert times to ISO 8601 with the correct timezone offset (e.g., `2025-06-03T10:00:00-08:00`).\n3. If the request is conversational (e.g., "lunch with John tomorrow at noon"), use Quick Add instead of building each field by hand.\n4. Run Create Event (or Quick Add) with the attendee emails as a comma-separated list.\n5. Set Send Email Notifications to `all` so attendees are invited.\n\n## Output\nConfirm the created event: title, start/end in a readable format, attendees, and the event link (htmlLink). If a conflict is likely, note it.', - }, - { - name: 'summarize-daily-agenda', - description: - "List today's Google Calendar events and produce a clean, ordered agenda summary.", - content: - '# Summarize the Daily Agenda\n\nProduce a readable agenda for a day or window.\n\n## Steps\n1. Resolve the target window into UTC ISO timestamps for Start Time Filter (timeMin) and End Time Filter (timeMax). For "today", use 00:00:00Z to 23:59:59Z.\n2. Run List Events on the chosen calendar with those filters and a reasonable Max Results.\n3. Sort events chronologically and read summary, start/end, location, and attendees for each.\n4. Flag back-to-back meetings and any event with no agenda or description.\n\n## Output\nA chronological agenda. Each line: time range, title, location (if any), and attendee count. Add a short header with total meetings and total meeting hours.', - }, - { - name: 'find-and-reschedule-event', - description: 'Locate an existing event and update its time, attendees, or details.', - content: - '# Find and Reschedule an Event\n\nUpdate an existing calendar event.\n\n## Steps\n1. If you do not have the event ID, run List Events over a suitable window and match by title/attendees to find the event ID.\n2. Run Get Event to read the current details and confirm it is the right one.\n3. Run Update Event with only the changed fields (new start/end in ISO 8601 with offset, new attendees, new location, or title).\n4. Set Send Email Notifications to `all` so attendees see the change.\n\n## Output\nConfirm what changed (old vs new time/attendees) and return the event link. If multiple events matched, list them and ask which to update before changing anything destructive.', - }, - { - name: 'invite-attendees-to-event', - description: 'Add attendees to an existing Google Calendar event and notify them.', - content: - '# Invite Attendees to an Event\n\nAdd people to an event without recreating it.\n\n## Steps\n1. Obtain the event ID (use List Events to find it if needed).\n2. Collect the attendee emails to add as a comma-separated list.\n3. Run Invite Attendees with Replace Existing set to `Add to existing attendees` (unless asked to replace the whole list).\n4. Set Send Email Notifications to `all`.\n\n## Output\nConfirm the added attendees and the resulting full attendee list, with the event link.', - }, - ], -} as const satisfies BlockMeta - -export const GoogleCalendarV2BlockMeta = { - tags: ['calendar', 'scheduling', 'google-workspace'], - url: 'https://workspace.google.com/products/calendar', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_contacts.display.ts b/apps/sim/blocks/blocks/google_contacts.display.ts index a60490973c8..73a6b14491e 100644 --- a/apps/sim/blocks/blocks/google_contacts.display.ts +++ b/apps/sim/blocks/blocks/google_contacts.display.ts @@ -1,6 +1,6 @@ import { GoogleContactsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleContactsBlockDisplay = { type: 'google_contacts', @@ -14,3 +14,101 @@ export const GoogleContactsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_contacts', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const GoogleContactsBlockMeta = { + tags: ['google-workspace', 'customer-support', 'enrichment'], + url: 'https://contacts.google.com', + templates: [ + { + icon: GoogleContactsIcon, + title: 'Google Contacts CRM sync', + prompt: + 'Build a scheduled workflow that mirrors Google Contacts into HubSpot, adding new contacts and updating fields, and writing a sync log for hygiene tracking.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'sync'], + alsoIntegrations: ['hubspot'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts duplicate cleaner', + prompt: + 'Create a scheduled workflow that scans Google Contacts for duplicates, merges them deterministically, and writes a cleanup report for review.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts enricher', + prompt: + 'Build a scheduled workflow that scans Google Contacts for entries missing company or title, enriches each via Apollo, and writes the enriched contact back to Google Contacts.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts + Calendar grouper', + prompt: + 'Create a workflow that groups Google Contacts into labels based on meeting frequency in Google Calendar, so frequent collaborators are easy to find when composing emails.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts birthday reminder', + prompt: + 'Build a scheduled workflow that runs daily, surfaces upcoming birthdays from Google Contacts, and emails the user a reminder with personalized message suggestions.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts deal-mapper', + prompt: + 'Create a workflow that maps Google Contacts to active Salesforce opportunities by email domain, tagging contacts as deal-relevant for fast follow-ups.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleContactsIcon, + title: 'Google Contacts new-hire onboarder', + prompt: + 'Build a workflow that on a new hire in Workday adds the new employee to relevant Google Contacts groups based on department and team.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + ], + skills: [ + { + name: 'add-contact', + description: 'Create a new Google Contact with name, email, phone, and organization details.', + content: + '# Add a Contact\n\nCreate a new entry in Google Contacts.\n\n## Steps\n1. Gather the contact fields from the request: first name (required), last name, email, phone, organization, job title, and notes.\n2. Before creating, run Search Contacts on the email or full name to avoid duplicates.\n3. If no match exists, run Create Contact with the gathered fields and the appropriate email/phone types (work, home, mobile).\n4. Capture the new resource name from the response.\n\n## Output\nConfirm the created contact with name, email, organization, and the resource name. If a likely duplicate was found, surface it and ask before creating.', + }, + { + name: 'find-contact', + description: + 'Search Google Contacts by name, email, phone, or organization and return matches.', + content: + '# Find a Contact\n\nLook up someone in Google Contacts.\n\n## Steps\n1. Build a query from whatever identifier you have (name, email, phone, or organization).\n2. Run Search Contacts with that query and a sensible Page Size.\n3. If you need full details for one match, take its resource name and run Get Contact.\n\n## Output\nA list of matching contacts with name, email, phone, organization, and resource name. If exactly one matches, return its full record; if several match, list them so the requester can disambiguate.', + }, + { + name: 'update-contact-details', + description: + 'Update fields on an existing Google Contact such as email, phone, or job title.', + content: + '# Update Contact Details\n\nModify an existing Google Contact safely.\n\n## Steps\n1. If you do not have the resource name, run Search Contacts to find it.\n2. Run Get Contact to read the current values and capture the ETag (required for updates).\n3. Run Update Contact with the resource name, the ETag, and the changed fields only.\n4. If the update fails on a stale ETag, re-run Get Contact and retry with the fresh ETag.\n\n## Output\nConfirm which fields changed (old vs new) and return the updated record. Never update without first fetching the current ETag.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_contacts.ts b/apps/sim/blocks/blocks/google_contacts.ts index d4cf59de5e3..76f3501e904 100644 --- a/apps/sim/blocks/blocks/google_contacts.ts +++ b/apps/sim/blocks/blocks/google_contacts.ts @@ -1,7 +1,6 @@ -import { GoogleContactsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleContactsBlockDisplay } from '@/blocks/blocks/google_contacts.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleContactsResponse } from '@/tools/google_contacts/types' @@ -265,101 +264,3 @@ export const GoogleContactsBlock: BlockConfig = { metadata: { type: 'json', description: 'Contact or contacts metadata' }, }, } - -export const GoogleContactsBlockMeta = { - tags: ['google-workspace', 'customer-support', 'enrichment'], - url: 'https://contacts.google.com', - templates: [ - { - icon: GoogleContactsIcon, - title: 'Google Contacts CRM sync', - prompt: - 'Build a scheduled workflow that mirrors Google Contacts into HubSpot, adding new contacts and updating fields, and writing a sync log for hygiene tracking.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'sync'], - alsoIntegrations: ['hubspot'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts duplicate cleaner', - prompt: - 'Create a scheduled workflow that scans Google Contacts for duplicates, merges them deterministically, and writes a cleanup report for review.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts enricher', - prompt: - 'Build a scheduled workflow that scans Google Contacts for entries missing company or title, enriches each via Apollo, and writes the enriched contact back to Google Contacts.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts + Calendar grouper', - prompt: - 'Create a workflow that groups Google Contacts into labels based on meeting frequency in Google Calendar, so frequent collaborators are easy to find when composing emails.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts birthday reminder', - prompt: - 'Build a scheduled workflow that runs daily, surfaces upcoming birthdays from Google Contacts, and emails the user a reminder with personalized message suggestions.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts deal-mapper', - prompt: - 'Create a workflow that maps Google Contacts to active Salesforce opportunities by email domain, tagging contacts as deal-relevant for fast follow-ups.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleContactsIcon, - title: 'Google Contacts new-hire onboarder', - prompt: - 'Build a workflow that on a new hire in Workday adds the new employee to relevant Google Contacts groups based on department and team.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - ], - skills: [ - { - name: 'add-contact', - description: 'Create a new Google Contact with name, email, phone, and organization details.', - content: - '# Add a Contact\n\nCreate a new entry in Google Contacts.\n\n## Steps\n1. Gather the contact fields from the request: first name (required), last name, email, phone, organization, job title, and notes.\n2. Before creating, run Search Contacts on the email or full name to avoid duplicates.\n3. If no match exists, run Create Contact with the gathered fields and the appropriate email/phone types (work, home, mobile).\n4. Capture the new resource name from the response.\n\n## Output\nConfirm the created contact with name, email, organization, and the resource name. If a likely duplicate was found, surface it and ask before creating.', - }, - { - name: 'find-contact', - description: - 'Search Google Contacts by name, email, phone, or organization and return matches.', - content: - '# Find a Contact\n\nLook up someone in Google Contacts.\n\n## Steps\n1. Build a query from whatever identifier you have (name, email, phone, or organization).\n2. Run Search Contacts with that query and a sensible Page Size.\n3. If you need full details for one match, take its resource name and run Get Contact.\n\n## Output\nA list of matching contacts with name, email, phone, organization, and resource name. If exactly one matches, return its full record; if several match, list them so the requester can disambiguate.', - }, - { - name: 'update-contact-details', - description: - 'Update fields on an existing Google Contact such as email, phone, or job title.', - content: - '# Update Contact Details\n\nModify an existing Google Contact safely.\n\n## Steps\n1. If you do not have the resource name, run Search Contacts to find it.\n2. Run Get Contact to read the current values and capture the ETag (required for updates).\n3. Run Update Contact with the resource name, the ETag, and the changed fields only.\n4. If the update fails on a stale ETag, re-run Get Contact and retry with the fresh ETag.\n\n## Output\nConfirm which fields changed (old vs new) and return the updated record. Never update without first fetching the current ETag.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_docs.display.ts b/apps/sim/blocks/blocks/google_docs.display.ts index 3364e957120..0d0d713564c 100644 --- a/apps/sim/blocks/blocks/google_docs.display.ts +++ b/apps/sim/blocks/blocks/google_docs.display.ts @@ -1,6 +1,6 @@ import { GoogleDocsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleDocsBlockDisplay = { type: 'google_docs', @@ -14,3 +14,99 @@ export const GoogleDocsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_docs', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const GoogleDocsBlockMeta = { + tags: ['google-workspace', 'document-processing', 'content-management'], + url: 'https://www.google.com/docs/about', + templates: [ + { + icon: GoogleDocsIcon, + title: 'Google Docs review request', + prompt: + 'Build a workflow that reads a Google Doc when its title is marked ready for review, summarizes the key points with an agent, and posts a review request with the doc link to the named reviewers in Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleDocsIcon, + title: 'Google Docs change digester', + prompt: + 'Create a scheduled weekly workflow that reads each tracked Google Doc, compares its content against the snapshot stored in a table, summarizes what changed with an agent, and posts a digest to the team in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleDocsIcon, + title: 'Google Docs translation copy', + prompt: + 'Build a workflow that takes a Google Docs document and creates translated copies into target languages with Google Translate, links them in the source, and notifies the localization team.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'enterprise'], + alsoIntegrations: ['google_translate'], + }, + { + icon: GoogleDocsIcon, + title: 'Meeting notes to Google Docs', + prompt: + 'Create a workflow that after a meeting pulls the transcript, summarizes decisions, action items, and owners with an agent, and creates a formatted Google Docs document in the shared team folder with a link posted to Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'meeting', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleDocsIcon, + title: 'Google Docs proposal generator', + prompt: + 'Build a workflow that on a closed-won deal reads the account details, creates a Google Docs document from the proposal template, fills in customer name, scope, and pricing, and shares the draft with the account owner for review.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'content', 'automation'], + }, + { + icon: GoogleDocsIcon, + title: 'Weekly report writer', + prompt: + 'Create a scheduled weekly workflow that reads metrics from my tables, writes a narrative status report with an agent, and appends the new section to a running Google Docs document so leadership has one living record.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis'], + }, + { + icon: GoogleDocsIcon, + title: 'Google Docs knowledge sync', + prompt: + 'Build a workflow that reads a set of Google Docs in a folder, extracts their content, and upserts it into a knowledge base so the team can ask questions and get answers grounded in the latest docs.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'research', 'sync'], + }, + ], + skills: [ + { + name: 'create-document-from-content', + description: 'Create a new Google Doc with a title and formatted content in a chosen folder.', + content: + '# Create a Document from Content\n\nGenerate a new Google Doc from supplied or drafted content.\n\n## Steps\n1. Determine the document title and the body content from the request.\n2. If the content uses headings, bold, lists, tables, or links, enable the Markdown option so it renders as formatted Doc content; otherwise leave it off for plain text.\n3. Optionally set the parent folder ID to file the doc in the right place.\n4. Run the Create Document operation with the title, content, and folder.\n\n## Output\nConfirm creation and return the document ID and link. If a folder was specified, confirm it was placed there.', + }, + { + name: 'summarize-document', + description: + 'Read a Google Doc and produce a concise summary with key points and action items.', + content: + '# Summarize a Document\n\nRead a Doc and distill it.\n\n## Steps\n1. Obtain the document ID (select the doc or pass its ID).\n2. Run the Read Document operation to pull the full text.\n3. Identify the main thesis, key points, decisions, and any action items or owners.\n4. Keep the summary faithful to the source; do not invent details not present.\n\n## Output\nA short summary: a one-line gist, 3-6 bullet key points, and an Action Items section (owner + task) if any exist. Reference the doc link.', + }, + { + name: 'append-to-document', + description: + 'Write additional content into an existing Google Doc, such as a running log or report section.', + content: + '# Append to a Document\n\nAdd a new section to an existing Doc.\n\n## Steps\n1. Obtain the target document ID.\n2. Draft the content to add, clearly delimited (e.g., a dated heading for a running log).\n3. Run the Write to Document operation with the document ID and the new content.\n4. For recurring updates, prefix each entry with a date or section header so the doc stays organized.\n\n## Output\nConfirm the content was written and return the document link. Summarize in one line what was appended.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_docs.ts b/apps/sim/blocks/blocks/google_docs.ts index 56047cf5531..d7cfaec6253 100644 --- a/apps/sim/blocks/blocks/google_docs.ts +++ b/apps/sim/blocks/blocks/google_docs.ts @@ -1,7 +1,6 @@ -import { GoogleDocsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleDocsBlockDisplay } from '@/blocks/blocks/google_docs.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleDocsResponse } from '@/tools/google_docs/types' @@ -204,99 +203,3 @@ Return ONLY the document content - no explanations, no extra text.`, updatedContent: { type: 'boolean', description: 'Content update status' }, }, } - -export const GoogleDocsBlockMeta = { - tags: ['google-workspace', 'document-processing', 'content-management'], - url: 'https://www.google.com/docs/about', - templates: [ - { - icon: GoogleDocsIcon, - title: 'Google Docs review request', - prompt: - 'Build a workflow that reads a Google Doc when its title is marked ready for review, summarizes the key points with an agent, and posts a review request with the doc link to the named reviewers in Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleDocsIcon, - title: 'Google Docs change digester', - prompt: - 'Create a scheduled weekly workflow that reads each tracked Google Doc, compares its content against the snapshot stored in a table, summarizes what changed with an agent, and posts a digest to the team in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleDocsIcon, - title: 'Google Docs translation copy', - prompt: - 'Build a workflow that takes a Google Docs document and creates translated copies into target languages with Google Translate, links them in the source, and notifies the localization team.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'enterprise'], - alsoIntegrations: ['google_translate'], - }, - { - icon: GoogleDocsIcon, - title: 'Meeting notes to Google Docs', - prompt: - 'Create a workflow that after a meeting pulls the transcript, summarizes decisions, action items, and owners with an agent, and creates a formatted Google Docs document in the shared team folder with a link posted to Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'meeting', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleDocsIcon, - title: 'Google Docs proposal generator', - prompt: - 'Build a workflow that on a closed-won deal reads the account details, creates a Google Docs document from the proposal template, fills in customer name, scope, and pricing, and shares the draft with the account owner for review.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'content', 'automation'], - }, - { - icon: GoogleDocsIcon, - title: 'Weekly report writer', - prompt: - 'Create a scheduled weekly workflow that reads metrics from my tables, writes a narrative status report with an agent, and appends the new section to a running Google Docs document so leadership has one living record.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis'], - }, - { - icon: GoogleDocsIcon, - title: 'Google Docs knowledge sync', - prompt: - 'Build a workflow that reads a set of Google Docs in a folder, extracts their content, and upserts it into a knowledge base so the team can ask questions and get answers grounded in the latest docs.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'research', 'sync'], - }, - ], - skills: [ - { - name: 'create-document-from-content', - description: 'Create a new Google Doc with a title and formatted content in a chosen folder.', - content: - '# Create a Document from Content\n\nGenerate a new Google Doc from supplied or drafted content.\n\n## Steps\n1. Determine the document title and the body content from the request.\n2. If the content uses headings, bold, lists, tables, or links, enable the Markdown option so it renders as formatted Doc content; otherwise leave it off for plain text.\n3. Optionally set the parent folder ID to file the doc in the right place.\n4. Run the Create Document operation with the title, content, and folder.\n\n## Output\nConfirm creation and return the document ID and link. If a folder was specified, confirm it was placed there.', - }, - { - name: 'summarize-document', - description: - 'Read a Google Doc and produce a concise summary with key points and action items.', - content: - '# Summarize a Document\n\nRead a Doc and distill it.\n\n## Steps\n1. Obtain the document ID (select the doc or pass its ID).\n2. Run the Read Document operation to pull the full text.\n3. Identify the main thesis, key points, decisions, and any action items or owners.\n4. Keep the summary faithful to the source; do not invent details not present.\n\n## Output\nA short summary: a one-line gist, 3-6 bullet key points, and an Action Items section (owner + task) if any exist. Reference the doc link.', - }, - { - name: 'append-to-document', - description: - 'Write additional content into an existing Google Doc, such as a running log or report section.', - content: - '# Append to a Document\n\nAdd a new section to an existing Doc.\n\n## Steps\n1. Obtain the target document ID.\n2. Draft the content to add, clearly delimited (e.g., a dated heading for a running log).\n3. Run the Write to Document operation with the document ID and the new content.\n4. For recurring updates, prefix each entry with a date or section header so the doc stays organized.\n\n## Output\nConfirm the content was written and return the document link. Summarize in one line what was appended.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_drive.display.ts b/apps/sim/blocks/blocks/google_drive.display.ts index 7d7b55dc230..5c039f0e797 100644 --- a/apps/sim/blocks/blocks/google_drive.display.ts +++ b/apps/sim/blocks/blocks/google_drive.display.ts @@ -1,6 +1,7 @@ +import { BookOpen } from '@/components/emcn/icons' import { GoogleDriveIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleDriveBlockDisplay = { type: 'google_drive', @@ -14,3 +15,107 @@ export const GoogleDriveBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_drive', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const GoogleDriveBlockMeta = { + tags: ['cloud', 'google-workspace', 'document-processing'], + url: 'https://workspace.google.com/products/drive', + templates: [ + { + icon: BookOpen, + title: 'Personal knowledge assistant', + prompt: + 'Create a knowledge base and connect it to my Google Drive, Notion, or Obsidian so all my notes, docs, and articles are automatically synced and embedded. Then build an agent that I can ask anything — it should answer with citations and deploy as a chat endpoint.', + modules: ['knowledge-base', 'agent'], + category: 'productivity', + tags: ['individual', 'research', 'team'], + alsoIntegrations: ['notion', 'obsidian'], + }, + { + icon: GoogleDriveIcon, + title: 'Google Drive knowledge search', + prompt: + 'Create a knowledge base connected to my Google Drive so all documents, spreadsheets, and presentations are automatically synced and searchable. Then build an agent I can ask things like "find the board deck from last quarter" or "what were the KPIs in the marketing plan?" and get answers with doc links.', + modules: ['knowledge-base', 'agent'], + category: 'productivity', + tags: ['individual', 'team', 'research'], + }, + { + icon: GoogleDriveIcon, + title: 'Google Drive contract intake', + prompt: + 'Create a workflow that watches a Google Drive intake folder for new contract PDFs, extracts clauses with Reducto, writes structured terms to a table, and pings legal in Slack.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + alsoIntegrations: ['reducto', 'slack'], + }, + { + icon: GoogleDriveIcon, + title: 'Google Drive new-hire kit deployer', + prompt: + 'Build a workflow triggered by a new hire in Greenhouse that copies the standard Google Drive onboarding folder, shares it with the new hire, and writes the link into the onboarding tracker.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['greenhouse'], + }, + { + icon: GoogleDriveIcon, + title: 'Google Drive retention enforcer', + prompt: + 'Create a scheduled monthly workflow that finds Google Drive files past the retention horizon, requires owner approval over Slack, and archives or deletes per the policy.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleDriveIcon, + title: 'Drive intake auto-filer', + prompt: + "Build a workflow that watches a Google Drive intake folder for new uploads, reads each file's content to classify it by type and customer, creates the right destination folder, and moves the file there with a renamed, consistent filename.", + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'document-processing'], + }, + { + icon: BookOpen, + title: 'Drive document Q&A assistant', + prompt: + 'Create a knowledge base synced from a Google Drive folder, then build an agent that searches the synced documents to answer team questions and replies with the answer plus a link to the source file in Drive.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'research', 'sync'], + }, + ], + skills: [ + { + name: 'find-file-in-drive', + description: + 'Search Google Drive with query syntax to locate files by name, type, content, or date.', + content: + "# Find a File in Drive\n\nLocate files using Drive query syntax.\n\n## Steps\n1. Translate the request into a Drive query. Common clauses: `name contains 'term'`, `fullText contains 'term'`, `mimeType = 'application/pdf'`, `modifiedTime > '2024-01-01T00:00:00'`, `'email' in owners`, `trashed = false`.\n2. Run the Search Files operation with that query and a Results Per Page value.\n3. If results are too broad, add `and` clauses (file type, owner, date) to narrow.\n4. For a chosen result, run Get File Info for full metadata.\n\n## Output\nA list of matching files: name, type, owner, modified date, and the file ID. Highlight the single best match if the intent was specific.", + }, + { + name: 'organize-files-into-folders', + description: + 'Create folders and move or copy files in Google Drive to keep storage organized.', + content: + '# Organize Files into Folders\n\nFile and tidy Drive content.\n\n## Steps\n1. Identify the target structure: which folder should exist and what goes in it.\n2. If the destination folder does not exist, run Create Folder (set its parent if needed) and capture the new folder ID.\n3. For each file to relocate, run Move File with the destination folder ID. Use Copy File instead when the original must stay in place.\n4. Optionally run Update File to rename files to a consistent convention.\n\n## Output\nA summary of what was created and moved: destination folder link, count of files relocated, and any renames applied.', + }, + { + name: 'share-file-with-people', + description: + 'Grant access to a Google Drive file for users, groups, a domain, or anyone with the link.', + content: + '# Share a File\n\nGrant access to a Drive file with the right permission level.\n\n## Steps\n1. Obtain the file ID (select it or run Search Files).\n2. Decide the share target: a specific user/group email, an entire domain, or anyone with the link.\n3. Choose the permission level: Viewer (reader), Commenter, or Editor (writer).\n4. Run the Share File operation with the target and role. For user/group shares, optionally include a notification message.\n\n## Output\nConfirm who now has access and at what level, plus the file link. Avoid `anyone` unless explicitly requested.', + }, + { + name: 'read-file-content', + description: + 'Extract the text content of a Google Drive file, exporting Workspace files to a usable format.', + content: + '# Read File Content\n\nPull the text out of a Drive file for downstream use.\n\n## Steps\n1. Obtain the file ID.\n2. Run the Get File Content operation. For Google Docs/Sheets/Slides, set Export Format (Auto picks the best, or choose Plain Text / PDF / DOCX explicitly).\n3. For non-Workspace files (PDF, TXT), the content is returned directly.\n4. Use the returned text for summarization, extraction, or indexing.\n\n## Output\nReturn the extracted content (or a summary of it if large), noting the file name and the export format used.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_drive.ts b/apps/sim/blocks/blocks/google_drive.ts index 94ad7cc6c44..625195e5f1e 100644 --- a/apps/sim/blocks/blocks/google_drive.ts +++ b/apps/sim/blocks/blocks/google_drive.ts @@ -1,8 +1,6 @@ -import { BookOpen } from '@/components/emcn/icons' -import { GoogleDriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleDriveBlockDisplay } from '@/blocks/blocks/google_drive.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleDriveResponse } from '@/tools/google_drive/types' @@ -1201,107 +1199,3 @@ Return ONLY the query string - no explanations, no quotes around the whole thing available: ['google_drive_poller'], }, } - -export const GoogleDriveBlockMeta = { - tags: ['cloud', 'google-workspace', 'document-processing'], - url: 'https://workspace.google.com/products/drive', - templates: [ - { - icon: BookOpen, - title: 'Personal knowledge assistant', - prompt: - 'Create a knowledge base and connect it to my Google Drive, Notion, or Obsidian so all my notes, docs, and articles are automatically synced and embedded. Then build an agent that I can ask anything — it should answer with citations and deploy as a chat endpoint.', - modules: ['knowledge-base', 'agent'], - category: 'productivity', - tags: ['individual', 'research', 'team'], - alsoIntegrations: ['notion', 'obsidian'], - }, - { - icon: GoogleDriveIcon, - title: 'Google Drive knowledge search', - prompt: - 'Create a knowledge base connected to my Google Drive so all documents, spreadsheets, and presentations are automatically synced and searchable. Then build an agent I can ask things like "find the board deck from last quarter" or "what were the KPIs in the marketing plan?" and get answers with doc links.', - modules: ['knowledge-base', 'agent'], - category: 'productivity', - tags: ['individual', 'team', 'research'], - }, - { - icon: GoogleDriveIcon, - title: 'Google Drive contract intake', - prompt: - 'Create a workflow that watches a Google Drive intake folder for new contract PDFs, extracts clauses with Reducto, writes structured terms to a table, and pings legal in Slack.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - alsoIntegrations: ['reducto', 'slack'], - }, - { - icon: GoogleDriveIcon, - title: 'Google Drive new-hire kit deployer', - prompt: - 'Build a workflow triggered by a new hire in Greenhouse that copies the standard Google Drive onboarding folder, shares it with the new hire, and writes the link into the onboarding tracker.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['greenhouse'], - }, - { - icon: GoogleDriveIcon, - title: 'Google Drive retention enforcer', - prompt: - 'Create a scheduled monthly workflow that finds Google Drive files past the retention horizon, requires owner approval over Slack, and archives or deletes per the policy.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleDriveIcon, - title: 'Drive intake auto-filer', - prompt: - "Build a workflow that watches a Google Drive intake folder for new uploads, reads each file's content to classify it by type and customer, creates the right destination folder, and moves the file there with a renamed, consistent filename.", - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'document-processing'], - }, - { - icon: BookOpen, - title: 'Drive document Q&A assistant', - prompt: - 'Create a knowledge base synced from a Google Drive folder, then build an agent that searches the synced documents to answer team questions and replies with the answer plus a link to the source file in Drive.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'research', 'sync'], - }, - ], - skills: [ - { - name: 'find-file-in-drive', - description: - 'Search Google Drive with query syntax to locate files by name, type, content, or date.', - content: - "# Find a File in Drive\n\nLocate files using Drive query syntax.\n\n## Steps\n1. Translate the request into a Drive query. Common clauses: `name contains 'term'`, `fullText contains 'term'`, `mimeType = 'application/pdf'`, `modifiedTime > '2024-01-01T00:00:00'`, `'email' in owners`, `trashed = false`.\n2. Run the Search Files operation with that query and a Results Per Page value.\n3. If results are too broad, add `and` clauses (file type, owner, date) to narrow.\n4. For a chosen result, run Get File Info for full metadata.\n\n## Output\nA list of matching files: name, type, owner, modified date, and the file ID. Highlight the single best match if the intent was specific.", - }, - { - name: 'organize-files-into-folders', - description: - 'Create folders and move or copy files in Google Drive to keep storage organized.', - content: - '# Organize Files into Folders\n\nFile and tidy Drive content.\n\n## Steps\n1. Identify the target structure: which folder should exist and what goes in it.\n2. If the destination folder does not exist, run Create Folder (set its parent if needed) and capture the new folder ID.\n3. For each file to relocate, run Move File with the destination folder ID. Use Copy File instead when the original must stay in place.\n4. Optionally run Update File to rename files to a consistent convention.\n\n## Output\nA summary of what was created and moved: destination folder link, count of files relocated, and any renames applied.', - }, - { - name: 'share-file-with-people', - description: - 'Grant access to a Google Drive file for users, groups, a domain, or anyone with the link.', - content: - '# Share a File\n\nGrant access to a Drive file with the right permission level.\n\n## Steps\n1. Obtain the file ID (select it or run Search Files).\n2. Decide the share target: a specific user/group email, an entire domain, or anyone with the link.\n3. Choose the permission level: Viewer (reader), Commenter, or Editor (writer).\n4. Run the Share File operation with the target and role. For user/group shares, optionally include a notification message.\n\n## Output\nConfirm who now has access and at what level, plus the file link. Avoid `anyone` unless explicitly requested.', - }, - { - name: 'read-file-content', - description: - 'Extract the text content of a Google Drive file, exporting Workspace files to a usable format.', - content: - '# Read File Content\n\nPull the text out of a Drive file for downstream use.\n\n## Steps\n1. Obtain the file ID.\n2. Run the Get File Content operation. For Google Docs/Sheets/Slides, set Export Format (Auto picks the best, or choose Plain Text / PDF / DOCX explicitly).\n3. For non-Workspace files (PDF, TXT), the content is returned directly.\n4. Use the returned text for summarization, extraction, or indexing.\n\n## Output\nReturn the extracted content (or a summary of it if large), noting the file name and the export format used.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_forms.display.ts b/apps/sim/blocks/blocks/google_forms.display.ts index 7b58ada5910..4c81b9a30d5 100644 --- a/apps/sim/blocks/blocks/google_forms.display.ts +++ b/apps/sim/blocks/blocks/google_forms.display.ts @@ -1,6 +1,6 @@ import { GoogleFormsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleFormsBlockDisplay = { type: 'google_forms', @@ -14,3 +14,101 @@ export const GoogleFormsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_forms', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const GoogleFormsBlockMeta = { + tags: ['google-workspace', 'forms', 'data-analytics'], + url: 'https://workspace.google.com/products/forms', + templates: [ + { + icon: GoogleFormsIcon, + title: 'Google Forms to CRM', + prompt: + 'Build a workflow that watches Google Forms responses, enriches each submitter with company data, and pushes qualified leads into HubSpot with the right owner and source.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms support intake', + prompt: + 'Create a workflow that turns Google Forms support submissions into Zendesk tickets, prioritizes them with an agent, and posts the new ticket to the support Slack channel.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + alsoIntegrations: ['zendesk', 'slack'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms event RSVP tracker', + prompt: + 'Build a workflow that captures Google Forms event RSVPs into a table, sends confirmation emails, and provides a daily attendee dashboard to the organizer.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms survey analyzer', + prompt: + 'Create a workflow that processes Google Forms survey responses, classifies sentiment and themes with an agent, and writes a weekly insight digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms approvals router', + prompt: + 'Build a workflow that turns Google Forms approval requests into Slack messages with quick-action buttons, captures the decision, and emails the requester the outcome.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms PTO collector', + prompt: + 'Create a workflow that processes PTO requests from Google Forms, captures manager approval over Slack, and updates the HR table with approved time off.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleFormsIcon, + title: 'Google Forms quiz grader', + prompt: + 'Build a workflow that captures Google Forms quiz responses, scores each automatically with an agent, writes scores to a tables-based gradebook, and emails the student.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'analysis'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'collect-form-responses', + description: 'Retrieve and structure responses from a Google Form for analysis or routing.', + content: + '# Collect Form Responses\n\nPull submissions from a Google Form.\n\n## Steps\n1. Select the form (or pass its form ID).\n2. Run the Get Responses operation; set Page Size to cover the expected volume. Leave Response ID empty to fetch all, or set it to fetch one specific submission.\n3. To map answers to questions, run Get Form once and use the item titles to label each answer.\n4. Normalize each response into clean rows keyed by question.\n\n## Output\nA structured list of responses with respondent answers labeled by question. Include the total count and the time range covered.', + }, + { + name: 'analyze-survey-results', + description: + 'Read Google Form responses and summarize trends, sentiment, and notable findings.', + content: + '# Analyze Survey Results\n\nTurn raw form responses into insight.\n\n## Steps\n1. Run Get Form to learn the questions and their types (choice, scale, text).\n2. Run Get Responses to pull all submissions.\n3. For choice/scale questions, compute distributions and averages. For free-text, cluster into themes and gauge sentiment.\n4. Surface the strongest signals and any outliers or recurring complaints.\n\n## Output\nA digest: response count, per-question breakdown (top choices, averages), 3-5 key themes from free text, and notable verbatim quotes. Keep numbers accurate to the data.', + }, + { + name: 'create-form', + description: 'Create a new Google Form and add questions via batch update.', + content: + '# Create a Form\n\nBuild a new Google Form with questions.\n\n## Steps\n1. Run Create Form with the form title (and optional document title). Capture the returned form ID.\n2. Build a Batch Update requests array to add questions. Use `createItem` with `choiceQuestion` (RADIO/CHECKBOX/DROP_DOWN), `textQuestion`, or `scaleQuestion`, each at a `location.index`.\n3. Run Batch Update on the form ID with that requests array.\n4. If the form should accept submissions, run Set Publish Settings with Published on.\n\n## Output\nConfirm the form was created, list the questions added, and return the responder URL and form ID.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_forms.ts b/apps/sim/blocks/blocks/google_forms.ts index 2db6f65cea6..2b075e54f15 100644 --- a/apps/sim/blocks/blocks/google_forms.ts +++ b/apps/sim/blocks/blocks/google_forms.ts @@ -1,7 +1,6 @@ -import { GoogleFormsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleFormsBlockDisplay } from '@/blocks/blocks/google_forms.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import { getTrigger } from '@/triggers' @@ -497,101 +496,3 @@ Example for "Add a required multiple choice question about favorite color": available: ['google_forms_webhook'], }, } - -export const GoogleFormsBlockMeta = { - tags: ['google-workspace', 'forms', 'data-analytics'], - url: 'https://workspace.google.com/products/forms', - templates: [ - { - icon: GoogleFormsIcon, - title: 'Google Forms to CRM', - prompt: - 'Build a workflow that watches Google Forms responses, enriches each submitter with company data, and pushes qualified leads into HubSpot with the right owner and source.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms support intake', - prompt: - 'Create a workflow that turns Google Forms support submissions into Zendesk tickets, prioritizes them with an agent, and posts the new ticket to the support Slack channel.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - alsoIntegrations: ['zendesk', 'slack'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms event RSVP tracker', - prompt: - 'Build a workflow that captures Google Forms event RSVPs into a table, sends confirmation emails, and provides a daily attendee dashboard to the organizer.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms survey analyzer', - prompt: - 'Create a workflow that processes Google Forms survey responses, classifies sentiment and themes with an agent, and writes a weekly insight digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms approvals router', - prompt: - 'Build a workflow that turns Google Forms approval requests into Slack messages with quick-action buttons, captures the decision, and emails the requester the outcome.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms PTO collector', - prompt: - 'Create a workflow that processes PTO requests from Google Forms, captures manager approval over Slack, and updates the HR table with approved time off.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleFormsIcon, - title: 'Google Forms quiz grader', - prompt: - 'Build a workflow that captures Google Forms quiz responses, scores each automatically with an agent, writes scores to a tables-based gradebook, and emails the student.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'analysis'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'collect-form-responses', - description: 'Retrieve and structure responses from a Google Form for analysis or routing.', - content: - '# Collect Form Responses\n\nPull submissions from a Google Form.\n\n## Steps\n1. Select the form (or pass its form ID).\n2. Run the Get Responses operation; set Page Size to cover the expected volume. Leave Response ID empty to fetch all, or set it to fetch one specific submission.\n3. To map answers to questions, run Get Form once and use the item titles to label each answer.\n4. Normalize each response into clean rows keyed by question.\n\n## Output\nA structured list of responses with respondent answers labeled by question. Include the total count and the time range covered.', - }, - { - name: 'analyze-survey-results', - description: - 'Read Google Form responses and summarize trends, sentiment, and notable findings.', - content: - '# Analyze Survey Results\n\nTurn raw form responses into insight.\n\n## Steps\n1. Run Get Form to learn the questions and their types (choice, scale, text).\n2. Run Get Responses to pull all submissions.\n3. For choice/scale questions, compute distributions and averages. For free-text, cluster into themes and gauge sentiment.\n4. Surface the strongest signals and any outliers or recurring complaints.\n\n## Output\nA digest: response count, per-question breakdown (top choices, averages), 3-5 key themes from free text, and notable verbatim quotes. Keep numbers accurate to the data.', - }, - { - name: 'create-form', - description: 'Create a new Google Form and add questions via batch update.', - content: - '# Create a Form\n\nBuild a new Google Form with questions.\n\n## Steps\n1. Run Create Form with the form title (and optional document title). Capture the returned form ID.\n2. Build a Batch Update requests array to add questions. Use `createItem` with `choiceQuestion` (RADIO/CHECKBOX/DROP_DOWN), `textQuestion`, or `scaleQuestion`, each at a `location.index`.\n3. Run Batch Update on the form ID with that requests array.\n4. If the form should accept submissions, run Set Publish Settings with Published on.\n\n## Output\nConfirm the form was created, list the questions added, and return the responder URL and form ID.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_groups.display.ts b/apps/sim/blocks/blocks/google_groups.display.ts index ff008ee86bc..7f814f30c64 100644 --- a/apps/sim/blocks/blocks/google_groups.display.ts +++ b/apps/sim/blocks/blocks/google_groups.display.ts @@ -1,6 +1,6 @@ import { GoogleGroupsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleGroupsBlockDisplay = { type: 'google_groups', @@ -14,3 +14,107 @@ export const GoogleGroupsBlockDisplay = { docsLink: 'https://developers.google.com/admin-sdk/directory/v1/guides/manage-groups', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const GoogleGroupsBlockMeta = { + tags: ['google-workspace', 'messaging', 'identity'], + url: 'https://groups.google.com', + templates: [ + { + icon: GoogleGroupsIcon, + title: 'Google Groups onboarding sync', + prompt: + 'Create a workflow that watches Rippling or Greenhouse for new hires, adds them to the right Google Groups based on team and department, and emails the new hire a list of the groups joined.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['rippling', 'greenhouse'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups quarterly access review', + prompt: + 'Build a scheduled workflow that runs each quarter, lists every Google Group with members and owners, writes the report to a table for compliance review, and pings owners to confirm membership in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups departure cleanup', + prompt: + 'Create a workflow that watches Workday or Rippling for terminations and removes the departing user from every Google Group they belonged to, writing the change to a security audit log.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday', 'rippling'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups self-serve requester', + prompt: + 'Build a workflow that accepts a Google Group access request via a form, gets manager approval over Slack, adds the user to the group, and notifies the requester when access is granted.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups distribution-list audit', + prompt: + 'Create a scheduled workflow that scans Google Groups marked as distribution lists, flags external members against an allowlist, and posts a Slack report to the security team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups empty-group cleanup', + prompt: + 'Build a scheduled workflow that lists Google Groups with no members, opens a confirmation thread with the owner in Slack, and deletes the group once approved.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleGroupsIcon, + title: 'Google Groups settings hardening', + prompt: + 'Create a scheduled workflow that reads the settings for every Google Group, flags groups that allow external posting or open membership against policy, and posts the findings to the security team in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'add-member-to-group', + description: + 'Add a user to a Google Workspace group with a chosen role and confirm membership.', + content: + '# Add a Member to a Group\n\nGrant someone membership in a Workspace group.\n\n## Steps\n1. Identify the group email or ID and the member email.\n2. Run Check Membership first to see if the user is already a member; skip the add if so.\n3. Run Add Member with the member email and the desired role (MEMBER, MANAGER, or OWNER; default MEMBER).\n4. Optionally run Check Membership again to confirm the add succeeded.\n\n## Output\nConfirm the user was added (or already present), the role granted, and the group. Note if the operation requires admin privileges that were missing.', + }, + { + name: 'audit-group-membership', + description: 'List the members and roles of a Google Group for access review or compliance.', + content: + '# Audit Group Membership\n\nProduce a membership roster for a group.\n\n## Steps\n1. Identify the group email or ID.\n2. Run List Members with a Max Results value; optionally filter by roles (OWNER, MANAGER, MEMBER).\n3. Page through results using the next page token until all members are collected.\n4. Separate owners/managers from regular members and flag any external-domain addresses.\n\n## Output\nA roster grouped by role: owners, managers, members. Include total counts and a list of any external members for review.', + }, + { + name: 'create-group', + description: 'Create a new Google Workspace group with an email, name, and description.', + content: + '# Create a Group\n\nStand up a new Workspace group.\n\n## Steps\n1. Decide the group email address, display name, and a clear description of its purpose.\n2. Run List Groups (filter by the intended email/name) to confirm it does not already exist.\n3. Run Create Group with the email, name, and description.\n4. Optionally run Add Member to seed initial owners/managers.\n\n## Output\nConfirm the created group with its email, name, and description. List any initial members added. Note that this requires Workspace admin access.', + }, + { + name: 'remove-member-from-group', + description: 'Remove a user from a Google Group, useful for offboarding and access cleanup.', + content: + "# Remove a Member from a Group\n\nRevoke a user's group membership.\n\n## Steps\n1. Identify the group email/ID and the member email or ID.\n2. Run Check Membership to confirm the user is actually a member.\n3. If present, run Remove Member with the group and member keys.\n4. For offboarding across many groups, run List Groups filtered by `memberKey:` first to find every group the user belongs to, then remove from each.\n\n## Output\nConfirm the removal per group, and for offboarding list every group the user was removed from. Note any failures for manual follow-up.", + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_groups.ts b/apps/sim/blocks/blocks/google_groups.ts index e6bbae31882..d0f7edddb01 100644 --- a/apps/sim/blocks/blocks/google_groups.ts +++ b/apps/sim/blocks/blocks/google_groups.ts @@ -1,7 +1,6 @@ -import { GoogleGroupsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleGroupsBlockDisplay } from '@/blocks/blocks/google_groups.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' @@ -447,107 +446,3 @@ Return ONLY the description text - no explanations, no quotes, no extra text.`, deleted: { type: 'boolean', description: 'Deletion result (for remove_alias)' }, }, } - -export const GoogleGroupsBlockMeta = { - tags: ['google-workspace', 'messaging', 'identity'], - url: 'https://groups.google.com', - templates: [ - { - icon: GoogleGroupsIcon, - title: 'Google Groups onboarding sync', - prompt: - 'Create a workflow that watches Rippling or Greenhouse for new hires, adds them to the right Google Groups based on team and department, and emails the new hire a list of the groups joined.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['rippling', 'greenhouse'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups quarterly access review', - prompt: - 'Build a scheduled workflow that runs each quarter, lists every Google Group with members and owners, writes the report to a table for compliance review, and pings owners to confirm membership in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups departure cleanup', - prompt: - 'Create a workflow that watches Workday or Rippling for terminations and removes the departing user from every Google Group they belonged to, writing the change to a security audit log.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday', 'rippling'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups self-serve requester', - prompt: - 'Build a workflow that accepts a Google Group access request via a form, gets manager approval over Slack, adds the user to the group, and notifies the requester when access is granted.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups distribution-list audit', - prompt: - 'Create a scheduled workflow that scans Google Groups marked as distribution lists, flags external members against an allowlist, and posts a Slack report to the security team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups empty-group cleanup', - prompt: - 'Build a scheduled workflow that lists Google Groups with no members, opens a confirmation thread with the owner in Slack, and deletes the group once approved.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleGroupsIcon, - title: 'Google Groups settings hardening', - prompt: - 'Create a scheduled workflow that reads the settings for every Google Group, flags groups that allow external posting or open membership against policy, and posts the findings to the security team in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'add-member-to-group', - description: - 'Add a user to a Google Workspace group with a chosen role and confirm membership.', - content: - '# Add a Member to a Group\n\nGrant someone membership in a Workspace group.\n\n## Steps\n1. Identify the group email or ID and the member email.\n2. Run Check Membership first to see if the user is already a member; skip the add if so.\n3. Run Add Member with the member email and the desired role (MEMBER, MANAGER, or OWNER; default MEMBER).\n4. Optionally run Check Membership again to confirm the add succeeded.\n\n## Output\nConfirm the user was added (or already present), the role granted, and the group. Note if the operation requires admin privileges that were missing.', - }, - { - name: 'audit-group-membership', - description: 'List the members and roles of a Google Group for access review or compliance.', - content: - '# Audit Group Membership\n\nProduce a membership roster for a group.\n\n## Steps\n1. Identify the group email or ID.\n2. Run List Members with a Max Results value; optionally filter by roles (OWNER, MANAGER, MEMBER).\n3. Page through results using the next page token until all members are collected.\n4. Separate owners/managers from regular members and flag any external-domain addresses.\n\n## Output\nA roster grouped by role: owners, managers, members. Include total counts and a list of any external members for review.', - }, - { - name: 'create-group', - description: 'Create a new Google Workspace group with an email, name, and description.', - content: - '# Create a Group\n\nStand up a new Workspace group.\n\n## Steps\n1. Decide the group email address, display name, and a clear description of its purpose.\n2. Run List Groups (filter by the intended email/name) to confirm it does not already exist.\n3. Run Create Group with the email, name, and description.\n4. Optionally run Add Member to seed initial owners/managers.\n\n## Output\nConfirm the created group with its email, name, and description. List any initial members added. Note that this requires Workspace admin access.', - }, - { - name: 'remove-member-from-group', - description: 'Remove a user from a Google Group, useful for offboarding and access cleanup.', - content: - "# Remove a Member from a Group\n\nRevoke a user's group membership.\n\n## Steps\n1. Identify the group email/ID and the member email or ID.\n2. Run Check Membership to confirm the user is actually a member.\n3. If present, run Remove Member with the group and member keys.\n4. For offboarding across many groups, run List Groups filtered by `memberKey:` first to find every group the user belongs to, then remove from each.\n\n## Output\nConfirm the removal per group, and for offboarding list every group the user was removed from. Note any failures for manual follow-up.", - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_maps.display.ts b/apps/sim/blocks/blocks/google_maps.display.ts index 22382347632..f3adbf12e6d 100644 --- a/apps/sim/blocks/blocks/google_maps.display.ts +++ b/apps/sim/blocks/blocks/google_maps.display.ts @@ -1,6 +1,6 @@ import { GoogleMapsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleMapsBlockDisplay = { type: 'google_maps', @@ -14,3 +14,107 @@ export const GoogleMapsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_maps', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const GoogleMapsBlockMeta = { + tags: ['google-workspace', 'enrichment'], + url: 'https://mapsplatform.google.com', + templates: [ + { + icon: GoogleMapsIcon, + title: 'Google Maps competitor location finder', + prompt: + 'Build a workflow that uses Google Maps to find competitor locations in a target city, writes coordinates and details to a table, and emails the sales team a route map.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps territory builder', + prompt: + 'Create a workflow that takes a list of CRM accounts, geocodes them via Google Maps, clusters into territories, and writes the assignment to a tables-based territory plan.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps event-attendee proximity', + prompt: + 'Build a workflow that for a Luma event sorts registrants by proximity to the venue via Google Maps, writes the list, and offers a quick-action transport option.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['luma'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps logistics planner', + prompt: + 'Create a workflow that takes a delivery list, optimizes the route via Google Maps directions, and writes a per-driver itinerary to a tables-based dispatcher view.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'automation'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps store-locator updater', + prompt: + 'Build a scheduled workflow that audits store locations on the website against Google Maps Places data, flags out-of-date hours or addresses, and pings the team to correct.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps review tracker', + prompt: + 'Create a scheduled workflow that watches Google Maps reviews of brand locations daily, classifies sentiment, and pings the right manager in Slack on new negative reviews.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleMapsIcon, + title: 'Google Maps lead-by-region exporter', + prompt: + 'Build a workflow that uses Google Maps to find businesses matching an ICP in a region, enriches via Hunter, and writes the prospect list to HubSpot.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['hunter', 'hubspot'], + }, + ], + skills: [ + { + name: 'geocode-address', + description: + 'Convert an address into latitude/longitude coordinates with a normalized formatted address.', + content: + '# Geocode an Address\n\nTurn a street address into coordinates.\n\n## Steps\n1. Take the address string from the request.\n2. Run the Geocode Address operation; optionally set a Region Bias (country code) to disambiguate.\n3. Read the returned lat, lng, formatted address, place ID, and location type.\n4. If multiple candidates are likely, note the accuracy/location type so the requester can confirm.\n\n## Output\nReturn the formatted address, latitude, longitude, and place ID. To go the other way (coordinates to address), use Reverse Geocode instead.', + }, + { + name: 'get-directions', + description: + 'Compute a route between two locations with distance, duration, and turn-by-turn steps.', + content: + '# Get Directions\n\nRoute between an origin and a destination.\n\n## Steps\n1. Capture origin and destination (addresses or `lat,lng`).\n2. Choose Travel Mode (driving, walking, bicycling, transit) and optionally features to Avoid (tolls, highways, ferries).\n3. Add Waypoints (pipe-separated) for intermediate stops if requested, and pick Units (metric/imperial).\n4. Run the Get Directions operation.\n\n## Output\nReturn total distance and duration (as text and numeric), start/end addresses, and a concise turn-by-turn step list. Mention the travel mode used.', + }, + { + name: 'find-nearby-places', + description: 'Search for places matching a query near a location and return ranked results.', + content: + '# Find Nearby Places\n\nDiscover places (restaurants, hotels, etc.) near a spot.\n\n## Steps\n1. Build the Search Query (e.g., "coffee near Times Square") and set a Location Bias (`lat,lng`) and Radius if known.\n2. Optionally constrain by Place Type (restaurant, hotel, gas_station, etc.).\n3. Run the Search Places operation.\n4. For a chosen result, run Place Details with its Place ID to get rating, hours, phone, and website.\n\n## Output\nA ranked list of places: name, address, rating and number of ratings, open-now status, and place ID. Include phone/website for the top pick when details were fetched.', + }, + { + name: 'calculate-travel-distances', + description: 'Compute distances and travel times from one origin to many destinations.', + content: + '# Calculate Travel Distances\n\nGet a distance matrix from an origin to multiple destinations.\n\n## Steps\n1. Set the Origin and provide Destinations as a pipe-separated list (e.g., "New York, NY|Boston, MA").\n2. Choose Travel Mode and Units; optionally set features to Avoid.\n3. Run the Distance Matrix operation.\n4. Read each row for distance and duration to each destination.\n\n## Output\nA table of destinations sorted by travel time or distance, each with distance text and duration text. Useful for picking the nearest option or planning routes.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_maps.ts b/apps/sim/blocks/blocks/google_maps.ts index f514b1c2938..253c0f6b17d 100644 --- a/apps/sim/blocks/blocks/google_maps.ts +++ b/apps/sim/blocks/blocks/google_maps.ts @@ -1,6 +1,5 @@ -import { GoogleMapsIcon } from '@/components/icons' import { GoogleMapsBlockDisplay } from '@/blocks/blocks/google_maps.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' export const GoogleMapsBlock: BlockConfig = { ...GoogleMapsBlockDisplay, @@ -695,107 +694,3 @@ export const GoogleMapsBlock: BlockConfig = { }, }, } - -export const GoogleMapsBlockMeta = { - tags: ['google-workspace', 'enrichment'], - url: 'https://mapsplatform.google.com', - templates: [ - { - icon: GoogleMapsIcon, - title: 'Google Maps competitor location finder', - prompt: - 'Build a workflow that uses Google Maps to find competitor locations in a target city, writes coordinates and details to a table, and emails the sales team a route map.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps territory builder', - prompt: - 'Create a workflow that takes a list of CRM accounts, geocodes them via Google Maps, clusters into territories, and writes the assignment to a tables-based territory plan.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps event-attendee proximity', - prompt: - 'Build a workflow that for a Luma event sorts registrants by proximity to the venue via Google Maps, writes the list, and offers a quick-action transport option.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['luma'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps logistics planner', - prompt: - 'Create a workflow that takes a delivery list, optimizes the route via Google Maps directions, and writes a per-driver itinerary to a tables-based dispatcher view.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'automation'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps store-locator updater', - prompt: - 'Build a scheduled workflow that audits store locations on the website against Google Maps Places data, flags out-of-date hours or addresses, and pings the team to correct.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps review tracker', - prompt: - 'Create a scheduled workflow that watches Google Maps reviews of brand locations daily, classifies sentiment, and pings the right manager in Slack on new negative reviews.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleMapsIcon, - title: 'Google Maps lead-by-region exporter', - prompt: - 'Build a workflow that uses Google Maps to find businesses matching an ICP in a region, enriches via Hunter, and writes the prospect list to HubSpot.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['hunter', 'hubspot'], - }, - ], - skills: [ - { - name: 'geocode-address', - description: - 'Convert an address into latitude/longitude coordinates with a normalized formatted address.', - content: - '# Geocode an Address\n\nTurn a street address into coordinates.\n\n## Steps\n1. Take the address string from the request.\n2. Run the Geocode Address operation; optionally set a Region Bias (country code) to disambiguate.\n3. Read the returned lat, lng, formatted address, place ID, and location type.\n4. If multiple candidates are likely, note the accuracy/location type so the requester can confirm.\n\n## Output\nReturn the formatted address, latitude, longitude, and place ID. To go the other way (coordinates to address), use Reverse Geocode instead.', - }, - { - name: 'get-directions', - description: - 'Compute a route between two locations with distance, duration, and turn-by-turn steps.', - content: - '# Get Directions\n\nRoute between an origin and a destination.\n\n## Steps\n1. Capture origin and destination (addresses or `lat,lng`).\n2. Choose Travel Mode (driving, walking, bicycling, transit) and optionally features to Avoid (tolls, highways, ferries).\n3. Add Waypoints (pipe-separated) for intermediate stops if requested, and pick Units (metric/imperial).\n4. Run the Get Directions operation.\n\n## Output\nReturn total distance and duration (as text and numeric), start/end addresses, and a concise turn-by-turn step list. Mention the travel mode used.', - }, - { - name: 'find-nearby-places', - description: 'Search for places matching a query near a location and return ranked results.', - content: - '# Find Nearby Places\n\nDiscover places (restaurants, hotels, etc.) near a spot.\n\n## Steps\n1. Build the Search Query (e.g., "coffee near Times Square") and set a Location Bias (`lat,lng`) and Radius if known.\n2. Optionally constrain by Place Type (restaurant, hotel, gas_station, etc.).\n3. Run the Search Places operation.\n4. For a chosen result, run Place Details with its Place ID to get rating, hours, phone, and website.\n\n## Output\nA ranked list of places: name, address, rating and number of ratings, open-now status, and place ID. Include phone/website for the top pick when details were fetched.', - }, - { - name: 'calculate-travel-distances', - description: 'Compute distances and travel times from one origin to many destinations.', - content: - '# Calculate Travel Distances\n\nGet a distance matrix from an origin to multiple destinations.\n\n## Steps\n1. Set the Origin and provide Destinations as a pipe-separated list (e.g., "New York, NY|Boston, MA").\n2. Choose Travel Mode and Units; optionally set features to Avoid.\n3. Run the Distance Matrix operation.\n4. Read each row for distance and duration to each destination.\n\n## Output\nA table of destinations sorted by travel time or distance, each with distance text and duration text. Useful for picking the nearest option or planning routes.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_meet.display.ts b/apps/sim/blocks/blocks/google_meet.display.ts index 5805bd853e0..a96ebc14c28 100644 --- a/apps/sim/blocks/blocks/google_meet.display.ts +++ b/apps/sim/blocks/blocks/google_meet.display.ts @@ -1,6 +1,6 @@ import { GoogleMeetIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleMeetBlockDisplay = { type: 'google_meet', @@ -14,3 +14,99 @@ export const GoogleMeetBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_meet', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const GoogleMeetBlockMeta = { + tags: ['meeting', 'google-workspace', 'scheduling'], + url: 'https://workspace.google.com/products/meet', + templates: [ + { + icon: GoogleMeetIcon, + title: 'Google Meet conference recap to Drive', + prompt: + 'Build a workflow that pulls the conference record and participant list for a finished Google Meet, generates a structured attendance and follow-up recap with an agent, and saves the document to a per-team folder in Google Drive.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['team', 'content'], + alsoIntegrations: ['google_drive'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet daily meeting links', + prompt: + "Create a scheduled workflow that reads the day's meetings from a table each morning, creates a Google Meet space for each one, and emails attendees the agenda and join link via Gmail.", + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet conference record archiver', + prompt: + 'Build a scheduled workflow that lists Google Meet conference records, captures attendance and duration per meeting, and writes the history to a source-of-truth meetings table for reporting.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet auto-invite from CRM', + prompt: + 'Create a workflow that watches Salesforce for new meetings logged on opportunities, creates a matching Google Meet event, invites the right attendees, and writes the meeting link back to the opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet daily standup link', + prompt: + 'Build a scheduled workflow that posts the day’s Google Meet standup link to the team Slack channel five minutes before standup, with the rolling agenda from the standup table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet customer interview logger', + prompt: + 'Create a workflow that takes a customer-interview note or transcript, pulls the matching Google Meet conference record and participants for context, extracts themes, quotes, and feature requests with an agent, and writes structured rows to a research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'product'], + }, + { + icon: GoogleMeetIcon, + title: 'Google Meet retro publisher', + prompt: + 'Build a workflow that runs after a sprint-retro Google Meet, summarizes what went well, what to improve, and action items, and posts the retro to a Notion page tagged with the sprint number.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['team', 'reporting'], + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'create-meeting-space', + description: 'Create a Google Meet space and return its join link and meeting code.', + content: + '# Create a Meeting Space\n\nSpin up a Google Meet space to share.\n\n## Steps\n1. Decide the Access Type: Open (anyone with link), Trusted (organization members), or Restricted (invited only).\n2. Optionally set Entry Point Access if the space should only be joinable from the creating app.\n3. Run the Create Space operation.\n4. Capture the meeting URI and meeting code from the response.\n\n## Output\nReturn the meeting link (meetingUri), the meeting code, the access type, and the space resource name so it can be referenced or shared.', + }, + { + name: 'summarize-meeting-attendance', + description: + 'Pull a Google Meet conference record and its participants to report who attended.', + content: + '# Summarize Meeting Attendance\n\nReport attendance for a finished meeting.\n\n## Steps\n1. If you only have the space, run List Conference Records (filter by `space.name = "spaces/..."`) to find the conference record name.\n2. Run Get Conference Record to read start time, end time, and duration.\n3. Run List Participants on that conference record name, paging through results.\n4. Build the attendee list and compute meeting duration.\n\n## Output\nAn attendance summary: meeting start/end and duration, total participant count, and the list of participants. Flag the meeting if no participants are recorded.', + }, + { + name: 'list-recent-conferences', + description: 'List recent Google Meet conference records for reporting or archival.', + content: + '# List Recent Conferences\n\nEnumerate past Meet conferences.\n\n## Steps\n1. Run List Conference Records with a Page Size; optionally apply a Filter (e.g., by space name or time).\n2. Page through using the next page token until you have the needed window.\n3. For each record capture the conference record name, associated space, start time, and end time.\n4. Optionally fetch participants per record (List Participants) when attendance is needed.\n\n## Output\nA list of conferences sorted by start time, each with space, start/end, and duration. Include the conference record name so any record can be drilled into.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_meet.ts b/apps/sim/blocks/blocks/google_meet.ts index 9b6469749bc..425b94e9a54 100644 --- a/apps/sim/blocks/blocks/google_meet.ts +++ b/apps/sim/blocks/blocks/google_meet.ts @@ -1,7 +1,6 @@ -import { GoogleMeetIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleMeetBlockDisplay } from '@/blocks/blocks/google_meet.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleMeetResponse } from '@/tools/google_meet/types' @@ -173,99 +172,3 @@ export const GoogleMeetBlock: BlockConfig = { totalSize: { type: 'number', description: 'Total participant count' }, }, } - -export const GoogleMeetBlockMeta = { - tags: ['meeting', 'google-workspace', 'scheduling'], - url: 'https://workspace.google.com/products/meet', - templates: [ - { - icon: GoogleMeetIcon, - title: 'Google Meet conference recap to Drive', - prompt: - 'Build a workflow that pulls the conference record and participant list for a finished Google Meet, generates a structured attendance and follow-up recap with an agent, and saves the document to a per-team folder in Google Drive.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['team', 'content'], - alsoIntegrations: ['google_drive'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet daily meeting links', - prompt: - "Create a scheduled workflow that reads the day's meetings from a table each morning, creates a Google Meet space for each one, and emails attendees the agenda and join link via Gmail.", - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet conference record archiver', - prompt: - 'Build a scheduled workflow that lists Google Meet conference records, captures attendance and duration per meeting, and writes the history to a source-of-truth meetings table for reporting.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet auto-invite from CRM', - prompt: - 'Create a workflow that watches Salesforce for new meetings logged on opportunities, creates a matching Google Meet event, invites the right attendees, and writes the meeting link back to the opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet daily standup link', - prompt: - 'Build a scheduled workflow that posts the day’s Google Meet standup link to the team Slack channel five minutes before standup, with the rolling agenda from the standup table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet customer interview logger', - prompt: - 'Create a workflow that takes a customer-interview note or transcript, pulls the matching Google Meet conference record and participants for context, extracts themes, quotes, and feature requests with an agent, and writes structured rows to a research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'product'], - }, - { - icon: GoogleMeetIcon, - title: 'Google Meet retro publisher', - prompt: - 'Build a workflow that runs after a sprint-retro Google Meet, summarizes what went well, what to improve, and action items, and posts the retro to a Notion page tagged with the sprint number.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['team', 'reporting'], - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'create-meeting-space', - description: 'Create a Google Meet space and return its join link and meeting code.', - content: - '# Create a Meeting Space\n\nSpin up a Google Meet space to share.\n\n## Steps\n1. Decide the Access Type: Open (anyone with link), Trusted (organization members), or Restricted (invited only).\n2. Optionally set Entry Point Access if the space should only be joinable from the creating app.\n3. Run the Create Space operation.\n4. Capture the meeting URI and meeting code from the response.\n\n## Output\nReturn the meeting link (meetingUri), the meeting code, the access type, and the space resource name so it can be referenced or shared.', - }, - { - name: 'summarize-meeting-attendance', - description: - 'Pull a Google Meet conference record and its participants to report who attended.', - content: - '# Summarize Meeting Attendance\n\nReport attendance for a finished meeting.\n\n## Steps\n1. If you only have the space, run List Conference Records (filter by `space.name = "spaces/..."`) to find the conference record name.\n2. Run Get Conference Record to read start time, end time, and duration.\n3. Run List Participants on that conference record name, paging through results.\n4. Build the attendee list and compute meeting duration.\n\n## Output\nAn attendance summary: meeting start/end and duration, total participant count, and the list of participants. Flag the meeting if no participants are recorded.', - }, - { - name: 'list-recent-conferences', - description: 'List recent Google Meet conference records for reporting or archival.', - content: - '# List Recent Conferences\n\nEnumerate past Meet conferences.\n\n## Steps\n1. Run List Conference Records with a Page Size; optionally apply a Filter (e.g., by space name or time).\n2. Page through using the next page token until you have the needed window.\n3. For each record capture the conference record name, associated space, start time, and end time.\n4. Optionally fetch participants per record (List Participants) when attendance is needed.\n\n## Output\nA list of conferences sorted by start time, each with space, start/end, and duration. Include the conference record name so any record can be drilled into.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_pagespeed.display.ts b/apps/sim/blocks/blocks/google_pagespeed.display.ts index 5aaca4f6330..71f9df1e3a5 100644 --- a/apps/sim/blocks/blocks/google_pagespeed.display.ts +++ b/apps/sim/blocks/blocks/google_pagespeed.display.ts @@ -1,6 +1,6 @@ import { GooglePagespeedIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GooglePagespeedBlockDisplay = { type: 'google_pagespeed', @@ -14,3 +14,100 @@ export const GooglePagespeedBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_pagespeed', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const GooglePagespeedBlockMeta = { + tags: ['google-workspace', 'seo', 'monitoring'], + url: 'https://pagespeed.web.dev', + templates: [ + { + icon: GooglePagespeedIcon, + title: 'PageSpeed monitor for top pages', + prompt: + 'Create a scheduled workflow that runs Google PageSpeed Insights weekly against my top landing pages, writes mobile and desktop scores to a tables-based history, and flags regressions in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GooglePagespeedIcon, + title: 'PageSpeed sitemap audit', + prompt: + 'Build a workflow that takes a sitemap URL, runs Google PageSpeed Insights against every page in batches, summarizes Core Web Vitals across the site, and saves the report as a file.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: GooglePagespeedIcon, + title: 'PageSpeed pre-deploy gate', + prompt: + 'Build a workflow triggered by a Vercel preview deployment that runs Google PageSpeed Insights against the preview URL, posts the scores as a GitHub PR comment, and fails the check if scores drop below threshold.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['vercel', 'github'], + }, + { + icon: GooglePagespeedIcon, + title: 'PageSpeed CWV regression watcher', + prompt: + 'Build a scheduled workflow that runs Google PageSpeed Insights daily for the top pages, captures Core Web Vitals, and pages on-call when LCP or CLS regress beyond threshold.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: GooglePagespeedIcon, + title: 'PageSpeed accessibility tracker', + prompt: + 'Build a scheduled weekly workflow that runs Google PageSpeed Insights with the accessibility audit, writes per-page scores to a tracking table, and opens Linear tickets on regressions.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: GooglePagespeedIcon, + title: 'Core Web Vitals release gate', + prompt: + 'Create a workflow triggered after a marketing-site deploy that runs Google PageSpeed Insights on the key landing pages for both mobile and desktop, compares Core Web Vitals against the prior baseline, and posts a pass/fail summary to Slack with the specific metrics that regressed.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'seo', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: GooglePagespeedIcon, + title: 'PageSpeed competitor benchmark', + prompt: + 'Build a workflow that runs Google PageSpeed Insights against my homepage and a list of competitor URLs on mobile, compares the performance scores and Core Web Vitals side by side, and writes the ranked benchmark to a sheet.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + alsoIntegrations: ['google_sheets'], + }, + ], + skills: [ + { + name: 'audit-page-performance', + description: + 'Run a PageSpeed Insights analysis on a URL and report scores and Core Web Vitals.', + content: + '# Audit Page Performance\n\nMeasure a page with PageSpeed Insights (Lighthouse).\n\n## Steps\n1. Take the page URL.\n2. Choose the Strategy: mobile (recommended for ranking) or desktop. Run once per strategy if both are needed.\n3. Optionally set Categories (performance, accessibility, best-practices, seo) and Locale.\n4. Run the analysis and read the category scores plus Core Web Vitals (LCP, FCP, CLS, TBT, Speed Index, TTI).\n\n## Output\nA report: per-category scores (0-100), Core Web Vitals with their display values, and the final URL analyzed. Call out any metric in the poor range and the strategy used.', + }, + { + name: 'compare-mobile-vs-desktop', + description: 'Analyze a page on both mobile and desktop and contrast the scores and vitals.', + content: + "# Compare Mobile vs Desktop\n\nContrast a page's performance across form factors.\n\n## Steps\n1. Run the analysis on the URL with Strategy = mobile.\n2. Run it again with Strategy = desktop.\n3. Line up the category scores and Core Web Vitals from each run.\n4. Identify the biggest gaps (typically LCP/TBT on mobile).\n\n## Output\nA side-by-side comparison table of mobile vs desktop scores and key vitals, plus a short note on where mobile lags and what likely causes it.", + }, + { + name: 'track-core-web-vitals', + description: 'Capture Core Web Vitals for one or more pages to feed a monitoring history.', + content: + '# Track Core Web Vitals\n\nCapture CWV metrics for trend tracking.\n\n## Steps\n1. For each target URL, run the analysis (usually Strategy = mobile) limiting Categories to performance for speed.\n2. Extract LCP, CLS, TBT, FCP, Speed Index, and TTI numeric values plus the performance score.\n3. Stamp each row with the URL and analysis timestamp.\n4. Compare against any prior baseline to detect regressions.\n\n## Output\nOne row per URL with the performance score and CWV numeric values, ready to append to a history table. Flag any metric that regressed beyond a threshold versus the baseline.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_pagespeed.ts b/apps/sim/blocks/blocks/google_pagespeed.ts index e75734c5602..042e3140b53 100644 --- a/apps/sim/blocks/blocks/google_pagespeed.ts +++ b/apps/sim/blocks/blocks/google_pagespeed.ts @@ -1,6 +1,5 @@ -import { GooglePagespeedIcon } from '@/components/icons' import { GooglePagespeedBlockDisplay } from '@/blocks/blocks/google_pagespeed.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { GooglePagespeedAnalyzeResponse } from '@/tools/google_pagespeed/types' export const GooglePagespeedBlock: BlockConfig = { @@ -117,100 +116,3 @@ export const GooglePagespeedBlock: BlockConfig = }, }, } - -export const GooglePagespeedBlockMeta = { - tags: ['google-workspace', 'seo', 'monitoring'], - url: 'https://pagespeed.web.dev', - templates: [ - { - icon: GooglePagespeedIcon, - title: 'PageSpeed monitor for top pages', - prompt: - 'Create a scheduled workflow that runs Google PageSpeed Insights weekly against my top landing pages, writes mobile and desktop scores to a tables-based history, and flags regressions in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GooglePagespeedIcon, - title: 'PageSpeed sitemap audit', - prompt: - 'Build a workflow that takes a sitemap URL, runs Google PageSpeed Insights against every page in batches, summarizes Core Web Vitals across the site, and saves the report as a file.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: GooglePagespeedIcon, - title: 'PageSpeed pre-deploy gate', - prompt: - 'Build a workflow triggered by a Vercel preview deployment that runs Google PageSpeed Insights against the preview URL, posts the scores as a GitHub PR comment, and fails the check if scores drop below threshold.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['vercel', 'github'], - }, - { - icon: GooglePagespeedIcon, - title: 'PageSpeed CWV regression watcher', - prompt: - 'Build a scheduled workflow that runs Google PageSpeed Insights daily for the top pages, captures Core Web Vitals, and pages on-call when LCP or CLS regress beyond threshold.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: GooglePagespeedIcon, - title: 'PageSpeed accessibility tracker', - prompt: - 'Build a scheduled weekly workflow that runs Google PageSpeed Insights with the accessibility audit, writes per-page scores to a tracking table, and opens Linear tickets on regressions.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: GooglePagespeedIcon, - title: 'Core Web Vitals release gate', - prompt: - 'Create a workflow triggered after a marketing-site deploy that runs Google PageSpeed Insights on the key landing pages for both mobile and desktop, compares Core Web Vitals against the prior baseline, and posts a pass/fail summary to Slack with the specific metrics that regressed.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'seo', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: GooglePagespeedIcon, - title: 'PageSpeed competitor benchmark', - prompt: - 'Build a workflow that runs Google PageSpeed Insights against my homepage and a list of competitor URLs on mobile, compares the performance scores and Core Web Vitals side by side, and writes the ranked benchmark to a sheet.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - alsoIntegrations: ['google_sheets'], - }, - ], - skills: [ - { - name: 'audit-page-performance', - description: - 'Run a PageSpeed Insights analysis on a URL and report scores and Core Web Vitals.', - content: - '# Audit Page Performance\n\nMeasure a page with PageSpeed Insights (Lighthouse).\n\n## Steps\n1. Take the page URL.\n2. Choose the Strategy: mobile (recommended for ranking) or desktop. Run once per strategy if both are needed.\n3. Optionally set Categories (performance, accessibility, best-practices, seo) and Locale.\n4. Run the analysis and read the category scores plus Core Web Vitals (LCP, FCP, CLS, TBT, Speed Index, TTI).\n\n## Output\nA report: per-category scores (0-100), Core Web Vitals with their display values, and the final URL analyzed. Call out any metric in the poor range and the strategy used.', - }, - { - name: 'compare-mobile-vs-desktop', - description: 'Analyze a page on both mobile and desktop and contrast the scores and vitals.', - content: - "# Compare Mobile vs Desktop\n\nContrast a page's performance across form factors.\n\n## Steps\n1. Run the analysis on the URL with Strategy = mobile.\n2. Run it again with Strategy = desktop.\n3. Line up the category scores and Core Web Vitals from each run.\n4. Identify the biggest gaps (typically LCP/TBT on mobile).\n\n## Output\nA side-by-side comparison table of mobile vs desktop scores and key vitals, plus a short note on where mobile lags and what likely causes it.", - }, - { - name: 'track-core-web-vitals', - description: 'Capture Core Web Vitals for one or more pages to feed a monitoring history.', - content: - '# Track Core Web Vitals\n\nCapture CWV metrics for trend tracking.\n\n## Steps\n1. For each target URL, run the analysis (usually Strategy = mobile) limiting Categories to performance for speed.\n2. Extract LCP, CLS, TBT, FCP, Speed Index, and TTI numeric values plus the performance score.\n3. Stamp each row with the URL and analysis timestamp.\n4. Compare against any prior baseline to detect regressions.\n\n## Output\nOne row per URL with the performance score and CWV numeric values, ready to append to a history table. Flag any metric that regressed beyond a threshold versus the baseline.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_sheets.display.ts b/apps/sim/blocks/blocks/google_sheets.display.ts index 1642acb93bc..3bb401df0d7 100644 --- a/apps/sim/blocks/blocks/google_sheets.display.ts +++ b/apps/sim/blocks/blocks/google_sheets.display.ts @@ -1,6 +1,6 @@ import { GoogleSheetsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleSheetsBlockDisplay = { type: 'google_sheets', @@ -29,3 +29,124 @@ export const GoogleSheetsV2BlockDisplay = { integrationType: IntegrationType.Documents, hideFromToolbar: false, } satisfies BlockDisplay + +export const GoogleSheetsBlockMeta = { + tags: ['spreadsheet', 'google-workspace', 'data-analytics'], + url: 'https://workspace.google.com/products/sheets', + templates: [ + { + icon: GoogleSheetsIcon, + title: 'Google Sheets approval gate', + prompt: + 'Build a workflow that watches a Google Sheets row for a status change to "review", posts the row context to Slack with approval buttons, and writes the decision back.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleSheetsIcon, + title: 'Google Sheets to Stripe payouts', + prompt: + 'Create a workflow that reads a Google Sheets payouts ledger, validates each row, processes Stripe payouts in batches, and writes the result and Stripe ID back.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['stripe'], + }, + { + icon: GoogleSheetsIcon, + title: 'Google Sheets CRM updater', + prompt: + 'Build a scheduled workflow that pulls Salesforce opportunities, refreshes the Google Sheets spreadsheet that ops uses for weekly forecasting, and notes the last-updated timestamp.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleSheetsIcon, + title: 'Google Sheets data validator', + prompt: + 'Create a scheduled workflow that validates a Google Sheets spreadsheet against a typed schema, flags rows with errors, writes a remediation column, and emails the sheet owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['team', 'analysis'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleSheetsIcon, + title: 'Google Sheets inventory sync', + prompt: + 'Build a workflow that pulls Shopify inventory into Google Sheets hourly, calculates days-of-cover, and highlights items needing reorder for the ops team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'sync'], + alsoIntegrations: ['shopify'], + }, + { + icon: GoogleSheetsIcon, + title: 'Google Sheets forms cleanup', + prompt: + 'Create a workflow that normalizes Google Sheets data submitted from Google Forms — title casing, phone formats, deduplication — and writes clean rows to a downstream sheet.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'analysis'], + alsoIntegrations: ['google_forms'], + }, + + { + icon: GoogleSheetsIcon, + title: 'Send Slack messages from Google Sheets', + prompt: + 'Build a workflow that watches a Google Sheets spreadsheet for new rows or changes, then posts formatted Slack updates to keep stakeholders informed in real time.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + { + icon: GoogleSheetsIcon, + title: 'Sync Google Sheets data into Notion', + prompt: + 'Create an agent that reads rows from Google Sheets and transforms them into structured Notion database entries for richer documentation and cross-team project tracking.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'read-sheet-data', + description: 'Read rows from a Google Sheet, optionally filtering by a column value.', + content: + '# Read Sheet Data\n\nPull data out of a spreadsheet tab.\n\n## Steps\n1. Select the spreadsheet and the Sheet (tab) to read.\n2. Optionally set a Cell Range (e.g., A1:D100); leave blank to read the used range.\n3. To narrow rows, set Filter Column (a header name), Filter Value, and Match Type (contains, exact, gt, etc.).\n4. Run the Read Data operation and treat the first row as headers if present.\n\n## Output\nReturn the rows (as a 2D array or labeled objects keyed by header), the range read, and a filter summary if a filter was applied. Note the row count.', + }, + { + name: 'append-rows-to-sheet', + description: 'Add new rows to the end of a Google Sheet without overwriting existing data.', + content: + '# Append Rows to a Sheet\n\nAdd records to the bottom of a tab.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab).\n2. Build the Values as a JSON array of arrays (each inner array is a row) or array of objects keyed by column.\n3. Set Insert Data Option to Insert Rows so existing data is not overwritten.\n4. Choose Value Input Option: User Entered (parses formulas/dates) or Raw.\n5. Run the Append Data operation.\n\n## Output\nConfirm the append: updated range, rows added, and the table range. Ensure column order matches the sheet headers.', + }, + { + name: 'update-cells', + description: 'Write or update values in a specific range of a Google Sheet.', + content: + '# Update Cells\n\nWrite values into a targeted range.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab) and set the Cell Range to write (e.g., B2:D2).\n2. Build the Values JSON so its dimensions match the range.\n3. Pick Value Input Option: User Entered to evaluate formulas, or Raw to store literal text.\n4. Run the Update Data operation (use Write Data to set a fresh block).\n\n## Output\nConfirm updated range and the count of updated cells/rows/columns. If writing formulas, confirm User Entered was used so they evaluate.', + }, + { + name: 'create-spreadsheet', + description: 'Create a new Google Sheets spreadsheet with named tabs and return its link.', + content: + '# Create a Spreadsheet\n\nStand up a new spreadsheet.\n\n## Steps\n1. Set the Spreadsheet Title.\n2. Optionally provide Sheet Names as a comma-separated list (e.g., "Data, Summary").\n3. Run the Create Spreadsheet operation and capture the spreadsheet ID and URL.\n4. Follow up with Write or Append operations to populate the tabs.\n\n## Output\nReturn the new spreadsheet title, ID, URL, and the list of sheets created. Hand back the ID so subsequent steps can write to it.', + }, + ], +} as const satisfies BlockMeta + +export const GoogleSheetsV2BlockMeta = { + tags: ['spreadsheet', 'google-workspace', 'data-analytics'], + url: 'https://workspace.google.com/products/sheets', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_sheets.ts b/apps/sim/blocks/blocks/google_sheets.ts index 4470a5b33fa..a7655cab74a 100644 --- a/apps/sim/blocks/blocks/google_sheets.ts +++ b/apps/sim/blocks/blocks/google_sheets.ts @@ -1,10 +1,9 @@ -import { GoogleSheetsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleSheetsBlockDisplay, GoogleSheetsV2BlockDisplay, } from '@/blocks/blocks/google_sheets.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleSheetsResponse, GoogleSheetsV2Response } from '@/tools/google_sheets/types' @@ -1197,124 +1196,3 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`, available: ['google_sheets_poller'], }, } - -export const GoogleSheetsBlockMeta = { - tags: ['spreadsheet', 'google-workspace', 'data-analytics'], - url: 'https://workspace.google.com/products/sheets', - templates: [ - { - icon: GoogleSheetsIcon, - title: 'Google Sheets approval gate', - prompt: - 'Build a workflow that watches a Google Sheets row for a status change to "review", posts the row context to Slack with approval buttons, and writes the decision back.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleSheetsIcon, - title: 'Google Sheets to Stripe payouts', - prompt: - 'Create a workflow that reads a Google Sheets payouts ledger, validates each row, processes Stripe payouts in batches, and writes the result and Stripe ID back.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['stripe'], - }, - { - icon: GoogleSheetsIcon, - title: 'Google Sheets CRM updater', - prompt: - 'Build a scheduled workflow that pulls Salesforce opportunities, refreshes the Google Sheets spreadsheet that ops uses for weekly forecasting, and notes the last-updated timestamp.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleSheetsIcon, - title: 'Google Sheets data validator', - prompt: - 'Create a scheduled workflow that validates a Google Sheets spreadsheet against a typed schema, flags rows with errors, writes a remediation column, and emails the sheet owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['team', 'analysis'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleSheetsIcon, - title: 'Google Sheets inventory sync', - prompt: - 'Build a workflow that pulls Shopify inventory into Google Sheets hourly, calculates days-of-cover, and highlights items needing reorder for the ops team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'sync'], - alsoIntegrations: ['shopify'], - }, - { - icon: GoogleSheetsIcon, - title: 'Google Sheets forms cleanup', - prompt: - 'Create a workflow that normalizes Google Sheets data submitted from Google Forms — title casing, phone formats, deduplication — and writes clean rows to a downstream sheet.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'analysis'], - alsoIntegrations: ['google_forms'], - }, - - { - icon: GoogleSheetsIcon, - title: 'Send Slack messages from Google Sheets', - prompt: - 'Build a workflow that watches a Google Sheets spreadsheet for new rows or changes, then posts formatted Slack updates to keep stakeholders informed in real time.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - { - icon: GoogleSheetsIcon, - title: 'Sync Google Sheets data into Notion', - prompt: - 'Create an agent that reads rows from Google Sheets and transforms them into structured Notion database entries for richer documentation and cross-team project tracking.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'read-sheet-data', - description: 'Read rows from a Google Sheet, optionally filtering by a column value.', - content: - '# Read Sheet Data\n\nPull data out of a spreadsheet tab.\n\n## Steps\n1. Select the spreadsheet and the Sheet (tab) to read.\n2. Optionally set a Cell Range (e.g., A1:D100); leave blank to read the used range.\n3. To narrow rows, set Filter Column (a header name), Filter Value, and Match Type (contains, exact, gt, etc.).\n4. Run the Read Data operation and treat the first row as headers if present.\n\n## Output\nReturn the rows (as a 2D array or labeled objects keyed by header), the range read, and a filter summary if a filter was applied. Note the row count.', - }, - { - name: 'append-rows-to-sheet', - description: 'Add new rows to the end of a Google Sheet without overwriting existing data.', - content: - '# Append Rows to a Sheet\n\nAdd records to the bottom of a tab.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab).\n2. Build the Values as a JSON array of arrays (each inner array is a row) or array of objects keyed by column.\n3. Set Insert Data Option to Insert Rows so existing data is not overwritten.\n4. Choose Value Input Option: User Entered (parses formulas/dates) or Raw.\n5. Run the Append Data operation.\n\n## Output\nConfirm the append: updated range, rows added, and the table range. Ensure column order matches the sheet headers.', - }, - { - name: 'update-cells', - description: 'Write or update values in a specific range of a Google Sheet.', - content: - '# Update Cells\n\nWrite values into a targeted range.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab) and set the Cell Range to write (e.g., B2:D2).\n2. Build the Values JSON so its dimensions match the range.\n3. Pick Value Input Option: User Entered to evaluate formulas, or Raw to store literal text.\n4. Run the Update Data operation (use Write Data to set a fresh block).\n\n## Output\nConfirm updated range and the count of updated cells/rows/columns. If writing formulas, confirm User Entered was used so they evaluate.', - }, - { - name: 'create-spreadsheet', - description: 'Create a new Google Sheets spreadsheet with named tabs and return its link.', - content: - '# Create a Spreadsheet\n\nStand up a new spreadsheet.\n\n## Steps\n1. Set the Spreadsheet Title.\n2. Optionally provide Sheet Names as a comma-separated list (e.g., "Data, Summary").\n3. Run the Create Spreadsheet operation and capture the spreadsheet ID and URL.\n4. Follow up with Write or Append operations to populate the tabs.\n\n## Output\nReturn the new spreadsheet title, ID, URL, and the list of sheets created. Hand back the ID so subsequent steps can write to it.', - }, - ], -} as const satisfies BlockMeta - -export const GoogleSheetsV2BlockMeta = { - tags: ['spreadsheet', 'google-workspace', 'data-analytics'], - url: 'https://workspace.google.com/products/sheets', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_slides.display.ts b/apps/sim/blocks/blocks/google_slides.display.ts index 0b2f5bc3a27..5c7e12f1e30 100644 --- a/apps/sim/blocks/blocks/google_slides.display.ts +++ b/apps/sim/blocks/blocks/google_slides.display.ts @@ -1,6 +1,6 @@ import { GoogleSlidesIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleSlidesBlockDisplay = { type: 'google_slides', @@ -24,3 +24,112 @@ export const GoogleSlidesV2BlockDisplay = { integrationType: IntegrationType.Documents, hideFromToolbar: false, } satisfies BlockDisplay + +export const GoogleSlidesBlockMeta = { + tags: ['google-workspace', 'document-processing', 'content-management'], + url: 'https://workspace.google.com/products/slides', + templates: [ + { + icon: GoogleSlidesIcon, + title: 'Google Slides QBR generator', + prompt: + 'Build a workflow that takes a customer account, pulls usage and support data, and generates a Google Slides QBR deck from a template with the metrics auto-filled.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides weekly board update', + prompt: + 'Create a scheduled weekly workflow that updates a Google Slides board deck with the latest KPIs from tables, swaps the cover image, and shares the link to the leadership thread.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['founder', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides case-study builder', + prompt: + 'Build a workflow that takes a customer story brief and generates a Google Slides case-study deck from a template, including pull quotes, metrics, and a logo.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides pitch personalizer', + prompt: + 'Create a workflow that takes a Salesforce opportunity, generates a Google Slides pitch deck personalized to the account, and attaches it to the opportunity record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'content'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides training builder', + prompt: + 'Build a workflow that takes a knowledge base topic, generates a Google Slides training deck with structured slides, talking points, and quiz slides at the end.', + modules: ['knowledge-base', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'content'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides exec metrics deck', + prompt: + 'Create a scheduled monthly workflow that generates a Google Slides executive metrics deck from BigQuery and Stripe data, swaps the cover with the month, and shares it with leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['founder', 'reporting'], + alsoIntegrations: ['google_bigquery', 'stripe'], + }, + { + icon: GoogleSlidesIcon, + title: 'Google Slides win-loss recap', + prompt: + 'Build a workflow that aggregates closed-won and closed-lost deals from Salesforce monthly, generates a Google Slides recap with patterns and insights, and emails it to the sales team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + alsoIntegrations: ['salesforce', 'gmail'], + }, + ], + skills: [ + { + name: 'generate-deck-from-template', + description: + 'Copy a Google Slides template and replace placeholder text and images with data to produce a finished deck.', + content: + '# Generate Deck From Template\n\nProduce a finished presentation by copying a template deck and filling in dynamic values.\n\n## Steps\n1. Create a copy of the template presentation, or create a new presentation, and capture its presentationId.\n2. For each placeholder token (e.g. {{company}}, {{date}}, {{metric}}), call replace all text to substitute the real value across every slide.\n3. Replace placeholder images by adding images to the relevant slides, sizing and positioning them on the page.\n4. Add or duplicate slides for repeating sections (one per item) so the deck length matches the data.\n5. Read the presentation back to confirm every placeholder was resolved.\n\n## Output\nReturn the presentationId and the shareable link. Note any placeholders that had no matching data so they can be reviewed.', + }, + { + name: 'build-metrics-slide', + description: + 'Add a slide with a table and shapes that summarizes KPIs or metrics into a Google Slides deck.', + content: + '# Build Metrics Slide\n\nInsert a clean, data-driven metrics slide into an existing presentation.\n\n## Steps\n1. Add a new slide to the target presentation and capture the new slide objectId.\n2. Create a table on the slide sized to the number of metrics (rows) and columns needed.\n3. Insert text into each cell with the metric name, current value, and change vs prior period.\n4. Optionally create shape callouts for headline numbers and apply text and paragraph styles for emphasis.\n5. Get a thumbnail to verify layout and readability.\n\n## Output\nReturn the slide objectId and a thumbnail link. Summarize which metrics were added.', + }, + { + name: 'extract-deck-content', + description: + 'Read a Google Slides presentation and extract all slide text into a structured outline.', + content: + '# Extract Deck Content\n\nPull the full text of a presentation into a structured outline for summarization or repurposing.\n\n## Steps\n1. Read the presentation by ID to get all slides and page elements.\n2. For each slide, collect title text, body text, table cell text, and speaker notes if present.\n3. Preserve slide order and group text under each slide number.\n4. Skip purely decorative elements with no text.\n\n## Output\nReturn a numbered outline (one section per slide) with the extracted text. Useful as input for a summary, recap email, or knowledge base entry.', + }, + { + name: 'rebrand-deck', + description: + 'Roll out a brand or naming change across an entire deck by swapping text and logo images everywhere.', + content: + '# Rebrand Deck\n\nApply a consistent brand or naming change across every slide in one pass.\n\n## Steps\n1. Read the presentation by ID to confirm which terms and logo placeholders appear.\n2. For each old-to-new term (product name, tagline, company name), call replace all text so it updates across every slide at once.\n3. Replace the old logo by calling replace all shapes with image, or replace image on each logo element, with the new asset URL.\n4. Optionally update shape or page properties to match new brand colors.\n5. Read the presentation back to confirm no stale terms or logos remain.\n\n## Output\nReturn the presentationId and a list of the terms and images that were replaced, flagging any old references that still appear.', + }, + ], +} as const satisfies BlockMeta + +export const GoogleSlidesV2BlockMeta = { + tags: ['google-workspace', 'document-processing', 'content-management'], + url: 'https://workspace.google.com/products/slides', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_slides.ts b/apps/sim/blocks/blocks/google_slides.ts index 55b5e63b3ab..01caeb2e99b 100644 --- a/apps/sim/blocks/blocks/google_slides.ts +++ b/apps/sim/blocks/blocks/google_slides.ts @@ -1,11 +1,10 @@ -import { GoogleSlidesIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils' import { GoogleSlidesBlockDisplay, GoogleSlidesV2BlockDisplay, } from '@/blocks/blocks/google_slides.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput, SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleSlidesResponse } from '@/tools/google_slides/types' @@ -3482,112 +3481,3 @@ export const GoogleSlidesV2Block: BlockConfig = { }, inputs: googleSlidesV2Inputs, } - -export const GoogleSlidesBlockMeta = { - tags: ['google-workspace', 'document-processing', 'content-management'], - url: 'https://workspace.google.com/products/slides', - templates: [ - { - icon: GoogleSlidesIcon, - title: 'Google Slides QBR generator', - prompt: - 'Build a workflow that takes a customer account, pulls usage and support data, and generates a Google Slides QBR deck from a template with the metrics auto-filled.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides weekly board update', - prompt: - 'Create a scheduled weekly workflow that updates a Google Slides board deck with the latest KPIs from tables, swaps the cover image, and shares the link to the leadership thread.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['founder', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides case-study builder', - prompt: - 'Build a workflow that takes a customer story brief and generates a Google Slides case-study deck from a template, including pull quotes, metrics, and a logo.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides pitch personalizer', - prompt: - 'Create a workflow that takes a Salesforce opportunity, generates a Google Slides pitch deck personalized to the account, and attaches it to the opportunity record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'content'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides training builder', - prompt: - 'Build a workflow that takes a knowledge base topic, generates a Google Slides training deck with structured slides, talking points, and quiz slides at the end.', - modules: ['knowledge-base', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'content'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides exec metrics deck', - prompt: - 'Create a scheduled monthly workflow that generates a Google Slides executive metrics deck from BigQuery and Stripe data, swaps the cover with the month, and shares it with leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['founder', 'reporting'], - alsoIntegrations: ['google_bigquery', 'stripe'], - }, - { - icon: GoogleSlidesIcon, - title: 'Google Slides win-loss recap', - prompt: - 'Build a workflow that aggregates closed-won and closed-lost deals from Salesforce monthly, generates a Google Slides recap with patterns and insights, and emails it to the sales team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - alsoIntegrations: ['salesforce', 'gmail'], - }, - ], - skills: [ - { - name: 'generate-deck-from-template', - description: - 'Copy a Google Slides template and replace placeholder text and images with data to produce a finished deck.', - content: - '# Generate Deck From Template\n\nProduce a finished presentation by copying a template deck and filling in dynamic values.\n\n## Steps\n1. Create a copy of the template presentation, or create a new presentation, and capture its presentationId.\n2. For each placeholder token (e.g. {{company}}, {{date}}, {{metric}}), call replace all text to substitute the real value across every slide.\n3. Replace placeholder images by adding images to the relevant slides, sizing and positioning them on the page.\n4. Add or duplicate slides for repeating sections (one per item) so the deck length matches the data.\n5. Read the presentation back to confirm every placeholder was resolved.\n\n## Output\nReturn the presentationId and the shareable link. Note any placeholders that had no matching data so they can be reviewed.', - }, - { - name: 'build-metrics-slide', - description: - 'Add a slide with a table and shapes that summarizes KPIs or metrics into a Google Slides deck.', - content: - '# Build Metrics Slide\n\nInsert a clean, data-driven metrics slide into an existing presentation.\n\n## Steps\n1. Add a new slide to the target presentation and capture the new slide objectId.\n2. Create a table on the slide sized to the number of metrics (rows) and columns needed.\n3. Insert text into each cell with the metric name, current value, and change vs prior period.\n4. Optionally create shape callouts for headline numbers and apply text and paragraph styles for emphasis.\n5. Get a thumbnail to verify layout and readability.\n\n## Output\nReturn the slide objectId and a thumbnail link. Summarize which metrics were added.', - }, - { - name: 'extract-deck-content', - description: - 'Read a Google Slides presentation and extract all slide text into a structured outline.', - content: - '# Extract Deck Content\n\nPull the full text of a presentation into a structured outline for summarization or repurposing.\n\n## Steps\n1. Read the presentation by ID to get all slides and page elements.\n2. For each slide, collect title text, body text, table cell text, and speaker notes if present.\n3. Preserve slide order and group text under each slide number.\n4. Skip purely decorative elements with no text.\n\n## Output\nReturn a numbered outline (one section per slide) with the extracted text. Useful as input for a summary, recap email, or knowledge base entry.', - }, - { - name: 'rebrand-deck', - description: - 'Roll out a brand or naming change across an entire deck by swapping text and logo images everywhere.', - content: - '# Rebrand Deck\n\nApply a consistent brand or naming change across every slide in one pass.\n\n## Steps\n1. Read the presentation by ID to confirm which terms and logo placeholders appear.\n2. For each old-to-new term (product name, tagline, company name), call replace all text so it updates across every slide at once.\n3. Replace the old logo by calling replace all shapes with image, or replace image on each logo element, with the new asset URL.\n4. Optionally update shape or page properties to match new brand colors.\n5. Read the presentation back to confirm no stale terms or logos remain.\n\n## Output\nReturn the presentationId and a list of the terms and images that were replaced, flagging any old references that still appear.', - }, - ], -} as const satisfies BlockMeta - -export const GoogleSlidesV2BlockMeta = { - tags: ['google-workspace', 'document-processing', 'content-management'], - url: 'https://workspace.google.com/products/slides', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_tasks.display.ts b/apps/sim/blocks/blocks/google_tasks.display.ts index e08096a91d2..02cc0daa306 100644 --- a/apps/sim/blocks/blocks/google_tasks.display.ts +++ b/apps/sim/blocks/blocks/google_tasks.display.ts @@ -1,6 +1,6 @@ import { GoogleTasksIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleTasksBlockDisplay = { type: 'google_tasks', @@ -14,3 +14,101 @@ export const GoogleTasksBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_tasks', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const GoogleTasksBlockMeta = { + tags: ['google-workspace', 'project-management', 'scheduling'], + url: 'https://workspace.google.com/products/tasks', + templates: [ + { + icon: GoogleTasksIcon, + title: 'Google Tasks digest', + prompt: + 'Build a scheduled daily workflow that summarizes Google Tasks due today and tomorrow, and emails the user a prioritized digest each morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks from Gmail', + prompt: + 'Create a workflow that watches Gmail for emails marked with a task label, extracts the action and due date, and creates a Google Tasks entry with a link back to the email.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks from meetings', + prompt: + 'Build a workflow that runs after Google Meet meetings, extracts action items from the transcript, and creates Google Tasks entries for the owner with due dates.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['google_meet'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks completion digest', + prompt: + 'Create a scheduled weekly workflow that summarizes Google Tasks completed by the user, captures the throughput, and emails a personal productivity report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks rolling cleanup', + prompt: + 'Build a scheduled workflow that runs daily, archives Google Tasks completed more than 30 days ago, and surfaces tasks past their due date for re-prioritization.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks Slack sync', + prompt: + 'Create a workflow that watches Slack for messages tagged with the saved-task emoji, captures the message and creates a Google Tasks entry with a link to the Slack thread.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'sync'], + alsoIntegrations: ['slack'], + }, + { + icon: GoogleTasksIcon, + title: 'Google Tasks calendar block builder', + prompt: + 'Build a workflow that on a Google Tasks creation also inserts a Google Calendar focus block with the task title, so the time is actually reserved.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['google_calendar'], + }, + ], + skills: [ + { + name: 'capture-action-items', + description: + 'Turn a list of action items into Google Tasks with titles, notes, and due dates in the right task list.', + content: + '# Capture Action Items\n\nConvert extracted action items into well-formed Google Tasks.\n\n## Steps\n1. List the available task lists and pick the target list (default to the primary list if none specified).\n2. For each action item, create a task with a concise title, detailed notes for context, and a due date if one was given.\n3. Avoid duplicates by skipping items whose title already exists in the list.\n\n## Output\nReturn the created task IDs and titles, grouped by task list. Note any items skipped as duplicates.', + }, + { + name: 'list-due-and-overdue', + description: + 'List open Google Tasks that are due soon or overdue across a task list for a daily review.', + content: + '# List Due and Overdue Tasks\n\nSurface tasks that need attention for a daily or weekly review.\n\n## Steps\n1. List the task lists, or use a specified list.\n2. List tasks in the list, including completed status and due dates.\n3. Filter to incomplete tasks and split into Overdue (due before today) and Due Soon (due within the next few days).\n4. Sort each group by due date ascending.\n\n## Output\nReturn two sections, Overdue and Due Soon, each with task title, due date, and task ID. Useful for posting a standup or reminder digest.', + }, + { + name: 'complete-task-by-title', + description: 'Find a Google Task by its title and mark it completed.', + content: + '# Complete Task By Title\n\nMark a task done when given a title rather than an ID.\n\n## Steps\n1. List tasks in the relevant task list and match the requested title (case-insensitive, allow partial match).\n2. If multiple match, prefer the incomplete one; if still ambiguous, return the candidates and ask for clarification.\n3. Update the matched task to set its status to completed.\n4. Confirm the update by reading the task back.\n\n## Output\nReturn the completed task title and ID, or the list of ambiguous candidates if no single match was found.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_tasks.ts b/apps/sim/blocks/blocks/google_tasks.ts index d1287933344..80615a18397 100644 --- a/apps/sim/blocks/blocks/google_tasks.ts +++ b/apps/sim/blocks/blocks/google_tasks.ts @@ -1,7 +1,6 @@ -import { GoogleTasksIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleTasksBlockDisplay } from '@/blocks/blocks/google_tasks.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' import type { GoogleTasksResponse } from '@/tools/google_tasks/types' @@ -272,101 +271,3 @@ Return ONLY the timestamp - no explanations, no extra text.`, nextPageToken: { type: 'string', description: 'Token for next page of results' }, }, } - -export const GoogleTasksBlockMeta = { - tags: ['google-workspace', 'project-management', 'scheduling'], - url: 'https://workspace.google.com/products/tasks', - templates: [ - { - icon: GoogleTasksIcon, - title: 'Google Tasks digest', - prompt: - 'Build a scheduled daily workflow that summarizes Google Tasks due today and tomorrow, and emails the user a prioritized digest each morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks from Gmail', - prompt: - 'Create a workflow that watches Gmail for emails marked with a task label, extracts the action and due date, and creates a Google Tasks entry with a link back to the email.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks from meetings', - prompt: - 'Build a workflow that runs after Google Meet meetings, extracts action items from the transcript, and creates Google Tasks entries for the owner with due dates.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['google_meet'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks completion digest', - prompt: - 'Create a scheduled weekly workflow that summarizes Google Tasks completed by the user, captures the throughput, and emails a personal productivity report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks rolling cleanup', - prompt: - 'Build a scheduled workflow that runs daily, archives Google Tasks completed more than 30 days ago, and surfaces tasks past their due date for re-prioritization.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks Slack sync', - prompt: - 'Create a workflow that watches Slack for messages tagged with the saved-task emoji, captures the message and creates a Google Tasks entry with a link to the Slack thread.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'sync'], - alsoIntegrations: ['slack'], - }, - { - icon: GoogleTasksIcon, - title: 'Google Tasks calendar block builder', - prompt: - 'Build a workflow that on a Google Tasks creation also inserts a Google Calendar focus block with the task title, so the time is actually reserved.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['google_calendar'], - }, - ], - skills: [ - { - name: 'capture-action-items', - description: - 'Turn a list of action items into Google Tasks with titles, notes, and due dates in the right task list.', - content: - '# Capture Action Items\n\nConvert extracted action items into well-formed Google Tasks.\n\n## Steps\n1. List the available task lists and pick the target list (default to the primary list if none specified).\n2. For each action item, create a task with a concise title, detailed notes for context, and a due date if one was given.\n3. Avoid duplicates by skipping items whose title already exists in the list.\n\n## Output\nReturn the created task IDs and titles, grouped by task list. Note any items skipped as duplicates.', - }, - { - name: 'list-due-and-overdue', - description: - 'List open Google Tasks that are due soon or overdue across a task list for a daily review.', - content: - '# List Due and Overdue Tasks\n\nSurface tasks that need attention for a daily or weekly review.\n\n## Steps\n1. List the task lists, or use a specified list.\n2. List tasks in the list, including completed status and due dates.\n3. Filter to incomplete tasks and split into Overdue (due before today) and Due Soon (due within the next few days).\n4. Sort each group by due date ascending.\n\n## Output\nReturn two sections, Overdue and Due Soon, each with task title, due date, and task ID. Useful for posting a standup or reminder digest.', - }, - { - name: 'complete-task-by-title', - description: 'Find a Google Task by its title and mark it completed.', - content: - '# Complete Task By Title\n\nMark a task done when given a title rather than an ID.\n\n## Steps\n1. List tasks in the relevant task list and match the requested title (case-insensitive, allow partial match).\n2. If multiple match, prefer the incomplete one; if still ambiguous, return the candidates and ask for clarification.\n3. Update the matched task to set its status to completed.\n4. Confirm the update by reading the task back.\n\n## Output\nReturn the completed task title and ID, or the list of ambiguous candidates if no single match was found.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_translate.display.ts b/apps/sim/blocks/blocks/google_translate.display.ts index 41258ffc81f..9c7db3967fc 100644 --- a/apps/sim/blocks/blocks/google_translate.display.ts +++ b/apps/sim/blocks/blocks/google_translate.display.ts @@ -1,6 +1,6 @@ import { GoogleTranslateIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleTranslateBlockDisplay = { type: 'google_translate', @@ -14,3 +14,101 @@ export const GoogleTranslateBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/google_translate', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const GoogleTranslateBlockMeta = { + tags: ['google-workspace', 'content-management', 'automation'], + url: 'https://cloud.google.com/translate', + templates: [ + { + icon: GoogleTranslateIcon, + title: 'Google Translate doc localizer', + prompt: + 'Create a workflow that watches a Google Drive folder of source-language docs, translates each into target languages with Google Translate while preserving structure, and writes the localized files back.', + modules: ['files', 'agent', 'workflows'], + category: 'marketing', + tags: ['content', 'enterprise'], + alsoIntegrations: ['google_drive'], + }, + { + icon: GoogleTranslateIcon, + title: 'Multilingual support replier', + prompt: + 'Build a workflow that detects the language of a new Intercom message, translates it to the agent language with Google Translate, drafts a reply, then translates the reply back before sending.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['intercom'], + }, + { + icon: GoogleTranslateIcon, + title: 'Google Translate + Hugging Face confidence', + prompt: + 'Create a workflow that runs Google Translate then scores translation quality with a Hugging Face model, flags low-confidence segments for human review, and writes the scored output.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'enterprise'], + alsoIntegrations: ['huggingface'], + }, + { + icon: GoogleTranslateIcon, + title: 'Google Translate + Mistral Parser localization', + prompt: + 'Build a workflow that uses Mistral Parser to extract structured content from source-language PDFs and Google Translate to localize each section while preserving structure.', + modules: ['files', 'agent', 'workflows'], + category: 'marketing', + tags: ['content', 'enterprise'], + alsoIntegrations: ['mistral_parse'], + }, + { + icon: GoogleTranslateIcon, + title: 'Google Translate Confluence localization', + prompt: + 'Create a workflow that watches Confluence pages tagged for localization, translates each into the target languages with Google Translate, and publishes localized copies.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['content', 'enterprise'], + alsoIntegrations: ['confluence'], + }, + { + icon: GoogleTranslateIcon, + title: 'Multilingual support replies', + prompt: + "Build a workflow that on a new support ticket detects the customer's language with Google Translate, translates the message to English for the agent, drafts a reply, then translates the response back into the customer's language before sending.", + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + }, + { + icon: GoogleTranslateIcon, + title: 'Slack channel translator', + prompt: + "Create a workflow that watches an international Slack channel, detects non-English messages with Google Translate, translates them to the team's language, and posts the translation in a thread so everyone stays in the loop.", + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'translate-to-language', + description: + 'Translate a block of text into a target language using Google Cloud Translation.', + content: + '# Translate To Language\n\nTranslate text into a specified target language.\n\n## Steps\n1. Take the source text and the target language code (e.g. es, fr, ja).\n2. If the source language is unknown, detect it first; otherwise pass it explicitly for accuracy.\n3. Call translate text with the target language and capture the translated output.\n4. For long content, split into paragraph-sized chunks and translate each to preserve formatting.\n\n## Output\nReturn the translated text along with the detected or supplied source language and the target language. Preserve line breaks from the original.', + }, + { + name: 'detect-and-route-language', + description: 'Detect the language of incoming text and route or label it accordingly.', + content: + '# Detect and Route Language\n\nIdentify the language of a message so it can be routed, labeled, or translated.\n\n## Steps\n1. Call detect language on the input text and capture the language code and confidence.\n2. If confidence is low, fall back to detecting on a longer sample or flag as uncertain.\n3. Decide the route: if the detected language differs from the team language, translate it; otherwise pass through unchanged.\n\n## Output\nReturn the detected language code, confidence, and a recommended action (translate or pass-through). Include the translated text when translation was performed.', + }, + { + name: 'localize-message-set', + description: + 'Translate one source message into several target languages for multilingual delivery.', + content: + '# Localize Message Set\n\nProduce localized versions of a single message for multiple audiences.\n\n## Steps\n1. Take the source text and the list of target language codes.\n2. For each target language, call translate text with the source language set explicitly for consistency.\n3. Keep placeholders, names, and URLs intact across all translations.\n\n## Output\nReturn a mapping of language code to translated text. Note any target language where translation appeared incomplete or unchanged.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_translate.ts b/apps/sim/blocks/blocks/google_translate.ts index c48ef432450..5db6a69564a 100644 --- a/apps/sim/blocks/blocks/google_translate.ts +++ b/apps/sim/blocks/blocks/google_translate.ts @@ -1,6 +1,5 @@ -import { GoogleTranslateIcon } from '@/components/icons' import { GoogleTranslateBlockDisplay } from '@/blocks/blocks/google_translate.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' const SUPPORTED_LANGUAGES = [ { label: 'Afrikaans', id: 'af' }, @@ -207,101 +206,3 @@ export const GoogleTranslateBlock: BlockConfig = { confidence: { type: 'number', description: 'Detection confidence score' }, }, } - -export const GoogleTranslateBlockMeta = { - tags: ['google-workspace', 'content-management', 'automation'], - url: 'https://cloud.google.com/translate', - templates: [ - { - icon: GoogleTranslateIcon, - title: 'Google Translate doc localizer', - prompt: - 'Create a workflow that watches a Google Drive folder of source-language docs, translates each into target languages with Google Translate while preserving structure, and writes the localized files back.', - modules: ['files', 'agent', 'workflows'], - category: 'marketing', - tags: ['content', 'enterprise'], - alsoIntegrations: ['google_drive'], - }, - { - icon: GoogleTranslateIcon, - title: 'Multilingual support replier', - prompt: - 'Build a workflow that detects the language of a new Intercom message, translates it to the agent language with Google Translate, drafts a reply, then translates the reply back before sending.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['intercom'], - }, - { - icon: GoogleTranslateIcon, - title: 'Google Translate + Hugging Face confidence', - prompt: - 'Create a workflow that runs Google Translate then scores translation quality with a Hugging Face model, flags low-confidence segments for human review, and writes the scored output.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'enterprise'], - alsoIntegrations: ['huggingface'], - }, - { - icon: GoogleTranslateIcon, - title: 'Google Translate + Mistral Parser localization', - prompt: - 'Build a workflow that uses Mistral Parser to extract structured content from source-language PDFs and Google Translate to localize each section while preserving structure.', - modules: ['files', 'agent', 'workflows'], - category: 'marketing', - tags: ['content', 'enterprise'], - alsoIntegrations: ['mistral_parse'], - }, - { - icon: GoogleTranslateIcon, - title: 'Google Translate Confluence localization', - prompt: - 'Create a workflow that watches Confluence pages tagged for localization, translates each into the target languages with Google Translate, and publishes localized copies.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['content', 'enterprise'], - alsoIntegrations: ['confluence'], - }, - { - icon: GoogleTranslateIcon, - title: 'Multilingual support replies', - prompt: - "Build a workflow that on a new support ticket detects the customer's language with Google Translate, translates the message to English for the agent, drafts a reply, then translates the response back into the customer's language before sending.", - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - }, - { - icon: GoogleTranslateIcon, - title: 'Slack channel translator', - prompt: - "Create a workflow that watches an international Slack channel, detects non-English messages with Google Translate, translates them to the team's language, and posts the translation in a thread so everyone stays in the loop.", - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'translate-to-language', - description: - 'Translate a block of text into a target language using Google Cloud Translation.', - content: - '# Translate To Language\n\nTranslate text into a specified target language.\n\n## Steps\n1. Take the source text and the target language code (e.g. es, fr, ja).\n2. If the source language is unknown, detect it first; otherwise pass it explicitly for accuracy.\n3. Call translate text with the target language and capture the translated output.\n4. For long content, split into paragraph-sized chunks and translate each to preserve formatting.\n\n## Output\nReturn the translated text along with the detected or supplied source language and the target language. Preserve line breaks from the original.', - }, - { - name: 'detect-and-route-language', - description: 'Detect the language of incoming text and route or label it accordingly.', - content: - '# Detect and Route Language\n\nIdentify the language of a message so it can be routed, labeled, or translated.\n\n## Steps\n1. Call detect language on the input text and capture the language code and confidence.\n2. If confidence is low, fall back to detecting on a longer sample or flag as uncertain.\n3. Decide the route: if the detected language differs from the team language, translate it; otherwise pass through unchanged.\n\n## Output\nReturn the detected language code, confidence, and a recommended action (translate or pass-through). Include the translated text when translation was performed.', - }, - { - name: 'localize-message-set', - description: - 'Translate one source message into several target languages for multilingual delivery.', - content: - '# Localize Message Set\n\nProduce localized versions of a single message for multiple audiences.\n\n## Steps\n1. Take the source text and the list of target language codes.\n2. For each target language, call translate text with the source language set explicitly for consistency.\n3. Keep placeholders, names, and URLs intact across all translations.\n\n## Output\nReturn a mapping of language code to translated text. Note any target language where translation appeared incomplete or unchanged.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_vault.display.ts b/apps/sim/blocks/blocks/google_vault.display.ts index 99a454fb4af..d12208903b0 100644 --- a/apps/sim/blocks/blocks/google_vault.display.ts +++ b/apps/sim/blocks/blocks/google_vault.display.ts @@ -1,6 +1,7 @@ +import { ShieldCheck } from '@/components/emcn/icons' import { GoogleVaultIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GoogleVaultBlockDisplay = { type: 'google_vault', @@ -14,3 +15,98 @@ export const GoogleVaultBlockDisplay = { docsLink: 'https://developers.google.com/vault', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const GoogleVaultBlockMeta = { + tags: ['google-workspace', 'document-processing'], + url: 'https://support.google.com/vault', + templates: [ + { + icon: ShieldCheck, + title: 'Google Vault legal hold automator', + prompt: + 'Build a scheduled workflow that polls Salesforce for new legal-hold instructions, creates a Google Vault matter and hold for the named custodians, and notifies legal with the hold details.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ShieldCheck, + title: 'Google Vault hold auditor', + prompt: + 'Create a scheduled workflow that lists Google Vault matters and holds, flags custodians missing expected holds, and writes the findings to a compliance review table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: ShieldCheck, + title: 'Google Vault eDiscovery exporter', + prompt: + 'Build a workflow that takes an eDiscovery request, runs a Google Vault search, exports the matters into structured archives, and writes the export manifest.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: ShieldCheck, + title: 'Google Vault hold reviewer', + prompt: + 'Create a scheduled workflow that lists Google Vault holds across matters, summarizes their custodians and scope, and writes a review report for the legal team to approve.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: ShieldCheck, + title: 'Google Vault sensitive-term exporter', + prompt: + 'Build a scheduled workflow that creates Google Vault exports for sensitive search terms weekly, downloads the export results, and writes the matching items to a compliance review queue.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: ShieldCheck, + title: 'Google Vault export archiver', + prompt: + 'Create a scheduled workflow that creates Google Vault matter exports, downloads the export files, archives them to S3 long-term storage, and writes the manifest to a compliance table.', + modules: ['scheduled', 'tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['s3'], + }, + { + icon: ShieldCheck, + title: 'Google Vault custodian dashboard', + prompt: + 'Build a scheduled monthly workflow that summarizes Google Vault holds and custodians, generates a status dashboard, and writes it to a legal review file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + ], + skills: [ + { + name: 'open-legal-hold', + description: + 'Create a Vault matter and place a legal hold on custodians for an investigation or litigation.', + content: + '# Open Legal Hold\n\nStand up a Vault matter and preserve data for the relevant custodians.\n\n## Steps\n1. Create a matter with a clear name and description tied to the case or investigation.\n2. List existing matters first to avoid creating a duplicate for the same case.\n3. Create a hold on the matter for the named custodians and the relevant service (mail, Drive, etc.).\n4. List holds on the matter to confirm the custodians were preserved.\n\n## Output\nReturn the matterId, the holdId, and the list of custodians now under hold. Note any custodian that could not be added.', + }, + { + name: 'run-discovery-export', + description: + 'Create a Vault export for a matter using a search query, then retrieve the export files.', + content: + '# Run Discovery Export\n\nProduce an export of matching data for eDiscovery or compliance review.\n\n## Steps\n1. Identify or create the matter for the export.\n2. Create an export with the search query, date range, and target accounts/org unit scoped as narrowly as possible.\n3. List exports on the matter and poll until the new export status is completed.\n4. Download the export files once the export is ready.\n\n## Output\nReturn the exportId, its status, and the downloaded file references. Summarize the query and scope used so the export is auditable.', + }, + { + name: 'audit-active-holds', + description: + 'List Vault matters and their holds to produce a custodian preservation status report.', + content: + '# Audit Active Holds\n\nGenerate a status report of which matters and custodians are currently preserved.\n\n## Steps\n1. List all matters and capture their IDs, names, and states.\n2. For each open matter, list its holds and the custodians and services covered.\n3. Flag matters with no holds and custodians that appear across multiple matters.\n\n## Output\nReturn a per-matter summary listing holds, services, and custodians, plus a flagged section for matters missing holds. Suitable for a monthly legal review.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/google_vault.ts b/apps/sim/blocks/blocks/google_vault.ts index 2561defa1c9..4f71a1a6865 100644 --- a/apps/sim/blocks/blocks/google_vault.ts +++ b/apps/sim/blocks/blocks/google_vault.ts @@ -1,7 +1,6 @@ -import { ShieldCheck } from '@/components/emcn/icons' import { getScopesForService } from '@/lib/oauth/utils' import { GoogleVaultBlockDisplay } from '@/blocks/blocks/google_vault.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils' @@ -537,98 +536,3 @@ Return ONLY the description text - no explanations, no quotes, no extra text.`, }, }, } - -export const GoogleVaultBlockMeta = { - tags: ['google-workspace', 'document-processing'], - url: 'https://support.google.com/vault', - templates: [ - { - icon: ShieldCheck, - title: 'Google Vault legal hold automator', - prompt: - 'Build a scheduled workflow that polls Salesforce for new legal-hold instructions, creates a Google Vault matter and hold for the named custodians, and notifies legal with the hold details.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ShieldCheck, - title: 'Google Vault hold auditor', - prompt: - 'Create a scheduled workflow that lists Google Vault matters and holds, flags custodians missing expected holds, and writes the findings to a compliance review table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: ShieldCheck, - title: 'Google Vault eDiscovery exporter', - prompt: - 'Build a workflow that takes an eDiscovery request, runs a Google Vault search, exports the matters into structured archives, and writes the export manifest.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: ShieldCheck, - title: 'Google Vault hold reviewer', - prompt: - 'Create a scheduled workflow that lists Google Vault holds across matters, summarizes their custodians and scope, and writes a review report for the legal team to approve.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: ShieldCheck, - title: 'Google Vault sensitive-term exporter', - prompt: - 'Build a scheduled workflow that creates Google Vault exports for sensitive search terms weekly, downloads the export results, and writes the matching items to a compliance review queue.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: ShieldCheck, - title: 'Google Vault export archiver', - prompt: - 'Create a scheduled workflow that creates Google Vault matter exports, downloads the export files, archives them to S3 long-term storage, and writes the manifest to a compliance table.', - modules: ['scheduled', 'tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['s3'], - }, - { - icon: ShieldCheck, - title: 'Google Vault custodian dashboard', - prompt: - 'Build a scheduled monthly workflow that summarizes Google Vault holds and custodians, generates a status dashboard, and writes it to a legal review file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - ], - skills: [ - { - name: 'open-legal-hold', - description: - 'Create a Vault matter and place a legal hold on custodians for an investigation or litigation.', - content: - '# Open Legal Hold\n\nStand up a Vault matter and preserve data for the relevant custodians.\n\n## Steps\n1. Create a matter with a clear name and description tied to the case or investigation.\n2. List existing matters first to avoid creating a duplicate for the same case.\n3. Create a hold on the matter for the named custodians and the relevant service (mail, Drive, etc.).\n4. List holds on the matter to confirm the custodians were preserved.\n\n## Output\nReturn the matterId, the holdId, and the list of custodians now under hold. Note any custodian that could not be added.', - }, - { - name: 'run-discovery-export', - description: - 'Create a Vault export for a matter using a search query, then retrieve the export files.', - content: - '# Run Discovery Export\n\nProduce an export of matching data for eDiscovery or compliance review.\n\n## Steps\n1. Identify or create the matter for the export.\n2. Create an export with the search query, date range, and target accounts/org unit scoped as narrowly as possible.\n3. List exports on the matter and poll until the new export status is completed.\n4. Download the export files once the export is ready.\n\n## Output\nReturn the exportId, its status, and the downloaded file references. Summarize the query and scope used so the export is auditable.', - }, - { - name: 'audit-active-holds', - description: - 'List Vault matters and their holds to produce a custodian preservation status report.', - content: - '# Audit Active Holds\n\nGenerate a status report of which matters and custodians are currently preserved.\n\n## Steps\n1. List all matters and capture their IDs, names, and states.\n2. For each open matter, list its holds and the custodians and services covered.\n3. Flag matters with no holds and custodians that appear across multiple matters.\n\n## Output\nReturn a per-matter summary listing holds, services, and custodians, plus a flagged section for matters missing holds. Suitable for a monthly legal review.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/grafana.display.ts b/apps/sim/blocks/blocks/grafana.display.ts index 0420e80a6c6..b59e561bc8d 100644 --- a/apps/sim/blocks/blocks/grafana.display.ts +++ b/apps/sim/blocks/blocks/grafana.display.ts @@ -1,6 +1,6 @@ import { GrafanaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GrafanaBlockDisplay = { type: 'grafana', @@ -14,3 +14,113 @@ export const GrafanaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/grafana', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const GrafanaBlockMeta = { + tags: ['monitoring', 'data-analytics'], + url: 'https://grafana.com', + templates: [ + { + icon: GrafanaIcon, + title: 'Grafana alert auto-context', + prompt: + 'Build a scheduled workflow that polls Grafana for firing alert rules, pulls related logs and recent deploys, summarizes them with an agent, and posts the enriched alert to PagerDuty and Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty', 'slack'], + }, + { + icon: GrafanaIcon, + title: 'Grafana SLO scorecard', + prompt: + 'Create a scheduled weekly workflow that queries Grafana for SLO compliance across services, calculates burn rates, and writes a scorecard to a tables-based SRE review board.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + }, + { + icon: GrafanaIcon, + title: 'Grafana dashboard auditor', + prompt: + 'Build a scheduled workflow that scans Grafana dashboards monthly for broken panels, unused dashboards, and missing alerts, and writes a cleanup queue for the platform team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: GrafanaIcon, + title: 'Grafana metric export', + prompt: + 'Create a workflow that exports Grafana metric queries on schedule into a Sim table, so the data can be combined with business metrics for unified reporting.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + }, + { + icon: GrafanaIcon, + title: 'Grafana incident annotator', + prompt: + 'Build a scheduled workflow that polls PagerDuty for new incidents and adds Grafana annotations to relevant dashboards with the incident link, so engineers can see the context immediately on the timeline.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: GrafanaIcon, + title: 'Grafana on-call digest', + prompt: + 'Create a scheduled daily workflow that summarizes the past 24 hours of Grafana alerts by service and severity, and posts an on-call digest to Slack each morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GrafanaIcon, + title: 'Grafana + Linear feature-impact', + prompt: + 'Build a scheduled workflow that polls Grafana for metric regressions correlated with recent Linear releases and posts a regression review to the team Slack with the suspected change.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['linear', 'slack'], + }, + ], + skills: [ + { + name: 'annotate-deploy', + description: + 'Create a Grafana annotation marking a deploy or incident so it shows on dashboards.', + content: + '# Annotate Deploy\n\nMark a deploy, release, or incident on Grafana dashboards for correlation.\n\n## Steps\n1. Build the annotation text (e.g. version, PR link, who triggered it) and tags for filtering.\n2. Create an annotation with the event time, or a time range for incidents with a start and end.\n3. Optionally scope the annotation to a specific dashboard so it appears only there.\n4. List annotations for the window to confirm it was recorded.\n\n## Output\nReturn the annotation ID, time, and tags. Useful for correlating metric changes with deploys later.', + }, + { + name: 'review-firing-alerts', + description: + 'List Grafana alert rules and surface those currently firing with their contact points.', + content: + '# Review Firing Alerts\n\nProduce a snapshot of alerting health for an on-call handoff or incident triage.\n\n## Steps\n1. List alert rules and capture each rule name, condition, and current state.\n2. Get details on rules that are firing or in a pending state.\n3. List contact points so each firing rule can be mapped to who gets notified.\n4. Group findings by severity or folder.\n\n## Output\nReturn a list of firing and pending alerts with rule name, state, and notification target, plus a count of healthy rules. Suitable for an on-call digest.', + }, + { + name: 'audit-dashboards', + description: 'List Grafana dashboards and folders and report data sources each depends on.', + content: + '# Audit Dashboards\n\nInventory dashboards and the data sources they rely on.\n\n## Steps\n1. List folders and dashboards to build the full inventory.\n2. Get details for each dashboard of interest to read its panels and referenced data sources.\n3. List data sources, then check the health of each one to flag dashboards pointing at unreachable or deprecated sources.\n\n## Output\nReturn an inventory grouped by folder, each dashboard with its UID and the data sources it uses, plus a flagged list of dashboards whose data sources failed their health check.', + }, + { + name: 'provision-monitoring-folder', + description: + 'Create a Grafana folder and seed it with a starter dashboard for a new service or team.', + content: + '# Provision Monitoring Folder\n\nSet up an organized monitoring home for a new service or team.\n\n## Steps\n1. Create a folder with a descriptive title for the service or team.\n2. List data sources and pick the one the new dashboard should query.\n3. Create a dashboard inside the folder with starter panels for the key metrics.\n4. Get the dashboard back to confirm it was created in the right folder.\n\n## Output\nReturn the folder UID and the new dashboard UID and link. Note the data source the dashboard was wired to.', + }, + { + name: 'provision-alerting', + description: + 'Stand up a Grafana alert rule and the contact point it notifies for a new service.', + content: + '# Provision Alerting\n\nWire up end-to-end alerting for a service: a notification target plus the rule that fires to it.\n\n## Steps\n1. List existing contact points to avoid duplicating one.\n2. Create a contact point for the destination (Slack, email, or PagerDuty) with its settings.\n3. Create an alert rule in the target folder with the query data, condition, and for-duration.\n4. Get the alert rule back to confirm it was created and is not paused.\n\n## Output\nReturn the new contact point UID and alert rule UID, with the data source and threshold the rule evaluates.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/grafana.ts b/apps/sim/blocks/blocks/grafana.ts index 538292ea4d8..9d79bb35583 100644 --- a/apps/sim/blocks/blocks/grafana.ts +++ b/apps/sim/blocks/blocks/grafana.ts @@ -1,6 +1,5 @@ -import { GrafanaIcon } from '@/components/icons' import { GrafanaBlockDisplay } from '@/blocks/blocks/grafana.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { GrafanaResponse } from '@/tools/grafana/types' @@ -1104,113 +1103,3 @@ Return ONLY the JSON object - no explanations, no markdown, no extra text.`, message: { type: 'string', description: 'Status message' }, }, } - -export const GrafanaBlockMeta = { - tags: ['monitoring', 'data-analytics'], - url: 'https://grafana.com', - templates: [ - { - icon: GrafanaIcon, - title: 'Grafana alert auto-context', - prompt: - 'Build a scheduled workflow that polls Grafana for firing alert rules, pulls related logs and recent deploys, summarizes them with an agent, and posts the enriched alert to PagerDuty and Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty', 'slack'], - }, - { - icon: GrafanaIcon, - title: 'Grafana SLO scorecard', - prompt: - 'Create a scheduled weekly workflow that queries Grafana for SLO compliance across services, calculates burn rates, and writes a scorecard to a tables-based SRE review board.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - }, - { - icon: GrafanaIcon, - title: 'Grafana dashboard auditor', - prompt: - 'Build a scheduled workflow that scans Grafana dashboards monthly for broken panels, unused dashboards, and missing alerts, and writes a cleanup queue for the platform team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: GrafanaIcon, - title: 'Grafana metric export', - prompt: - 'Create a workflow that exports Grafana metric queries on schedule into a Sim table, so the data can be combined with business metrics for unified reporting.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - }, - { - icon: GrafanaIcon, - title: 'Grafana incident annotator', - prompt: - 'Build a scheduled workflow that polls PagerDuty for new incidents and adds Grafana annotations to relevant dashboards with the incident link, so engineers can see the context immediately on the timeline.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: GrafanaIcon, - title: 'Grafana on-call digest', - prompt: - 'Create a scheduled daily workflow that summarizes the past 24 hours of Grafana alerts by service and severity, and posts an on-call digest to Slack each morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GrafanaIcon, - title: 'Grafana + Linear feature-impact', - prompt: - 'Build a scheduled workflow that polls Grafana for metric regressions correlated with recent Linear releases and posts a regression review to the team Slack with the suspected change.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['linear', 'slack'], - }, - ], - skills: [ - { - name: 'annotate-deploy', - description: - 'Create a Grafana annotation marking a deploy or incident so it shows on dashboards.', - content: - '# Annotate Deploy\n\nMark a deploy, release, or incident on Grafana dashboards for correlation.\n\n## Steps\n1. Build the annotation text (e.g. version, PR link, who triggered it) and tags for filtering.\n2. Create an annotation with the event time, or a time range for incidents with a start and end.\n3. Optionally scope the annotation to a specific dashboard so it appears only there.\n4. List annotations for the window to confirm it was recorded.\n\n## Output\nReturn the annotation ID, time, and tags. Useful for correlating metric changes with deploys later.', - }, - { - name: 'review-firing-alerts', - description: - 'List Grafana alert rules and surface those currently firing with their contact points.', - content: - '# Review Firing Alerts\n\nProduce a snapshot of alerting health for an on-call handoff or incident triage.\n\n## Steps\n1. List alert rules and capture each rule name, condition, and current state.\n2. Get details on rules that are firing or in a pending state.\n3. List contact points so each firing rule can be mapped to who gets notified.\n4. Group findings by severity or folder.\n\n## Output\nReturn a list of firing and pending alerts with rule name, state, and notification target, plus a count of healthy rules. Suitable for an on-call digest.', - }, - { - name: 'audit-dashboards', - description: 'List Grafana dashboards and folders and report data sources each depends on.', - content: - '# Audit Dashboards\n\nInventory dashboards and the data sources they rely on.\n\n## Steps\n1. List folders and dashboards to build the full inventory.\n2. Get details for each dashboard of interest to read its panels and referenced data sources.\n3. List data sources, then check the health of each one to flag dashboards pointing at unreachable or deprecated sources.\n\n## Output\nReturn an inventory grouped by folder, each dashboard with its UID and the data sources it uses, plus a flagged list of dashboards whose data sources failed their health check.', - }, - { - name: 'provision-monitoring-folder', - description: - 'Create a Grafana folder and seed it with a starter dashboard for a new service or team.', - content: - '# Provision Monitoring Folder\n\nSet up an organized monitoring home for a new service or team.\n\n## Steps\n1. Create a folder with a descriptive title for the service or team.\n2. List data sources and pick the one the new dashboard should query.\n3. Create a dashboard inside the folder with starter panels for the key metrics.\n4. Get the dashboard back to confirm it was created in the right folder.\n\n## Output\nReturn the folder UID and the new dashboard UID and link. Note the data source the dashboard was wired to.', - }, - { - name: 'provision-alerting', - description: - 'Stand up a Grafana alert rule and the contact point it notifies for a new service.', - content: - '# Provision Alerting\n\nWire up end-to-end alerting for a service: a notification target plus the rule that fires to it.\n\n## Steps\n1. List existing contact points to avoid duplicating one.\n2. Create a contact point for the destination (Slack, email, or PagerDuty) with its settings.\n3. Create an alert rule in the target folder with the query data, condition, and for-duration.\n4. Get the alert rule back to confirm it was created and is not paused.\n\n## Output\nReturn the new contact point UID and alert rule UID, with the data source and threshold the rule evaluates.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/grain.display.ts b/apps/sim/blocks/blocks/grain.display.ts index 4bf9030b57d..c16517fd445 100644 --- a/apps/sim/blocks/blocks/grain.display.ts +++ b/apps/sim/blocks/blocks/grain.display.ts @@ -1,6 +1,6 @@ import { GrainIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GrainBlockDisplay = { type: 'grain', @@ -15,3 +15,100 @@ export const GrainBlockDisplay = { integrationType: IntegrationType.Productivity, triggerAllowed: true, } satisfies BlockDisplay + +export const GrainBlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://grain.com', + templates: [ + { + icon: GrainIcon, + title: 'Grain highlight to CRM', + prompt: + 'Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: GrainIcon, + title: 'Grain customer-quote miner', + prompt: + 'Create a workflow that processes Grain customer interview recordings, extracts notable quotes and themes, and writes them to a marketing research table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: GrainIcon, + title: 'Grain action-item ticket creator', + prompt: + 'Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: GrainIcon, + title: 'Grain weekly call digest', + prompt: + 'Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GrainIcon, + title: 'Grain coaching dashboard', + prompt: + 'Build a scheduled weekly workflow that analyzes Grain sales calls per rep, calculates talk ratio, objection handling, and next-step clarity, and writes coaching notes to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + }, + { + icon: GrainIcon, + title: 'Grain + Notion knowledge sync', + prompt: + 'Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: GrainIcon, + title: 'Grain competitor mentions tracker', + prompt: + 'Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'summarize-recent-calls', + description: + 'Pull recent Grain recordings and produce a digest of key takeaways and action items per call.', + content: + '# Summarize Recent Calls\n\nTurn recent meeting recordings into a readable digest.\n\n## Steps\n1. List recordings, optionally filtered by a before/after datetime window, and paginate with the cursor if needed.\n2. For each recording, get the recording details and the transcript.\n3. From each transcript, extract the main topic, key takeaways, decisions, and action items with owners.\n4. Keep the per-call summary concise and consistent in structure.\n\n## Output\nReturn a digest with one section per call: title, date, participants, takeaways, and action items. Suitable for a daily or weekly recap.', + }, + { + name: 'extract-deal-signals', + description: + 'Scan Grain sales-call transcripts for buying signals, objections, and competitor mentions.', + content: + '# Extract Deal Signals\n\nMine sales transcripts for signals that move a deal forward.\n\n## Steps\n1. List recordings for the target time window, or filter by a view that holds sales calls.\n2. Get the transcript for each recording.\n3. Classify mentions into buying signals, objections/risks, competitor mentions, and next steps, capturing the verbatim quote and context.\n4. Apply a framework (e.g. MEDDIC or SPICED) if one is specified to tag each insight.\n\n## Output\nReturn a structured list of signals grouped by category, each with the quote, the call it came from, and a suggested follow-up. Useful for CRM notes or a deal review.', + }, + { + name: 'pull-transcript', + description: 'Retrieve a specific Grain recording and its full transcript by ID.', + content: + '# Pull Transcript\n\nFetch a single recording and its transcript for downstream use.\n\n## Steps\n1. If only a title or date is known, list recordings and match to find the recording ID.\n2. Get the recording details for metadata (title, participants, duration, date).\n3. Get the transcript for the recording.\n4. Clean the transcript into readable speaker-labeled turns.\n\n## Output\nReturn the recording metadata plus the formatted transcript. This is the building block for summaries, follow-up emails, or knowledge base ingestion.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/grain.ts b/apps/sim/blocks/blocks/grain.ts index 8a9c70ace0e..fd9b6017ee6 100644 --- a/apps/sim/blocks/blocks/grain.ts +++ b/apps/sim/blocks/blocks/grain.ts @@ -1,6 +1,5 @@ -import { GrainIcon } from '@/components/icons' import { GrainBlockDisplay } from '@/blocks/blocks/grain.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' import { grainTriggerOptions } from '@/triggers/grain/utils' @@ -452,100 +451,3 @@ Return ONLY the search term - no explanations, no quotes, no extra text.`, ], }, } - -export const GrainBlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://grain.com', - templates: [ - { - icon: GrainIcon, - title: 'Grain highlight to CRM', - prompt: - 'Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: GrainIcon, - title: 'Grain customer-quote miner', - prompt: - 'Create a workflow that processes Grain customer interview recordings, extracts notable quotes and themes, and writes them to a marketing research table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: GrainIcon, - title: 'Grain action-item ticket creator', - prompt: - 'Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: GrainIcon, - title: 'Grain weekly call digest', - prompt: - 'Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GrainIcon, - title: 'Grain coaching dashboard', - prompt: - 'Build a scheduled weekly workflow that analyzes Grain sales calls per rep, calculates talk ratio, objection handling, and next-step clarity, and writes coaching notes to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - }, - { - icon: GrainIcon, - title: 'Grain + Notion knowledge sync', - prompt: - 'Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: GrainIcon, - title: 'Grain competitor mentions tracker', - prompt: - 'Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'summarize-recent-calls', - description: - 'Pull recent Grain recordings and produce a digest of key takeaways and action items per call.', - content: - '# Summarize Recent Calls\n\nTurn recent meeting recordings into a readable digest.\n\n## Steps\n1. List recordings, optionally filtered by a before/after datetime window, and paginate with the cursor if needed.\n2. For each recording, get the recording details and the transcript.\n3. From each transcript, extract the main topic, key takeaways, decisions, and action items with owners.\n4. Keep the per-call summary concise and consistent in structure.\n\n## Output\nReturn a digest with one section per call: title, date, participants, takeaways, and action items. Suitable for a daily or weekly recap.', - }, - { - name: 'extract-deal-signals', - description: - 'Scan Grain sales-call transcripts for buying signals, objections, and competitor mentions.', - content: - '# Extract Deal Signals\n\nMine sales transcripts for signals that move a deal forward.\n\n## Steps\n1. List recordings for the target time window, or filter by a view that holds sales calls.\n2. Get the transcript for each recording.\n3. Classify mentions into buying signals, objections/risks, competitor mentions, and next steps, capturing the verbatim quote and context.\n4. Apply a framework (e.g. MEDDIC or SPICED) if one is specified to tag each insight.\n\n## Output\nReturn a structured list of signals grouped by category, each with the quote, the call it came from, and a suggested follow-up. Useful for CRM notes or a deal review.', - }, - { - name: 'pull-transcript', - description: 'Retrieve a specific Grain recording and its full transcript by ID.', - content: - '# Pull Transcript\n\nFetch a single recording and its transcript for downstream use.\n\n## Steps\n1. If only a title or date is known, list recordings and match to find the recording ID.\n2. Get the recording details for metadata (title, participants, duration, date).\n3. Get the transcript for the recording.\n4. Clean the transcript into readable speaker-labeled turns.\n\n## Output\nReturn the recording metadata plus the formatted transcript. This is the building block for summaries, follow-up emails, or knowledge base ingestion.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/granola.display.ts b/apps/sim/blocks/blocks/granola.display.ts index d6cb3fddd6c..1328028a6db 100644 --- a/apps/sim/blocks/blocks/granola.display.ts +++ b/apps/sim/blocks/blocks/granola.display.ts @@ -1,6 +1,6 @@ import { GranolaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GranolaBlockDisplay = { type: 'granola', @@ -14,3 +14,100 @@ export const GranolaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/granola', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const GranolaBlockMeta = { + tags: ['meeting', 'note-taking'], + url: 'https://granola.ai', + templates: [ + { + icon: GranolaIcon, + title: 'Granola meeting brief', + prompt: + 'Build a scheduled workflow that reads upcoming meetings from Granola notes, researches attendees and topic with Apollo, and posts a prep brief to Slack before each meeting.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo', 'slack'], + }, + { + icon: GranolaIcon, + title: 'Granola action-item ticket creator', + prompt: + 'Create a workflow that extracts action items from Granola meeting notes, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['linear', 'asana'], + }, + { + icon: GranolaIcon, + title: 'Granola CRM updater', + prompt: + 'Build a workflow that runs after a Granola sales meeting, summarizes the meeting notes into a deal-ready summary, and updates the linked Salesforce or HubSpot opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: GranolaIcon, + title: 'Granola weekly digest', + prompt: + 'Create a scheduled weekly workflow that aggregates Granola meeting notes, identifies recurring themes and decisions, and writes a digest to the team Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GranolaIcon, + title: 'Granola + Notion publisher', + prompt: + 'Build a scheduled workflow that polls Granola for new meeting notes, generates a polished meeting-notes page in Notion under the right team space, and links the original Granola note.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: GranolaIcon, + title: 'Granola customer-interview extractor', + prompt: + 'Create a workflow that processes Granola customer-interview notes, extracts notable quotes and pain points, and writes them to a tables-based research log.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: GranolaIcon, + title: 'Granola decision-log keeper', + prompt: + 'Build a workflow that scans Granola meeting notes for decisions made, writes each to a tables-based decision log with date, owner, and context, and shares the link.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + }, + ], + skills: [ + { + name: 'digest-meeting-notes', + description: + 'List recent Granola notes and produce a structured digest of takeaways and action items.', + content: + '# Digest Meeting Notes\n\nTurn recent Granola meeting notes into a concise digest.\n\n## Steps\n1. List notes, optionally limited to a recent time window.\n2. For each note, get the full note content.\n3. Extract the meeting title, key decisions, takeaways, and action items with owners and due dates if present.\n4. Keep each meeting summary short and uniformly structured.\n\n## Output\nReturn a digest with one section per meeting: title, date, decisions, takeaways, and action items. Suitable for a team recap or daily summary.', + }, + { + name: 'extract-action-items', + description: 'Read a Granola note and pull out a clean list of action items with owners.', + content: + '# Extract Action Items\n\nIsolate the follow-ups from a single meeting note.\n\n## Steps\n1. If only a title or date is known, list notes and match to find the note ID.\n2. Get the note content.\n3. Identify every action item, normalizing each into a clear task with an owner and due date when stated.\n4. Drop duplicates and merge near-identical items.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date. Ready to push into a task manager or tracking table.', + }, + { + name: 'log-decisions', + description: + 'Scan Granola notes for decisions made and compile them into a dated decision log.', + content: + '# Log Decisions\n\nBuild an auditable record of decisions captured in meetings.\n\n## Steps\n1. List notes across the target window.\n2. Get each note and identify explicit decisions, the rationale, and who made them.\n3. Normalize each into a row with date, decision, owner, and context.\n\n## Output\nReturn a chronological decision log, each entry with date, decision, owner, and supporting context. Useful for writing to a decision-tracking table.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/granola.ts b/apps/sim/blocks/blocks/granola.ts index 65c970eadf8..9de434dd99b 100644 --- a/apps/sim/blocks/blocks/granola.ts +++ b/apps/sim/blocks/blocks/granola.ts @@ -1,6 +1,5 @@ -import { GranolaIcon } from '@/components/icons' import { GranolaBlockDisplay } from '@/blocks/blocks/granola.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' export const GranolaBlock: BlockConfig = { ...GranolaBlockDisplay, @@ -173,100 +172,3 @@ export const GranolaBlock: BlockConfig = { }, }, } - -export const GranolaBlockMeta = { - tags: ['meeting', 'note-taking'], - url: 'https://granola.ai', - templates: [ - { - icon: GranolaIcon, - title: 'Granola meeting brief', - prompt: - 'Build a scheduled workflow that reads upcoming meetings from Granola notes, researches attendees and topic with Apollo, and posts a prep brief to Slack before each meeting.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo', 'slack'], - }, - { - icon: GranolaIcon, - title: 'Granola action-item ticket creator', - prompt: - 'Create a workflow that extracts action items from Granola meeting notes, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['linear', 'asana'], - }, - { - icon: GranolaIcon, - title: 'Granola CRM updater', - prompt: - 'Build a workflow that runs after a Granola sales meeting, summarizes the meeting notes into a deal-ready summary, and updates the linked Salesforce or HubSpot opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: GranolaIcon, - title: 'Granola weekly digest', - prompt: - 'Create a scheduled weekly workflow that aggregates Granola meeting notes, identifies recurring themes and decisions, and writes a digest to the team Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GranolaIcon, - title: 'Granola + Notion publisher', - prompt: - 'Build a scheduled workflow that polls Granola for new meeting notes, generates a polished meeting-notes page in Notion under the right team space, and links the original Granola note.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: GranolaIcon, - title: 'Granola customer-interview extractor', - prompt: - 'Create a workflow that processes Granola customer-interview notes, extracts notable quotes and pain points, and writes them to a tables-based research log.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: GranolaIcon, - title: 'Granola decision-log keeper', - prompt: - 'Build a workflow that scans Granola meeting notes for decisions made, writes each to a tables-based decision log with date, owner, and context, and shares the link.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - }, - ], - skills: [ - { - name: 'digest-meeting-notes', - description: - 'List recent Granola notes and produce a structured digest of takeaways and action items.', - content: - '# Digest Meeting Notes\n\nTurn recent Granola meeting notes into a concise digest.\n\n## Steps\n1. List notes, optionally limited to a recent time window.\n2. For each note, get the full note content.\n3. Extract the meeting title, key decisions, takeaways, and action items with owners and due dates if present.\n4. Keep each meeting summary short and uniformly structured.\n\n## Output\nReturn a digest with one section per meeting: title, date, decisions, takeaways, and action items. Suitable for a team recap or daily summary.', - }, - { - name: 'extract-action-items', - description: 'Read a Granola note and pull out a clean list of action items with owners.', - content: - '# Extract Action Items\n\nIsolate the follow-ups from a single meeting note.\n\n## Steps\n1. If only a title or date is known, list notes and match to find the note ID.\n2. Get the note content.\n3. Identify every action item, normalizing each into a clear task with an owner and due date when stated.\n4. Drop duplicates and merge near-identical items.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date. Ready to push into a task manager or tracking table.', - }, - { - name: 'log-decisions', - description: - 'Scan Granola notes for decisions made and compile them into a dated decision log.', - content: - '# Log Decisions\n\nBuild an auditable record of decisions captured in meetings.\n\n## Steps\n1. List notes across the target window.\n2. Get each note and identify explicit decisions, the rationale, and who made them.\n3. Normalize each into a row with date, decision, owner, and context.\n\n## Output\nReturn a chronological decision log, each entry with date, decision, owner, and supporting context. Useful for writing to a decision-tracking table.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/greenhouse.display.ts b/apps/sim/blocks/blocks/greenhouse.display.ts index d0d369d1adf..747cbf702e2 100644 --- a/apps/sim/blocks/blocks/greenhouse.display.ts +++ b/apps/sim/blocks/blocks/greenhouse.display.ts @@ -1,6 +1,6 @@ import { GreenhouseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GreenhouseBlockDisplay = { type: 'greenhouse', @@ -15,3 +15,102 @@ export const GreenhouseBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/greenhouse', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const GreenhouseBlockMeta = { + tags: ['hiring'], + url: 'https://www.greenhouse.com', + templates: [ + { + icon: GreenhouseIcon, + title: 'Recruiting pipeline automator', + prompt: + 'Build a scheduled workflow that syncs open jobs and candidates from Greenhouse to a tracking table daily, flags candidates who have been in the same stage for more than 5 days, and sends a Slack summary to hiring managers with pipeline stats and bottlenecks.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse to onboarding kickoff', + prompt: + 'Build a workflow that fires when a Greenhouse application is marked hired, gathers the new hire profile, kicks off an onboarding plan in a table, schedules week-one meetings via Google Calendar, and posts a welcome announcement to Slack.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation', 'team'], + alsoIntegrations: ['google_calendar', 'slack'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse candidate enricher', + prompt: + 'Create a workflow that watches for new Greenhouse candidates, enriches each profile with LinkedIn background, GitHub activity, and public writing, and writes a structured research summary to a recruiting table for recruiters to review.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'research'], + alsoIntegrations: ['linkedin', 'github'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse interview scheduler', + prompt: + 'Build a workflow that runs after a Greenhouse application reaches the interview stage, finds the right interviewer panel based on job stage, proposes time slots from Google Calendar, drafts a coordination email to the candidate, and confirms the booking in a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'automation'], + alsoIntegrations: ['google_calendar', 'gmail'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse offer drafter', + prompt: + 'Create a workflow that takes an approved Greenhouse application, pulls compensation bands from a knowledge base, drafts a tailored offer letter file, prepares an explanation email, and routes both to the hiring manager for review before sending to the candidate.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'content'], + alsoIntegrations: ['gmail'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse rejection follow-up', + prompt: + 'Build a workflow that runs when a Greenhouse candidate is rejected, drafts a warm and respectful rejection email tailored to how far they progressed, sends it via Gmail, and logs the candidate with their interest areas to a future-talent table for re-engagement.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'communication', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: GreenhouseIcon, + title: 'Greenhouse interview prep packet', + prompt: + 'Create a workflow that runs the morning of every Greenhouse interview, pulls the candidate profile, prior interview notes, and job rubric, assembles a one-page prep file for the interviewer, and emails it with a Slack DM reminder thirty minutes before the slot.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'team'], + alsoIntegrations: ['gmail', 'slack'], + }, + ], + skills: [ + { + name: 'build-pipeline-report', + description: + 'Summarize Greenhouse applications per job by stage to produce a hiring pipeline report.', + content: + '# Build Pipeline Report\n\nReport how candidates are progressing through each open job.\n\n## Steps\n1. List jobs and filter to open requisitions, capturing job IDs and titles.\n2. List job stages so application counts can be bucketed correctly.\n3. List applications, optionally filtered by status, and group them by job and current stage.\n4. Compute counts per stage and flag jobs with no recent movement.\n\n## Output\nReturn a per-job breakdown showing candidate counts by stage, total active candidates, and a flagged list of stalled requisitions. Suitable for a weekly recruiting standup.', + }, + { + name: 'assemble-candidate-brief', + description: + 'Pull a Greenhouse candidate and their application details into a one-page interviewer brief.', + content: + '# Assemble Candidate Brief\n\nCompile everything an interviewer needs about a candidate.\n\n## Steps\n1. Find the candidate by listing candidates and matching name, or use a known candidate ID.\n2. Get the candidate to retrieve profile details and attachments.\n3. Get the application to read the job applied for, current stage, and source.\n4. Get the job for the role context and requirements.\n\n## Output\nReturn a one-page brief: candidate summary, role and current stage, key background points, and any notes. Ready to email or DM to the interviewer before the slot.', + }, + { + name: 'audit-open-roles', + description: 'List open Greenhouse jobs with their departments, offices, and hiring teams.', + content: + '# Audit Open Roles\n\nInventory active requisitions and who owns them.\n\n## Steps\n1. List jobs and filter to open status.\n2. List departments and offices to resolve the names referenced on each job.\n3. List users to map hiring team members and recruiters to each role.\n4. Assemble each job with its department, office, and owning team.\n\n## Output\nReturn an inventory of open roles, each with title, department, office, and hiring team. Flag any role missing a recruiter or hiring manager.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/greenhouse.ts b/apps/sim/blocks/blocks/greenhouse.ts index 209a028d7be..f5e8346f34c 100644 --- a/apps/sim/blocks/blocks/greenhouse.ts +++ b/apps/sim/blocks/blocks/greenhouse.ts @@ -1,6 +1,5 @@ -import { GreenhouseIcon } from '@/components/icons' import { GreenhouseBlockDisplay } from '@/blocks/blocks/greenhouse.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { GreenhouseResponse } from '@/tools/greenhouse/types' import { getTrigger } from '@/triggers' @@ -411,102 +410,3 @@ Return ONLY the ISO 8601 timestamp - no explanations, no extra text.`, updated_at: { type: 'string', description: 'Last updated timestamp (ISO 8601)' }, }, } - -export const GreenhouseBlockMeta = { - tags: ['hiring'], - url: 'https://www.greenhouse.com', - templates: [ - { - icon: GreenhouseIcon, - title: 'Recruiting pipeline automator', - prompt: - 'Build a scheduled workflow that syncs open jobs and candidates from Greenhouse to a tracking table daily, flags candidates who have been in the same stage for more than 5 days, and sends a Slack summary to hiring managers with pipeline stats and bottlenecks.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse to onboarding kickoff', - prompt: - 'Build a workflow that fires when a Greenhouse application is marked hired, gathers the new hire profile, kicks off an onboarding plan in a table, schedules week-one meetings via Google Calendar, and posts a welcome announcement to Slack.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation', 'team'], - alsoIntegrations: ['google_calendar', 'slack'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse candidate enricher', - prompt: - 'Create a workflow that watches for new Greenhouse candidates, enriches each profile with LinkedIn background, GitHub activity, and public writing, and writes a structured research summary to a recruiting table for recruiters to review.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'research'], - alsoIntegrations: ['linkedin', 'github'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse interview scheduler', - prompt: - 'Build a workflow that runs after a Greenhouse application reaches the interview stage, finds the right interviewer panel based on job stage, proposes time slots from Google Calendar, drafts a coordination email to the candidate, and confirms the booking in a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'automation'], - alsoIntegrations: ['google_calendar', 'gmail'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse offer drafter', - prompt: - 'Create a workflow that takes an approved Greenhouse application, pulls compensation bands from a knowledge base, drafts a tailored offer letter file, prepares an explanation email, and routes both to the hiring manager for review before sending to the candidate.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'content'], - alsoIntegrations: ['gmail'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse rejection follow-up', - prompt: - 'Build a workflow that runs when a Greenhouse candidate is rejected, drafts a warm and respectful rejection email tailored to how far they progressed, sends it via Gmail, and logs the candidate with their interest areas to a future-talent table for re-engagement.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'communication', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: GreenhouseIcon, - title: 'Greenhouse interview prep packet', - prompt: - 'Create a workflow that runs the morning of every Greenhouse interview, pulls the candidate profile, prior interview notes, and job rubric, assembles a one-page prep file for the interviewer, and emails it with a Slack DM reminder thirty minutes before the slot.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'team'], - alsoIntegrations: ['gmail', 'slack'], - }, - ], - skills: [ - { - name: 'build-pipeline-report', - description: - 'Summarize Greenhouse applications per job by stage to produce a hiring pipeline report.', - content: - '# Build Pipeline Report\n\nReport how candidates are progressing through each open job.\n\n## Steps\n1. List jobs and filter to open requisitions, capturing job IDs and titles.\n2. List job stages so application counts can be bucketed correctly.\n3. List applications, optionally filtered by status, and group them by job and current stage.\n4. Compute counts per stage and flag jobs with no recent movement.\n\n## Output\nReturn a per-job breakdown showing candidate counts by stage, total active candidates, and a flagged list of stalled requisitions. Suitable for a weekly recruiting standup.', - }, - { - name: 'assemble-candidate-brief', - description: - 'Pull a Greenhouse candidate and their application details into a one-page interviewer brief.', - content: - '# Assemble Candidate Brief\n\nCompile everything an interviewer needs about a candidate.\n\n## Steps\n1. Find the candidate by listing candidates and matching name, or use a known candidate ID.\n2. Get the candidate to retrieve profile details and attachments.\n3. Get the application to read the job applied for, current stage, and source.\n4. Get the job for the role context and requirements.\n\n## Output\nReturn a one-page brief: candidate summary, role and current stage, key background points, and any notes. Ready to email or DM to the interviewer before the slot.', - }, - { - name: 'audit-open-roles', - description: 'List open Greenhouse jobs with their departments, offices, and hiring teams.', - content: - '# Audit Open Roles\n\nInventory active requisitions and who owns them.\n\n## Steps\n1. List jobs and filter to open status.\n2. List departments and offices to resolve the names referenced on each job.\n3. List users to map hiring team members and recruiters to each role.\n4. Assemble each job with its department, office, and owning team.\n\n## Output\nReturn an inventory of open roles, each with title, department, office, and hiring team. Flag any role missing a recruiter or hiring manager.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/greptile.display.ts b/apps/sim/blocks/blocks/greptile.display.ts index be50795d5bb..831744084fb 100644 --- a/apps/sim/blocks/blocks/greptile.display.ts +++ b/apps/sim/blocks/blocks/greptile.display.ts @@ -1,6 +1,7 @@ -import { GreptileIcon } from '@/components/icons' +import { ClipboardList } from '@/components/emcn/icons' +import { GreptileIcon, SlackIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const GreptileBlockDisplay = { type: 'greptile', @@ -14,3 +15,63 @@ export const GreptileBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/greptile', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const GreptileBlockMeta = { + tags: ['version-control', 'knowledge-base'], + url: 'https://www.greptile.com', + templates: [ + { + icon: SlackIcon, + title: 'Slack code Q&A bot', + prompt: + 'Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: GreptileIcon, + title: 'Onboarding codebase explainer', + prompt: + 'Create a workflow where a new engineer asks how a part of the codebase works, Greptile answers against the indexed repository with cited files, and the explanation is saved to a Google Doc.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'onboarding'], + alsoIntegrations: ['google_docs'], + }, + { + icon: ClipboardList, + title: 'PR review with codebase context', + prompt: + 'Build a workflow that takes a pull request, asks Greptile how the changed code interacts with the rest of the repository, and writes a review comment summarizing impact and risks with cited files.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'code-review'], + alsoIntegrations: ['github'], + }, + ], + skills: [ + { + name: 'answer-codebase-question', + description: + 'Ask Greptile a natural-language question about an indexed repository and return a cited answer.', + content: + '# Answer Codebase Question\n\nGet an accurate, source-cited answer about how a codebase works.\n\n## Steps\n1. Confirm the repository is indexed by checking its index status; if not ready, index it first and wait.\n2. Query Greptile with the natural-language question (e.g. how authentication flows, where payments are processed).\n3. Capture the answer along with the file and function references it cites.\n4. If the answer is vague, refine the question with more specifics and re-query.\n\n## Output\nReturn the answer plus a list of cited files and symbols. Useful for onboarding, debugging, and understanding unfamiliar code.', + }, + { + name: 'review-pull-request', + description: + 'Use Greptile to assess how a PR diff interacts with the rest of the repo and draft review notes.', + content: + '# Review Pull Request\n\nProduce a codebase-aware review of a set of changes.\n\n## Steps\n1. Ensure the repository is indexed (check status, index if needed).\n2. Query Greptile describing the changed files and ask how they interact with the rest of the codebase, what might break, and what edge cases to test.\n3. Collect the impact analysis and the cited files affected beyond the diff.\n4. Organize findings into bugs/risks, style/consistency, and suggested tests.\n\n## Output\nReturn structured review notes grouped by severity, each with the cited file and a concrete suggestion. Ready to post as a PR comment.', + }, + { + name: 'index-and-verify-repo', + description: + 'Trigger Greptile indexing for a repository and poll until it is ready to query.', + content: + '# Index and Verify Repo\n\nMake a repository queryable in Greptile.\n\n## Steps\n1. Start indexing for the repository, specifying the remote, owner/repo, and branch.\n2. Poll the index status until it reports completed or fails.\n3. On failure, report the error and the branch/remote used so it can be corrected.\n4. On success, run a quick sanity query to confirm answers come back with citations.\n\n## Output\nReturn the final index status, the branch indexed, and the result of the sanity query. Confirms the repo is ready for codebase questions and reviews.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/greptile.ts b/apps/sim/blocks/blocks/greptile.ts index cf38adcb418..b2ed5c1c70b 100644 --- a/apps/sim/blocks/blocks/greptile.ts +++ b/apps/sim/blocks/blocks/greptile.ts @@ -1,7 +1,5 @@ -import { ClipboardList } from '@/components/emcn/icons' -import { GreptileIcon, SlackIcon } from '@/components/icons' import { GreptileBlockDisplay } from '@/blocks/blocks/greptile.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { GreptileResponse } from '@/tools/greptile/types' @@ -188,63 +186,3 @@ export const GreptileBlock: BlockConfig = { sha: { type: 'string', description: 'Git commit SHA' }, }, } - -export const GreptileBlockMeta = { - tags: ['version-control', 'knowledge-base'], - url: 'https://www.greptile.com', - templates: [ - { - icon: SlackIcon, - title: 'Slack code Q&A bot', - prompt: - 'Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: GreptileIcon, - title: 'Onboarding codebase explainer', - prompt: - 'Create a workflow where a new engineer asks how a part of the codebase works, Greptile answers against the indexed repository with cited files, and the explanation is saved to a Google Doc.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'onboarding'], - alsoIntegrations: ['google_docs'], - }, - { - icon: ClipboardList, - title: 'PR review with codebase context', - prompt: - 'Build a workflow that takes a pull request, asks Greptile how the changed code interacts with the rest of the repository, and writes a review comment summarizing impact and risks with cited files.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'code-review'], - alsoIntegrations: ['github'], - }, - ], - skills: [ - { - name: 'answer-codebase-question', - description: - 'Ask Greptile a natural-language question about an indexed repository and return a cited answer.', - content: - '# Answer Codebase Question\n\nGet an accurate, source-cited answer about how a codebase works.\n\n## Steps\n1. Confirm the repository is indexed by checking its index status; if not ready, index it first and wait.\n2. Query Greptile with the natural-language question (e.g. how authentication flows, where payments are processed).\n3. Capture the answer along with the file and function references it cites.\n4. If the answer is vague, refine the question with more specifics and re-query.\n\n## Output\nReturn the answer plus a list of cited files and symbols. Useful for onboarding, debugging, and understanding unfamiliar code.', - }, - { - name: 'review-pull-request', - description: - 'Use Greptile to assess how a PR diff interacts with the rest of the repo and draft review notes.', - content: - '# Review Pull Request\n\nProduce a codebase-aware review of a set of changes.\n\n## Steps\n1. Ensure the repository is indexed (check status, index if needed).\n2. Query Greptile describing the changed files and ask how they interact with the rest of the codebase, what might break, and what edge cases to test.\n3. Collect the impact analysis and the cited files affected beyond the diff.\n4. Organize findings into bugs/risks, style/consistency, and suggested tests.\n\n## Output\nReturn structured review notes grouped by severity, each with the cited file and a concrete suggestion. Ready to post as a PR comment.', - }, - { - name: 'index-and-verify-repo', - description: - 'Trigger Greptile indexing for a repository and poll until it is ready to query.', - content: - '# Index and Verify Repo\n\nMake a repository queryable in Greptile.\n\n## Steps\n1. Start indexing for the repository, specifying the remote, owner/repo, and branch.\n2. Poll the index status until it reports completed or fails.\n3. On failure, report the error and the branch/remote used so it can be corrected.\n4. On success, run a quick sanity query to confirm answers come back with citations.\n\n## Output\nReturn the final index status, the branch indexed, and the result of the sanity query. Confirms the repo is ready for codebase questions and reviews.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hex.display.ts b/apps/sim/blocks/blocks/hex.display.ts index 899b802e6de..ebe0952edf8 100644 --- a/apps/sim/blocks/blocks/hex.display.ts +++ b/apps/sim/blocks/blocks/hex.display.ts @@ -1,6 +1,6 @@ import { HexIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const HexBlockDisplay = { type: 'hex', @@ -14,3 +14,106 @@ export const HexBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/hex', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const HexBlockMeta = { + tags: ['data-analytics'], + url: 'https://hex.tech', + templates: [ + { + icon: HexIcon, + title: 'Hex project notebook runner', + prompt: + 'Create a scheduled workflow that runs a Hex notebook with parameters every morning, waits for the run to finish, and posts a summary with the published notebook link to a Slack data channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: HexIcon, + title: 'Hex anomaly digest', + prompt: + 'Build a workflow that runs a Hex notebook for anomaly detection on key metrics nightly, captures detected anomalies into a table, and pages the on-call data team on Slack for severe deltas.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: HexIcon, + title: 'Hex executive metrics email', + prompt: + 'Create a scheduled weekly workflow that runs a Hex executive dashboard notebook, summarizes the run results, and emails a snapshot with the dashboard link to the leadership distribution list every Monday morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + alsoIntegrations: ['gmail'], + }, + { + icon: HexIcon, + title: 'Hex + Tinybird realtime data app', + prompt: + 'Create a workflow that powers a Hex data app with Tinybird realtime data, refreshes the dashboard on schedule, and writes usage analytics to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + alsoIntegrations: ['tinybird'], + }, + { + icon: HexIcon, + title: 'Hex + Stripe revenue notebook', + prompt: + 'Build a scheduled workflow that runs a Hex notebook over Stripe payment data daily, captures MRR, churn, and expansion metrics, and posts a summary with the notebook link to a Slack data channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + alsoIntegrations: ['stripe', 'slack'], + }, + { + icon: HexIcon, + title: 'Hex + Amplitude product notebook', + prompt: + 'Create a scheduled workflow that runs a Hex notebook joining Amplitude data with internal sources weekly, captures retention and feature adoption, and emails a summary with the notebook link to the product team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['amplitude', 'gmail'], + }, + { + icon: HexIcon, + title: 'Hex run failure monitor', + prompt: + 'Build a workflow that lists recent Hex project runs every hour, checks each run status, and when a scheduled notebook fails pulls the error, summarizes the likely cause with an agent, and posts a Slack alert with a link to the run.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'analysis'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'run-project-with-params', + description: 'Trigger a Hex project run with input parameters and poll until it completes.', + content: + '# Run Project With Params\n\nKick off a Hex project and wait for the result.\n\n## Steps\n1. If only a project name is known, list projects to resolve the project ID.\n2. Run the project, passing any input parameters the project expects.\n3. Capture the run ID and poll the run status until it reaches a terminal state (completed, errored, or killed).\n4. If it is still pending after a reasonable timeout, report the current status rather than blocking indefinitely.\n\n## Output\nReturn the run ID, final status, and any output or result link. On error, include the failure reason.', + }, + { + name: 'monitor-recent-runs', + description: 'List recent Hex project runs, check their statuses, and surface failures.', + content: + '# Monitor Recent Runs\n\nWatch project runs and flag the ones that failed.\n\n## Steps\n1. List project runs for the relevant project or projects.\n2. Get the run status for each recent run.\n3. Filter to runs that errored or were killed and capture the error detail.\n4. Group successes and failures with timestamps.\n\n## Output\nReturn a summary of recent runs with status and timing, plus a flagged failures section with run IDs, error messages, and links. Suitable for an hourly monitoring digest.', + }, + { + name: 'cancel-stuck-run', + description: 'Find a long-running or stuck Hex run and cancel it.', + content: + '# Cancel Stuck Run\n\nStop a run that is hung or no longer needed.\n\n## Steps\n1. List project runs and get the status of in-progress runs.\n2. Identify runs exceeding an expected duration or explicitly targeted for cancellation.\n3. Cancel the run by its run ID.\n4. Re-check the status to confirm cancellation took effect.\n\n## Output\nReturn the cancelled run ID and its confirmed final status. Note any run that could not be cancelled.', + }, + { + name: 'inventory-projects', + description: 'List Hex projects, collections, and data connections to map analytics assets.', + content: + '# Inventory Projects\n\nMap what projects and data sources exist in the workspace.\n\n## Steps\n1. List projects and capture IDs, names, and owners.\n2. List collections and get details to see how projects are grouped.\n3. List data connections to map which sources power the projects.\n4. Cross-reference projects to their collections and data connections.\n\n## Output\nReturn an inventory of projects grouped by collection, each annotated with its data connections. Useful for governance and cleanup.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hex.ts b/apps/sim/blocks/blocks/hex.ts index ae7ceefa4d7..bdf6f83c657 100644 --- a/apps/sim/blocks/blocks/hex.ts +++ b/apps/sim/blocks/blocks/hex.ts @@ -1,6 +1,5 @@ -import { HexIcon } from '@/components/icons' import { HexBlockDisplay } from '@/blocks/blocks/hex.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { HexResponse } from '@/tools/hex/types' @@ -437,106 +436,3 @@ Example: allowWritebackCells: { type: 'boolean', description: 'Writeback cells allowed' }, }, } - -export const HexBlockMeta = { - tags: ['data-analytics'], - url: 'https://hex.tech', - templates: [ - { - icon: HexIcon, - title: 'Hex project notebook runner', - prompt: - 'Create a scheduled workflow that runs a Hex notebook with parameters every morning, waits for the run to finish, and posts a summary with the published notebook link to a Slack data channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: HexIcon, - title: 'Hex anomaly digest', - prompt: - 'Build a workflow that runs a Hex notebook for anomaly detection on key metrics nightly, captures detected anomalies into a table, and pages the on-call data team on Slack for severe deltas.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: HexIcon, - title: 'Hex executive metrics email', - prompt: - 'Create a scheduled weekly workflow that runs a Hex executive dashboard notebook, summarizes the run results, and emails a snapshot with the dashboard link to the leadership distribution list every Monday morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - alsoIntegrations: ['gmail'], - }, - { - icon: HexIcon, - title: 'Hex + Tinybird realtime data app', - prompt: - 'Create a workflow that powers a Hex data app with Tinybird realtime data, refreshes the dashboard on schedule, and writes usage analytics to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - alsoIntegrations: ['tinybird'], - }, - { - icon: HexIcon, - title: 'Hex + Stripe revenue notebook', - prompt: - 'Build a scheduled workflow that runs a Hex notebook over Stripe payment data daily, captures MRR, churn, and expansion metrics, and posts a summary with the notebook link to a Slack data channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - alsoIntegrations: ['stripe', 'slack'], - }, - { - icon: HexIcon, - title: 'Hex + Amplitude product notebook', - prompt: - 'Create a scheduled workflow that runs a Hex notebook joining Amplitude data with internal sources weekly, captures retention and feature adoption, and emails a summary with the notebook link to the product team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['amplitude', 'gmail'], - }, - { - icon: HexIcon, - title: 'Hex run failure monitor', - prompt: - 'Build a workflow that lists recent Hex project runs every hour, checks each run status, and when a scheduled notebook fails pulls the error, summarizes the likely cause with an agent, and posts a Slack alert with a link to the run.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'analysis'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'run-project-with-params', - description: 'Trigger a Hex project run with input parameters and poll until it completes.', - content: - '# Run Project With Params\n\nKick off a Hex project and wait for the result.\n\n## Steps\n1. If only a project name is known, list projects to resolve the project ID.\n2. Run the project, passing any input parameters the project expects.\n3. Capture the run ID and poll the run status until it reaches a terminal state (completed, errored, or killed).\n4. If it is still pending after a reasonable timeout, report the current status rather than blocking indefinitely.\n\n## Output\nReturn the run ID, final status, and any output or result link. On error, include the failure reason.', - }, - { - name: 'monitor-recent-runs', - description: 'List recent Hex project runs, check their statuses, and surface failures.', - content: - '# Monitor Recent Runs\n\nWatch project runs and flag the ones that failed.\n\n## Steps\n1. List project runs for the relevant project or projects.\n2. Get the run status for each recent run.\n3. Filter to runs that errored or were killed and capture the error detail.\n4. Group successes and failures with timestamps.\n\n## Output\nReturn a summary of recent runs with status and timing, plus a flagged failures section with run IDs, error messages, and links. Suitable for an hourly monitoring digest.', - }, - { - name: 'cancel-stuck-run', - description: 'Find a long-running or stuck Hex run and cancel it.', - content: - '# Cancel Stuck Run\n\nStop a run that is hung or no longer needed.\n\n## Steps\n1. List project runs and get the status of in-progress runs.\n2. Identify runs exceeding an expected duration or explicitly targeted for cancellation.\n3. Cancel the run by its run ID.\n4. Re-check the status to confirm cancellation took effect.\n\n## Output\nReturn the cancelled run ID and its confirmed final status. Note any run that could not be cancelled.', - }, - { - name: 'inventory-projects', - description: 'List Hex projects, collections, and data connections to map analytics assets.', - content: - '# Inventory Projects\n\nMap what projects and data sources exist in the workspace.\n\n## Steps\n1. List projects and capture IDs, names, and owners.\n2. List collections and get details to see how projects are grouped.\n3. List data connections to map which sources power the projects.\n4. Cross-reference projects to their collections and data connections.\n\n## Output\nReturn an inventory of projects grouped by collection, each annotated with its data connections. Useful for governance and cleanup.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hubspot.display.ts b/apps/sim/blocks/blocks/hubspot.display.ts index b42e721f26a..8bea5f1df1c 100644 --- a/apps/sim/blocks/blocks/hubspot.display.ts +++ b/apps/sim/blocks/blocks/hubspot.display.ts @@ -1,6 +1,6 @@ import { HubspotIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const HubSpotBlockDisplay = { type: 'hubspot', @@ -16,3 +16,142 @@ export const HubSpotBlockDisplay = { integrationType: IntegrationType.Sales, triggerAllowed: true, } satisfies BlockDisplay + +export const HubSpotBlockMeta = { + tags: ['marketing', 'sales-engagement', 'customer-support'], + url: 'https://www.hubspot.com', + templates: [ + { + icon: HubspotIcon, + title: 'HubSpot deal search', + prompt: + 'Create a knowledge base connected to my HubSpot account so all deals, contacts, and activity history are automatically synced and searchable. Then build an agent I can ask things like "what happened with the Stripe integration deal?" or "which deals closed last quarter over $50k?" and get answers with HubSpot record links.', + modules: ['knowledge-base', 'agent'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + }, + { + icon: HubspotIcon, + title: 'Win/loss analyzer', + prompt: + 'Build a workflow that pulls closed deals from HubSpot each week, analyzes patterns in wins vs losses — deal size, industry, sales cycle length, objections — and generates a report file with actionable insights on what to change. Schedule it to run every Monday.', + modules: ['agent', 'files', 'scheduled', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'analysis', 'reporting'], + }, + + { + icon: HubspotIcon, + title: 'Get HubSpot deal alerts in Slack', + prompt: + 'Build a workflow that watches HubSpot for deal stage changes, new contacts, and revenue milestones, then posts instant Slack notifications to your sales team.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + { + icon: HubspotIcon, + title: 'Send personalised emails from HubSpot events', + prompt: + 'Build a workflow that triggers whenever a HubSpot contact enters a new lifecycle stage and sends a personalised Gmail message tailored to that stage.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['gmail'], + }, + { + icon: HubspotIcon, + title: 'HubSpot lead enrichment and dedupe', + prompt: + 'Build a workflow that on a new HubSpot contact searches for existing duplicates, enriches the record with company size, industry, and verified email, and updates the contact and its associated company with the cleaned data.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation', 'enrichment'], + }, + { + icon: HubspotIcon, + title: 'HubSpot pipeline weekly digest', + prompt: + 'Create a scheduled weekly workflow that lists HubSpot deals by stage, computes movement and at-risk deals with an agent, logs the snapshot to a table, and emails a pipeline summary to the sales leadership team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'crm'], + alsoIntegrations: ['gmail'], + }, + { + icon: HubspotIcon, + title: 'HubSpot ticket triage', + prompt: + 'Build a workflow that on a new HubSpot support ticket classifies priority and topic, adds a triage note, associates it with the right company, and posts an alert to the support Slack channel for high-priority cases.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'crm'], + alsoIntegrations: ['slack'], + }, + { + icon: HubspotIcon, + title: 'Backfill HubSpot contact email history from Gmail', + prompt: + 'Build a workflow that finds HubSpot contacts in the lead stage with no logged email activity, searches my Gmail for each person’s thread, and logs it back to HubSpot as an email engagement associated with the contact.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'upsert-contact', + description: + 'Find a HubSpot contact by email and update it, or create it if it does not exist.', + content: + '# Upsert Contact\n\nKeep a contact record current without creating duplicates.\n\n## Steps\n1. Search contacts by the email address to check if the person already exists.\n2. If a match is found, update the contact with the new property values.\n3. If no match exists, create a new contact with the email and known properties.\n4. Read the contact back to confirm the final property values.\n\n## Output\nReturn the contact ID and whether it was created or updated, along with the properties that were set.', + }, + { + name: 'create-deal-for-account', + description: 'Create a HubSpot deal and associate it with the right company and contact.', + content: + '# Create Deal For Account\n\nLog a new opportunity tied to the correct account.\n\n## Steps\n1. Search companies to resolve the company by name or domain; create it if missing.\n2. Search contacts to find the primary contact for the deal.\n3. Create the deal with name, amount, pipeline, and stage, associating it with the company and contact.\n4. Read the deal back to confirm associations and stage.\n\n## Output\nReturn the deal ID, its stage and amount, and the associated company and contact IDs.', + }, + { + name: 'triage-support-ticket', + description: + 'Classify a HubSpot ticket, set priority, and associate it with the correct company.', + content: + '# Triage Support Ticket\n\nRoute and prioritize an incoming support ticket.\n\n## Steps\n1. Get the ticket to read its subject and content.\n2. Classify topic and priority from the content.\n3. Update the ticket with the priority and any pipeline stage change.\n4. Search companies to find the requesting account and associate the ticket with it.\n\n## Output\nReturn the ticket ID, assigned priority and topic, and the associated company. Flag high-priority tickets for escalation.', + }, + { + name: 'summarize-open-deals', + description: 'Search HubSpot deals by stage and produce a pipeline summary with totals.', + content: + '# Summarize Open Deals\n\nReport on the active sales pipeline.\n\n## Steps\n1. Search deals filtered to open stages, paginating through all results.\n2. Group deals by pipeline stage and capture amount and close date.\n3. Sum amounts per stage and overall, and flag deals with a close date in the past.\n4. Identify the largest deals and any missing key properties.\n\n## Output\nReturn a per-stage breakdown with deal counts and total value, a grand total, and a flagged list of overdue or incomplete deals. Suitable for a sales pipeline review.', + }, + { + name: 'build-quote-from-deal', + description: 'Gather a HubSpot deal and its line items to assemble a quote summary.', + content: + '# Build Quote From Deal\n\nCompile the commercial details needed to quote a deal.\n\n## Steps\n1. Get the deal by ID for its name, amount, and stage.\n2. List line items and get details to capture product, quantity, and price for each.\n3. Get the associated quote if one exists, or summarize the line items into a draft quote.\n4. Total the line items and compare against the deal amount, flagging mismatches.\n\n## Output\nReturn the deal summary, an itemized line-item list with totals, and any existing quote reference. Flag discrepancies between the line-item total and the deal amount.', + }, + { + name: 'log-email-to-contact', + description: 'Log an email engagement in HubSpot and associate it with a contact.', + content: + '# Log Email To Contact\n\nRecord an email activity on a contact’s timeline.\n\n## Steps\n1. Search contacts by email to resolve the contact ID.\n2. Create an email engagement with hs_timestamp, subject, body, and direction.\n3. Associate the email with the contact (associationTypeId 198, or the default association).\n4. List associations from the contact to emails to confirm the link.\n\n## Output\nReturn the email engagement ID and the associated contact ID.', + }, + { + name: 'audit-contacts-missing-activity', + description: 'Find contacts in a lead stage that have no logged email activity.', + content: + '# Audit Contacts Missing Activity\n\nSurface leads with no recorded email history.\n\n## Steps\n1. Get properties for contacts to read the hs_lead_status options and confirm the target stage value.\n2. Search contacts filtered to that lead status, paginating through all results.\n3. For each contact, list associations to emails and flag those with zero associated emails.\n4. Collect the contacts that need follow-up.\n\n## Output\nReturn the list of contact IDs with no logged email activity, ready for backfill.', + }, + { + name: 'inspect-property-options', + description: 'Read the enumeration (picklist) values for a HubSpot property.', + content: + '# Inspect Property Options\n\nList the allowed values for a dropdown property.\n\n## Steps\n1. Get properties for the object type (e.g., contacts).\n2. Find the property by name (e.g., lifecyclestage or hs_lead_status).\n3. Read its options array for label/value pairs.\n\n## Output\nReturn the property label and its enumeration options as label/value pairs.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hubspot.ts b/apps/sim/blocks/blocks/hubspot.ts index 908ffd2440d..14b8bf0c9a5 100644 --- a/apps/sim/blocks/blocks/hubspot.ts +++ b/apps/sim/blocks/blocks/hubspot.ts @@ -1,7 +1,6 @@ -import { HubspotIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { HubSpotBlockDisplay } from '@/blocks/blocks/hubspot.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { HubSpotResponse } from '@/tools/hubspot/types' import { getTrigger } from '@/triggers' @@ -1471,142 +1470,3 @@ Return ONLY the JSON array of property names - no explanations, no markdown, no available: ['hubspot_poller'], }, } - -export const HubSpotBlockMeta = { - tags: ['marketing', 'sales-engagement', 'customer-support'], - url: 'https://www.hubspot.com', - templates: [ - { - icon: HubspotIcon, - title: 'HubSpot deal search', - prompt: - 'Create a knowledge base connected to my HubSpot account so all deals, contacts, and activity history are automatically synced and searchable. Then build an agent I can ask things like "what happened with the Stripe integration deal?" or "which deals closed last quarter over $50k?" and get answers with HubSpot record links.', - modules: ['knowledge-base', 'agent'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - }, - { - icon: HubspotIcon, - title: 'Win/loss analyzer', - prompt: - 'Build a workflow that pulls closed deals from HubSpot each week, analyzes patterns in wins vs losses — deal size, industry, sales cycle length, objections — and generates a report file with actionable insights on what to change. Schedule it to run every Monday.', - modules: ['agent', 'files', 'scheduled', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'analysis', 'reporting'], - }, - - { - icon: HubspotIcon, - title: 'Get HubSpot deal alerts in Slack', - prompt: - 'Build a workflow that watches HubSpot for deal stage changes, new contacts, and revenue milestones, then posts instant Slack notifications to your sales team.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - { - icon: HubspotIcon, - title: 'Send personalised emails from HubSpot events', - prompt: - 'Build a workflow that triggers whenever a HubSpot contact enters a new lifecycle stage and sends a personalised Gmail message tailored to that stage.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['gmail'], - }, - { - icon: HubspotIcon, - title: 'HubSpot lead enrichment and dedupe', - prompt: - 'Build a workflow that on a new HubSpot contact searches for existing duplicates, enriches the record with company size, industry, and verified email, and updates the contact and its associated company with the cleaned data.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation', 'enrichment'], - }, - { - icon: HubspotIcon, - title: 'HubSpot pipeline weekly digest', - prompt: - 'Create a scheduled weekly workflow that lists HubSpot deals by stage, computes movement and at-risk deals with an agent, logs the snapshot to a table, and emails a pipeline summary to the sales leadership team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'crm'], - alsoIntegrations: ['gmail'], - }, - { - icon: HubspotIcon, - title: 'HubSpot ticket triage', - prompt: - 'Build a workflow that on a new HubSpot support ticket classifies priority and topic, adds a triage note, associates it with the right company, and posts an alert to the support Slack channel for high-priority cases.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'crm'], - alsoIntegrations: ['slack'], - }, - { - icon: HubspotIcon, - title: 'Backfill HubSpot contact email history from Gmail', - prompt: - 'Build a workflow that finds HubSpot contacts in the lead stage with no logged email activity, searches my Gmail for each person’s thread, and logs it back to HubSpot as an email engagement associated with the contact.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'upsert-contact', - description: - 'Find a HubSpot contact by email and update it, or create it if it does not exist.', - content: - '# Upsert Contact\n\nKeep a contact record current without creating duplicates.\n\n## Steps\n1. Search contacts by the email address to check if the person already exists.\n2. If a match is found, update the contact with the new property values.\n3. If no match exists, create a new contact with the email and known properties.\n4. Read the contact back to confirm the final property values.\n\n## Output\nReturn the contact ID and whether it was created or updated, along with the properties that were set.', - }, - { - name: 'create-deal-for-account', - description: 'Create a HubSpot deal and associate it with the right company and contact.', - content: - '# Create Deal For Account\n\nLog a new opportunity tied to the correct account.\n\n## Steps\n1. Search companies to resolve the company by name or domain; create it if missing.\n2. Search contacts to find the primary contact for the deal.\n3. Create the deal with name, amount, pipeline, and stage, associating it with the company and contact.\n4. Read the deal back to confirm associations and stage.\n\n## Output\nReturn the deal ID, its stage and amount, and the associated company and contact IDs.', - }, - { - name: 'triage-support-ticket', - description: - 'Classify a HubSpot ticket, set priority, and associate it with the correct company.', - content: - '# Triage Support Ticket\n\nRoute and prioritize an incoming support ticket.\n\n## Steps\n1. Get the ticket to read its subject and content.\n2. Classify topic and priority from the content.\n3. Update the ticket with the priority and any pipeline stage change.\n4. Search companies to find the requesting account and associate the ticket with it.\n\n## Output\nReturn the ticket ID, assigned priority and topic, and the associated company. Flag high-priority tickets for escalation.', - }, - { - name: 'summarize-open-deals', - description: 'Search HubSpot deals by stage and produce a pipeline summary with totals.', - content: - '# Summarize Open Deals\n\nReport on the active sales pipeline.\n\n## Steps\n1. Search deals filtered to open stages, paginating through all results.\n2. Group deals by pipeline stage and capture amount and close date.\n3. Sum amounts per stage and overall, and flag deals with a close date in the past.\n4. Identify the largest deals and any missing key properties.\n\n## Output\nReturn a per-stage breakdown with deal counts and total value, a grand total, and a flagged list of overdue or incomplete deals. Suitable for a sales pipeline review.', - }, - { - name: 'build-quote-from-deal', - description: 'Gather a HubSpot deal and its line items to assemble a quote summary.', - content: - '# Build Quote From Deal\n\nCompile the commercial details needed to quote a deal.\n\n## Steps\n1. Get the deal by ID for its name, amount, and stage.\n2. List line items and get details to capture product, quantity, and price for each.\n3. Get the associated quote if one exists, or summarize the line items into a draft quote.\n4. Total the line items and compare against the deal amount, flagging mismatches.\n\n## Output\nReturn the deal summary, an itemized line-item list with totals, and any existing quote reference. Flag discrepancies between the line-item total and the deal amount.', - }, - { - name: 'log-email-to-contact', - description: 'Log an email engagement in HubSpot and associate it with a contact.', - content: - '# Log Email To Contact\n\nRecord an email activity on a contact’s timeline.\n\n## Steps\n1. Search contacts by email to resolve the contact ID.\n2. Create an email engagement with hs_timestamp, subject, body, and direction.\n3. Associate the email with the contact (associationTypeId 198, or the default association).\n4. List associations from the contact to emails to confirm the link.\n\n## Output\nReturn the email engagement ID and the associated contact ID.', - }, - { - name: 'audit-contacts-missing-activity', - description: 'Find contacts in a lead stage that have no logged email activity.', - content: - '# Audit Contacts Missing Activity\n\nSurface leads with no recorded email history.\n\n## Steps\n1. Get properties for contacts to read the hs_lead_status options and confirm the target stage value.\n2. Search contacts filtered to that lead status, paginating through all results.\n3. For each contact, list associations to emails and flag those with zero associated emails.\n4. Collect the contacts that need follow-up.\n\n## Output\nReturn the list of contact IDs with no logged email activity, ready for backfill.', - }, - { - name: 'inspect-property-options', - description: 'Read the enumeration (picklist) values for a HubSpot property.', - content: - '# Inspect Property Options\n\nList the allowed values for a dropdown property.\n\n## Steps\n1. Get properties for the object type (e.g., contacts).\n2. Find the property by name (e.g., lifecyclestage or hs_lead_status).\n3. Read its options array for label/value pairs.\n\n## Output\nReturn the property label and its enumeration options as label/value pairs.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/huggingface.display.ts b/apps/sim/blocks/blocks/huggingface.display.ts index 88eebcbc091..efc6d419a93 100644 --- a/apps/sim/blocks/blocks/huggingface.display.ts +++ b/apps/sim/blocks/blocks/huggingface.display.ts @@ -1,6 +1,6 @@ import { HuggingFaceIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const HuggingFaceBlockDisplay = { type: 'huggingface', @@ -14,3 +14,97 @@ export const HuggingFaceBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/huggingface', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const HuggingFaceBlockMeta = { + tags: ['llm', 'agentic'], + url: 'https://huggingface.co', + templates: [ + { + icon: HuggingFaceIcon, + title: 'Hugging Face row classifier', + prompt: + 'Build a workflow that runs each row in a table through a Hugging Face chat model with custom labels in the prompt, writes the predicted label and a confidence rating back, and flags low-confidence rows for review.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'automation'], + }, + { + icon: HuggingFaceIcon, + title: 'Open-source sentiment scorer', + prompt: + 'Create a workflow that scores customer feedback with a Hugging Face chat model, writes sentiment and score columns back to the table, and pings Slack on a sudden negative spike.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: HuggingFaceIcon, + title: 'Hugging Face candidate reranker', + prompt: + 'Create a retrieval pipeline that fetches top-50 candidates from a knowledge base, reranks them with a Hugging Face chat model scoring relevance, and returns the top-5 to the answering agent for higher precision.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: HuggingFaceIcon, + title: 'Hugging Face PII redactor', + prompt: + 'Build a workflow that runs a Hugging Face chat model over text uploads to detect PII, redacts the sensitive entities, and writes the cleaned text to a downstream table.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + }, + { + icon: HuggingFaceIcon, + title: 'Hugging Face open-model summarizer', + prompt: + 'Create a workflow that on a new document fetches the text and runs it through a Hugging Face chat model to produce a concise summary and key takeaways, then writes the result back to a table — keeping the workload on open-weight models you control.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['llm', 'content', 'automation'], + }, + { + icon: HuggingFaceIcon, + title: 'Hugging Face feedback classifier', + prompt: + 'Build a workflow that reads new customer feedback rows, uses a Hugging Face chat model to classify sentiment and theme, writes the labels back to the table, and posts a Slack alert when negative feedback spikes.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'llm', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: HuggingFaceIcon, + title: 'Hugging Face model A/B harness', + prompt: + 'Create a workflow that runs the same prompt through a Hugging Face open model and a hosted model side by side, compares the outputs with a grading agent, and logs quality, latency, and cost to a table for evaluation.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['llm', 'engineering', 'analysis'], + }, + ], + skills: [ + { + name: 'run-chat-completion', + description: + 'Send a prompt to a Hugging Face chat model via the Inference API and return the response.', + content: + '# Run Chat Completion\n\nGenerate a completion from an open chat model.\n\n## Steps\n1. Choose the model (e.g. an instruct or chat-tuned model available via the Inference API).\n2. Build the messages with a clear system instruction and the user prompt.\n3. Call chat with the model and messages, setting temperature and max tokens appropriate to the task.\n4. Capture the assistant response and any token usage returned.\n\n## Output\nReturn the model output and the model name used. Note token usage when available for cost tracking.', + }, + { + name: 'extract-structured-data', + description: + 'Use a Hugging Face chat model to extract fields from unstructured text into a structured object.', + content: + '# Extract Structured Data\n\nPull named fields out of free text using an open model.\n\n## Steps\n1. Define the exact fields to extract and their types.\n2. Build a system message instructing the model to return only valid JSON matching the schema, with nulls for missing fields.\n3. Call chat with the source text as the user message and a low temperature for determinism.\n4. Parse the response and validate it against the expected fields; retry once with a stricter instruction if parsing fails.\n\n## Output\nReturn the parsed structured object. On repeated parse failure, return the raw model text and an error note.', + }, + { + name: 'compare-model-outputs', + description: 'Run the same prompt through two Hugging Face models and compare their outputs.', + content: + '# Compare Model Outputs\n\nEvaluate how two open models handle the same task.\n\n## Steps\n1. Define the shared prompt and the two model identifiers to compare.\n2. Call chat once per model with identical messages and generation settings.\n3. Capture each output along with latency and token usage.\n4. Score the outputs against the task criteria (accuracy, format, completeness).\n\n## Output\nReturn both responses side by side with their latency, token usage, and a brief quality comparison. Suitable for logging to an evaluation table.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/huggingface.ts b/apps/sim/blocks/blocks/huggingface.ts index 9a4393eff7c..9b4cce77fc5 100644 --- a/apps/sim/blocks/blocks/huggingface.ts +++ b/apps/sim/blocks/blocks/huggingface.ts @@ -1,6 +1,5 @@ -import { HuggingFaceIcon } from '@/components/icons' import { HuggingFaceBlockDisplay } from '@/blocks/blocks/huggingface.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { HuggingFaceChatResponse } from '@/tools/huggingface/types' @@ -112,97 +111,3 @@ export const HuggingFaceBlock: BlockConfig = { usage: { type: 'json', description: 'Token usage stats' }, }, } - -export const HuggingFaceBlockMeta = { - tags: ['llm', 'agentic'], - url: 'https://huggingface.co', - templates: [ - { - icon: HuggingFaceIcon, - title: 'Hugging Face row classifier', - prompt: - 'Build a workflow that runs each row in a table through a Hugging Face chat model with custom labels in the prompt, writes the predicted label and a confidence rating back, and flags low-confidence rows for review.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'automation'], - }, - { - icon: HuggingFaceIcon, - title: 'Open-source sentiment scorer', - prompt: - 'Create a workflow that scores customer feedback with a Hugging Face chat model, writes sentiment and score columns back to the table, and pings Slack on a sudden negative spike.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: HuggingFaceIcon, - title: 'Hugging Face candidate reranker', - prompt: - 'Create a retrieval pipeline that fetches top-50 candidates from a knowledge base, reranks them with a Hugging Face chat model scoring relevance, and returns the top-5 to the answering agent for higher precision.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: HuggingFaceIcon, - title: 'Hugging Face PII redactor', - prompt: - 'Build a workflow that runs a Hugging Face chat model over text uploads to detect PII, redacts the sensitive entities, and writes the cleaned text to a downstream table.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - }, - { - icon: HuggingFaceIcon, - title: 'Hugging Face open-model summarizer', - prompt: - 'Create a workflow that on a new document fetches the text and runs it through a Hugging Face chat model to produce a concise summary and key takeaways, then writes the result back to a table — keeping the workload on open-weight models you control.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['llm', 'content', 'automation'], - }, - { - icon: HuggingFaceIcon, - title: 'Hugging Face feedback classifier', - prompt: - 'Build a workflow that reads new customer feedback rows, uses a Hugging Face chat model to classify sentiment and theme, writes the labels back to the table, and posts a Slack alert when negative feedback spikes.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'llm', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: HuggingFaceIcon, - title: 'Hugging Face model A/B harness', - prompt: - 'Create a workflow that runs the same prompt through a Hugging Face open model and a hosted model side by side, compares the outputs with a grading agent, and logs quality, latency, and cost to a table for evaluation.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['llm', 'engineering', 'analysis'], - }, - ], - skills: [ - { - name: 'run-chat-completion', - description: - 'Send a prompt to a Hugging Face chat model via the Inference API and return the response.', - content: - '# Run Chat Completion\n\nGenerate a completion from an open chat model.\n\n## Steps\n1. Choose the model (e.g. an instruct or chat-tuned model available via the Inference API).\n2. Build the messages with a clear system instruction and the user prompt.\n3. Call chat with the model and messages, setting temperature and max tokens appropriate to the task.\n4. Capture the assistant response and any token usage returned.\n\n## Output\nReturn the model output and the model name used. Note token usage when available for cost tracking.', - }, - { - name: 'extract-structured-data', - description: - 'Use a Hugging Face chat model to extract fields from unstructured text into a structured object.', - content: - '# Extract Structured Data\n\nPull named fields out of free text using an open model.\n\n## Steps\n1. Define the exact fields to extract and their types.\n2. Build a system message instructing the model to return only valid JSON matching the schema, with nulls for missing fields.\n3. Call chat with the source text as the user message and a low temperature for determinism.\n4. Parse the response and validate it against the expected fields; retry once with a stricter instruction if parsing fails.\n\n## Output\nReturn the parsed structured object. On repeated parse failure, return the raw model text and an error note.', - }, - { - name: 'compare-model-outputs', - description: 'Run the same prompt through two Hugging Face models and compare their outputs.', - content: - '# Compare Model Outputs\n\nEvaluate how two open models handle the same task.\n\n## Steps\n1. Define the shared prompt and the two model identifiers to compare.\n2. Call chat once per model with identical messages and generation settings.\n3. Capture each output along with latency and token usage.\n4. Score the outputs against the task criteria (accuracy, format, completeness).\n\n## Output\nReturn both responses side by side with their latency, token usage, and a brief quality comparison. Suitable for logging to an evaluation table.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hunter.display.ts b/apps/sim/blocks/blocks/hunter.display.ts index c517456c829..45b71c426fa 100644 --- a/apps/sim/blocks/blocks/hunter.display.ts +++ b/apps/sim/blocks/blocks/hunter.display.ts @@ -1,6 +1,6 @@ import { HunterIOIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const HunterBlockDisplay = { type: 'hunter', @@ -14,3 +14,99 @@ export const HunterBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/hunter', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const HunterBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://hunter.io', + templates: [ + { + icon: HunterIOIcon, + title: 'Hunter email finder', + prompt: + 'Build a workflow that takes a target company and role from a table, runs Hunter to find the matching email, validates it, and writes the verified contact back.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: HunterIOIcon, + title: 'Hunter email verifier', + prompt: + 'Create a workflow that runs a list of email addresses through Hunter verification, removes invalid emails, and writes a clean list for outbound sends.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: HunterIOIcon, + title: 'Hunter + Email Bison outbound', + prompt: + 'Build a workflow that uses Hunter to find prospect emails, validates each, and pushes valid prospects into an active Email Bison campaign.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: HunterIOIcon, + title: 'Hunter domain finder', + prompt: + 'Create a workflow that takes a list of company names, finds the matching domains via Hunter, and enriches the rows so the CRM has accurate domain data.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + }, + { + icon: HunterIOIcon, + title: 'Hunter event-list enricher', + prompt: + 'Build a workflow that takes a Luma event registrants list, finds their work emails via Hunter, and writes the verified emails into HubSpot for followup.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['luma', 'hubspot'], + }, + { + icon: HunterIOIcon, + title: 'Hunter CRM gap-filler', + prompt: + 'Create a scheduled workflow that finds HubSpot contacts missing email addresses, looks them up via Hunter, validates each, and updates the contact record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: HunterIOIcon, + title: 'Hunter + Apollo prospect builder', + prompt: + 'Build a workflow that runs an Apollo search for an ICP, finds verified emails via Hunter, and writes the deliverable prospect list to a sender table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['apollo'], + }, + ], + skills: [ + { + name: 'find-decision-maker-emails', + description: + 'Find verified email addresses for key roles at a target company using domain search.', + content: + '# Find Decision-Maker Emails\n\nGiven a company domain, find verified professional email addresses for the people who matter.\n\n## Steps\n1. Run a domain search for the target domain (e.g. example.com).\n2. Filter results by department or seniority (executive, sales, IT) to surface decision-makers.\n3. For each candidate, capture the full name, role, email, and confidence score.\n4. Drop any result below your confidence threshold (e.g. < 80).\n\n## Output\nReturn a list of contacts with name, title, email, and confidence score, sorted by seniority. Note the total emails available on the domain so the user knows coverage.', + }, + { + name: 'verify-email-list', + description: + 'Verify a batch of email addresses and flag undeliverable or risky ones before sending.', + content: + '# Verify Email List\n\nClean a list of email addresses so a campaign only sends to deliverable inboxes.\n\n## Steps\n1. For each address, run the email verifier.\n2. Record the verification status (valid, invalid, accept-all, disposable, webmail) and the deliverability score.\n3. Bucket addresses into deliverable, risky, and undeliverable.\n\n## Output\nReturn the three buckets with counts, and a recommended clean list containing only deliverable addresses.', + }, + { + name: 'find-person-email', + description: 'Find the most likely email address for a named person at a specific company.', + content: + '# Find a Person Email\n\nGiven a first name, last name, and company domain, find that person email address.\n\n## Steps\n1. Run the email finder with the full name and domain.\n2. Capture the returned email, confidence score, and the sources Hunter used.\n3. If confidence is low, optionally run a domain search to confirm the pattern.\n\n## Output\nReturn the email, confidence score, and supporting sources. State clearly when no confident match was found.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/hunter.ts b/apps/sim/blocks/blocks/hunter.ts index 1941ce0dbf8..47b9128098e 100644 --- a/apps/sim/blocks/blocks/hunter.ts +++ b/apps/sim/blocks/blocks/hunter.ts @@ -1,6 +1,5 @@ -import { HunterIOIcon } from '@/components/icons' import { HunterBlockDisplay } from '@/blocks/blocks/hunter.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { HunterResponse } from '@/tools/hunter/types' export const HunterBlock: BlockConfig = { @@ -400,99 +399,3 @@ Return ONLY the search query text - no explanations.`, }, }, } - -export const HunterBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://hunter.io', - templates: [ - { - icon: HunterIOIcon, - title: 'Hunter email finder', - prompt: - 'Build a workflow that takes a target company and role from a table, runs Hunter to find the matching email, validates it, and writes the verified contact back.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: HunterIOIcon, - title: 'Hunter email verifier', - prompt: - 'Create a workflow that runs a list of email addresses through Hunter verification, removes invalid emails, and writes a clean list for outbound sends.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: HunterIOIcon, - title: 'Hunter + Email Bison outbound', - prompt: - 'Build a workflow that uses Hunter to find prospect emails, validates each, and pushes valid prospects into an active Email Bison campaign.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - { - icon: HunterIOIcon, - title: 'Hunter domain finder', - prompt: - 'Create a workflow that takes a list of company names, finds the matching domains via Hunter, and enriches the rows so the CRM has accurate domain data.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - }, - { - icon: HunterIOIcon, - title: 'Hunter event-list enricher', - prompt: - 'Build a workflow that takes a Luma event registrants list, finds their work emails via Hunter, and writes the verified emails into HubSpot for followup.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['luma', 'hubspot'], - }, - { - icon: HunterIOIcon, - title: 'Hunter CRM gap-filler', - prompt: - 'Create a scheduled workflow that finds HubSpot contacts missing email addresses, looks them up via Hunter, validates each, and updates the contact record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: HunterIOIcon, - title: 'Hunter + Apollo prospect builder', - prompt: - 'Build a workflow that runs an Apollo search for an ICP, finds verified emails via Hunter, and writes the deliverable prospect list to a sender table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['apollo'], - }, - ], - skills: [ - { - name: 'find-decision-maker-emails', - description: - 'Find verified email addresses for key roles at a target company using domain search.', - content: - '# Find Decision-Maker Emails\n\nGiven a company domain, find verified professional email addresses for the people who matter.\n\n## Steps\n1. Run a domain search for the target domain (e.g. example.com).\n2. Filter results by department or seniority (executive, sales, IT) to surface decision-makers.\n3. For each candidate, capture the full name, role, email, and confidence score.\n4. Drop any result below your confidence threshold (e.g. < 80).\n\n## Output\nReturn a list of contacts with name, title, email, and confidence score, sorted by seniority. Note the total emails available on the domain so the user knows coverage.', - }, - { - name: 'verify-email-list', - description: - 'Verify a batch of email addresses and flag undeliverable or risky ones before sending.', - content: - '# Verify Email List\n\nClean a list of email addresses so a campaign only sends to deliverable inboxes.\n\n## Steps\n1. For each address, run the email verifier.\n2. Record the verification status (valid, invalid, accept-all, disposable, webmail) and the deliverability score.\n3. Bucket addresses into deliverable, risky, and undeliverable.\n\n## Output\nReturn the three buckets with counts, and a recommended clean list containing only deliverable addresses.', - }, - { - name: 'find-person-email', - description: 'Find the most likely email address for a named person at a specific company.', - content: - '# Find a Person Email\n\nGiven a first name, last name, and company domain, find that person email address.\n\n## Steps\n1. Run the email finder with the full name and domain.\n2. Capture the returned email, confidence score, and the sources Hunter used.\n3. If confidence is low, optionally run a domain search to confirm the pattern.\n\n## Output\nReturn the email, confidence score, and supporting sources. State clearly when no confident match was found.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/iam.display.ts b/apps/sim/blocks/blocks/iam.display.ts index ca35346ae3c..0242acdc623 100644 --- a/apps/sim/blocks/blocks/iam.display.ts +++ b/apps/sim/blocks/blocks/iam.display.ts @@ -1,6 +1,6 @@ import { IAMIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const IAMBlockDisplay = { type: 'iam', @@ -14,3 +14,109 @@ export const IAMBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/iam', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const IAMBlockMeta = { + tags: ['cloud', 'identity'], + url: 'https://aws.amazon.com/iam', + templates: [ + { + icon: IAMIcon, + title: 'IAM permission drift detector', + prompt: + 'Build a scheduled workflow that diffs AWS IAM policies against the Terraform source of truth, alerts on drift, and writes the drift report to a security Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: IAMIcon, + title: 'IAM wildcard policy auditor', + prompt: + 'Create a scheduled workflow that scans AWS IAM policies for wildcard permissions, scores each by blast radius, and writes a remediation queue to a security table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: IAMIcon, + title: 'IAM access-review automator', + prompt: + 'Build a scheduled quarterly workflow that posts AWS IAM access-review requests to role owners in Slack, captures attestations, and writes the audit log to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: IAMIcon, + title: 'IAM stale-key sweeper', + prompt: + 'Create a scheduled workflow that reviews IAM users for aged access keys, notifies the owner via Slack, and rotates the key with a fresh one or removes it after a grace period.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: IAMIcon, + title: 'IAM unused-role cleaner', + prompt: + 'Build a scheduled monthly workflow that finds IAM roles with no recent activity, requires owner approval in Slack, and removes the role to reduce attack surface.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: IAMIcon, + title: 'IAM least-privilege recommender', + prompt: + 'Create a workflow that simulates IAM principal policies against expected actions, generates least-privilege policy suggestions for over-permissioned roles, and opens Linear tickets for engineers to apply.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['linear'], + }, + { + icon: IAMIcon, + title: 'IAM policy guardrail watcher', + prompt: + 'Build a scheduled workflow that snapshots AWS IAM managed policies and role attachments, classifies risk on each change, and pings the security team in Slack when a change broadens permissions.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'audit-iam-permissions', + description: + 'List IAM users, roles, and their attached policies to produce an access audit. Use for security reviews and least-privilege checks.', + content: + '# Audit IAM Permissions\n\nReport who and what has access in IAM.\n\n## Steps\n1. List users and roles to establish the inventory.\n2. For each principal of interest, list attached user or role policies.\n3. Optionally simulate principal policy to confirm whether a principal can perform sensitive actions.\n4. Flag overly broad policies, unused principals, or access keys that should be rotated.\n\n## Output\nAn audit summary: principals and their attached policies, with risky or excessive grants called out. Do not expose secret values.', + }, + { + name: 'check-effective-permissions', + description: + 'Use IAM policy simulation to verify whether a user or role can perform specific actions on resources. Use for troubleshooting access and validating changes.', + content: + '# Check Effective Permissions\n\nDetermine whether a principal is actually allowed to do something.\n\n## Steps\n1. Identify the principal (user or role) and the actions and resource ARNs to test.\n2. Run simulate principal policy for those actions against the resources.\n3. Read the allowed or denied decision for each action, noting which statement governs it.\n4. If denied unexpectedly, inspect the attached policies to explain why.\n\n## Output\nA per-action allow/deny verdict with the governing policy, and a plain-language explanation of any denial.', + }, + { + name: 'provision-iam-principal', + description: + 'Create an IAM user or role, attach managed policies, and place users into groups to grant scoped access. Use for onboarding and standing up service roles.', + content: + '# Provision IAM Principal\n\nStand up a new IAM user or role with the right permissions.\n\n## Steps\n1. Decide whether to create a user (for a person or app) or a role (for a service or cross-account access).\n2. For a user, create the user, then add them to the relevant groups or attach the needed managed policy ARNs. For a role, create the role with a trust policy that names the allowed principal, then attach the policy ARNs.\n3. Prefer attaching existing managed policies over broad wildcards; grant only the actions required.\n4. Confirm the result by listing the attached user or role policies.\n\n## Output\nReport the created principal name and ARN and the policies now attached. Do not print any generated secret values.', + }, + { + name: 'rotate-access-keys', + description: + 'Create a fresh IAM access key for a user and delete the old one to complete a safe rotation. Use for scheduled key rotation and remediating aged keys.', + content: + '# Rotate Access Keys\n\nReplace a user’s access key following the two-step rotation pattern.\n\n## Steps\n1. Create a new access key for the target user so two keys exist briefly.\n2. Hand the new key to its consumer securely and let dependents switch over and verify they still work.\n3. Once the new key is confirmed in use, delete the old access key by its ID.\n4. Confirm only the intended key remains for the user.\n\n## Output\nReport the user, that a new key was issued, and the old key ID that was deleted. Never print the secret access key value — reference keys only by their access key ID.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/iam.ts b/apps/sim/blocks/blocks/iam.ts index ef4faf772d8..a72072cda36 100644 --- a/apps/sim/blocks/blocks/iam.ts +++ b/apps/sim/blocks/blocks/iam.ts @@ -1,6 +1,5 @@ -import { IAMIcon } from '@/components/icons' import { IAMBlockDisplay } from '@/blocks/blocks/iam.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { IAMBaseResponse } from '@/tools/iam/types' @@ -656,109 +655,3 @@ export const IAMBlock: BlockConfig = { }, }, } - -export const IAMBlockMeta = { - tags: ['cloud', 'identity'], - url: 'https://aws.amazon.com/iam', - templates: [ - { - icon: IAMIcon, - title: 'IAM permission drift detector', - prompt: - 'Build a scheduled workflow that diffs AWS IAM policies against the Terraform source of truth, alerts on drift, and writes the drift report to a security Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: IAMIcon, - title: 'IAM wildcard policy auditor', - prompt: - 'Create a scheduled workflow that scans AWS IAM policies for wildcard permissions, scores each by blast radius, and writes a remediation queue to a security table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: IAMIcon, - title: 'IAM access-review automator', - prompt: - 'Build a scheduled quarterly workflow that posts AWS IAM access-review requests to role owners in Slack, captures attestations, and writes the audit log to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: IAMIcon, - title: 'IAM stale-key sweeper', - prompt: - 'Create a scheduled workflow that reviews IAM users for aged access keys, notifies the owner via Slack, and rotates the key with a fresh one or removes it after a grace period.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: IAMIcon, - title: 'IAM unused-role cleaner', - prompt: - 'Build a scheduled monthly workflow that finds IAM roles with no recent activity, requires owner approval in Slack, and removes the role to reduce attack surface.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: IAMIcon, - title: 'IAM least-privilege recommender', - prompt: - 'Create a workflow that simulates IAM principal policies against expected actions, generates least-privilege policy suggestions for over-permissioned roles, and opens Linear tickets for engineers to apply.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['linear'], - }, - { - icon: IAMIcon, - title: 'IAM policy guardrail watcher', - prompt: - 'Build a scheduled workflow that snapshots AWS IAM managed policies and role attachments, classifies risk on each change, and pings the security team in Slack when a change broadens permissions.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'audit-iam-permissions', - description: - 'List IAM users, roles, and their attached policies to produce an access audit. Use for security reviews and least-privilege checks.', - content: - '# Audit IAM Permissions\n\nReport who and what has access in IAM.\n\n## Steps\n1. List users and roles to establish the inventory.\n2. For each principal of interest, list attached user or role policies.\n3. Optionally simulate principal policy to confirm whether a principal can perform sensitive actions.\n4. Flag overly broad policies, unused principals, or access keys that should be rotated.\n\n## Output\nAn audit summary: principals and their attached policies, with risky or excessive grants called out. Do not expose secret values.', - }, - { - name: 'check-effective-permissions', - description: - 'Use IAM policy simulation to verify whether a user or role can perform specific actions on resources. Use for troubleshooting access and validating changes.', - content: - '# Check Effective Permissions\n\nDetermine whether a principal is actually allowed to do something.\n\n## Steps\n1. Identify the principal (user or role) and the actions and resource ARNs to test.\n2. Run simulate principal policy for those actions against the resources.\n3. Read the allowed or denied decision for each action, noting which statement governs it.\n4. If denied unexpectedly, inspect the attached policies to explain why.\n\n## Output\nA per-action allow/deny verdict with the governing policy, and a plain-language explanation of any denial.', - }, - { - name: 'provision-iam-principal', - description: - 'Create an IAM user or role, attach managed policies, and place users into groups to grant scoped access. Use for onboarding and standing up service roles.', - content: - '# Provision IAM Principal\n\nStand up a new IAM user or role with the right permissions.\n\n## Steps\n1. Decide whether to create a user (for a person or app) or a role (for a service or cross-account access).\n2. For a user, create the user, then add them to the relevant groups or attach the needed managed policy ARNs. For a role, create the role with a trust policy that names the allowed principal, then attach the policy ARNs.\n3. Prefer attaching existing managed policies over broad wildcards; grant only the actions required.\n4. Confirm the result by listing the attached user or role policies.\n\n## Output\nReport the created principal name and ARN and the policies now attached. Do not print any generated secret values.', - }, - { - name: 'rotate-access-keys', - description: - 'Create a fresh IAM access key for a user and delete the old one to complete a safe rotation. Use for scheduled key rotation and remediating aged keys.', - content: - '# Rotate Access Keys\n\nReplace a user’s access key following the two-step rotation pattern.\n\n## Steps\n1. Create a new access key for the target user so two keys exist briefly.\n2. Hand the new key to its consumer securely and let dependents switch over and verify they still work.\n3. Once the new key is confirmed in use, delete the old access key by its ID.\n4. Confirm only the intended key remains for the user.\n\n## Output\nReport the user, that a new key was issued, and the old key ID that was deleted. Never print the secret access key value — reference keys only by their access key ID.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/icypeas.display.ts b/apps/sim/blocks/blocks/icypeas.display.ts index 8213500d73e..e932b01c830 100644 --- a/apps/sim/blocks/blocks/icypeas.display.ts +++ b/apps/sim/blocks/blocks/icypeas.display.ts @@ -1,6 +1,6 @@ import { IcypeasIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const IcypeasBlockDisplay = { type: 'icypeas', @@ -14,3 +14,8 @@ export const IcypeasBlockDisplay = { docsLink: 'https://docs.sim.ai/tools/icypeas', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const IcypeasBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.icypeas.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/icypeas.ts b/apps/sim/blocks/blocks/icypeas.ts index da234f7e032..4f1d5a1cc8a 100644 --- a/apps/sim/blocks/blocks/icypeas.ts +++ b/apps/sim/blocks/blocks/icypeas.ts @@ -1,5 +1,5 @@ import { IcypeasBlockDisplay } from '@/blocks/blocks/icypeas.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { IcypeasResponse } from '@/tools/icypeas/types' export const IcypeasBlock: BlockConfig = { @@ -147,8 +147,3 @@ export const IcypeasBlock: BlockConfig = { }, }, } - -export const IcypeasBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.icypeas.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/identity_center.display.ts b/apps/sim/blocks/blocks/identity_center.display.ts index 8218ea2711f..e4dbe683849 100644 --- a/apps/sim/blocks/blocks/identity_center.display.ts +++ b/apps/sim/blocks/blocks/identity_center.display.ts @@ -1,6 +1,6 @@ import { IdentityCenterIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const IdentityCenterBlockDisplay = { type: 'identity_center', @@ -14,3 +14,102 @@ export const IdentityCenterBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/identity_center', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const IdentityCenterBlockMeta = { + tags: ['cloud', 'identity'], + url: 'https://aws.amazon.com/iam/identity-center', + templates: [ + { + icon: IdentityCenterIcon, + title: 'Identity Center access-review', + prompt: + 'Build a scheduled quarterly workflow that surfaces AWS Identity Center permission sets and group memberships, requests owner attestation in Slack, and writes the audit log to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center new-hire onboarder', + prompt: + 'Create a workflow that on a Workday new-hire event provisions AWS Identity Center permission sets based on role, and writes the assignment to a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center offboarder', + prompt: + 'Build a workflow that on a Workday termination revokes the user’s AWS Identity Center assignments and writes the action log to the security audit table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center assignment monitor', + prompt: + 'Create a scheduled workflow that snapshots AWS Identity Center account assignments and permission sets, flags new or broadened access, and pings the security Slack channel on changes.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center permission-set drift', + prompt: + 'Build a scheduled workflow that diffs AWS Identity Center permission sets against the Terraform source of truth, alerts on drift, and writes the report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center orphaned-access finder', + prompt: + 'Create a scheduled workflow that lists AWS Identity Center account assignments, flags principals with stale or unexpected access, emails owners for confirmation, and writes the findings to a security dashboard table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['gmail'], + }, + { + icon: IdentityCenterIcon, + title: 'Identity Center compliance reporter', + prompt: + 'Build a scheduled workflow that produces an AWS Identity Center compliance report — permission sets, group memberships, and account assignments — and writes the file for auditors.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + ], + skills: [ + { + name: 'grant-temporary-access', + description: + 'Assign a permission set to a user or group on an AWS account through Identity Center and confirm the assignment completes. Use for just-in-time elevated access.', + content: + '# Grant Temporary Access\n\nProvision elevated access via an Identity Center account assignment.\n\n## Steps\n1. Resolve the Identity Center instance, target account, and permission set.\n2. Resolve the principal — get the user or group to confirm the correct ID and type.\n3. Create the account assignment for that principal, permission set, and account.\n4. Poll check assignment status until it reports SUCCEEDED.\n\n## Output\nConfirm the principal, account, permission set, and final assignment status. If it failed, surface the failure reason.', + }, + { + name: 'revoke-access', + description: + 'Remove a permission set assignment from a user or group in Identity Center and confirm deletion. Use to wind down temporary or expired access.', + content: + '# Revoke Access\n\nRemove an account assignment to revoke access.\n\n## Steps\n1. List account assignments to confirm the principal currently holds the permission set on the account.\n2. Delete the account assignment for that principal, permission set, and account.\n3. Poll check assignment deletion status until it reports SUCCEEDED.\n4. Re-list assignments to verify the grant is gone.\n\n## Output\nConfirm what was revoked and the final deletion status. Note if the assignment did not exist.', + }, + { + name: 'access-audit-report', + description: + 'Enumerate permission sets, group memberships, and account assignments in Identity Center to produce an access report. Use for compliance and periodic reviews.', + content: + '# Access Audit Report\n\nReport who has access to what across accounts.\n\n## Steps\n1. List instances and accounts to scope the report.\n2. List permission sets and, per account, list account assignments.\n3. Resolve users and groups behind each assignment with get user and get group.\n4. Compile assignments grouped by account and permission set.\n\n## Output\nAn access report: per account, which principals hold which permission sets, with anything unexpected flagged for review.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/identity_center.ts b/apps/sim/blocks/blocks/identity_center.ts index d7fde95a167..f7e8b9b7808 100644 --- a/apps/sim/blocks/blocks/identity_center.ts +++ b/apps/sim/blocks/blocks/identity_center.ts @@ -1,6 +1,5 @@ -import { IdentityCenterIcon } from '@/components/icons' import { IdentityCenterBlockDisplay } from '@/blocks/blocks/identity_center.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { IdentityCenterBaseResponse } from '@/tools/identity_center/types' @@ -427,102 +426,3 @@ export const IdentityCenterBlock: BlockConfig = { count: { type: 'number', description: 'Number of items returned' }, }, } - -export const IdentityCenterBlockMeta = { - tags: ['cloud', 'identity'], - url: 'https://aws.amazon.com/iam/identity-center', - templates: [ - { - icon: IdentityCenterIcon, - title: 'Identity Center access-review', - prompt: - 'Build a scheduled quarterly workflow that surfaces AWS Identity Center permission sets and group memberships, requests owner attestation in Slack, and writes the audit log to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center new-hire onboarder', - prompt: - 'Create a workflow that on a Workday new-hire event provisions AWS Identity Center permission sets based on role, and writes the assignment to a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center offboarder', - prompt: - 'Build a workflow that on a Workday termination revokes the user’s AWS Identity Center assignments and writes the action log to the security audit table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center assignment monitor', - prompt: - 'Create a scheduled workflow that snapshots AWS Identity Center account assignments and permission sets, flags new or broadened access, and pings the security Slack channel on changes.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center permission-set drift', - prompt: - 'Build a scheduled workflow that diffs AWS Identity Center permission sets against the Terraform source of truth, alerts on drift, and writes the report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center orphaned-access finder', - prompt: - 'Create a scheduled workflow that lists AWS Identity Center account assignments, flags principals with stale or unexpected access, emails owners for confirmation, and writes the findings to a security dashboard table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['gmail'], - }, - { - icon: IdentityCenterIcon, - title: 'Identity Center compliance reporter', - prompt: - 'Build a scheduled workflow that produces an AWS Identity Center compliance report — permission sets, group memberships, and account assignments — and writes the file for auditors.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - ], - skills: [ - { - name: 'grant-temporary-access', - description: - 'Assign a permission set to a user or group on an AWS account through Identity Center and confirm the assignment completes. Use for just-in-time elevated access.', - content: - '# Grant Temporary Access\n\nProvision elevated access via an Identity Center account assignment.\n\n## Steps\n1. Resolve the Identity Center instance, target account, and permission set.\n2. Resolve the principal — get the user or group to confirm the correct ID and type.\n3. Create the account assignment for that principal, permission set, and account.\n4. Poll check assignment status until it reports SUCCEEDED.\n\n## Output\nConfirm the principal, account, permission set, and final assignment status. If it failed, surface the failure reason.', - }, - { - name: 'revoke-access', - description: - 'Remove a permission set assignment from a user or group in Identity Center and confirm deletion. Use to wind down temporary or expired access.', - content: - '# Revoke Access\n\nRemove an account assignment to revoke access.\n\n## Steps\n1. List account assignments to confirm the principal currently holds the permission set on the account.\n2. Delete the account assignment for that principal, permission set, and account.\n3. Poll check assignment deletion status until it reports SUCCEEDED.\n4. Re-list assignments to verify the grant is gone.\n\n## Output\nConfirm what was revoked and the final deletion status. Note if the assignment did not exist.', - }, - { - name: 'access-audit-report', - description: - 'Enumerate permission sets, group memberships, and account assignments in Identity Center to produce an access report. Use for compliance and periodic reviews.', - content: - '# Access Audit Report\n\nReport who has access to what across accounts.\n\n## Steps\n1. List instances and accounts to scope the report.\n2. List permission sets and, per account, list account assignments.\n3. Resolve users and groups behind each assignment with get user and get group.\n4. Compile assignments grouped by account and permission set.\n\n## Output\nAn access report: per account, which principals hold which permission sets, with anything unexpected flagged for review.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/imap.display.ts b/apps/sim/blocks/blocks/imap.display.ts index 0c42405785b..2f4d1ad6d80 100644 --- a/apps/sim/blocks/blocks/imap.display.ts +++ b/apps/sim/blocks/blocks/imap.display.ts @@ -1,6 +1,7 @@ +import { ClipboardList, Table } from '@/components/emcn/icons' import { MailServerIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ImapBlockDisplay = { type: 'imap', @@ -16,3 +17,37 @@ export const ImapBlockDisplay = { hideFromToolbar: false, triggerAllowed: true, } satisfies BlockDisplay + +export const ImapBlockMeta = { + tags: ['automation', 'messaging'], + templates: [ + { + icon: MailServerIcon, + title: 'Inbound email to Slack', + prompt: + 'Build a workflow that triggers when a new email arrives via IMAP, summarizes the subject and body with an agent, and posts the summary with the sender to a Slack channel.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['communication', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: ClipboardList, + title: 'Support inbox triage', + prompt: + 'Create a workflow that triggers on new emails arriving via IMAP, classifies each one by topic and urgency with an agent, and logs the sender, subject, and category to a triage table.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['communication', 'automation'], + }, + { + icon: Table, + title: 'Invoice email to records', + prompt: + 'Build a workflow that triggers when an email arrives via IMAP, extracts the vendor, amount, and due date from the body and attachments with an agent, and writes a row to an invoices table.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['communication', 'automation'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/imap.ts b/apps/sim/blocks/blocks/imap.ts index ac454aabf95..f7bde73839f 100644 --- a/apps/sim/blocks/blocks/imap.ts +++ b/apps/sim/blocks/blocks/imap.ts @@ -1,7 +1,5 @@ -import { ClipboardList, Table } from '@/components/emcn/icons' -import { MailServerIcon } from '@/components/icons' import { ImapBlockDisplay } from '@/blocks/blocks/imap.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const ImapBlock: BlockConfig = { @@ -43,37 +41,3 @@ export const ImapBlock: BlockConfig = { available: ['imap_poller'], }, } - -export const ImapBlockMeta = { - tags: ['automation', 'messaging'], - templates: [ - { - icon: MailServerIcon, - title: 'Inbound email to Slack', - prompt: - 'Build a workflow that triggers when a new email arrives via IMAP, summarizes the subject and body with an agent, and posts the summary with the sender to a Slack channel.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['communication', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: ClipboardList, - title: 'Support inbox triage', - prompt: - 'Create a workflow that triggers on new emails arriving via IMAP, classifies each one by topic and urgency with an agent, and logs the sender, subject, and category to a triage table.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['communication', 'automation'], - }, - { - icon: Table, - title: 'Invoice email to records', - prompt: - 'Build a workflow that triggers when an email arrives via IMAP, extracts the vendor, amount, and due date from the body and attachments with an agent, and writes a row to an invoices table.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['communication', 'automation'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/incidentio.display.ts b/apps/sim/blocks/blocks/incidentio.display.ts index 5868dae3d7e..d0381daabf7 100644 --- a/apps/sim/blocks/blocks/incidentio.display.ts +++ b/apps/sim/blocks/blocks/incidentio.display.ts @@ -1,6 +1,6 @@ import { IncidentioIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const IncidentioBlockDisplay = { type: 'incidentio', @@ -14,3 +14,107 @@ export const IncidentioBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/incidentio', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const IncidentioBlockMeta = { + tags: ['incident-management', 'monitoring'], + url: 'https://incident.io', + templates: [ + { + icon: IncidentioIcon, + title: 'incident.io commander', + prompt: + 'Build a scheduled workflow that polls incident.io for newly declared incidents, opens a Slack war-room for each, invites responders from the on-call schedule, pulls related PagerDuty alerts, and pins the runbook.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack', 'pagerduty'], + }, + { + icon: IncidentioIcon, + title: 'incident.io postmortem starter', + prompt: + 'Create a scheduled workflow that polls incident.io for recently resolved incidents, pulls the Slack thread, related Sentry errors, and deploy timeline, then drafts a postmortem doc in Google Docs.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['sentry', 'google_docs'], + }, + { + icon: IncidentioIcon, + title: 'incident.io action-item tracker', + prompt: + 'Build a workflow that watches incident.io for new follow-up actions, creates Linear tickets for each, and writes a tracking table that surfaces overdue actions on a weekly digest.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['linear'], + }, + { + icon: IncidentioIcon, + title: 'incident.io weekly digest', + prompt: + 'Create a scheduled weekly workflow that summarizes incident.io activity — declared incidents, MTTR, top affected services, action-item completion rate — and posts to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: IncidentioIcon, + title: 'incident.io customer comms drafter', + prompt: + 'Build a workflow that during a high-severity incident.io incident drafts customer status-page copy and a tailored email update, holds for approval, and dispatches once approved.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: IncidentioIcon, + title: 'incident.io SLO impact mapper', + prompt: + 'Create a workflow that on each incident.io incident maps impacted services to active SLOs, calculates SLO burn, and writes the impact analysis back to the incident timeline.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'analysis'], + }, + { + icon: IncidentioIcon, + title: 'incident.io noise filter', + prompt: + 'Build a workflow that pulls incident.io declared incidents, classifies a subset as low-impact noise, auto-resolves them after auditing, and writes a noise-rate metric to a table.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + }, + ], + skills: [ + { + name: 'declare-incident-from-alert', + description: + 'Open an incident.io incident from an inbound alert with the right severity and summary.', + content: + '# Declare an Incident From an Alert\n\nTurn a monitoring alert into a structured incident.io incident so responders can act fast.\n\n## Steps\n1. Look up available severities and pick the one matching the alert impact.\n2. Create the incident with a clear name, a summary describing impact and affected service, and the chosen severity.\n3. Set incident type and any required custom fields from the alert payload.\n4. Capture the new incident reference and link.\n\n## Output\nReturn the incident ID, reference, severity, and link. Confirm the responder channel was created so the team can jump in.', + }, + { + name: 'post-incident-update', + description: + 'Update an active incident with current status and a progress note for stakeholders.', + content: + '# Post an Incident Update\n\nKeep stakeholders informed by moving an active incident through its lifecycle.\n\n## Steps\n1. Look up the incident by reference or ID to confirm its current status.\n2. List valid incident statuses and choose the next one (investigating, identified, monitoring, resolved).\n3. Update the incident with the new status and a concise progress message.\n\n## Output\nReturn the incident reference, the new status, and a one-line summary of what changed and when.', + }, + { + name: 'on-call-handoff-report', + description: 'Summarize who is on call and recent open incidents for an on-call handoff.', + content: + '# On-Call Handoff Report\n\nBuild a clean handoff so the next on-call engineer knows the state of the world.\n\n## Steps\n1. List current schedules and active escalation paths to determine who is on call.\n2. List recent incidents and filter to those that are open or recently resolved.\n3. For each open incident, capture severity, status, and outstanding follow-ups.\n\n## Output\nReturn a handoff brief: who is on call now, open incidents with severity and status, and follow-ups that still need owners.', + }, + { + name: 'export-incident-followups', + description: + 'Pull follow-ups from recent incidents into an actionable list for post-incident review.', + content: + '# Export Incident Follow-Ups\n\nGather the action items that came out of recent incidents so none slip through.\n\n## Steps\n1. List incidents within the target time window.\n2. For each, list its follow-ups and capture title, owner, status, and linked incident.\n3. Group follow-ups by owner and by open vs completed.\n\n## Output\nReturn a table of follow-ups grouped by owner with status and source incident, highlighting overdue or unassigned items.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/incidentio.ts b/apps/sim/blocks/blocks/incidentio.ts index 58b8973acad..81192f50b8f 100644 --- a/apps/sim/blocks/blocks/incidentio.ts +++ b/apps/sim/blocks/blocks/incidentio.ts @@ -1,6 +1,5 @@ -import { IncidentioIcon } from '@/components/icons' import { IncidentioBlockDisplay } from '@/blocks/blocks/incidentio.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { IncidentioResponse } from '@/tools/incidentio/types' @@ -1216,107 +1215,3 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, pagination_meta: { type: 'json', description: 'Pagination metadata' }, }, } - -export const IncidentioBlockMeta = { - tags: ['incident-management', 'monitoring'], - url: 'https://incident.io', - templates: [ - { - icon: IncidentioIcon, - title: 'incident.io commander', - prompt: - 'Build a scheduled workflow that polls incident.io for newly declared incidents, opens a Slack war-room for each, invites responders from the on-call schedule, pulls related PagerDuty alerts, and pins the runbook.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack', 'pagerduty'], - }, - { - icon: IncidentioIcon, - title: 'incident.io postmortem starter', - prompt: - 'Create a scheduled workflow that polls incident.io for recently resolved incidents, pulls the Slack thread, related Sentry errors, and deploy timeline, then drafts a postmortem doc in Google Docs.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['sentry', 'google_docs'], - }, - { - icon: IncidentioIcon, - title: 'incident.io action-item tracker', - prompt: - 'Build a workflow that watches incident.io for new follow-up actions, creates Linear tickets for each, and writes a tracking table that surfaces overdue actions on a weekly digest.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['linear'], - }, - { - icon: IncidentioIcon, - title: 'incident.io weekly digest', - prompt: - 'Create a scheduled weekly workflow that summarizes incident.io activity — declared incidents, MTTR, top affected services, action-item completion rate — and posts to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: IncidentioIcon, - title: 'incident.io customer comms drafter', - prompt: - 'Build a workflow that during a high-severity incident.io incident drafts customer status-page copy and a tailored email update, holds for approval, and dispatches once approved.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: IncidentioIcon, - title: 'incident.io SLO impact mapper', - prompt: - 'Create a workflow that on each incident.io incident maps impacted services to active SLOs, calculates SLO burn, and writes the impact analysis back to the incident timeline.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'analysis'], - }, - { - icon: IncidentioIcon, - title: 'incident.io noise filter', - prompt: - 'Build a workflow that pulls incident.io declared incidents, classifies a subset as low-impact noise, auto-resolves them after auditing, and writes a noise-rate metric to a table.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - }, - ], - skills: [ - { - name: 'declare-incident-from-alert', - description: - 'Open an incident.io incident from an inbound alert with the right severity and summary.', - content: - '# Declare an Incident From an Alert\n\nTurn a monitoring alert into a structured incident.io incident so responders can act fast.\n\n## Steps\n1. Look up available severities and pick the one matching the alert impact.\n2. Create the incident with a clear name, a summary describing impact and affected service, and the chosen severity.\n3. Set incident type and any required custom fields from the alert payload.\n4. Capture the new incident reference and link.\n\n## Output\nReturn the incident ID, reference, severity, and link. Confirm the responder channel was created so the team can jump in.', - }, - { - name: 'post-incident-update', - description: - 'Update an active incident with current status and a progress note for stakeholders.', - content: - '# Post an Incident Update\n\nKeep stakeholders informed by moving an active incident through its lifecycle.\n\n## Steps\n1. Look up the incident by reference or ID to confirm its current status.\n2. List valid incident statuses and choose the next one (investigating, identified, monitoring, resolved).\n3. Update the incident with the new status and a concise progress message.\n\n## Output\nReturn the incident reference, the new status, and a one-line summary of what changed and when.', - }, - { - name: 'on-call-handoff-report', - description: 'Summarize who is on call and recent open incidents for an on-call handoff.', - content: - '# On-Call Handoff Report\n\nBuild a clean handoff so the next on-call engineer knows the state of the world.\n\n## Steps\n1. List current schedules and active escalation paths to determine who is on call.\n2. List recent incidents and filter to those that are open or recently resolved.\n3. For each open incident, capture severity, status, and outstanding follow-ups.\n\n## Output\nReturn a handoff brief: who is on call now, open incidents with severity and status, and follow-ups that still need owners.', - }, - { - name: 'export-incident-followups', - description: - 'Pull follow-ups from recent incidents into an actionable list for post-incident review.', - content: - '# Export Incident Follow-Ups\n\nGather the action items that came out of recent incidents so none slip through.\n\n## Steps\n1. List incidents within the target time window.\n2. For each, list its follow-ups and capture title, owner, status, and linked incident.\n3. Group follow-ups by owner and by open vs completed.\n\n## Output\nReturn a table of follow-ups grouped by owner with status and source incident, highlighting overdue or unassigned items.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/infisical.display.ts b/apps/sim/blocks/blocks/infisical.display.ts index af9042d297f..44afdb4275b 100644 --- a/apps/sim/blocks/blocks/infisical.display.ts +++ b/apps/sim/blocks/blocks/infisical.display.ts @@ -1,6 +1,6 @@ import { InfisicalIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const InfisicalBlockDisplay = { type: 'infisical', @@ -14,3 +14,101 @@ export const InfisicalBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/infisical', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const InfisicalBlockMeta = { + tags: ['secrets-management'], + url: 'https://infisical.com', + templates: [ + { + icon: InfisicalIcon, + title: 'Infisical secret rotation orchestrator', + prompt: + 'Build a scheduled workflow that lists Infisical secrets, generates fresh values for those due for rotation, updates them across each environment, and writes rotation status to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + }, + { + icon: InfisicalIcon, + title: 'Infisical environment drift detector', + prompt: + 'Create a scheduled workflow that diffs Infisical environments against expected schemas, alerts on missing or extra secrets, and writes a remediation queue.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: InfisicalIcon, + title: 'Infisical env bootstrapper', + prompt: + 'Build a workflow that on a Workday new-hire event creates the standard set of Infisical secrets for the new engineer’s scoped dev environment from a template, and writes the provisioning record to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: InfisicalIcon, + title: 'Infisical offboarding rotation', + prompt: + 'Create a workflow that on a Workday termination rotates the shared Infisical secrets the departing engineer had access to by generating new values and updating them across environments, then writes the action log to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: InfisicalIcon, + title: 'Infisical CI sync', + prompt: + 'Build a workflow that mirrors Infisical secrets into GitHub Actions environments for CI deploys, keeping the secret store as the single source of truth.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + alsoIntegrations: ['github'], + }, + { + icon: InfisicalIcon, + title: 'Infisical secret-inventory reviewer', + prompt: + 'Create a scheduled quarterly workflow that lists Infisical secrets per project and environment, flags ones with weak or aged values for owner attestation in Slack, and writes the review to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: InfisicalIcon, + title: 'Infisical secret-inventory snapshot', + prompt: + 'Build a scheduled workflow that lists Infisical secrets across environments, writes a redacted inventory snapshot to S3 for long-term retention, and tracks secret count trends in a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['s3'], + }, + ], + skills: [ + { + name: 'fetch-secret-for-run', + description: + 'Retrieve a named secret from Infisical to use as a credential during a workflow run.', + content: + '# Fetch a Secret for a Run\n\nPull a single secret from Infisical so a downstream step can authenticate without hardcoding credentials.\n\n## Steps\n1. Identify the project, environment (e.g. dev, staging, prod), and secret path.\n2. Get the secret by name from that scope.\n3. Pass the value to the consuming step. Never echo the raw secret into logs or output.\n\n## Output\nConfirm the secret was retrieved (by name and environment) and that it was used. Do not print the secret value itself.', + }, + { + name: 'rotate-secret', + description: 'Update an existing secret in Infisical with a new value as part of a rotation.', + content: + '# Rotate a Secret\n\nReplace a secret value in Infisical during a credential rotation.\n\n## Steps\n1. Confirm the project, environment, and secret name to rotate.\n2. Update the secret with the new value at that path.\n3. Optionally read the secret back by name to confirm it now exists (without printing the value).\n\n## Output\nConfirm the secret name and environment that was rotated and the timestamp. Never expose the old or new value.', + }, + { + name: 'audit-environment-secrets', + description: + 'List the secret names present in an Infisical environment for an inventory or audit.', + content: + '# Audit Environment Secrets\n\nProduce an inventory of which secrets exist in an Infisical environment without exposing their values.\n\n## Steps\n1. Choose the project, environment, and path to audit.\n2. List secrets at that scope and collect only the keys and metadata.\n3. Compare against the expected set if one is provided and flag missing or unexpected keys.\n\n## Output\nReturn a list of secret names (keys only) with count, and any discrepancies versus the expected set. Never include secret values.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/infisical.ts b/apps/sim/blocks/blocks/infisical.ts index 1c5eaf41fc4..5f2f97d4e40 100644 --- a/apps/sim/blocks/blocks/infisical.ts +++ b/apps/sim/blocks/blocks/infisical.ts @@ -1,6 +1,5 @@ -import { InfisicalIcon } from '@/components/icons' import { InfisicalBlockDisplay } from '@/blocks/blocks/infisical.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { InfisicalResponse } from '@/tools/infisical/types' @@ -230,101 +229,3 @@ export const InfisicalBlock: BlockConfig = { }, }, } - -export const InfisicalBlockMeta = { - tags: ['secrets-management'], - url: 'https://infisical.com', - templates: [ - { - icon: InfisicalIcon, - title: 'Infisical secret rotation orchestrator', - prompt: - 'Build a scheduled workflow that lists Infisical secrets, generates fresh values for those due for rotation, updates them across each environment, and writes rotation status to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - }, - { - icon: InfisicalIcon, - title: 'Infisical environment drift detector', - prompt: - 'Create a scheduled workflow that diffs Infisical environments against expected schemas, alerts on missing or extra secrets, and writes a remediation queue.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: InfisicalIcon, - title: 'Infisical env bootstrapper', - prompt: - 'Build a workflow that on a Workday new-hire event creates the standard set of Infisical secrets for the new engineer’s scoped dev environment from a template, and writes the provisioning record to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: InfisicalIcon, - title: 'Infisical offboarding rotation', - prompt: - 'Create a workflow that on a Workday termination rotates the shared Infisical secrets the departing engineer had access to by generating new values and updating them across environments, then writes the action log to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: InfisicalIcon, - title: 'Infisical CI sync', - prompt: - 'Build a workflow that mirrors Infisical secrets into GitHub Actions environments for CI deploys, keeping the secret store as the single source of truth.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - alsoIntegrations: ['github'], - }, - { - icon: InfisicalIcon, - title: 'Infisical secret-inventory reviewer', - prompt: - 'Create a scheduled quarterly workflow that lists Infisical secrets per project and environment, flags ones with weak or aged values for owner attestation in Slack, and writes the review to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: InfisicalIcon, - title: 'Infisical secret-inventory snapshot', - prompt: - 'Build a scheduled workflow that lists Infisical secrets across environments, writes a redacted inventory snapshot to S3 for long-term retention, and tracks secret count trends in a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['s3'], - }, - ], - skills: [ - { - name: 'fetch-secret-for-run', - description: - 'Retrieve a named secret from Infisical to use as a credential during a workflow run.', - content: - '# Fetch a Secret for a Run\n\nPull a single secret from Infisical so a downstream step can authenticate without hardcoding credentials.\n\n## Steps\n1. Identify the project, environment (e.g. dev, staging, prod), and secret path.\n2. Get the secret by name from that scope.\n3. Pass the value to the consuming step. Never echo the raw secret into logs or output.\n\n## Output\nConfirm the secret was retrieved (by name and environment) and that it was used. Do not print the secret value itself.', - }, - { - name: 'rotate-secret', - description: 'Update an existing secret in Infisical with a new value as part of a rotation.', - content: - '# Rotate a Secret\n\nReplace a secret value in Infisical during a credential rotation.\n\n## Steps\n1. Confirm the project, environment, and secret name to rotate.\n2. Update the secret with the new value at that path.\n3. Optionally read the secret back by name to confirm it now exists (without printing the value).\n\n## Output\nConfirm the secret name and environment that was rotated and the timestamp. Never expose the old or new value.', - }, - { - name: 'audit-environment-secrets', - description: - 'List the secret names present in an Infisical environment for an inventory or audit.', - content: - '# Audit Environment Secrets\n\nProduce an inventory of which secrets exist in an Infisical environment without exposing their values.\n\n## Steps\n1. Choose the project, environment, and path to audit.\n2. List secrets at that scope and collect only the keys and metadata.\n3. Compare against the expected set if one is provided and flag missing or unexpected keys.\n\n## Output\nReturn a list of secret names (keys only) with count, and any discrepancies versus the expected set. Never include secret values.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/instantly.display.ts b/apps/sim/blocks/blocks/instantly.display.ts index 5b38148e96f..4e93af75b68 100644 --- a/apps/sim/blocks/blocks/instantly.display.ts +++ b/apps/sim/blocks/blocks/instantly.display.ts @@ -1,6 +1,6 @@ import { InstantlyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const InstantlyBlockDisplay = { type: 'instantly', @@ -14,3 +14,106 @@ export const InstantlyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/instantly', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const InstantlyBlockMeta = { + tags: ['sales-engagement', 'email-marketing', 'automation'], + url: 'https://instantly.ai', + templates: [ + { + icon: InstantlyIcon, + title: 'Instantly lead loader', + prompt: + 'Build a workflow that reads new prospects from a table and creates each as a lead in the right Instantly campaign, then writes the Instantly lead ID back so the sender table stays in sync.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: InstantlyIcon, + title: 'Instantly reply triager', + prompt: + 'Create a workflow triggered when an Instantly reply is received that classifies intent, updates the lead interest status, and posts a Slack alert for positive replies so reps follow up fast.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: InstantlyIcon, + title: 'Instantly campaign launcher', + prompt: + 'Build a workflow that creates a new Instantly campaign from a brief, builds a lead list, loads the prospects, and activates the campaign once the list is ready.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: InstantlyIcon, + title: 'Instantly performance report', + prompt: + 'Create a scheduled weekly workflow that lists Instantly campaigns and emails, computes reply and interest rates per campaign, logs them to a table for trend tracking, and Slacks a summary to the sales team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: InstantlyIcon, + title: 'Instantly meeting-booked sync', + prompt: + 'Build a workflow triggered when an Instantly lead is marked meeting booked that creates or updates the matching HubSpot contact and deal so the CRM reflects pipeline from outbound.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: InstantlyIcon, + title: 'Hunter + Instantly outbound', + prompt: + 'Create a workflow that finds verified prospect emails with Hunter, validates each, and loads the deliverable contacts into an active Instantly campaign.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['hunter'], + }, + { + icon: InstantlyIcon, + title: 'Instantly reply router', + prompt: + "Build a scheduled workflow that lists new Instantly campaign email replies, classifies each as interested, objection, or out-of-office with an agent, updates the lead's interest status, and posts hot replies to the sales Slack channel for a fast follow-up.", + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'communication'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'add-leads-to-campaign', + description: + 'Push a batch of prospects into an Instantly campaign as new leads with personalization fields.', + content: + '# Add Leads to a Campaign\n\nLoad a set of prospects into an Instantly cold-email campaign so they enter the sending sequence.\n\n## Steps\n1. List campaigns and identify the target campaign by name.\n2. For each prospect, create a lead with email, first name, last name, company, and any custom personalization variables.\n3. Attach each lead to the chosen campaign.\n\n## Output\nReturn how many leads were added, the campaign name, and any rows skipped for missing or invalid emails.', + }, + { + name: 'launch-outreach-campaign', + description: 'Create a cold-email campaign, load a lead list, and activate it for sending.', + content: + '# Launch an Outreach Campaign\n\nStand up a new Instantly campaign end to end and start sending.\n\n## Steps\n1. Create a lead list and add the target prospects to it.\n2. Create the campaign with its sending sequence and schedule.\n3. Add the leads to the campaign.\n4. Activate the campaign so sending begins.\n\n## Output\nReturn the campaign name, lead count, and activation status. Confirm the campaign is live.', + }, + { + name: 'triage-campaign-replies', + description: 'Review recent campaign email replies and update each lead interest status.', + content: + '# Triage Campaign Replies\n\nProcess inbound replies on a campaign and route each lead by interest.\n\n## Steps\n1. List recent emails for the campaign and identify replies from leads.\n2. Read each reply and classify intent (interested, not interested, out of office, wrong person).\n3. Update the matching lead interest status to reflect the classification.\n4. For interested leads, draft a reply to the email.\n\n## Output\nReturn a summary of replies by category, the leads marked interested, and any drafted responses for review.', + }, + { + name: 'campaign-performance-snapshot', + description: + 'Summarize active campaigns and their leads into a quick outreach performance snapshot.', + content: + '# Campaign Performance Snapshot\n\nGive a quick read on how outreach is going across campaigns.\n\n## Steps\n1. List campaigns and note which are active.\n2. For each active campaign, list leads and tally counts by interest status.\n3. Pull recent emails to gauge reply volume.\n\n## Output\nReturn a per-campaign snapshot: total leads, breakdown by interest status, and reply activity, highlighting the top-performing campaign.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/instantly.ts b/apps/sim/blocks/blocks/instantly.ts index b2d2285607d..4e74cc577ad 100644 --- a/apps/sim/blocks/blocks/instantly.ts +++ b/apps/sim/blocks/blocks/instantly.ts @@ -1,7 +1,6 @@ import { isRecordLike } from '@sim/utils/object' -import { InstantlyIcon } from '@/components/icons' import { InstantlyBlockDisplay } from '@/blocks/blocks/instantly.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { InstantlyResponse } from '@/tools/instantly/types' import { getTrigger } from '@/triggers' @@ -1241,106 +1240,3 @@ function optionalIdParam(value: unknown): string | undefined { if (trimmed === '' || trimmed === '-') return undefined return trimmed } - -export const InstantlyBlockMeta = { - tags: ['sales-engagement', 'email-marketing', 'automation'], - url: 'https://instantly.ai', - templates: [ - { - icon: InstantlyIcon, - title: 'Instantly lead loader', - prompt: - 'Build a workflow that reads new prospects from a table and creates each as a lead in the right Instantly campaign, then writes the Instantly lead ID back so the sender table stays in sync.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: InstantlyIcon, - title: 'Instantly reply triager', - prompt: - 'Create a workflow triggered when an Instantly reply is received that classifies intent, updates the lead interest status, and posts a Slack alert for positive replies so reps follow up fast.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: InstantlyIcon, - title: 'Instantly campaign launcher', - prompt: - 'Build a workflow that creates a new Instantly campaign from a brief, builds a lead list, loads the prospects, and activates the campaign once the list is ready.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: InstantlyIcon, - title: 'Instantly performance report', - prompt: - 'Create a scheduled weekly workflow that lists Instantly campaigns and emails, computes reply and interest rates per campaign, logs them to a table for trend tracking, and Slacks a summary to the sales team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: InstantlyIcon, - title: 'Instantly meeting-booked sync', - prompt: - 'Build a workflow triggered when an Instantly lead is marked meeting booked that creates or updates the matching HubSpot contact and deal so the CRM reflects pipeline from outbound.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: InstantlyIcon, - title: 'Hunter + Instantly outbound', - prompt: - 'Create a workflow that finds verified prospect emails with Hunter, validates each, and loads the deliverable contacts into an active Instantly campaign.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['hunter'], - }, - { - icon: InstantlyIcon, - title: 'Instantly reply router', - prompt: - "Build a scheduled workflow that lists new Instantly campaign email replies, classifies each as interested, objection, or out-of-office with an agent, updates the lead's interest status, and posts hot replies to the sales Slack channel for a fast follow-up.", - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'communication'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'add-leads-to-campaign', - description: - 'Push a batch of prospects into an Instantly campaign as new leads with personalization fields.', - content: - '# Add Leads to a Campaign\n\nLoad a set of prospects into an Instantly cold-email campaign so they enter the sending sequence.\n\n## Steps\n1. List campaigns and identify the target campaign by name.\n2. For each prospect, create a lead with email, first name, last name, company, and any custom personalization variables.\n3. Attach each lead to the chosen campaign.\n\n## Output\nReturn how many leads were added, the campaign name, and any rows skipped for missing or invalid emails.', - }, - { - name: 'launch-outreach-campaign', - description: 'Create a cold-email campaign, load a lead list, and activate it for sending.', - content: - '# Launch an Outreach Campaign\n\nStand up a new Instantly campaign end to end and start sending.\n\n## Steps\n1. Create a lead list and add the target prospects to it.\n2. Create the campaign with its sending sequence and schedule.\n3. Add the leads to the campaign.\n4. Activate the campaign so sending begins.\n\n## Output\nReturn the campaign name, lead count, and activation status. Confirm the campaign is live.', - }, - { - name: 'triage-campaign-replies', - description: 'Review recent campaign email replies and update each lead interest status.', - content: - '# Triage Campaign Replies\n\nProcess inbound replies on a campaign and route each lead by interest.\n\n## Steps\n1. List recent emails for the campaign and identify replies from leads.\n2. Read each reply and classify intent (interested, not interested, out of office, wrong person).\n3. Update the matching lead interest status to reflect the classification.\n4. For interested leads, draft a reply to the email.\n\n## Output\nReturn a summary of replies by category, the leads marked interested, and any drafted responses for review.', - }, - { - name: 'campaign-performance-snapshot', - description: - 'Summarize active campaigns and their leads into a quick outreach performance snapshot.', - content: - '# Campaign Performance Snapshot\n\nGive a quick read on how outreach is going across campaigns.\n\n## Steps\n1. List campaigns and note which are active.\n2. For each active campaign, list leads and tally counts by interest status.\n3. Pull recent emails to gauge reply volume.\n\n## Output\nReturn a per-campaign snapshot: total leads, breakdown by interest status, and reply activity, highlighting the top-performing campaign.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/intercom.display.ts b/apps/sim/blocks/blocks/intercom.display.ts index a24e8562c35..6cb22a9f445 100644 --- a/apps/sim/blocks/blocks/intercom.display.ts +++ b/apps/sim/blocks/blocks/intercom.display.ts @@ -1,6 +1,6 @@ import { IntercomIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const IntercomBlockDisplay = { type: 'intercom', @@ -23,3 +23,114 @@ export const IntercomV2BlockDisplay = { integrationType: IntegrationType.Support, hideFromToolbar: false, } satisfies BlockDisplay + +export const IntercomBlockMeta = { + tags: ['customer-support', 'messaging'], + url: 'https://www.intercom.com', + templates: [ + { + icon: IntercomIcon, + title: 'Customer feedback analyzer', + prompt: + 'Build a scheduled workflow that pulls support tickets and conversations from Intercom daily, categorizes them by theme and sentiment, tracks trends in a table, and sends a weekly Slack report highlighting the top feature requests and pain points.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'product', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: IntercomIcon, + title: 'Intercom auto-resolver', + prompt: + 'Create a knowledge base from my help center and product docs, then build a workflow that watches new Intercom conversations, attempts an answer with cited sources, and only assigns to a human admin when confidence is low or the customer asks.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'communication'], + }, + { + icon: IntercomIcon, + title: 'Intercom to Linear bug ticketer', + prompt: + 'Build a workflow triggered by new Intercom conversations that classifies whether the message is a bug report, extracts the repro steps and affected area, creates a Linear issue with the conversation transcript attached, and replies in Intercom with the issue ID.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['support', 'engineering', 'automation'], + alsoIntegrations: ['linear'], + }, + { + icon: IntercomIcon, + title: 'Intercom VIP escalation', + prompt: + 'Create a workflow that monitors new Intercom conversations, looks up the contact in the CRM, and when the contact belongs to a top-tier account, snoozes the conversation, posts a Slack alert in #vip-support with full context, and tags the conversation as VIP.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: IntercomIcon, + title: 'Intercom conversation summarizer', + prompt: + 'Build a workflow triggered when an Intercom conversation is closed that summarizes the issue, resolution, and any follow-up actions, then appends the summary to a Notion knowledge log so the team can learn from past conversations.', + modules: ['agent', 'workflows', 'knowledge-base'], + category: 'support', + tags: ['support', 'team', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: IntercomIcon, + title: 'Intercom contact enrichment', + prompt: + 'Create a workflow triggered when a new Intercom contact is created that enriches the contact with company, title, and seniority data from Apollo, updates the Intercom contact attributes, and adds a note with the enrichment source.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['apollo'], + }, + { + icon: IntercomIcon, + title: 'Intercom-Zendesk migration mirror', + prompt: + 'Build a workflow that mirrors new Intercom conversations into Zendesk as tickets during a migration window, syncs status and replies in both directions, and writes a table of every mapped conversation-to-ticket pair for audit.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'sync', 'enterprise'], + alsoIntegrations: ['zendesk'], + }, + ], + skills: [ + { + name: 'triage-open-conversations', + description: + 'Review open Intercom conversations and assign each to the right teammate with a priority.', + content: + '# Triage Open Conversations\n\nKeep the inbox moving by routing open Intercom conversations to the right people.\n\n## Steps\n1. List or search open conversations.\n2. Read each conversation to understand the customer issue and urgency.\n3. List admins to find the right owner, then assign the conversation.\n4. Tag the conversation by topic (billing, bug, onboarding) and add an internal note summarizing next steps.\n\n## Output\nReturn each conversation with its assigned owner, applied tags, and a one-line summary. Flag anything that looks urgent.', + }, + { + name: 'reply-and-resolve', + description: + 'Draft a reply to a customer conversation, send it, and close the conversation when resolved.', + content: + '# Reply and Resolve\n\nRespond to a customer in Intercom and wrap up the conversation.\n\n## Steps\n1. Get the conversation and read the full thread for context.\n2. Draft a helpful, on-brand reply that addresses the customer question.\n3. Reply to the conversation with the message.\n4. If the issue is fully handled, close the conversation; otherwise snooze it until a follow-up time.\n\n## Output\nReturn the reply that was sent and the final conversation state (closed or snoozed).', + }, + { + name: 'enrich-contact-record', + description: + 'Create or update an Intercom contact and link it to its company with current details.', + content: + '# Enrich a Contact Record\n\nKeep contact data accurate by creating or updating an Intercom contact.\n\n## Steps\n1. Search contacts by email to see if the person already exists.\n2. Create the contact if missing, or update the existing record with name, role, and attributes.\n3. Find or create the company and attach the contact to it.\n4. Tag the contact to reflect segment or lifecycle stage.\n\n## Output\nReturn the contact ID, the linked company, and the fields that were created or changed.', + }, + { + name: 'open-support-ticket', + description: + 'Create an Intercom ticket from a conversation and capture the key issue details.', + content: + '# Open a Support Ticket\n\nEscalate a customer issue into a tracked Intercom ticket.\n\n## Steps\n1. Get the source conversation and summarize the issue, impact, and steps to reproduce.\n2. Create a ticket with a clear title, the summary, and the linked contact.\n3. Add a note to the conversation referencing the new ticket so context is preserved.\n\n## Output\nReturn the ticket ID, title, linked contact, and the conversation it came from.', + }, + ], +} as const satisfies BlockMeta + +export const IntercomV2BlockMeta = { + tags: ['customer-support', 'messaging'], + url: 'https://www.intercom.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/intercom.ts b/apps/sim/blocks/blocks/intercom.ts index 6d5976bf9c0..63d2b20f00d 100644 --- a/apps/sim/blocks/blocks/intercom.ts +++ b/apps/sim/blocks/blocks/intercom.ts @@ -1,6 +1,5 @@ -import { IntercomIcon } from '@/components/icons' import { IntercomBlockDisplay, IntercomV2BlockDisplay } from '@/blocks/blocks/intercom.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import { getTrigger } from '@/triggers' @@ -1724,114 +1723,3 @@ export const IntercomV2Block: BlockConfig = { }, }, } - -export const IntercomBlockMeta = { - tags: ['customer-support', 'messaging'], - url: 'https://www.intercom.com', - templates: [ - { - icon: IntercomIcon, - title: 'Customer feedback analyzer', - prompt: - 'Build a scheduled workflow that pulls support tickets and conversations from Intercom daily, categorizes them by theme and sentiment, tracks trends in a table, and sends a weekly Slack report highlighting the top feature requests and pain points.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'product', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: IntercomIcon, - title: 'Intercom auto-resolver', - prompt: - 'Create a knowledge base from my help center and product docs, then build a workflow that watches new Intercom conversations, attempts an answer with cited sources, and only assigns to a human admin when confidence is low or the customer asks.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'communication'], - }, - { - icon: IntercomIcon, - title: 'Intercom to Linear bug ticketer', - prompt: - 'Build a workflow triggered by new Intercom conversations that classifies whether the message is a bug report, extracts the repro steps and affected area, creates a Linear issue with the conversation transcript attached, and replies in Intercom with the issue ID.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['support', 'engineering', 'automation'], - alsoIntegrations: ['linear'], - }, - { - icon: IntercomIcon, - title: 'Intercom VIP escalation', - prompt: - 'Create a workflow that monitors new Intercom conversations, looks up the contact in the CRM, and when the contact belongs to a top-tier account, snoozes the conversation, posts a Slack alert in #vip-support with full context, and tags the conversation as VIP.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: IntercomIcon, - title: 'Intercom conversation summarizer', - prompt: - 'Build a workflow triggered when an Intercom conversation is closed that summarizes the issue, resolution, and any follow-up actions, then appends the summary to a Notion knowledge log so the team can learn from past conversations.', - modules: ['agent', 'workflows', 'knowledge-base'], - category: 'support', - tags: ['support', 'team', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: IntercomIcon, - title: 'Intercom contact enrichment', - prompt: - 'Create a workflow triggered when a new Intercom contact is created that enriches the contact with company, title, and seniority data from Apollo, updates the Intercom contact attributes, and adds a note with the enrichment source.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['apollo'], - }, - { - icon: IntercomIcon, - title: 'Intercom-Zendesk migration mirror', - prompt: - 'Build a workflow that mirrors new Intercom conversations into Zendesk as tickets during a migration window, syncs status and replies in both directions, and writes a table of every mapped conversation-to-ticket pair for audit.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'sync', 'enterprise'], - alsoIntegrations: ['zendesk'], - }, - ], - skills: [ - { - name: 'triage-open-conversations', - description: - 'Review open Intercom conversations and assign each to the right teammate with a priority.', - content: - '# Triage Open Conversations\n\nKeep the inbox moving by routing open Intercom conversations to the right people.\n\n## Steps\n1. List or search open conversations.\n2. Read each conversation to understand the customer issue and urgency.\n3. List admins to find the right owner, then assign the conversation.\n4. Tag the conversation by topic (billing, bug, onboarding) and add an internal note summarizing next steps.\n\n## Output\nReturn each conversation with its assigned owner, applied tags, and a one-line summary. Flag anything that looks urgent.', - }, - { - name: 'reply-and-resolve', - description: - 'Draft a reply to a customer conversation, send it, and close the conversation when resolved.', - content: - '# Reply and Resolve\n\nRespond to a customer in Intercom and wrap up the conversation.\n\n## Steps\n1. Get the conversation and read the full thread for context.\n2. Draft a helpful, on-brand reply that addresses the customer question.\n3. Reply to the conversation with the message.\n4. If the issue is fully handled, close the conversation; otherwise snooze it until a follow-up time.\n\n## Output\nReturn the reply that was sent and the final conversation state (closed or snoozed).', - }, - { - name: 'enrich-contact-record', - description: - 'Create or update an Intercom contact and link it to its company with current details.', - content: - '# Enrich a Contact Record\n\nKeep contact data accurate by creating or updating an Intercom contact.\n\n## Steps\n1. Search contacts by email to see if the person already exists.\n2. Create the contact if missing, or update the existing record with name, role, and attributes.\n3. Find or create the company and attach the contact to it.\n4. Tag the contact to reflect segment or lifecycle stage.\n\n## Output\nReturn the contact ID, the linked company, and the fields that were created or changed.', - }, - { - name: 'open-support-ticket', - description: - 'Create an Intercom ticket from a conversation and capture the key issue details.', - content: - '# Open a Support Ticket\n\nEscalate a customer issue into a tracked Intercom ticket.\n\n## Steps\n1. Get the source conversation and summarize the issue, impact, and steps to reproduce.\n2. Create a ticket with a clear title, the summary, and the linked contact.\n3. Add a note to the conversation referencing the new ticket so context is preserved.\n\n## Output\nReturn the ticket ID, title, linked contact, and the conversation it came from.', - }, - ], -} as const satisfies BlockMeta - -export const IntercomV2BlockMeta = { - tags: ['customer-support', 'messaging'], - url: 'https://www.intercom.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jina.display.ts b/apps/sim/blocks/blocks/jina.display.ts index 51dcfb66310..c14d386ec65 100644 --- a/apps/sim/blocks/blocks/jina.display.ts +++ b/apps/sim/blocks/blocks/jina.display.ts @@ -1,6 +1,6 @@ import { JinaAIIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const JinaBlockDisplay = { type: 'jina', @@ -14,3 +14,96 @@ export const JinaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/jina', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const JinaBlockMeta = { + tags: ['web-scraping', 'knowledge-base'], + url: 'https://jina.ai', + templates: [ + { + icon: JinaAIIcon, + title: 'Jina URL-to-knowledge ingester', + prompt: + 'Build a workflow that reads a list of source URLs with Jina Reader, converts each into clean text, and ingests the content into a research knowledge base for retrieval.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + }, + { + icon: JinaAIIcon, + title: 'Jina web-research digest', + prompt: + 'Create a scheduled workflow that runs Jina web search on tracked topics, reads the top results with Jina Reader, and writes a summarized digest to a research table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'research'], + }, + { + icon: JinaAIIcon, + title: 'Jina web-content reader', + prompt: + 'Build a workflow that uses Jina Reader to convert any URL into clean text, summarizes with an agent, and stores the result in a research knowledge base.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: JinaAIIcon, + title: 'Jina competitor watch', + prompt: + 'Create a scheduled workflow that reads competitor pricing and changelog pages with Jina Reader, diffs against the last snapshot, and posts notable changes to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: JinaAIIcon, + title: 'Jina answer enrichment', + prompt: + 'Build a workflow that takes a user question, runs a Jina web search for current sources, reads the top pages with Jina Reader, and has an agent answer with citations.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'automation'], + }, + { + icon: JinaAIIcon, + title: 'Jina Slack research bot', + prompt: + 'Create a Slack bot that runs Jina web search on the asked question, reads the most relevant results with Jina Reader, and replies with a summarized answer and source links.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'research'], + alsoIntegrations: ['slack'], + }, + { + icon: JinaAIIcon, + title: 'Jina docs-to-Notion clipper', + prompt: + 'Build a workflow that reads a submitted URL with Jina Reader, summarizes the content with an agent, and appends a clean clipped entry to a Notion research database.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'extract-article-content', + description: 'Read a URL and return clean, LLM-ready text stripped of navigation and ads.', + content: + '# Extract Article Content\n\nTurn a messy web page into clean, readable text an agent can reason over.\n\n## Steps\n1. Take the target URL.\n2. Read the URL to get the parsed main content as markdown or text.\n3. Strip boilerplate (nav, footers, ads) if any remains and keep the core article body.\n\n## Output\nReturn the page title and the cleaned content, plus the source URL. Note if the page could not be fully extracted.', + }, + { + name: 'research-topic-from-web', + description: 'Search the web for a topic and summarize the top results into a briefing.', + content: + '# Research a Topic From the Web\n\nGather and condense current web information on a topic.\n\n## Steps\n1. Run a web search for the topic with a focused query.\n2. Take the top results and read the most relevant URLs for full content.\n3. Synthesize the findings, noting points of agreement and disagreement across sources.\n\n## Output\nReturn a short briefing with key findings, each backed by the source URL it came from.', + }, + { + name: 'summarize-url', + description: 'Fetch a single URL and produce a concise summary with the main takeaways.', + content: + '# Summarize a URL\n\nGive a quick, faithful summary of a single web page.\n\n## Steps\n1. Read the URL to extract its main content.\n2. Identify the core thesis and the most important supporting points.\n3. Condense into a short summary without adding outside information.\n\n## Output\nReturn the page title, a 3-5 bullet summary of the key takeaways, and the source URL.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jina.ts b/apps/sim/blocks/blocks/jina.ts index e009b3fc816..26b2c29e4b2 100644 --- a/apps/sim/blocks/blocks/jina.ts +++ b/apps/sim/blocks/blocks/jina.ts @@ -1,6 +1,5 @@ -import { JinaAIIcon } from '@/components/icons' import { JinaBlockDisplay } from '@/blocks/blocks/jina.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ReadUrlResponse, SearchResponse } from '@/tools/jina/types' export const JinaBlock: BlockConfig = { @@ -186,96 +185,3 @@ export const JinaBlock: BlockConfig = { }, }, } - -export const JinaBlockMeta = { - tags: ['web-scraping', 'knowledge-base'], - url: 'https://jina.ai', - templates: [ - { - icon: JinaAIIcon, - title: 'Jina URL-to-knowledge ingester', - prompt: - 'Build a workflow that reads a list of source URLs with Jina Reader, converts each into clean text, and ingests the content into a research knowledge base for retrieval.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - }, - { - icon: JinaAIIcon, - title: 'Jina web-research digest', - prompt: - 'Create a scheduled workflow that runs Jina web search on tracked topics, reads the top results with Jina Reader, and writes a summarized digest to a research table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'research'], - }, - { - icon: JinaAIIcon, - title: 'Jina web-content reader', - prompt: - 'Build a workflow that uses Jina Reader to convert any URL into clean text, summarizes with an agent, and stores the result in a research knowledge base.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: JinaAIIcon, - title: 'Jina competitor watch', - prompt: - 'Create a scheduled workflow that reads competitor pricing and changelog pages with Jina Reader, diffs against the last snapshot, and posts notable changes to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: JinaAIIcon, - title: 'Jina answer enrichment', - prompt: - 'Build a workflow that takes a user question, runs a Jina web search for current sources, reads the top pages with Jina Reader, and has an agent answer with citations.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'automation'], - }, - { - icon: JinaAIIcon, - title: 'Jina Slack research bot', - prompt: - 'Create a Slack bot that runs Jina web search on the asked question, reads the most relevant results with Jina Reader, and replies with a summarized answer and source links.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'research'], - alsoIntegrations: ['slack'], - }, - { - icon: JinaAIIcon, - title: 'Jina docs-to-Notion clipper', - prompt: - 'Build a workflow that reads a submitted URL with Jina Reader, summarizes the content with an agent, and appends a clean clipped entry to a Notion research database.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'extract-article-content', - description: 'Read a URL and return clean, LLM-ready text stripped of navigation and ads.', - content: - '# Extract Article Content\n\nTurn a messy web page into clean, readable text an agent can reason over.\n\n## Steps\n1. Take the target URL.\n2. Read the URL to get the parsed main content as markdown or text.\n3. Strip boilerplate (nav, footers, ads) if any remains and keep the core article body.\n\n## Output\nReturn the page title and the cleaned content, plus the source URL. Note if the page could not be fully extracted.', - }, - { - name: 'research-topic-from-web', - description: 'Search the web for a topic and summarize the top results into a briefing.', - content: - '# Research a Topic From the Web\n\nGather and condense current web information on a topic.\n\n## Steps\n1. Run a web search for the topic with a focused query.\n2. Take the top results and read the most relevant URLs for full content.\n3. Synthesize the findings, noting points of agreement and disagreement across sources.\n\n## Output\nReturn a short briefing with key findings, each backed by the source URL it came from.', - }, - { - name: 'summarize-url', - description: 'Fetch a single URL and produce a concise summary with the main takeaways.', - content: - '# Summarize a URL\n\nGive a quick, faithful summary of a single web page.\n\n## Steps\n1. Read the URL to extract its main content.\n2. Identify the core thesis and the most important supporting points.\n3. Condense into a short summary without adding outside information.\n\n## Output\nReturn the page title, a 3-5 bullet summary of the key takeaways, and the source URL.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jira.display.ts b/apps/sim/blocks/blocks/jira.display.ts index 35c34f7621d..6dc90206269 100644 --- a/apps/sim/blocks/blocks/jira.display.ts +++ b/apps/sim/blocks/blocks/jira.display.ts @@ -1,6 +1,6 @@ import { JiraIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const JiraBlockDisplay = { type: 'jira', @@ -15,3 +15,106 @@ export const JiraBlockDisplay = { integrationType: IntegrationType.Productivity, triggerAllowed: true, } satisfies BlockDisplay + +export const JiraBlockMeta = { + tags: ['project-management', 'ticketing'], + url: 'https://www.atlassian.com/software/jira', + templates: [ + { + icon: JiraIcon, + title: 'Jira knowledge search', + prompt: + 'Create a knowledge base connected to my Jira project so all tickets, comments, and resolutions are automatically synced and searchable. Then build an agent I can ask things like "how did we fix the auth timeout issue?" or "what was decided about the API redesign?" and get answers with ticket citations.', + modules: ['knowledge-base', 'agent'], + category: 'engineering', + tags: ['engineering', 'research'], + }, + { + icon: JiraIcon, + title: 'Sprint report generator', + prompt: + 'Create a scheduled workflow that runs at the end of each sprint, pulls all completed, in-progress, and blocked Jira tickets, calculates velocity and carry-over, and generates a sprint summary document with charts and trends to share with the team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'reporting', 'team'], + }, + { + icon: JiraIcon, + title: 'Jira backlog grooming digest', + prompt: + 'Build a scheduled weekly workflow that scans Jira backlog for tickets missing estimates, owners, or priorities, generates a grooming queue, and posts the top items to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'team'], + alsoIntegrations: ['slack'], + }, + { + icon: JiraIcon, + title: 'Jira stale-ticket sweeper', + prompt: + 'Create a scheduled workflow that lists Jira tickets with no activity in 14 days, pings the assignee in Slack with a status prompt, and updates the ticket based on the response.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: JiraIcon, + title: 'Jira release notes builder', + prompt: + 'Build a workflow that pulls Jira tickets resolved since the last release tag, groups by feature area, and drafts user-facing release notes for marketing review.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['engineering', 'content'], + }, + { + icon: JiraIcon, + title: 'Jira to Linear migrator', + prompt: + 'Create a workflow that imports a Jira project into Linear, preserving status mapping, labels, comments, and assignees, and writes a mapping table for redirect URLs.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['linear'], + }, + + { + icon: JiraIcon, + title: 'Auto-generate Confluence pages from Jira sprints', + prompt: + 'Build a workflow that runs at the end of each Jira sprint, pulls all completed and in-progress tickets, and automatically creates a structured Confluence documentation page so sprint reporting requires no manual effort.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['confluence'], + }, + ], + skills: [ + { + name: 'create-bug-from-report', + description: + 'Turn a bug report into a well-structured Jira issue with steps, severity, and labels.', + content: + '# Create a Bug From a Report\n\nConvert a raw bug report into a clean, actionable Jira issue.\n\n## Steps\n1. Parse the report for summary, steps to reproduce, expected vs actual behavior, and environment.\n2. Create an issue in the target project with type Bug, a clear summary, and a structured description.\n3. Set priority based on impact and add relevant labels or components.\n4. Optionally assign it to the right owner.\n\n## Output\nReturn the issue key, URL, priority, and assignee. Confirm the description includes reproduction steps.', + }, + { + name: 'triage-open-issues', + description: 'Search open issues with JQL and propose assignees, priorities, and labels.', + content: + '# Triage Open Issues\n\nBring order to a backlog of unassigned or stale issues.\n\n## Steps\n1. Search issues using JQL (e.g. unassigned and recently created in a project).\n2. Read each issue to understand scope and urgency.\n3. For each, propose a priority, suggested assignee, and labels; apply updates where confident.\n4. Add a short triage comment explaining the decision.\n\n## Output\nReturn a table of issues with proposed/applied priority, assignee, and labels, flagging any that need a human decision.', + }, + { + name: 'transition-and-comment', + description: 'Move an issue to a new workflow status and post a progress comment.', + content: + '# Transition and Comment\n\nAdvance a Jira issue through its workflow with a clear note.\n\n## Steps\n1. Retrieve the issue and read its current status.\n2. Get available transitions and choose the correct next status (e.g. In Progress, In Review, Done).\n3. Transition the issue to that status.\n4. Add a comment summarizing what changed and any next steps.\n\n## Output\nReturn the issue key, the new status, and the comment that was posted.', + }, + { + name: 'sprint-status-digest', + description: 'Summarize issues in a project or sprint grouped by status and assignee.', + content: + '# Sprint Status Digest\n\nProduce a quick read on where work stands.\n\n## Steps\n1. Search issues with JQL scoped to the project or current sprint.\n2. Group results by status and by assignee.\n3. Identify blocked issues, overdue items, and anything unassigned.\n\n## Output\nReturn a digest: counts by status, work per assignee, and a callout list of blocked or at-risk issues with their keys.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jira.ts b/apps/sim/blocks/blocks/jira.ts index 25a862e52a0..8f363f266e0 100644 --- a/apps/sim/blocks/blocks/jira.ts +++ b/apps/sim/blocks/blocks/jira.ts @@ -1,7 +1,6 @@ -import { JiraIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { JiraBlockDisplay } from '@/blocks/blocks/jira.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { JiraResponse } from '@/tools/jira/types' @@ -1327,106 +1326,3 @@ Return ONLY the comment text - no explanations.`, ], }, } - -export const JiraBlockMeta = { - tags: ['project-management', 'ticketing'], - url: 'https://www.atlassian.com/software/jira', - templates: [ - { - icon: JiraIcon, - title: 'Jira knowledge search', - prompt: - 'Create a knowledge base connected to my Jira project so all tickets, comments, and resolutions are automatically synced and searchable. Then build an agent I can ask things like "how did we fix the auth timeout issue?" or "what was decided about the API redesign?" and get answers with ticket citations.', - modules: ['knowledge-base', 'agent'], - category: 'engineering', - tags: ['engineering', 'research'], - }, - { - icon: JiraIcon, - title: 'Sprint report generator', - prompt: - 'Create a scheduled workflow that runs at the end of each sprint, pulls all completed, in-progress, and blocked Jira tickets, calculates velocity and carry-over, and generates a sprint summary document with charts and trends to share with the team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'reporting', 'team'], - }, - { - icon: JiraIcon, - title: 'Jira backlog grooming digest', - prompt: - 'Build a scheduled weekly workflow that scans Jira backlog for tickets missing estimates, owners, or priorities, generates a grooming queue, and posts the top items to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'team'], - alsoIntegrations: ['slack'], - }, - { - icon: JiraIcon, - title: 'Jira stale-ticket sweeper', - prompt: - 'Create a scheduled workflow that lists Jira tickets with no activity in 14 days, pings the assignee in Slack with a status prompt, and updates the ticket based on the response.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: JiraIcon, - title: 'Jira release notes builder', - prompt: - 'Build a workflow that pulls Jira tickets resolved since the last release tag, groups by feature area, and drafts user-facing release notes for marketing review.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['engineering', 'content'], - }, - { - icon: JiraIcon, - title: 'Jira to Linear migrator', - prompt: - 'Create a workflow that imports a Jira project into Linear, preserving status mapping, labels, comments, and assignees, and writes a mapping table for redirect URLs.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['linear'], - }, - - { - icon: JiraIcon, - title: 'Auto-generate Confluence pages from Jira sprints', - prompt: - 'Build a workflow that runs at the end of each Jira sprint, pulls all completed and in-progress tickets, and automatically creates a structured Confluence documentation page so sprint reporting requires no manual effort.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['confluence'], - }, - ], - skills: [ - { - name: 'create-bug-from-report', - description: - 'Turn a bug report into a well-structured Jira issue with steps, severity, and labels.', - content: - '# Create a Bug From a Report\n\nConvert a raw bug report into a clean, actionable Jira issue.\n\n## Steps\n1. Parse the report for summary, steps to reproduce, expected vs actual behavior, and environment.\n2. Create an issue in the target project with type Bug, a clear summary, and a structured description.\n3. Set priority based on impact and add relevant labels or components.\n4. Optionally assign it to the right owner.\n\n## Output\nReturn the issue key, URL, priority, and assignee. Confirm the description includes reproduction steps.', - }, - { - name: 'triage-open-issues', - description: 'Search open issues with JQL and propose assignees, priorities, and labels.', - content: - '# Triage Open Issues\n\nBring order to a backlog of unassigned or stale issues.\n\n## Steps\n1. Search issues using JQL (e.g. unassigned and recently created in a project).\n2. Read each issue to understand scope and urgency.\n3. For each, propose a priority, suggested assignee, and labels; apply updates where confident.\n4. Add a short triage comment explaining the decision.\n\n## Output\nReturn a table of issues with proposed/applied priority, assignee, and labels, flagging any that need a human decision.', - }, - { - name: 'transition-and-comment', - description: 'Move an issue to a new workflow status and post a progress comment.', - content: - '# Transition and Comment\n\nAdvance a Jira issue through its workflow with a clear note.\n\n## Steps\n1. Retrieve the issue and read its current status.\n2. Get available transitions and choose the correct next status (e.g. In Progress, In Review, Done).\n3. Transition the issue to that status.\n4. Add a comment summarizing what changed and any next steps.\n\n## Output\nReturn the issue key, the new status, and the comment that was posted.', - }, - { - name: 'sprint-status-digest', - description: 'Summarize issues in a project or sprint grouped by status and assignee.', - content: - '# Sprint Status Digest\n\nProduce a quick read on where work stands.\n\n## Steps\n1. Search issues with JQL scoped to the project or current sprint.\n2. Group results by status and by assignee.\n3. Identify blocked issues, overdue items, and anything unassigned.\n\n## Output\nReturn a digest: counts by status, work per assignee, and a callout list of blocked or at-risk issues with their keys.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jira_service_management.display.ts b/apps/sim/blocks/blocks/jira_service_management.display.ts index a61e4630324..8a66583ff3b 100644 --- a/apps/sim/blocks/blocks/jira_service_management.display.ts +++ b/apps/sim/blocks/blocks/jira_service_management.display.ts @@ -1,6 +1,6 @@ import { JiraServiceManagementIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const JiraServiceManagementBlockDisplay = { type: 'jira_service_management', @@ -14,3 +14,98 @@ export const JiraServiceManagementBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/jira_service_management', integrationType: IntegrationType.Support, } satisfies BlockDisplay + +export const JiraServiceManagementBlockMeta = { + tags: ['customer-support', 'ticketing', 'incident-management'], + url: 'https://www.atlassian.com/software/jira/service-management', + templates: [ + { + icon: JiraServiceManagementIcon, + title: 'JSM major incident broadcaster', + prompt: + 'Build a workflow triggered when a major-incident request is created in Jira Service Management that pulls the affected service from PagerDuty, identifies the current on-call, posts a structured incident brief to a Slack war-room channel, and adds the responders as JSM request participants.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'engineering', 'automation'], + alsoIntegrations: ['slack', 'pagerduty'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM request auto-triage', + prompt: + 'Create a workflow triggered by new Jira Service Management requests that classifies the request type, sets the correct priority based on impact and urgency, transitions it to the right initial status, and adds the assignment-group customer organization as a participant.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['support', 'automation', 'enterprise'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM approval router', + prompt: + 'Build a workflow that watches Jira Service Management requests for new approval steps, posts a Slack DM to each approver with request context and quick-action buttons, and answers the approval in JSM based on their response while keeping the request in sync.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation', 'team'], + alsoIntegrations: ['slack'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM form auto-completer', + prompt: + 'Create a workflow that when a Jira Service Management request is created with an attached ProForma form, pre-fills the answers from the requester profile, attached email, and CMDB lookup, and saves the answers so agents only review rather than retype.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM weekly service desk report', + prompt: + 'Build a scheduled weekly workflow that pulls Jira Service Management request volume by queue, SLA performance, top request types, and bottleneck assignees, and generates a service desk health report file for the operations review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis', 'enterprise'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM-to-ServiceNow bridge', + prompt: + 'Create a workflow that mirrors Jira Service Management incident requests into ServiceNow incident records and vice versa, keeping status, assignment, and comments in sync so teams on either side see the same truth.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync', 'automation'], + alsoIntegrations: ['servicenow'], + }, + { + icon: JiraServiceManagementIcon, + title: 'JSM self-service deflection bot', + prompt: + "Create a knowledge base from internal IT docs, then build a Slack agent that answers employee help requests with cited steps and, when it can't resolve the issue, creates a Jira Service Management request with the right request type so nothing falls through.", + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'team'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'raise-service-request', + description: + 'Create a customer request on the right service desk with the correct request type.', + content: + '# Raise a Service Request\n\nLog an inbound customer request into the correct Jira Service Management queue.\n\n## Steps\n1. Get service desks and identify the right one for the request.\n2. Get request types for that service desk and choose the matching type.\n3. Create the request with a clear summary, description, and any required request-type fields.\n4. Capture the request key and reporter.\n\n## Output\nReturn the request key, the service desk and request type used, and the reporter. Confirm required fields were filled.', + }, + { + name: 'respond-and-update-request', + description: 'Add a public reply to a customer request and move it to the right status.', + content: + '# Respond and Update a Request\n\nReply to a customer on their request and advance it.\n\n## Steps\n1. Get the request and read its history and current status.\n2. Add a comment with the response (public to the customer).\n3. Get available transitions and move the request to the appropriate status.\n\n## Output\nReturn the request key, the comment added, and the new status.', + }, + { + name: 'sla-breach-watch', + description: 'Scan open requests on a queue and flag ones at risk of breaching SLA.', + content: + '# SLA Breach Watch\n\nSurface requests that are about to miss their SLA so the team can act.\n\n## Steps\n1. Get the service desk and its queues, then get requests in the target queue.\n2. For each request, get its SLA information and time remaining.\n3. Flag requests that are breached or close to breaching their target.\n\n## Output\nReturn a prioritized list of at-risk requests with key, summary, SLA metric, and time remaining, worst first.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/jira_service_management.ts b/apps/sim/blocks/blocks/jira_service_management.ts index a9585d56e81..35b7f0e2439 100644 --- a/apps/sim/blocks/blocks/jira_service_management.ts +++ b/apps/sim/blocks/blocks/jira_service_management.ts @@ -1,7 +1,6 @@ -import { JiraServiceManagementIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { JiraServiceManagementBlockDisplay } from '@/blocks/blocks/jira_service_management.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { JsmResponse } from '@/tools/jsm/types' import { getTrigger } from '@/triggers' @@ -1624,98 +1623,3 @@ Return ONLY the comment text - no explanations.`, ], }, } - -export const JiraServiceManagementBlockMeta = { - tags: ['customer-support', 'ticketing', 'incident-management'], - url: 'https://www.atlassian.com/software/jira/service-management', - templates: [ - { - icon: JiraServiceManagementIcon, - title: 'JSM major incident broadcaster', - prompt: - 'Build a workflow triggered when a major-incident request is created in Jira Service Management that pulls the affected service from PagerDuty, identifies the current on-call, posts a structured incident brief to a Slack war-room channel, and adds the responders as JSM request participants.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'engineering', 'automation'], - alsoIntegrations: ['slack', 'pagerduty'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM request auto-triage', - prompt: - 'Create a workflow triggered by new Jira Service Management requests that classifies the request type, sets the correct priority based on impact and urgency, transitions it to the right initial status, and adds the assignment-group customer organization as a participant.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['support', 'automation', 'enterprise'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM approval router', - prompt: - 'Build a workflow that watches Jira Service Management requests for new approval steps, posts a Slack DM to each approver with request context and quick-action buttons, and answers the approval in JSM based on their response while keeping the request in sync.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation', 'team'], - alsoIntegrations: ['slack'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM form auto-completer', - prompt: - 'Create a workflow that when a Jira Service Management request is created with an attached ProForma form, pre-fills the answers from the requester profile, attached email, and CMDB lookup, and saves the answers so agents only review rather than retype.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM weekly service desk report', - prompt: - 'Build a scheduled weekly workflow that pulls Jira Service Management request volume by queue, SLA performance, top request types, and bottleneck assignees, and generates a service desk health report file for the operations review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis', 'enterprise'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM-to-ServiceNow bridge', - prompt: - 'Create a workflow that mirrors Jira Service Management incident requests into ServiceNow incident records and vice versa, keeping status, assignment, and comments in sync so teams on either side see the same truth.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync', 'automation'], - alsoIntegrations: ['servicenow'], - }, - { - icon: JiraServiceManagementIcon, - title: 'JSM self-service deflection bot', - prompt: - "Create a knowledge base from internal IT docs, then build a Slack agent that answers employee help requests with cited steps and, when it can't resolve the issue, creates a Jira Service Management request with the right request type so nothing falls through.", - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'team'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'raise-service-request', - description: - 'Create a customer request on the right service desk with the correct request type.', - content: - '# Raise a Service Request\n\nLog an inbound customer request into the correct Jira Service Management queue.\n\n## Steps\n1. Get service desks and identify the right one for the request.\n2. Get request types for that service desk and choose the matching type.\n3. Create the request with a clear summary, description, and any required request-type fields.\n4. Capture the request key and reporter.\n\n## Output\nReturn the request key, the service desk and request type used, and the reporter. Confirm required fields were filled.', - }, - { - name: 'respond-and-update-request', - description: 'Add a public reply to a customer request and move it to the right status.', - content: - '# Respond and Update a Request\n\nReply to a customer on their request and advance it.\n\n## Steps\n1. Get the request and read its history and current status.\n2. Add a comment with the response (public to the customer).\n3. Get available transitions and move the request to the appropriate status.\n\n## Output\nReturn the request key, the comment added, and the new status.', - }, - { - name: 'sla-breach-watch', - description: 'Scan open requests on a queue and flag ones at risk of breaching SLA.', - content: - '# SLA Breach Watch\n\nSurface requests that are about to miss their SLA so the team can act.\n\n## Steps\n1. Get the service desk and its queues, then get requests in the target queue.\n2. For each request, get its SLA information and time remaining.\n3. Flag requests that are breached or close to breaching their target.\n\n## Output\nReturn a prioritized list of at-risk requests with key, summary, SLA metric, and time remaining, worst first.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/kalshi.display.ts b/apps/sim/blocks/blocks/kalshi.display.ts index 0d716781e55..da0aea633e0 100644 --- a/apps/sim/blocks/blocks/kalshi.display.ts +++ b/apps/sim/blocks/blocks/kalshi.display.ts @@ -1,6 +1,6 @@ import { KalshiIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const KalshiBlockDisplay = { type: 'kalshi', @@ -27,3 +27,105 @@ export const KalshiV2BlockDisplay = { integrationType: IntegrationType.Analytics, hideFromToolbar: false, } satisfies BlockDisplay + +export const KalshiBlockMeta = { + tags: ['prediction-markets', 'data-analytics'], + url: 'https://kalshi.com', + templates: [ + { + icon: KalshiIcon, + title: 'Kalshi event-contract tracker', + prompt: + 'Create a scheduled workflow that polls Kalshi for prices on tracked event contracts, writes the price history to a tables-based portfolio, and posts large-move alerts to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: KalshiIcon, + title: 'Kalshi macroeconomic dashboard', + prompt: + 'Build a scheduled workflow that pulls Kalshi probability markets for selected macroeconomic events, writes the implied probabilities to a tables-based dashboard, and emails a weekly summary.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: KalshiIcon, + title: 'Kalshi + Polymarket arbitrage scanner', + prompt: + 'Create a scheduled workflow that fetches comparable contracts on Kalshi and Polymarket, computes implied-probability spreads, writes the top arbitrage candidates to a table, and pings Slack on significant gaps.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis'], + alsoIntegrations: ['polymarket', 'slack'], + }, + { + icon: KalshiIcon, + title: 'Kalshi + Profound macro signal', + prompt: + 'Build a scheduled workflow that combines Kalshi event-contract prices with Profound AI signal to forecast macro events and writes a thesis file weekly.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'research'], + alsoIntegrations: ['profound'], + }, + { + icon: KalshiIcon, + title: 'Kalshi position rebalancer', + prompt: + 'Build a workflow that monitors Kalshi position weights against a target allocation, captures drift, and pings Slack with proposed rebalancing trades.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: KalshiIcon, + title: 'Kalshi earnings event tracker', + prompt: + 'Create a workflow that pulls Kalshi earnings-event contracts, captures implied probabilities the day before each event, and writes a per-ticker table for review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'research'], + }, + { + icon: KalshiIcon, + title: 'Kalshi election-market dashboard', + prompt: + 'Build a scheduled workflow that pulls Kalshi election market prices, captures movement over time, and writes a per-race tracking table for political analysts.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis'], + }, + ], + skills: [ + { + name: 'market-odds-snapshot', + description: + 'Pull current prices and odds for a Kalshi event and summarize the implied probabilities.', + content: + '# Market Odds Snapshot\n\nReport the current state of a Kalshi prediction market.\n\n## Steps\n1. Find the event by ticker or search recent events.\n2. Get the markets under that event and their current yes/no prices.\n3. Convert prices to implied probabilities and capture volume and open interest.\n\n## Output\nReturn each market with its current yes/no price, implied probability, and recent volume, plus a one-line read on where the market is leaning.', + }, + { + name: 'track-position-pnl', + description: + 'Report account balance, open positions, and unrealized profit or loss on Kalshi.', + content: + '# Track Position P&L\n\nGive a clear read on the current trading account state.\n\n## Steps\n1. Get the account balance.\n2. Get current positions and, for each, the market and entry exposure.\n3. Get current market prices to estimate unrealized P&L per position.\n\n## Output\nReturn balance, each open position with its market and estimated unrealized P&L, and a total exposure figure.', + }, + { + name: 'place-limit-order', + description: 'Place a limit order on a Kalshi market after confirming price and balance.', + content: + '# Place a Limit Order\n\nSubmit a limit order on a chosen Kalshi market with guardrails.\n\n## Steps\n1. Get the target market and confirm its current price and orderbook.\n2. Check the account balance to ensure the order is affordable.\n3. Create a limit order with the side (yes/no), price, and quantity.\n4. Confirm the order was accepted and capture its ID.\n\n## Output\nReturn the order ID, market, side, price, quantity, and status. State clearly if the order was rejected or only partially filled.', + }, + ], +} as const satisfies BlockMeta + +export const KalshiV2BlockMeta = { + tags: ['prediction-markets', 'data-analytics'], + url: 'https://kalshi.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/kalshi.ts b/apps/sim/blocks/blocks/kalshi.ts index cabe4b270fd..3965e0092cf 100644 --- a/apps/sim/blocks/blocks/kalshi.ts +++ b/apps/sim/blocks/blocks/kalshi.ts @@ -1,6 +1,5 @@ -import { KalshiIcon } from '@/components/icons' import { KalshiBlockDisplay, KalshiV2BlockDisplay } from '@/blocks/blocks/kalshi.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' @@ -921,105 +920,3 @@ export const KalshiV2Block: BlockConfig = { cursor: { type: 'string', description: 'Pagination cursor for fetching more results' }, }, } - -export const KalshiBlockMeta = { - tags: ['prediction-markets', 'data-analytics'], - url: 'https://kalshi.com', - templates: [ - { - icon: KalshiIcon, - title: 'Kalshi event-contract tracker', - prompt: - 'Create a scheduled workflow that polls Kalshi for prices on tracked event contracts, writes the price history to a tables-based portfolio, and posts large-move alerts to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: KalshiIcon, - title: 'Kalshi macroeconomic dashboard', - prompt: - 'Build a scheduled workflow that pulls Kalshi probability markets for selected macroeconomic events, writes the implied probabilities to a tables-based dashboard, and emails a weekly summary.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: KalshiIcon, - title: 'Kalshi + Polymarket arbitrage scanner', - prompt: - 'Create a scheduled workflow that fetches comparable contracts on Kalshi and Polymarket, computes implied-probability spreads, writes the top arbitrage candidates to a table, and pings Slack on significant gaps.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis'], - alsoIntegrations: ['polymarket', 'slack'], - }, - { - icon: KalshiIcon, - title: 'Kalshi + Profound macro signal', - prompt: - 'Build a scheduled workflow that combines Kalshi event-contract prices with Profound AI signal to forecast macro events and writes a thesis file weekly.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'research'], - alsoIntegrations: ['profound'], - }, - { - icon: KalshiIcon, - title: 'Kalshi position rebalancer', - prompt: - 'Build a workflow that monitors Kalshi position weights against a target allocation, captures drift, and pings Slack with proposed rebalancing trades.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: KalshiIcon, - title: 'Kalshi earnings event tracker', - prompt: - 'Create a workflow that pulls Kalshi earnings-event contracts, captures implied probabilities the day before each event, and writes a per-ticker table for review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'research'], - }, - { - icon: KalshiIcon, - title: 'Kalshi election-market dashboard', - prompt: - 'Build a scheduled workflow that pulls Kalshi election market prices, captures movement over time, and writes a per-race tracking table for political analysts.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis'], - }, - ], - skills: [ - { - name: 'market-odds-snapshot', - description: - 'Pull current prices and odds for a Kalshi event and summarize the implied probabilities.', - content: - '# Market Odds Snapshot\n\nReport the current state of a Kalshi prediction market.\n\n## Steps\n1. Find the event by ticker or search recent events.\n2. Get the markets under that event and their current yes/no prices.\n3. Convert prices to implied probabilities and capture volume and open interest.\n\n## Output\nReturn each market with its current yes/no price, implied probability, and recent volume, plus a one-line read on where the market is leaning.', - }, - { - name: 'track-position-pnl', - description: - 'Report account balance, open positions, and unrealized profit or loss on Kalshi.', - content: - '# Track Position P&L\n\nGive a clear read on the current trading account state.\n\n## Steps\n1. Get the account balance.\n2. Get current positions and, for each, the market and entry exposure.\n3. Get current market prices to estimate unrealized P&L per position.\n\n## Output\nReturn balance, each open position with its market and estimated unrealized P&L, and a total exposure figure.', - }, - { - name: 'place-limit-order', - description: 'Place a limit order on a Kalshi market after confirming price and balance.', - content: - '# Place a Limit Order\n\nSubmit a limit order on a chosen Kalshi market with guardrails.\n\n## Steps\n1. Get the target market and confirm its current price and orderbook.\n2. Check the account balance to ensure the order is affordable.\n3. Create a limit order with the side (yes/no), price, and quantity.\n4. Confirm the order was accepted and capture its ID.\n\n## Output\nReturn the order ID, market, side, price, quantity, and status. State clearly if the order was rejected or only partially filled.', - }, - ], -} as const satisfies BlockMeta - -export const KalshiV2BlockMeta = { - tags: ['prediction-markets', 'data-analytics'], - url: 'https://kalshi.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ketch.display.ts b/apps/sim/blocks/blocks/ketch.display.ts index 8456460cf70..513eb99e053 100644 --- a/apps/sim/blocks/blocks/ketch.display.ts +++ b/apps/sim/blocks/blocks/ketch.display.ts @@ -1,6 +1,6 @@ import { KetchIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const KetchBlockDisplay = { type: 'ketch', @@ -14,3 +14,102 @@ export const KetchBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/ketch', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const KetchBlockMeta = { + tags: ['identity'], + url: 'https://www.ketch.com', + templates: [ + { + icon: KetchIcon, + title: 'Ketch consent propagator', + prompt: + 'Build a workflow that on a consent change reads the contact’s Ketch consent state and propagates it to downstream systems — HubSpot and Loops — keeping privacy preferences in sync.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['legal', 'sync'], + alsoIntegrations: ['hubspot', 'loops'], + }, + { + icon: KetchIcon, + title: 'Ketch DSR fulfillment', + prompt: + 'Create a workflow that on a Ketch data subject request collects matching personal data from connected systems, generates the export, and writes the fulfillment audit.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: KetchIcon, + title: 'Ketch deletion-request handler', + prompt: + 'Build a workflow that on a Ketch deletion request propagates the deletion to all connected systems, captures confirmations, and writes the chain of custody.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: KetchIcon, + title: 'Ketch consent-drift detector', + prompt: + 'Create a scheduled workflow that compares Ketch consent state with downstream systems, flags drift, and writes a remediation queue for the privacy team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'monitoring'], + }, + { + icon: KetchIcon, + title: 'Ketch subscription sync', + prompt: + 'Build a workflow that reads each contact’s Ketch subscription topics and mirrors the opt-in state to the marketing tool so unsubscribe preferences stay consistent across systems.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['legal', 'sync'], + alsoIntegrations: ['loops'], + }, + { + icon: KetchIcon, + title: 'Ketch right-invocation handler', + prompt: + 'Create a workflow that on an incoming privacy request invokes the matching Ketch right for the data subject, captures the confirmation, and writes the action to a compliance file.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: KetchIcon, + title: 'Ketch consent-rate digest', + prompt: + 'Build a scheduled monthly workflow that samples Ketch consent state across a contact list, computes opt-in rates per purpose, and writes a privacy report file for executive review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'reporting'], + }, + ], + skills: [ + { + name: 'check-user-consent', + description: 'Look up a user current consent state in Ketch before processing their data.', + content: + '# Check User Consent\n\nConfirm what a user has consented to before a workflow uses their data.\n\n## Steps\n1. Identify the user (by identity key) and the jurisdiction/policy scope.\n2. Get the user current consent for the relevant purposes (analytics, marketing, etc.).\n3. Determine which downstream actions are permitted based on the consent state.\n\n## Output\nReturn the consent state per purpose and a clear allow/deny decision for the intended data use. Stop the workflow if required consent is missing.', + }, + { + name: 'record-consent-update', + description: 'Set or update a user consent choices in Ketch from a preference change.', + content: + '# Record a Consent Update\n\nPersist a user updated consent choices to Ketch.\n\n## Steps\n1. Capture the user identity and the new consent choices per purpose.\n2. Set the consent for that user in the correct jurisdiction/policy scope.\n3. Read the consent back to confirm it was applied.\n\n## Output\nConfirm the user identity, the purposes updated, and the resulting consent state.', + }, + { + name: 'fulfill-data-subject-request', + description: 'Invoke a data subject right (access, delete) in Ketch and track the request.', + content: + '# Fulfill a Data Subject Request\n\nKick off a DSR (e.g. access or deletion) on behalf of a user.\n\n## Steps\n1. Capture the requester identity and the right being exercised (access, deletion, correction).\n2. Invoke the right in Ketch with the required identity and jurisdiction context.\n3. Capture the request reference for tracking.\n\n## Output\nReturn the request reference, the right invoked, and the requester identity so the request can be tracked to completion.', + }, + { + name: 'sync-subscription-preferences', + description: + 'Read a user subscription topics in Ketch and update them to honor an opt-in or opt-out.', + content: + '# Sync Subscription Preferences\n\nKeep a user communication preferences accurate in Ketch when they opt in or out of a channel or topic.\n\n## Steps\n1. Identify the user and get their current subscription topics and controls.\n2. Determine the requested change (e.g. opt out of the newsletter, set a global unsubscribe).\n3. Set the subscription topics and controls to the new state for that user.\n4. Read the subscriptions back to confirm the change applied.\n\n## Output\nReturn the topics and controls that changed and the resulting opt-in or opt-out state per channel. Confirm any global unsubscribe was honored.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ketch.ts b/apps/sim/blocks/blocks/ketch.ts index a34f4adea36..a74aa485306 100644 --- a/apps/sim/blocks/blocks/ketch.ts +++ b/apps/sim/blocks/blocks/ketch.ts @@ -1,6 +1,5 @@ -import { KetchIcon } from '@/components/icons' import { KetchBlockDisplay } from '@/blocks/blocks/ketch.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { KetchResponse } from '@/tools/ketch/types' export const KetchBlock: BlockConfig = { @@ -224,102 +223,3 @@ export const KetchBlock: BlockConfig = { message: { type: 'string', description: 'Response message from Ketch' }, }, } - -export const KetchBlockMeta = { - tags: ['identity'], - url: 'https://www.ketch.com', - templates: [ - { - icon: KetchIcon, - title: 'Ketch consent propagator', - prompt: - 'Build a workflow that on a consent change reads the contact’s Ketch consent state and propagates it to downstream systems — HubSpot and Loops — keeping privacy preferences in sync.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['legal', 'sync'], - alsoIntegrations: ['hubspot', 'loops'], - }, - { - icon: KetchIcon, - title: 'Ketch DSR fulfillment', - prompt: - 'Create a workflow that on a Ketch data subject request collects matching personal data from connected systems, generates the export, and writes the fulfillment audit.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: KetchIcon, - title: 'Ketch deletion-request handler', - prompt: - 'Build a workflow that on a Ketch deletion request propagates the deletion to all connected systems, captures confirmations, and writes the chain of custody.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: KetchIcon, - title: 'Ketch consent-drift detector', - prompt: - 'Create a scheduled workflow that compares Ketch consent state with downstream systems, flags drift, and writes a remediation queue for the privacy team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'monitoring'], - }, - { - icon: KetchIcon, - title: 'Ketch subscription sync', - prompt: - 'Build a workflow that reads each contact’s Ketch subscription topics and mirrors the opt-in state to the marketing tool so unsubscribe preferences stay consistent across systems.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['legal', 'sync'], - alsoIntegrations: ['loops'], - }, - { - icon: KetchIcon, - title: 'Ketch right-invocation handler', - prompt: - 'Create a workflow that on an incoming privacy request invokes the matching Ketch right for the data subject, captures the confirmation, and writes the action to a compliance file.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: KetchIcon, - title: 'Ketch consent-rate digest', - prompt: - 'Build a scheduled monthly workflow that samples Ketch consent state across a contact list, computes opt-in rates per purpose, and writes a privacy report file for executive review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'reporting'], - }, - ], - skills: [ - { - name: 'check-user-consent', - description: 'Look up a user current consent state in Ketch before processing their data.', - content: - '# Check User Consent\n\nConfirm what a user has consented to before a workflow uses their data.\n\n## Steps\n1. Identify the user (by identity key) and the jurisdiction/policy scope.\n2. Get the user current consent for the relevant purposes (analytics, marketing, etc.).\n3. Determine which downstream actions are permitted based on the consent state.\n\n## Output\nReturn the consent state per purpose and a clear allow/deny decision for the intended data use. Stop the workflow if required consent is missing.', - }, - { - name: 'record-consent-update', - description: 'Set or update a user consent choices in Ketch from a preference change.', - content: - '# Record a Consent Update\n\nPersist a user updated consent choices to Ketch.\n\n## Steps\n1. Capture the user identity and the new consent choices per purpose.\n2. Set the consent for that user in the correct jurisdiction/policy scope.\n3. Read the consent back to confirm it was applied.\n\n## Output\nConfirm the user identity, the purposes updated, and the resulting consent state.', - }, - { - name: 'fulfill-data-subject-request', - description: 'Invoke a data subject right (access, delete) in Ketch and track the request.', - content: - '# Fulfill a Data Subject Request\n\nKick off a DSR (e.g. access or deletion) on behalf of a user.\n\n## Steps\n1. Capture the requester identity and the right being exercised (access, deletion, correction).\n2. Invoke the right in Ketch with the required identity and jurisdiction context.\n3. Capture the request reference for tracking.\n\n## Output\nReturn the request reference, the right invoked, and the requester identity so the request can be tracked to completion.', - }, - { - name: 'sync-subscription-preferences', - description: - 'Read a user subscription topics in Ketch and update them to honor an opt-in or opt-out.', - content: - '# Sync Subscription Preferences\n\nKeep a user communication preferences accurate in Ketch when they opt in or out of a channel or topic.\n\n## Steps\n1. Identify the user and get their current subscription topics and controls.\n2. Determine the requested change (e.g. opt out of the newsletter, set a global unsubscribe).\n3. Set the subscription topics and controls to the new state for that user.\n4. Read the subscriptions back to confirm the change applied.\n\n## Output\nReturn the topics and controls that changed and the resulting opt-in or opt-out state per channel. Confirm any global unsubscribe was honored.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/langsmith.display.ts b/apps/sim/blocks/blocks/langsmith.display.ts index eb650b515c6..25c88954333 100644 --- a/apps/sim/blocks/blocks/langsmith.display.ts +++ b/apps/sim/blocks/blocks/langsmith.display.ts @@ -1,6 +1,6 @@ import { LangsmithIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LangsmithBlockDisplay = { type: 'langsmith', @@ -14,3 +14,90 @@ export const LangsmithBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/langsmith', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const LangsmithBlockMeta = { + tags: ['monitoring', 'llm'], + url: 'https://www.langchain.com/langsmith', + templates: [ + { + icon: LangsmithIcon, + title: 'LangSmith agent-run tracer', + prompt: + 'Build a workflow that wraps an agent step and forwards each run to LangSmith with inputs, outputs, and latency so the ML team can trace executions in one project.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith error logger', + prompt: + 'Create a workflow that on a failed agent step forwards a LangSmith run tagged as an error with the inputs and error message, and posts the run link to Slack for the ML team.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith feedback capture', + prompt: + 'Build a workflow that collects user-reported agent failures from a table and forwards each as a tagged LangSmith run with the inputs and expected output for later review.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith batch run shipper', + prompt: + 'Create a scheduled workflow that reads completed agent runs from a table and posts them to LangSmith in a single batch so observability stays in sync without per-run overhead.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith session tagger', + prompt: + 'Build a workflow that forwards each agent run to LangSmith tagged with the originating feature and environment so traces can be filtered by surface in the LangSmith project.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith RAG step logger', + prompt: + 'Create a workflow that runs a retrieval-augmented agent and forwards a LangSmith run per step — retriever, prompt, and llm — so the ML team can inspect each stage of the chain.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: LangsmithIcon, + title: 'LangSmith multi-agent tracer', + prompt: + 'Build a workflow that forwards a LangSmith run for each agent in a multi-step pipeline under one trace, so the full conversation is visible end-to-end in LangSmith.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + }, + ], + skills: [ + { + name: 'log-llm-run-to-langsmith', + description: + 'Send a single LLM or chain run to LangSmith with inputs, outputs, and timing for tracing.', + content: + '# Log an LLM Run to LangSmith\n\nForward one workflow step into LangSmith so it shows up in tracing and evals.\n\n## Steps\n1. Capture the run name, run type (llm, chain, tool), and the project to log into.\n2. Record the inputs (prompt or arguments) and the outputs the step produced.\n3. Include start and end times so latency is captured, plus any error if the step failed.\n4. Create the run in LangSmith.\n\n## Output\nConfirm the run was logged with its name, type, and project, and surface the run ID for follow-up inspection.', + }, + { + name: 'batch-export-runs', + description: + 'Send a batch of completed workflow runs to LangSmith in one call for observability.', + content: + '# Batch Export Runs\n\nShip multiple completed runs to LangSmith at once instead of one by one.\n\n## Steps\n1. Collect the runs to export, each with name, type, inputs, outputs, and timing.\n2. Assign a shared project so the runs land together.\n3. Submit them as a single batch.\n\n## Output\nReturn how many runs were exported, the project they landed in, and any runs that failed validation.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/langsmith.ts b/apps/sim/blocks/blocks/langsmith.ts index 83426d84ecf..ca28bd2f86f 100644 --- a/apps/sim/blocks/blocks/langsmith.ts +++ b/apps/sim/blocks/blocks/langsmith.ts @@ -1,7 +1,6 @@ import { toError } from '@sim/utils/errors' -import { LangsmithIcon } from '@/components/icons' import { LangsmithBlockDisplay } from '@/blocks/blocks/langsmith.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { LangsmithResponse } from '@/tools/langsmith/types' export const LangsmithBlock: BlockConfig = { @@ -288,90 +287,3 @@ Common patch fields: outputs, end_time, status, error`, messages: { type: 'array', description: 'Per-run response messages' }, }, } - -export const LangsmithBlockMeta = { - tags: ['monitoring', 'llm'], - url: 'https://www.langchain.com/langsmith', - templates: [ - { - icon: LangsmithIcon, - title: 'LangSmith agent-run tracer', - prompt: - 'Build a workflow that wraps an agent step and forwards each run to LangSmith with inputs, outputs, and latency so the ML team can trace executions in one project.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith error logger', - prompt: - 'Create a workflow that on a failed agent step forwards a LangSmith run tagged as an error with the inputs and error message, and posts the run link to Slack for the ML team.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith feedback capture', - prompt: - 'Build a workflow that collects user-reported agent failures from a table and forwards each as a tagged LangSmith run with the inputs and expected output for later review.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith batch run shipper', - prompt: - 'Create a scheduled workflow that reads completed agent runs from a table and posts them to LangSmith in a single batch so observability stays in sync without per-run overhead.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith session tagger', - prompt: - 'Build a workflow that forwards each agent run to LangSmith tagged with the originating feature and environment so traces can be filtered by surface in the LangSmith project.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith RAG step logger', - prompt: - 'Create a workflow that runs a retrieval-augmented agent and forwards a LangSmith run per step — retriever, prompt, and llm — so the ML team can inspect each stage of the chain.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: LangsmithIcon, - title: 'LangSmith multi-agent tracer', - prompt: - 'Build a workflow that forwards a LangSmith run for each agent in a multi-step pipeline under one trace, so the full conversation is visible end-to-end in LangSmith.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - }, - ], - skills: [ - { - name: 'log-llm-run-to-langsmith', - description: - 'Send a single LLM or chain run to LangSmith with inputs, outputs, and timing for tracing.', - content: - '# Log an LLM Run to LangSmith\n\nForward one workflow step into LangSmith so it shows up in tracing and evals.\n\n## Steps\n1. Capture the run name, run type (llm, chain, tool), and the project to log into.\n2. Record the inputs (prompt or arguments) and the outputs the step produced.\n3. Include start and end times so latency is captured, plus any error if the step failed.\n4. Create the run in LangSmith.\n\n## Output\nConfirm the run was logged with its name, type, and project, and surface the run ID for follow-up inspection.', - }, - { - name: 'batch-export-runs', - description: - 'Send a batch of completed workflow runs to LangSmith in one call for observability.', - content: - '# Batch Export Runs\n\nShip multiple completed runs to LangSmith at once instead of one by one.\n\n## Steps\n1. Collect the runs to export, each with name, type, inputs, outputs, and timing.\n2. Assign a shared project so the runs land together.\n3. Submit them as a single batch.\n\n## Output\nReturn how many runs were exported, the project they landed in, and any runs that failed validation.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/latex.display.ts b/apps/sim/blocks/blocks/latex.display.ts index 9396e3cd6ec..9f009623f15 100644 --- a/apps/sim/blocks/blocks/latex.display.ts +++ b/apps/sim/blocks/blocks/latex.display.ts @@ -1,6 +1,6 @@ import { LatexIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LatexBlockDisplay = { type: 'latex', @@ -14,3 +14,125 @@ export const LatexBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/latex', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const LatexBlockMeta = { + tags: ['document-processing'], + url: 'https://www.latex-project.org', + templates: [ + { + icon: LatexIcon, + title: 'LaTeX invoice generator', + prompt: + 'Build a workflow that takes invoice line items from a table, fills a LaTeX invoice template, compiles it to PDF, and emails the invoice to the customer.', + modules: ['tables', 'workflows'], + category: 'operations', + tags: ['documents', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: LatexIcon, + title: 'LaTeX research report writer', + prompt: + 'Create a workflow where an agent researches a topic from the knowledge base, writes the findings as a LaTeX article, and compiles a polished PDF report.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['documents', 'research'], + }, + { + icon: LatexIcon, + title: 'LaTeX weekly metrics report', + prompt: + 'Build a scheduled weekly workflow that pulls metrics from a table, typesets a LaTeX report with charts and tables, compiles it to PDF, and posts it to Slack.', + modules: ['scheduled', 'tables', 'workflows'], + category: 'operations', + tags: ['documents', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: LatexIcon, + title: 'LaTeX offer letter generator', + prompt: + 'Create a workflow that takes candidate details from a form, fills a LaTeX offer letter template, compiles it to PDF, and sends it for e-signature.', + modules: ['workflows'], + category: 'operations', + tags: ['documents', 'hr'], + alsoIntegrations: ['docusign'], + }, + { + icon: LatexIcon, + title: 'LaTeX math worksheet builder', + prompt: + 'Build a workflow where an agent generates practice problems for a given math topic and difficulty, typesets them with LaTeX equations, and compiles a printable worksheet PDF.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['documents', 'education'], + }, + { + icon: LatexIcon, + title: 'LaTeX proposal generator', + prompt: + 'Create a workflow that pulls deal details from HubSpot, has an agent draft a tailored proposal in LaTeX, compiles it to PDF, and saves it to the deal record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['documents', 'proposals'], + alsoIntegrations: ['hubspot'], + }, + { + icon: LatexIcon, + title: 'LaTeX paper digest compiler', + prompt: + 'Build a scheduled workflow that fetches new ArXiv papers on tracked topics, has an agent summarize each one, typesets the digest as a LaTeX document, and compiles a weekly PDF.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['documents', 'research'], + alsoIntegrations: ['arxiv'], + }, + { + icon: LatexIcon, + title: 'LaTeX certificate generator', + prompt: + 'Create a workflow that reads attendee names from a spreadsheet, fills a LaTeX certificate template for each attendee, compiles the PDFs, and emails each certificate to its recipient.', + modules: ['workflows'], + category: 'operations', + tags: ['documents', 'automation'], + alsoIntegrations: ['google_sheets', 'gmail'], + }, + ], + skills: [ + { + name: 'compile-document-to-pdf', + description: + 'Compile LaTeX source into a finished PDF, choosing the right compiler and reporting any compilation errors. Use whenever a polished, print-ready document is needed.', + content: + '# Compile Document to PDF\n\nTurn LaTeX source into a finished PDF.\n\n## Steps\n1. Assemble the complete LaTeX source, from \\documentclass to \\end{document}.\n2. Pick the compiler: pdflatex for standard documents, xelatex or lualatex when custom fonts or full unicode are needed.\n3. Attach any supporting files (images, included .tex files, .bib bibliographies) as resources with the paths the source references.\n4. Compile and capture the resulting PDF.\n\n## Output\nThe compiled PDF file and its URL. If compilation fails, report the TeX errors verbatim so they can be fixed.', + }, + { + name: 'generate-document-from-template', + description: + 'Fill a LaTeX template with structured data and compile it to PDF. Use for repeatable documents like invoices, certificates, letters, and contracts.', + content: + '# Generate Document from Template\n\nProduce a templated document with real data filled in.\n\n## Steps\n1. Start from the LaTeX template and identify its placeholders.\n2. Substitute each placeholder with the provided data, escaping LaTeX special characters (&, %, $, #, _, {, }) in user-supplied values.\n3. Compile the filled-in source to PDF.\n4. Name the output file after the document, e.g. invoice-1042.pdf.\n\n## Output\nA compiled PDF per record, named for its contents. List any records that failed to compile and why.', + }, + { + name: 'typeset-math-content', + description: + 'Write mathematical content — equations, proofs, problem sets — in LaTeX and compile a printable PDF. Use for worksheets, solution sheets, and technical notes.', + content: + '# Typeset Math Content\n\nProduce a clean PDF of mathematical material.\n\n## Steps\n1. Draft the content using proper LaTeX math: inline $...$, display equations, and environments like align and theorem as appropriate.\n2. Load only the packages the content needs (amsmath, amssymb, amsthm).\n3. Structure the document with sections and consistent numbering.\n4. Compile to PDF and verify there are no errors.\n\n## Output\nA printable PDF of the typeset material, plus the LaTeX source so it can be edited later.', + }, + { + name: 'build-report-with-bibliography', + description: + 'Compile a report or paper that cites sources, attaching a BibTeX bibliography as a resource. Use for research reports, literature reviews, and academic writing.', + content: + '# Build Report with Bibliography\n\nCompile a citing document with its references resolved.\n\n## Steps\n1. Write the report source with \\cite commands and a \\bibliography{refs} (or biblatex equivalent) reference.\n2. Attach the BibTeX entries as a resource at the cited path, e.g. refs.bib.\n3. Compile — the bibliography pass runs automatically.\n4. Check the output for unresolved citation warnings and fix missing entries.\n\n## Output\nThe compiled PDF with a formatted reference list. Note any citations that could not be resolved.', + }, + { + name: 'fix-compilation-errors', + description: + 'Diagnose failed LaTeX builds from the compiler error output and iterate until the document compiles. Use when a compilation returns errors instead of a PDF.', + content: + '# Fix Compilation Errors\n\nGet a failing LaTeX document to build.\n\n## Steps\n1. Read the TeX error lines from the failed compile (lines starting with !), which name the problem and its location.\n2. Apply the targeted fix: missing packages (verify availability with Get Package Details or Search Packages), unescaped special characters, unmatched braces or environments, or commands needing a different compiler (e.g. fontspec requires xelatex or lualatex — confirm the font exists with List Fonts).\n3. Recompile and repeat until the build succeeds.\n4. Keep edits minimal — fix the errors without rewriting the document.\n\n## Output\nThe compiled PDF and a short list of the fixes that were applied.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/latex.ts b/apps/sim/blocks/blocks/latex.ts index 33a7454b6f7..c4082447d71 100644 --- a/apps/sim/blocks/blocks/latex.ts +++ b/apps/sim/blocks/blocks/latex.ts @@ -1,6 +1,5 @@ -import { LatexIcon } from '@/components/icons' import { LatexBlockDisplay } from '@/blocks/blocks/latex.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { LatexResponse } from '@/tools/latex/types' export const LatexBlock: BlockConfig = { @@ -227,125 +226,3 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`, totalMatches: { type: 'number', description: 'Total matches found before truncation' }, }, } - -export const LatexBlockMeta = { - tags: ['document-processing'], - url: 'https://www.latex-project.org', - templates: [ - { - icon: LatexIcon, - title: 'LaTeX invoice generator', - prompt: - 'Build a workflow that takes invoice line items from a table, fills a LaTeX invoice template, compiles it to PDF, and emails the invoice to the customer.', - modules: ['tables', 'workflows'], - category: 'operations', - tags: ['documents', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: LatexIcon, - title: 'LaTeX research report writer', - prompt: - 'Create a workflow where an agent researches a topic from the knowledge base, writes the findings as a LaTeX article, and compiles a polished PDF report.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['documents', 'research'], - }, - { - icon: LatexIcon, - title: 'LaTeX weekly metrics report', - prompt: - 'Build a scheduled weekly workflow that pulls metrics from a table, typesets a LaTeX report with charts and tables, compiles it to PDF, and posts it to Slack.', - modules: ['scheduled', 'tables', 'workflows'], - category: 'operations', - tags: ['documents', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: LatexIcon, - title: 'LaTeX offer letter generator', - prompt: - 'Create a workflow that takes candidate details from a form, fills a LaTeX offer letter template, compiles it to PDF, and sends it for e-signature.', - modules: ['workflows'], - category: 'operations', - tags: ['documents', 'hr'], - alsoIntegrations: ['docusign'], - }, - { - icon: LatexIcon, - title: 'LaTeX math worksheet builder', - prompt: - 'Build a workflow where an agent generates practice problems for a given math topic and difficulty, typesets them with LaTeX equations, and compiles a printable worksheet PDF.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['documents', 'education'], - }, - { - icon: LatexIcon, - title: 'LaTeX proposal generator', - prompt: - 'Create a workflow that pulls deal details from HubSpot, has an agent draft a tailored proposal in LaTeX, compiles it to PDF, and saves it to the deal record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['documents', 'proposals'], - alsoIntegrations: ['hubspot'], - }, - { - icon: LatexIcon, - title: 'LaTeX paper digest compiler', - prompt: - 'Build a scheduled workflow that fetches new ArXiv papers on tracked topics, has an agent summarize each one, typesets the digest as a LaTeX document, and compiles a weekly PDF.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['documents', 'research'], - alsoIntegrations: ['arxiv'], - }, - { - icon: LatexIcon, - title: 'LaTeX certificate generator', - prompt: - 'Create a workflow that reads attendee names from a spreadsheet, fills a LaTeX certificate template for each attendee, compiles the PDFs, and emails each certificate to its recipient.', - modules: ['workflows'], - category: 'operations', - tags: ['documents', 'automation'], - alsoIntegrations: ['google_sheets', 'gmail'], - }, - ], - skills: [ - { - name: 'compile-document-to-pdf', - description: - 'Compile LaTeX source into a finished PDF, choosing the right compiler and reporting any compilation errors. Use whenever a polished, print-ready document is needed.', - content: - '# Compile Document to PDF\n\nTurn LaTeX source into a finished PDF.\n\n## Steps\n1. Assemble the complete LaTeX source, from \\documentclass to \\end{document}.\n2. Pick the compiler: pdflatex for standard documents, xelatex or lualatex when custom fonts or full unicode are needed.\n3. Attach any supporting files (images, included .tex files, .bib bibliographies) as resources with the paths the source references.\n4. Compile and capture the resulting PDF.\n\n## Output\nThe compiled PDF file and its URL. If compilation fails, report the TeX errors verbatim so they can be fixed.', - }, - { - name: 'generate-document-from-template', - description: - 'Fill a LaTeX template with structured data and compile it to PDF. Use for repeatable documents like invoices, certificates, letters, and contracts.', - content: - '# Generate Document from Template\n\nProduce a templated document with real data filled in.\n\n## Steps\n1. Start from the LaTeX template and identify its placeholders.\n2. Substitute each placeholder with the provided data, escaping LaTeX special characters (&, %, $, #, _, {, }) in user-supplied values.\n3. Compile the filled-in source to PDF.\n4. Name the output file after the document, e.g. invoice-1042.pdf.\n\n## Output\nA compiled PDF per record, named for its contents. List any records that failed to compile and why.', - }, - { - name: 'typeset-math-content', - description: - 'Write mathematical content — equations, proofs, problem sets — in LaTeX and compile a printable PDF. Use for worksheets, solution sheets, and technical notes.', - content: - '# Typeset Math Content\n\nProduce a clean PDF of mathematical material.\n\n## Steps\n1. Draft the content using proper LaTeX math: inline $...$, display equations, and environments like align and theorem as appropriate.\n2. Load only the packages the content needs (amsmath, amssymb, amsthm).\n3. Structure the document with sections and consistent numbering.\n4. Compile to PDF and verify there are no errors.\n\n## Output\nA printable PDF of the typeset material, plus the LaTeX source so it can be edited later.', - }, - { - name: 'build-report-with-bibliography', - description: - 'Compile a report or paper that cites sources, attaching a BibTeX bibliography as a resource. Use for research reports, literature reviews, and academic writing.', - content: - '# Build Report with Bibliography\n\nCompile a citing document with its references resolved.\n\n## Steps\n1. Write the report source with \\cite commands and a \\bibliography{refs} (or biblatex equivalent) reference.\n2. Attach the BibTeX entries as a resource at the cited path, e.g. refs.bib.\n3. Compile — the bibliography pass runs automatically.\n4. Check the output for unresolved citation warnings and fix missing entries.\n\n## Output\nThe compiled PDF with a formatted reference list. Note any citations that could not be resolved.', - }, - { - name: 'fix-compilation-errors', - description: - 'Diagnose failed LaTeX builds from the compiler error output and iterate until the document compiles. Use when a compilation returns errors instead of a PDF.', - content: - '# Fix Compilation Errors\n\nGet a failing LaTeX document to build.\n\n## Steps\n1. Read the TeX error lines from the failed compile (lines starting with !), which name the problem and its location.\n2. Apply the targeted fix: missing packages (verify availability with Get Package Details or Search Packages), unescaped special characters, unmatched braces or environments, or commands needing a different compiler (e.g. fontspec requires xelatex or lualatex — confirm the font exists with List Fonts).\n3. Recompile and repeat until the build succeeds.\n4. Keep edits minimal — fix the errors without rewriting the document.\n\n## Output\nThe compiled PDF and a short list of the fixes that were applied.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/launchdarkly.display.ts b/apps/sim/blocks/blocks/launchdarkly.display.ts index f47bc3e63c6..623f7847bfa 100644 --- a/apps/sim/blocks/blocks/launchdarkly.display.ts +++ b/apps/sim/blocks/blocks/launchdarkly.display.ts @@ -1,6 +1,6 @@ import { LaunchDarklyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LaunchDarklyBlockDisplay = { type: 'launchdarkly', @@ -15,3 +15,114 @@ export const LaunchDarklyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/launchdarkly', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const LaunchDarklyBlockMeta = { + tags: ['feature-flags', 'ci-cd'], + url: 'https://launchdarkly.com', + templates: [ + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly flag-flip auditor', + prompt: + 'Build a scheduled workflow that reads the LaunchDarkly audit log, captures who flipped which flag and when, and writes the audit trail to a tracking table with diff context.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly stale-flag sweeper', + prompt: + 'Create a scheduled workflow that identifies LaunchDarkly flags inactive for 60 days, opens Linear tickets to remove them, and writes the cleanup queue to a dashboard table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + alsoIntegrations: ['linear'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly rollout digest', + prompt: + 'Build a scheduled weekly workflow that lists LaunchDarkly flags with their current status and rollout percentage per environment, summarizes what changed since last week, and posts a digest to the product Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly flag-flip safety gate', + prompt: + 'Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['sentry', 'datadog', 'slack'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly targeted rollout assistant', + prompt: + 'Build a workflow that takes a LaunchDarkly flag and a rollout plan, advances the rollout percentage on a schedule while watching health metrics, pausing on degradation.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['datadog'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly + Linear release planner', + prompt: + 'Create a workflow that watches Linear releases marked behind a LaunchDarkly flag, validates the flag exists, posts the rollout plan to Slack, and tracks rollout progress on the release ticket.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: LaunchDarklyIcon, + title: 'LaunchDarkly customer-segment toggler', + prompt: + 'Build a workflow that turns a HubSpot segment into a LaunchDarkly targeting rule, keeping the rule in sync with the segment, and writes the sync log to a tracking table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm', 'sync'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'toggle-flag-in-environment', + description: 'Turn a LaunchDarkly feature flag on or off in a specific environment safely.', + content: + '# Toggle a Flag in an Environment\n\nFlip a feature flag for a target environment with a confirmation step.\n\n## Steps\n1. Identify the project and the environment (e.g. production, staging) and the flag key.\n2. Get the current flag status to confirm its present state.\n3. Toggle the flag to the desired on/off state in that environment.\n4. Re-check the status to confirm the change took effect.\n\n## Output\nReturn the flag key, environment, previous state, and new state. Confirm the toggle was applied.', + }, + { + name: 'create-feature-flag', + description: + 'Create a new LaunchDarkly feature flag in a project with a clear key and description.', + content: + '# Create a Feature Flag\n\nStand up a new feature flag for an upcoming release.\n\n## Steps\n1. Choose the project and define a descriptive flag key and human-readable name.\n2. Set a description explaining what the flag controls and whether it is temporary or permanent.\n3. Create the flag, defaulting it to off so it can be rolled out deliberately.\n\n## Output\nReturn the flag key, name, project, and initial state. Confirm the flag starts disabled.', + }, + { + name: 'flag-rollout-audit', + description: + 'Report on a flag state across environments and recent changes from the audit log.', + content: + '# Flag Rollout Audit\n\nUnderstand where a flag stands and who changed it recently.\n\n## Steps\n1. Get the flag and list environments for the project.\n2. For each environment, capture the flag on/off state and targeting.\n3. Pull the audit log entries for the flag to see recent changes and who made them.\n\n## Output\nReturn a per-environment state table for the flag and a short changelog of recent modifications with actor and timestamp.', + }, + { + name: 'emergency-flag-kill-switch', + description: + 'Instantly disable a feature flag in production during an incident and confirm it is off.', + content: + '# Emergency Flag Kill-Switch\n\nKill a misbehaving feature in production immediately.\n\n## Steps\n1. Identify the project, the production environment key, and the flag key to disable.\n2. Toggle the flag off in that environment.\n3. Get the flag status to confirm it is now off and no longer being served.\n\n## Output\nReturn the flag key, environment, and confirmation that the flag is off, with the timestamp of the change.', + }, + { + name: 'stale-flag-cleanup', + description: 'Find temporary or long-untouched feature flags and surface them for removal.', + content: + '# Stale Flag Cleanup\n\nKeep flag debt under control by surfacing flags that have outlived their purpose.\n\n## Steps\n1. List the flags in the project, noting which are marked temporary and their creation dates.\n2. Cross-reference the audit log to find flags with no recent changes.\n3. Compile the candidates that are temporary and inactive into a cleanup list.\n\n## Output\nReturn a list of stale flag keys with their age, temporary status, and last-change date so an owner can decide whether to archive or delete them.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/launchdarkly.ts b/apps/sim/blocks/blocks/launchdarkly.ts index bd1dfb1ab77..4e2720db85c 100644 --- a/apps/sim/blocks/blocks/launchdarkly.ts +++ b/apps/sim/blocks/blocks/launchdarkly.ts @@ -1,6 +1,5 @@ -import { LaunchDarklyIcon } from '@/components/icons' import { LaunchDarklyBlockDisplay } from '@/blocks/blocks/launchdarkly.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const LaunchDarklyBlock: BlockConfig = { @@ -343,114 +342,3 @@ Return ONLY the resource specifier string - no explanations, no extra text.`, defaultVal: { type: 'string', description: 'The default variation value from flag status' }, }, } - -export const LaunchDarklyBlockMeta = { - tags: ['feature-flags', 'ci-cd'], - url: 'https://launchdarkly.com', - templates: [ - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly flag-flip auditor', - prompt: - 'Build a scheduled workflow that reads the LaunchDarkly audit log, captures who flipped which flag and when, and writes the audit trail to a tracking table with diff context.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly stale-flag sweeper', - prompt: - 'Create a scheduled workflow that identifies LaunchDarkly flags inactive for 60 days, opens Linear tickets to remove them, and writes the cleanup queue to a dashboard table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - alsoIntegrations: ['linear'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly rollout digest', - prompt: - 'Build a scheduled weekly workflow that lists LaunchDarkly flags with their current status and rollout percentage per environment, summarizes what changed since last week, and posts a digest to the product Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly flag-flip safety gate', - prompt: - 'Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['sentry', 'datadog', 'slack'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly targeted rollout assistant', - prompt: - 'Build a workflow that takes a LaunchDarkly flag and a rollout plan, advances the rollout percentage on a schedule while watching health metrics, pausing on degradation.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['datadog'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly + Linear release planner', - prompt: - 'Create a workflow that watches Linear releases marked behind a LaunchDarkly flag, validates the flag exists, posts the rollout plan to Slack, and tracks rollout progress on the release ticket.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: LaunchDarklyIcon, - title: 'LaunchDarkly customer-segment toggler', - prompt: - 'Build a workflow that turns a HubSpot segment into a LaunchDarkly targeting rule, keeping the rule in sync with the segment, and writes the sync log to a tracking table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm', 'sync'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'toggle-flag-in-environment', - description: 'Turn a LaunchDarkly feature flag on or off in a specific environment safely.', - content: - '# Toggle a Flag in an Environment\n\nFlip a feature flag for a target environment with a confirmation step.\n\n## Steps\n1. Identify the project and the environment (e.g. production, staging) and the flag key.\n2. Get the current flag status to confirm its present state.\n3. Toggle the flag to the desired on/off state in that environment.\n4. Re-check the status to confirm the change took effect.\n\n## Output\nReturn the flag key, environment, previous state, and new state. Confirm the toggle was applied.', - }, - { - name: 'create-feature-flag', - description: - 'Create a new LaunchDarkly feature flag in a project with a clear key and description.', - content: - '# Create a Feature Flag\n\nStand up a new feature flag for an upcoming release.\n\n## Steps\n1. Choose the project and define a descriptive flag key and human-readable name.\n2. Set a description explaining what the flag controls and whether it is temporary or permanent.\n3. Create the flag, defaulting it to off so it can be rolled out deliberately.\n\n## Output\nReturn the flag key, name, project, and initial state. Confirm the flag starts disabled.', - }, - { - name: 'flag-rollout-audit', - description: - 'Report on a flag state across environments and recent changes from the audit log.', - content: - '# Flag Rollout Audit\n\nUnderstand where a flag stands and who changed it recently.\n\n## Steps\n1. Get the flag and list environments for the project.\n2. For each environment, capture the flag on/off state and targeting.\n3. Pull the audit log entries for the flag to see recent changes and who made them.\n\n## Output\nReturn a per-environment state table for the flag and a short changelog of recent modifications with actor and timestamp.', - }, - { - name: 'emergency-flag-kill-switch', - description: - 'Instantly disable a feature flag in production during an incident and confirm it is off.', - content: - '# Emergency Flag Kill-Switch\n\nKill a misbehaving feature in production immediately.\n\n## Steps\n1. Identify the project, the production environment key, and the flag key to disable.\n2. Toggle the flag off in that environment.\n3. Get the flag status to confirm it is now off and no longer being served.\n\n## Output\nReturn the flag key, environment, and confirmation that the flag is off, with the timestamp of the change.', - }, - { - name: 'stale-flag-cleanup', - description: 'Find temporary or long-untouched feature flags and surface them for removal.', - content: - '# Stale Flag Cleanup\n\nKeep flag debt under control by surfacing flags that have outlived their purpose.\n\n## Steps\n1. List the flags in the project, noting which are marked temporary and their creation dates.\n2. Cross-reference the audit log to find flags with no recent changes.\n3. Compile the candidates that are temporary and inactive into a cleanup list.\n\n## Output\nReturn a list of stale flag keys with their age, temporary status, and last-change date so an owner can decide whether to archive or delete them.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/leadmagic.display.ts b/apps/sim/blocks/blocks/leadmagic.display.ts index 9c1b2dcfcbc..b9eace4374a 100644 --- a/apps/sim/blocks/blocks/leadmagic.display.ts +++ b/apps/sim/blocks/blocks/leadmagic.display.ts @@ -1,6 +1,6 @@ import { LeadMagicIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LeadMagicBlockDisplay = { type: 'leadmagic', @@ -14,3 +14,8 @@ export const LeadMagicBlockDisplay = { docsLink: 'https://docs.sim.ai/tools/leadmagic', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const LeadMagicBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://leadmagic.io', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/leadmagic.ts b/apps/sim/blocks/blocks/leadmagic.ts index 13978ab653d..f1737ecf086 100644 --- a/apps/sim/blocks/blocks/leadmagic.ts +++ b/apps/sim/blocks/blocks/leadmagic.ts @@ -1,5 +1,5 @@ import { LeadMagicBlockDisplay } from '@/blocks/blocks/leadmagic.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { LeadMagicResponse } from '@/tools/leadmagic/types' export const LeadMagicBlock: BlockConfig = { @@ -374,8 +374,3 @@ export const LeadMagicBlock: BlockConfig = { credits: { type: 'number', description: 'Remaining credit balance' }, }, } - -export const LeadMagicBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://leadmagic.io', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/lemlist.display.ts b/apps/sim/blocks/blocks/lemlist.display.ts index ea150ff2363..5bc9eaf9cd8 100644 --- a/apps/sim/blocks/blocks/lemlist.display.ts +++ b/apps/sim/blocks/blocks/lemlist.display.ts @@ -1,6 +1,6 @@ import { LemlistIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LemlistBlockDisplay = { type: 'lemlist', @@ -14,3 +14,101 @@ export const LemlistBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/lemlist', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const LemlistBlockMeta = { + tags: ['sales-engagement', 'email-marketing', 'automation'], + url: 'https://www.lemlist.com', + templates: [ + { + icon: LemlistIcon, + title: 'Lemlist reply router', + prompt: + 'Create a workflow triggered by Lemlist reply webhooks that classifies each reply by intent and posts a Slack notification to the lead owner with a one-line summary, the intent, and the reply text.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: LemlistIcon, + title: 'Lemlist campaign analyzer', + prompt: + 'Build a scheduled workflow that pulls Lemlist campaign activities, computes open, click, reply, and bounce rates per campaign and per step, and writes the results to a tracking table so I can spot the steps that need rewriting.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis', 'reporting'], + }, + { + icon: LemlistIcon, + title: 'Lemlist + Apollo prospect feeder', + prompt: + 'Create a workflow that runs an Apollo search for an ICP, enriches each prospect with role and company signals, and sends a personalized first-touch email through Lemlist with a custom opening line per prospect.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'automation'], + alsoIntegrations: ['apollo'], + }, + { + icon: LemlistIcon, + title: 'Lemlist interested-lead booker', + prompt: + 'Build a workflow triggered when a Lemlist lead is marked interested that drafts a Calendly link tailored to the lead, replies to them through Lemlist with the link, and creates a follow-up task for the rep.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication', 'automation'], + alsoIntegrations: ['calendly'], + }, + { + icon: LemlistIcon, + title: 'Lemlist activity dashboard', + prompt: + 'Create a scheduled daily workflow that pulls Lemlist activity for the last 24 hours, summarizes opens, clicks, replies, and step performance per campaign, and writes a per-rep dashboard to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'analysis'], + }, + { + icon: LemlistIcon, + title: 'Lemlist bounced lead sweeper', + prompt: + 'Build a workflow triggered by Lemlist email-bounced events that looks up the lead, writes the bounce to a suppression table, and posts a Slack alert so the team can clean the list and keep quality high.', + alsoIntegrations: ['slack'], + modules: ['agent', 'tables', 'workflows'], + category: 'sales', + tags: ['sales', 'automation', 'analysis'], + }, + { + icon: LemlistIcon, + title: 'Lemlist to HubSpot logger', + prompt: + 'Create a workflow that watches Lemlist activity and logs every send, open, click, and reply to the matching HubSpot contact as an engagement, and creates a HubSpot task for the rep on positive replies.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'sync'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'triage-campaign-replies', + description: + 'Pull recent Lemlist reply activity, classify each reply by intent, and surface the ones that need a human.', + content: + '# Triage Campaign Replies\n\nMonitor Lemlist replies and route them by intent so reps act on hot leads fast.\n\n## Steps\n1. Get Activities filtered to the Email Replied type, optionally scoped to a campaign ID, with a sensible limit.\n2. For each reply, look up the lead with Get Lead to attach name, company, and job title.\n3. Classify the reply intent: interested, not interested, out-of-office, unsubscribe, or question.\n4. For interested or question replies, build a short summary with the lead name, campaign, and the reply text.\n\n## Output\nA list of replies grouped by intent. For each interested or question reply, include lead name, company, campaign, a one-line summary, and the raw reply text so a rep can respond.', + }, + { + name: 'analyze-campaign-performance', + description: + 'Compute open, click, reply, and bounce rates per campaign and per step from Lemlist activities and flag weak steps.', + content: + '# Analyze Campaign Performance\n\nTurn raw Lemlist activity into step-level metrics and concrete fixes.\n\n## Steps\n1. Get Activities for the target campaign with a high limit, paging with offset until all activity is collected.\n2. Tally events by type: emails sent, opened, clicked, replied, and bounced.\n3. Compute open rate, click rate, reply rate, and bounce rate overall and per sequence step.\n4. Flag steps where reply rate is low, bounce rate is high, or drop-off between steps is steep.\n\n## Output\nA per-campaign and per-step metrics table plus a short list of recommendations, such as rewriting a low-reply subject line or pausing a high-bounce step.', + }, + { + name: 'qualify-and-reply-to-lead', + description: + 'Look up a Lemlist lead and send a personalized reply through their Lemlist mailbox.', + content: + '# Qualify and Reply to Lead\n\nRespond to an inbound lead with a tailored message sent from your Lemlist inbox.\n\n## Steps\n1. Get Lead by email or lead ID to pull first name, company, and job title.\n2. Draft a concise, personalized reply that references the lead context and includes a clear next step or booking link.\n3. Send Email through Lemlist using the sender user ID, sender email, mailbox ID, contact ID, lead ID, subject, and the drafted HTML message body.\n\n## Output\nConfirmation that the email was sent, the lead identity it went to, and the message body that was used.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/lemlist.ts b/apps/sim/blocks/blocks/lemlist.ts index 61f47deb5b0..47c0344dd33 100644 --- a/apps/sim/blocks/blocks/lemlist.ts +++ b/apps/sim/blocks/blocks/lemlist.ts @@ -1,6 +1,5 @@ -import { LemlistIcon } from '@/components/icons' import { LemlistBlockDisplay } from '@/blocks/blocks/lemlist.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { LemlistResponse } from '@/tools/lemlist/types' import { getTrigger } from '@/triggers' @@ -227,101 +226,3 @@ export const LemlistBlock: BlockConfig = { ], }, } - -export const LemlistBlockMeta = { - tags: ['sales-engagement', 'email-marketing', 'automation'], - url: 'https://www.lemlist.com', - templates: [ - { - icon: LemlistIcon, - title: 'Lemlist reply router', - prompt: - 'Create a workflow triggered by Lemlist reply webhooks that classifies each reply by intent and posts a Slack notification to the lead owner with a one-line summary, the intent, and the reply text.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: LemlistIcon, - title: 'Lemlist campaign analyzer', - prompt: - 'Build a scheduled workflow that pulls Lemlist campaign activities, computes open, click, reply, and bounce rates per campaign and per step, and writes the results to a tracking table so I can spot the steps that need rewriting.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis', 'reporting'], - }, - { - icon: LemlistIcon, - title: 'Lemlist + Apollo prospect feeder', - prompt: - 'Create a workflow that runs an Apollo search for an ICP, enriches each prospect with role and company signals, and sends a personalized first-touch email through Lemlist with a custom opening line per prospect.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'automation'], - alsoIntegrations: ['apollo'], - }, - { - icon: LemlistIcon, - title: 'Lemlist interested-lead booker', - prompt: - 'Build a workflow triggered when a Lemlist lead is marked interested that drafts a Calendly link tailored to the lead, replies to them through Lemlist with the link, and creates a follow-up task for the rep.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication', 'automation'], - alsoIntegrations: ['calendly'], - }, - { - icon: LemlistIcon, - title: 'Lemlist activity dashboard', - prompt: - 'Create a scheduled daily workflow that pulls Lemlist activity for the last 24 hours, summarizes opens, clicks, replies, and step performance per campaign, and writes a per-rep dashboard to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'analysis'], - }, - { - icon: LemlistIcon, - title: 'Lemlist bounced lead sweeper', - prompt: - 'Build a workflow triggered by Lemlist email-bounced events that looks up the lead, writes the bounce to a suppression table, and posts a Slack alert so the team can clean the list and keep quality high.', - alsoIntegrations: ['slack'], - modules: ['agent', 'tables', 'workflows'], - category: 'sales', - tags: ['sales', 'automation', 'analysis'], - }, - { - icon: LemlistIcon, - title: 'Lemlist to HubSpot logger', - prompt: - 'Create a workflow that watches Lemlist activity and logs every send, open, click, and reply to the matching HubSpot contact as an engagement, and creates a HubSpot task for the rep on positive replies.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'sync'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'triage-campaign-replies', - description: - 'Pull recent Lemlist reply activity, classify each reply by intent, and surface the ones that need a human.', - content: - '# Triage Campaign Replies\n\nMonitor Lemlist replies and route them by intent so reps act on hot leads fast.\n\n## Steps\n1. Get Activities filtered to the Email Replied type, optionally scoped to a campaign ID, with a sensible limit.\n2. For each reply, look up the lead with Get Lead to attach name, company, and job title.\n3. Classify the reply intent: interested, not interested, out-of-office, unsubscribe, or question.\n4. For interested or question replies, build a short summary with the lead name, campaign, and the reply text.\n\n## Output\nA list of replies grouped by intent. For each interested or question reply, include lead name, company, campaign, a one-line summary, and the raw reply text so a rep can respond.', - }, - { - name: 'analyze-campaign-performance', - description: - 'Compute open, click, reply, and bounce rates per campaign and per step from Lemlist activities and flag weak steps.', - content: - '# Analyze Campaign Performance\n\nTurn raw Lemlist activity into step-level metrics and concrete fixes.\n\n## Steps\n1. Get Activities for the target campaign with a high limit, paging with offset until all activity is collected.\n2. Tally events by type: emails sent, opened, clicked, replied, and bounced.\n3. Compute open rate, click rate, reply rate, and bounce rate overall and per sequence step.\n4. Flag steps where reply rate is low, bounce rate is high, or drop-off between steps is steep.\n\n## Output\nA per-campaign and per-step metrics table plus a short list of recommendations, such as rewriting a low-reply subject line or pausing a high-bounce step.', - }, - { - name: 'qualify-and-reply-to-lead', - description: - 'Look up a Lemlist lead and send a personalized reply through their Lemlist mailbox.', - content: - '# Qualify and Reply to Lead\n\nRespond to an inbound lead with a tailored message sent from your Lemlist inbox.\n\n## Steps\n1. Get Lead by email or lead ID to pull first name, company, and job title.\n2. Draft a concise, personalized reply that references the lead context and includes a clear next step or booking link.\n3. Send Email through Lemlist using the sender user ID, sender email, mailbox ID, contact ID, lead ID, subject, and the drafted HTML message body.\n\n## Output\nConfirmation that the email was sent, the lead identity it went to, and the message body that was used.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linear.display.ts b/apps/sim/blocks/blocks/linear.display.ts index 940313d264e..801a2b7d438 100644 --- a/apps/sim/blocks/blocks/linear.display.ts +++ b/apps/sim/blocks/blocks/linear.display.ts @@ -1,6 +1,6 @@ -import { LinearIcon } from '@/components/icons' +import { DevinIcon, LinearIcon, SlackIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LinearBlockDisplay = { type: 'linear', @@ -23,3 +23,110 @@ export const LinearV2BlockDisplay = { name: 'Linear', hideFromToolbar: false, } satisfies BlockDisplay + +export const LinearBlockMeta = { + tags: ['project-management', 'ticketing'], + url: 'https://linear.app', + templates: [ + { + icon: LinearIcon, + title: 'Linear knowledge search', + prompt: + 'Create a knowledge base connected to my Linear workspace so all issues, comments, project updates, and decisions are automatically synced and searchable. Then build an agent I can ask things like "why did we deprioritize the mobile app?" or "what was the root cause of the checkout bug?" and get answers traced back to specific issues.', + modules: ['knowledge-base', 'agent'], + category: 'engineering', + tags: ['engineering', 'research', 'product'], + }, + { + icon: DevinIcon, + title: 'Linear ticket to Devin pipeline', + prompt: + 'Create a workflow that fires when a Linear ticket gets the "devin" label, transforms the ticket description, acceptance criteria, and linked context into a Devin prompt, creates a session, and posts the session link plus an estimated completion window back on the ticket.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'agentic', 'automation'], + alsoIntegrations: ['devin'], + }, + { + icon: SlackIcon, + title: 'Meeting notes to action items', + prompt: + 'Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['asana', 'slack'], + }, + + { + icon: LinearIcon, + title: 'Linear issue updates in Slack', + prompt: + 'Build a workflow that monitors Linear for new issues, assignments, and completions, and posts a formatted Slack message for each event so your team is always in the loop.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + { + icon: LinearIcon, + title: 'Bug report to Linear issue', + prompt: + 'Build a workflow that watches a Slack channel for bug reports, extracts the steps to reproduce and severity with an agent, creates a labeled Linear issue in the right team, and replies in-thread with the issue link.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: LinearIcon, + title: 'Linear triage labeler', + prompt: + 'Create a workflow that on a newly created Linear issue reads the title and description, adds the right labels for type and priority, assigns it to the correct team based on the area, and comments a triage summary.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation', 'project-management'], + }, + { + icon: LinearIcon, + title: 'Linear sprint review digest', + prompt: + 'Build a scheduled weekly workflow that searches Linear for issues completed and still open in the active cycle, summarizes progress and blockers with an agent, logs velocity to a table, and posts a sprint review digest to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'reporting', 'project-management'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'create-triaged-issue', + description: + 'Create a Linear issue in the right team with a clear title, description, priority, and labels.', + content: + '# Create Triaged Issue\n\nTurn a request or bug report into a well-formed Linear issue.\n\n## Steps\n1. If the team is unknown, List Teams and pick the team that owns the area.\n2. Write a concise title and a description with context, steps to reproduce, and acceptance criteria.\n3. Create Issue with the team ID, title, description, and a priority that matches severity.\n4. Optionally Add Label to Issue for type and area labels using IDs from List Labels.\n\n## Output\nThe created issue ID, its identifier and URL, and the team, priority, and labels applied.', + }, + { + name: 'triage-new-issue', + description: + 'Read a Linear issue, apply type and priority labels, set assignee and state, and comment a triage summary.', + content: + '# Triage New Issue\n\nTriage an incoming Linear issue so it lands in the right place with the right metadata.\n\n## Steps\n1. Get Issue to read the title and description.\n2. Determine the issue type, priority, and owning area from the content.\n3. Add Label to Issue for type and priority, and Update Issue to set the assignee, state, and priority.\n4. Create Comment with a short triage summary explaining the classification and next step.\n\n## Output\nThe issue identifier, the labels added, the assignee and state set, and the triage comment posted.', + }, + { + name: 'summarize-active-cycle', + description: + 'Pull completed and open issues in the active cycle and produce a sprint progress digest.', + content: + '# Summarize Active Cycle\n\nProduce a sprint review digest from the current Linear cycle.\n\n## Steps\n1. Get Active Cycle for the team to find the current cycle.\n2. Read Issues or Search Issues scoped to that cycle, separating completed from still-open issues.\n3. Compute counts, completion percentage, and call out blocked or at-risk issues by priority.\n4. Summarize progress, blockers, and what is likely to slip.\n\n## Output\nA digest with completed vs open counts, completion percentage, a list of blockers, and a short narrative of cycle health.', + }, + { + name: 'post-project-update', + description: + 'Assess a Linear project and post a project update with a health status and progress summary.', + content: + '# Post Project Update\n\nWrite a stakeholder-ready project update in Linear.\n\n## Steps\n1. Get Project to read its current state, target date, and lead.\n2. Read Issues for the project to gauge progress against the milestone or target date.\n3. Decide a health status of on track, at risk, or off track based on remaining work and timeline.\n4. Create Project Update with the chosen health and a concise body covering progress, risks, and next steps.\n\n## Output\nConfirmation of the posted update, the health status chosen, and the update body.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linear.ts b/apps/sim/blocks/blocks/linear.ts index 007a8805ba0..bc2adaebab4 100644 --- a/apps/sim/blocks/blocks/linear.ts +++ b/apps/sim/blocks/blocks/linear.ts @@ -1,7 +1,6 @@ -import { DevinIcon, LinearIcon, SlackIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { LinearBlockDisplay, LinearV2BlockDisplay } from '@/blocks/blocks/linear.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { LinearResponse } from '@/tools/linear/types' @@ -2598,110 +2597,3 @@ export const LinearV2Block: BlockConfig = { ], }, } - -export const LinearBlockMeta = { - tags: ['project-management', 'ticketing'], - url: 'https://linear.app', - templates: [ - { - icon: LinearIcon, - title: 'Linear knowledge search', - prompt: - 'Create a knowledge base connected to my Linear workspace so all issues, comments, project updates, and decisions are automatically synced and searchable. Then build an agent I can ask things like "why did we deprioritize the mobile app?" or "what was the root cause of the checkout bug?" and get answers traced back to specific issues.', - modules: ['knowledge-base', 'agent'], - category: 'engineering', - tags: ['engineering', 'research', 'product'], - }, - { - icon: DevinIcon, - title: 'Linear ticket to Devin pipeline', - prompt: - 'Create a workflow that fires when a Linear ticket gets the "devin" label, transforms the ticket description, acceptance criteria, and linked context into a Devin prompt, creates a session, and posts the session link plus an estimated completion window back on the ticket.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'agentic', 'automation'], - alsoIntegrations: ['devin'], - }, - { - icon: SlackIcon, - title: 'Meeting notes to action items', - prompt: - 'Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['asana', 'slack'], - }, - - { - icon: LinearIcon, - title: 'Linear issue updates in Slack', - prompt: - 'Build a workflow that monitors Linear for new issues, assignments, and completions, and posts a formatted Slack message for each event so your team is always in the loop.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - { - icon: LinearIcon, - title: 'Bug report to Linear issue', - prompt: - 'Build a workflow that watches a Slack channel for bug reports, extracts the steps to reproduce and severity with an agent, creates a labeled Linear issue in the right team, and replies in-thread with the issue link.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: LinearIcon, - title: 'Linear triage labeler', - prompt: - 'Create a workflow that on a newly created Linear issue reads the title and description, adds the right labels for type and priority, assigns it to the correct team based on the area, and comments a triage summary.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation', 'project-management'], - }, - { - icon: LinearIcon, - title: 'Linear sprint review digest', - prompt: - 'Build a scheduled weekly workflow that searches Linear for issues completed and still open in the active cycle, summarizes progress and blockers with an agent, logs velocity to a table, and posts a sprint review digest to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'reporting', 'project-management'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'create-triaged-issue', - description: - 'Create a Linear issue in the right team with a clear title, description, priority, and labels.', - content: - '# Create Triaged Issue\n\nTurn a request or bug report into a well-formed Linear issue.\n\n## Steps\n1. If the team is unknown, List Teams and pick the team that owns the area.\n2. Write a concise title and a description with context, steps to reproduce, and acceptance criteria.\n3. Create Issue with the team ID, title, description, and a priority that matches severity.\n4. Optionally Add Label to Issue for type and area labels using IDs from List Labels.\n\n## Output\nThe created issue ID, its identifier and URL, and the team, priority, and labels applied.', - }, - { - name: 'triage-new-issue', - description: - 'Read a Linear issue, apply type and priority labels, set assignee and state, and comment a triage summary.', - content: - '# Triage New Issue\n\nTriage an incoming Linear issue so it lands in the right place with the right metadata.\n\n## Steps\n1. Get Issue to read the title and description.\n2. Determine the issue type, priority, and owning area from the content.\n3. Add Label to Issue for type and priority, and Update Issue to set the assignee, state, and priority.\n4. Create Comment with a short triage summary explaining the classification and next step.\n\n## Output\nThe issue identifier, the labels added, the assignee and state set, and the triage comment posted.', - }, - { - name: 'summarize-active-cycle', - description: - 'Pull completed and open issues in the active cycle and produce a sprint progress digest.', - content: - '# Summarize Active Cycle\n\nProduce a sprint review digest from the current Linear cycle.\n\n## Steps\n1. Get Active Cycle for the team to find the current cycle.\n2. Read Issues or Search Issues scoped to that cycle, separating completed from still-open issues.\n3. Compute counts, completion percentage, and call out blocked or at-risk issues by priority.\n4. Summarize progress, blockers, and what is likely to slip.\n\n## Output\nA digest with completed vs open counts, completion percentage, a list of blockers, and a short narrative of cycle health.', - }, - { - name: 'post-project-update', - description: - 'Assess a Linear project and post a project update with a health status and progress summary.', - content: - '# Post Project Update\n\nWrite a stakeholder-ready project update in Linear.\n\n## Steps\n1. Get Project to read its current state, target date, and lead.\n2. Read Issues for the project to gauge progress against the milestone or target date.\n3. Decide a health status of on track, at risk, or off track based on remaining work and timeline.\n4. Create Project Update with the chosen health and a concise body covering progress, risks, and next steps.\n\n## Output\nConfirmation of the posted update, the health status chosen, and the update body.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linkedin.display.ts b/apps/sim/blocks/blocks/linkedin.display.ts index d82d534f4f9..5e136d1a0dd 100644 --- a/apps/sim/blocks/blocks/linkedin.display.ts +++ b/apps/sim/blocks/blocks/linkedin.display.ts @@ -1,6 +1,6 @@ import { LinkedInIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LinkedInBlockDisplay = { type: 'linkedin', @@ -15,3 +15,96 @@ export const LinkedInBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/linkedin', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const LinkedInBlockMeta = { + tags: ['marketing', 'sales-engagement'], + url: 'https://www.linkedin.com', + templates: [ + { + icon: LinkedInIcon, + title: 'LinkedIn content engine', + prompt: + 'Build a workflow that scrapes my company blog for new posts, generates LinkedIn posts with hooks, insights, and calls-to-action optimized for engagement, and saves drafts as files for my review before posting to LinkedIn.', + modules: ['agent', 'files', 'scheduled', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: LinkedInIcon, + title: 'LinkedIn news-to-post writer', + prompt: + 'Build a scheduled workflow that searches the web for news in my industry, drafts a short take with a hook and a call-to-action for each top story, and shares the best one to my LinkedIn feed.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: LinkedInIcon, + title: 'LinkedIn launch announcer', + prompt: + 'Create a workflow that on a launch trigger from a table drafts a LinkedIn announcement post with the key details and a link, shares it to my LinkedIn feed, and marks the row as posted.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: LinkedInIcon, + title: 'LinkedIn weekly recap poster', + prompt: + 'Build a scheduled weekly workflow that summarizes the week’s wins from a table, drafts a recap post with an agent, and shares it to my LinkedIn feed.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: LinkedInIcon, + title: 'LinkedIn content scheduler', + prompt: + 'Create a workflow that reads a tables-based LinkedIn content calendar, posts each entry at the scheduled time, and writes the post URL back to the row.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: LinkedInIcon, + title: 'Blog-to-LinkedIn repurposer', + prompt: + 'Build a workflow that on a newly published blog post drafts a punchy LinkedIn post summarizing the key insight with an agent, shares it to my LinkedIn profile, and logs the post URL to a content table for tracking.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: LinkedInIcon, + title: 'LinkedIn thought-leadership cadence', + prompt: + 'Create a scheduled workflow that picks the next idea from a content table, expands it into a full LinkedIn post with an agent, shares it to my LinkedIn feed, and logs the publish time back to the row.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + ], + skills: [ + { + name: 'publish-linkedin-post', + description: + 'Draft and share a post to your LinkedIn feed with a hook, value, and a clear call-to-action.', + content: + '# Publish LinkedIn Post\n\nWrite and publish an engagement-optimized post to your LinkedIn feed.\n\n## Steps\n1. Take the source idea, article, or update to post about.\n2. Draft post text with a strong first-line hook, two to three lines of value or insight, and a clear call-to-action, kept within LinkedIn length limits.\n3. Share Post with the drafted text and a visibility of PUBLIC or CONNECTIONS.\n\n## Output\nConfirmation the post was shared, the created post ID, and the final post text used.', + }, + { + name: 'repurpose-content-to-post', + description: + 'Turn a blog post, release note, or announcement into a punchy LinkedIn post and share it.', + content: + '# Repurpose Content to Post\n\nRepurpose long-form content into a native LinkedIn post.\n\n## Steps\n1. Read the source content and pull out the single most compelling insight or takeaway.\n2. Rewrite it as a standalone LinkedIn post with a hook, a concise body, and a call-to-action or link.\n3. Share Post with PUBLIC visibility.\n\n## Output\nThe published post ID and the post text, plus a note of the source it was derived from.', + }, + { + name: 'get-my-profile', + description: + 'Fetch your LinkedIn profile information for use in downstream personalization or logging.', + content: + '# Get My Profile\n\nRetrieve your authenticated LinkedIn profile.\n\n## Steps\n1. Run Get Profile to fetch the connected account profile.\n2. Extract the fields you need, such as name and identifiers, for personalization or record-keeping.\n\n## Output\nThe profile JSON and a short summary of the key fields available.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linkedin.ts b/apps/sim/blocks/blocks/linkedin.ts index eb9b6e87211..bdf1d380150 100644 --- a/apps/sim/blocks/blocks/linkedin.ts +++ b/apps/sim/blocks/blocks/linkedin.ts @@ -1,7 +1,6 @@ -import { LinkedInIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { LinkedInBlockDisplay } from '@/blocks/blocks/linkedin.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { LinkedInResponse } from '@/tools/linkedin/types' @@ -114,96 +113,3 @@ export const LinkedInBlock: BlockConfig = { error: { type: 'string', description: 'Error message if operation failed' }, }, } - -export const LinkedInBlockMeta = { - tags: ['marketing', 'sales-engagement'], - url: 'https://www.linkedin.com', - templates: [ - { - icon: LinkedInIcon, - title: 'LinkedIn content engine', - prompt: - 'Build a workflow that scrapes my company blog for new posts, generates LinkedIn posts with hooks, insights, and calls-to-action optimized for engagement, and saves drafts as files for my review before posting to LinkedIn.', - modules: ['agent', 'files', 'scheduled', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: LinkedInIcon, - title: 'LinkedIn news-to-post writer', - prompt: - 'Build a scheduled workflow that searches the web for news in my industry, drafts a short take with a hook and a call-to-action for each top story, and shares the best one to my LinkedIn feed.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: LinkedInIcon, - title: 'LinkedIn launch announcer', - prompt: - 'Create a workflow that on a launch trigger from a table drafts a LinkedIn announcement post with the key details and a link, shares it to my LinkedIn feed, and marks the row as posted.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: LinkedInIcon, - title: 'LinkedIn weekly recap poster', - prompt: - 'Build a scheduled weekly workflow that summarizes the week’s wins from a table, drafts a recap post with an agent, and shares it to my LinkedIn feed.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: LinkedInIcon, - title: 'LinkedIn content scheduler', - prompt: - 'Create a workflow that reads a tables-based LinkedIn content calendar, posts each entry at the scheduled time, and writes the post URL back to the row.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: LinkedInIcon, - title: 'Blog-to-LinkedIn repurposer', - prompt: - 'Build a workflow that on a newly published blog post drafts a punchy LinkedIn post summarizing the key insight with an agent, shares it to my LinkedIn profile, and logs the post URL to a content table for tracking.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: LinkedInIcon, - title: 'LinkedIn thought-leadership cadence', - prompt: - 'Create a scheduled workflow that picks the next idea from a content table, expands it into a full LinkedIn post with an agent, shares it to my LinkedIn feed, and logs the publish time back to the row.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - ], - skills: [ - { - name: 'publish-linkedin-post', - description: - 'Draft and share a post to your LinkedIn feed with a hook, value, and a clear call-to-action.', - content: - '# Publish LinkedIn Post\n\nWrite and publish an engagement-optimized post to your LinkedIn feed.\n\n## Steps\n1. Take the source idea, article, or update to post about.\n2. Draft post text with a strong first-line hook, two to three lines of value or insight, and a clear call-to-action, kept within LinkedIn length limits.\n3. Share Post with the drafted text and a visibility of PUBLIC or CONNECTIONS.\n\n## Output\nConfirmation the post was shared, the created post ID, and the final post text used.', - }, - { - name: 'repurpose-content-to-post', - description: - 'Turn a blog post, release note, or announcement into a punchy LinkedIn post and share it.', - content: - '# Repurpose Content to Post\n\nRepurpose long-form content into a native LinkedIn post.\n\n## Steps\n1. Read the source content and pull out the single most compelling insight or takeaway.\n2. Rewrite it as a standalone LinkedIn post with a hook, a concise body, and a call-to-action or link.\n3. Share Post with PUBLIC visibility.\n\n## Output\nThe published post ID and the post text, plus a note of the source it was derived from.', - }, - { - name: 'get-my-profile', - description: - 'Fetch your LinkedIn profile information for use in downstream personalization or logging.', - content: - '# Get My Profile\n\nRetrieve your authenticated LinkedIn profile.\n\n## Steps\n1. Run Get Profile to fetch the connected account profile.\n2. Extract the fields you need, such as name and identifiers, for personalization or record-keeping.\n\n## Output\nThe profile JSON and a short summary of the key fields available.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linkup.display.ts b/apps/sim/blocks/blocks/linkup.display.ts index 41f0454db85..d37e10861ba 100644 --- a/apps/sim/blocks/blocks/linkup.display.ts +++ b/apps/sim/blocks/blocks/linkup.display.ts @@ -1,6 +1,6 @@ import { LinkupIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LinkupBlockDisplay = { type: 'linkup', @@ -13,3 +13,99 @@ export const LinkupBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/linkup', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const LinkupBlockMeta = { + tags: ['web-scraping', 'enrichment'], + url: 'https://www.linkup.so', + templates: [ + { + icon: LinkupIcon, + title: 'Linkup research agent', + prompt: + 'Build a research agent that uses Linkup to find authoritative sources on a topic, returns answers with citations, and saves long-form research to a knowledge base.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: LinkupIcon, + title: 'Linkup daily digest', + prompt: + 'Create a scheduled daily workflow that runs Linkup searches on tracked topics, summarizes the top hits with citations, and emails the user a research digest.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: LinkupIcon, + title: 'Linkup competitor monitor', + prompt: + 'Build a scheduled workflow that runs Linkup searches for competitor mentions weekly, scores each by relevance, and writes a log to a tables-based competitive intel base.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: LinkupIcon, + title: 'Linkup CRM account refresh', + prompt: + 'Create a scheduled workflow that for accounts in the CRM runs Linkup research on each weekly, surfaces new signals, and writes the digest into the account record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: LinkupIcon, + title: 'Linkup + Slack research bot', + prompt: + 'Build a Slack bot that answers research questions with Linkup-grounded citations, hands off to a human on low-confidence answers, and logs each conversation.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: LinkupIcon, + title: 'Linkup deep-research file', + prompt: + 'Create a workflow that for a chosen topic runs Linkup deep research, captures the structured findings, and writes a full report file with citations.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + { + icon: LinkupIcon, + title: 'Linkup pipeline-research feeder', + prompt: + 'Build a workflow that takes a list of accounts in a research table, runs Linkup on each for the latest news, and writes findings back to the row.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + ], + skills: [ + { + name: 'answer-with-citations', + description: + 'Answer a question with Linkup using a sourced answer and surface the supporting source URLs.', + content: + '# Answer with Citations\n\nGround an answer in live web facts using Linkup.\n\n## Steps\n1. Set the search query to the user question, phrased clearly.\n2. Choose the Answer output type and include sources so the response carries verifiable URLs.\n3. Use Deep search depth for complex or multi-part questions, otherwise Standard.\n4. Present the answer and attach the source links.\n\n## Output\nA concise answer followed by a list of the source URLs that support it.', + }, + { + name: 'gather-research-sources', + description: + 'Run a Linkup search and return a ranked list of relevant sources with snippets for a topic.', + content: + '# Gather Research Sources\n\nCollect authoritative sources on a topic for downstream research.\n\n## Steps\n1. Set the search query to the research topic, narrowing with key terms.\n2. Choose the Search output type to get raw results with sources.\n3. Optionally restrict or exclude domains, and set a from and to date to bound recency.\n4. Review the returned sources and order them by relevance.\n\n## Output\nA ranked list of sources with titles, URLs, and snippets, ready to feed a summarizer or knowledge base.', + }, + { + name: 'monitor-topic-mentions', + description: + 'Search Linkup for recent mentions of a topic, competitor, or brand within a date window.', + content: + '# Monitor Topic Mentions\n\nTrack fresh mentions of a topic or competitor.\n\n## Steps\n1. Set the search query to the brand, competitor, or topic to monitor.\n2. Use the Search output type and set the from date to the start of the window you want to cover.\n3. Optionally restrict to news or specific domains.\n4. Filter the results to genuinely new or relevant mentions and summarize each.\n\n## Output\nA list of new mentions with source URL, date, and a one-line summary of each.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linkup.ts b/apps/sim/blocks/blocks/linkup.ts index 3c85133b02e..b3881f658db 100644 --- a/apps/sim/blocks/blocks/linkup.ts +++ b/apps/sim/blocks/blocks/linkup.ts @@ -1,6 +1,5 @@ -import { LinkupIcon } from '@/components/icons' import { LinkupBlockDisplay } from '@/blocks/blocks/linkup.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { LinkupSearchToolResponse } from '@/tools/linkup/types' export const LinkupBlock: BlockConfig = { @@ -147,99 +146,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n sources: { type: 'json', description: 'Source references' }, }, } - -export const LinkupBlockMeta = { - tags: ['web-scraping', 'enrichment'], - url: 'https://www.linkup.so', - templates: [ - { - icon: LinkupIcon, - title: 'Linkup research agent', - prompt: - 'Build a research agent that uses Linkup to find authoritative sources on a topic, returns answers with citations, and saves long-form research to a knowledge base.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: LinkupIcon, - title: 'Linkup daily digest', - prompt: - 'Create a scheduled daily workflow that runs Linkup searches on tracked topics, summarizes the top hits with citations, and emails the user a research digest.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: LinkupIcon, - title: 'Linkup competitor monitor', - prompt: - 'Build a scheduled workflow that runs Linkup searches for competitor mentions weekly, scores each by relevance, and writes a log to a tables-based competitive intel base.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: LinkupIcon, - title: 'Linkup CRM account refresh', - prompt: - 'Create a scheduled workflow that for accounts in the CRM runs Linkup research on each weekly, surfaces new signals, and writes the digest into the account record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: LinkupIcon, - title: 'Linkup + Slack research bot', - prompt: - 'Build a Slack bot that answers research questions with Linkup-grounded citations, hands off to a human on low-confidence answers, and logs each conversation.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: LinkupIcon, - title: 'Linkup deep-research file', - prompt: - 'Create a workflow that for a chosen topic runs Linkup deep research, captures the structured findings, and writes a full report file with citations.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - { - icon: LinkupIcon, - title: 'Linkup pipeline-research feeder', - prompt: - 'Build a workflow that takes a list of accounts in a research table, runs Linkup on each for the latest news, and writes findings back to the row.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - ], - skills: [ - { - name: 'answer-with-citations', - description: - 'Answer a question with Linkup using a sourced answer and surface the supporting source URLs.', - content: - '# Answer with Citations\n\nGround an answer in live web facts using Linkup.\n\n## Steps\n1. Set the search query to the user question, phrased clearly.\n2. Choose the Answer output type and include sources so the response carries verifiable URLs.\n3. Use Deep search depth for complex or multi-part questions, otherwise Standard.\n4. Present the answer and attach the source links.\n\n## Output\nA concise answer followed by a list of the source URLs that support it.', - }, - { - name: 'gather-research-sources', - description: - 'Run a Linkup search and return a ranked list of relevant sources with snippets for a topic.', - content: - '# Gather Research Sources\n\nCollect authoritative sources on a topic for downstream research.\n\n## Steps\n1. Set the search query to the research topic, narrowing with key terms.\n2. Choose the Search output type to get raw results with sources.\n3. Optionally restrict or exclude domains, and set a from and to date to bound recency.\n4. Review the returned sources and order them by relevance.\n\n## Output\nA ranked list of sources with titles, URLs, and snippets, ready to feed a summarizer or knowledge base.', - }, - { - name: 'monitor-topic-mentions', - description: - 'Search Linkup for recent mentions of a topic, competitor, or brand within a date window.', - content: - '# Monitor Topic Mentions\n\nTrack fresh mentions of a topic or competitor.\n\n## Steps\n1. Set the search query to the brand, competitor, or topic to monitor.\n2. Use the Search output type and set the from date to the start of the window you want to cover.\n3. Optionally restrict to news or specific domains.\n4. Filter the results to genuinely new or relevant mentions and summarize each.\n\n## Output\nA list of new mentions with source URL, date, and a one-line summary of each.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linq.display.ts b/apps/sim/blocks/blocks/linq.display.ts index 1e2a31aa03a..29376c22970 100644 --- a/apps/sim/blocks/blocks/linq.display.ts +++ b/apps/sim/blocks/blocks/linq.display.ts @@ -1,6 +1,6 @@ import { LinqIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LinqBlockDisplay = { type: 'linq', @@ -14,3 +14,60 @@ export const LinqBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/linq', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const LinqBlockMeta = { + tags: ['messaging', 'automation', 'webhooks'], + url: 'https://www.linqapp.com', + templates: [ + { + icon: LinqIcon, + title: 'Linq iMessage campaign sender', + prompt: + 'Build a workflow that reads a contact list from a table, composes a personalized iMessage for each recipient using an agent, and sends them via Linq in batches.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['messaging', 'automation'], + }, + { + icon: LinqIcon, + title: 'Linq SMS support responder', + prompt: + 'Create a scheduled workflow that lists recent unread Linq messages, generates a reply for each with an agent, and sends the response back to the same chat.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['messaging', 'support'], + }, + { + icon: LinqIcon, + title: 'Linq RCS notification dispatcher', + prompt: + 'Build a workflow that monitors a table for new alert rows, formats an RCS notification for each, and dispatches it to the relevant phone number via Linq.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation'], + }, + ], + skills: [ + { + name: 'send-personalized-message', + description: + 'Start a Linq chat and send a personalized iMessage, SMS, or RCS message to a recipient.', + content: + '# Send Personalized Message\n\nReach a person on iMessage, SMS, or RCS through Linq.\n\n## Steps\n1. Create Chat with your sending number in From and the recipient handle in To.\n2. Draft a friendly, concise message body tailored to the recipient.\n3. Send Message to the chat with the message text, optionally setting a preferred service or media URL.\n4. Optionally Check iMessage or Check RCS first to pick the best service for the recipient.\n\n## Output\nThe chat ID, the message ID, the delivery service used, and the delivery status.', + }, + { + name: 'respond-to-unread-messages', + description: + 'List recent Linq chats and messages, draft a reply for each unread conversation, and send it.', + content: + '# Respond to Unread Messages\n\nClear an inbox by replying to recent unread Linq conversations.\n\n## Steps\n1. List Chats to find active conversations, then List Messages per chat to find unread inbound messages.\n2. For each conversation needing a reply, read the recent thread for context.\n3. Draft a relevant reply.\n4. Send Message to that chat ID with the drafted text.\n\n## Output\nFor each handled chat: the chat ID, the reply sent, and the delivery status.', + }, + { + name: 'dispatch-alert-notifications', + description: + 'Send an RCS or SMS notification to one or more recipients from a list of alerts.', + content: + '# Dispatch Alert Notifications\n\nFan out notifications to recipients through Linq.\n\n## Steps\n1. Take the list of recipients and the alert content to send.\n2. For each recipient, Create Chat from your sending number to their handle.\n3. Format a clear notification message and Send Message, setting the preferred service to RCS or SMS as needed.\n4. Use an idempotency key per message so retries do not double-send.\n\n## Output\nA per-recipient list of chat IDs, message IDs, and delivery statuses.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/linq.ts b/apps/sim/blocks/blocks/linq.ts index 1e64b55d8e6..cd2f3cdb1c3 100644 --- a/apps/sim/blocks/blocks/linq.ts +++ b/apps/sim/blocks/blocks/linq.ts @@ -1,6 +1,5 @@ -import { LinqIcon } from '@/components/icons' import { LinqBlockDisplay } from '@/blocks/blocks/linq.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' @@ -856,60 +855,3 @@ export const LinqBlock: BlockConfig = { docUrl: { type: 'string', description: 'Documentation URL' }, }, } - -export const LinqBlockMeta = { - tags: ['messaging', 'automation', 'webhooks'], - url: 'https://www.linqapp.com', - templates: [ - { - icon: LinqIcon, - title: 'Linq iMessage campaign sender', - prompt: - 'Build a workflow that reads a contact list from a table, composes a personalized iMessage for each recipient using an agent, and sends them via Linq in batches.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['messaging', 'automation'], - }, - { - icon: LinqIcon, - title: 'Linq SMS support responder', - prompt: - 'Create a scheduled workflow that lists recent unread Linq messages, generates a reply for each with an agent, and sends the response back to the same chat.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['messaging', 'support'], - }, - { - icon: LinqIcon, - title: 'Linq RCS notification dispatcher', - prompt: - 'Build a workflow that monitors a table for new alert rows, formats an RCS notification for each, and dispatches it to the relevant phone number via Linq.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation'], - }, - ], - skills: [ - { - name: 'send-personalized-message', - description: - 'Start a Linq chat and send a personalized iMessage, SMS, or RCS message to a recipient.', - content: - '# Send Personalized Message\n\nReach a person on iMessage, SMS, or RCS through Linq.\n\n## Steps\n1. Create Chat with your sending number in From and the recipient handle in To.\n2. Draft a friendly, concise message body tailored to the recipient.\n3. Send Message to the chat with the message text, optionally setting a preferred service or media URL.\n4. Optionally Check iMessage or Check RCS first to pick the best service for the recipient.\n\n## Output\nThe chat ID, the message ID, the delivery service used, and the delivery status.', - }, - { - name: 'respond-to-unread-messages', - description: - 'List recent Linq chats and messages, draft a reply for each unread conversation, and send it.', - content: - '# Respond to Unread Messages\n\nClear an inbox by replying to recent unread Linq conversations.\n\n## Steps\n1. List Chats to find active conversations, then List Messages per chat to find unread inbound messages.\n2. For each conversation needing a reply, read the recent thread for context.\n3. Draft a relevant reply.\n4. Send Message to that chat ID with the drafted text.\n\n## Output\nFor each handled chat: the chat ID, the reply sent, and the delivery status.', - }, - { - name: 'dispatch-alert-notifications', - description: - 'Send an RCS or SMS notification to one or more recipients from a list of alerts.', - content: - '# Dispatch Alert Notifications\n\nFan out notifications to recipients through Linq.\n\n## Steps\n1. Take the list of recipients and the alert content to send.\n2. For each recipient, Create Chat from your sending number to their handle.\n3. Format a clear notification message and Send Message, setting the preferred service to RCS or SMS as needed.\n4. Use an idempotency key per message so retries do not double-send.\n\n## Output\nA per-recipient list of chat IDs, message IDs, and delivery statuses.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/loops.display.ts b/apps/sim/blocks/blocks/loops.display.ts index db93be14d45..2cb2ab02ea4 100644 --- a/apps/sim/blocks/blocks/loops.display.ts +++ b/apps/sim/blocks/blocks/loops.display.ts @@ -1,6 +1,6 @@ import { LoopsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LoopsBlockDisplay = { type: 'loops', @@ -14,3 +14,103 @@ export const LoopsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/loops', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const LoopsBlockMeta = { + tags: ['email-marketing', 'marketing', 'automation'], + url: 'https://loops.so', + templates: [ + { + icon: LoopsIcon, + title: 'Loops product event tracker', + prompt: + 'Build a workflow that listens for product events from my tables, sends matching Loops events for each user with structured properties, and updates contact properties so Loops automations can branch on real product behavior.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'product'], + }, + { + icon: LoopsIcon, + title: 'Loops list hygiene', + prompt: + 'Create a scheduled workflow that reads a Sim table of user activity to find accounts inactive for 90 days, updates each contact in Loops to the dormant user group and unsubscribes them from non-essential mailing lists, and writes a hygiene report to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'analysis'], + }, + { + icon: LoopsIcon, + title: 'Loops onboarding orchestrator', + prompt: + 'Build a workflow triggered on signup that creates a Loops contact, kicks off the onboarding event sequence, and updates user group as the user completes activation steps so the right Loops email goes out at every milestone.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + { + icon: LoopsIcon, + title: 'Loops contact property enricher', + prompt: + 'Create a scheduled workflow that reads a Sim table of contacts missing key custom properties, enriches each one using Clay or web research, updates the matching contact in Loops with the new properties, and tracks enrichment coverage in a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm', 'sync'], + alsoIntegrations: ['clay'], + }, + { + icon: LoopsIcon, + title: 'Loops signup welcome flow', + prompt: + 'Build a workflow that on a new product signup creates the contact in Loops with their plan and source, sends a transactional welcome email, and fires a signup event so the onboarding campaign starts automatically.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + { + icon: LoopsIcon, + title: 'Loops milestone event sender', + prompt: + 'Create a workflow that watches product usage in a table for key milestones — first integration, team invite, plan upgrade — and sends the matching Loops event for each so lifecycle emails fire on real behavior instead of guesses.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'product'], + }, + { + icon: LoopsIcon, + title: 'Loops churn win-back', + prompt: + 'Build a scheduled workflow that reads a Sim table of product-usage data to identify users who have gone inactive, sends each a personalized transactional win-back email through Loops, fires a re-engagement event, and logs who was contacted to a table for follow-up.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + ], + skills: [ + { + name: 'onboard-new-contact', + description: 'Create a Loops contact on signup and send a transactional welcome email.', + content: + '# Onboard New Contact\n\nAdd a new signup to Loops and welcome them.\n\n## Steps\n1. Create Contact with the email, first and last name, and any source or user group, plus custom properties like plan.\n2. Send Transactional Email using the welcome template ID, passing the contact data as data variables.\n3. Optionally Send Event with a signup event name so any onboarding automation begins.\n\n## Output\nThe created contact ID, confirmation the welcome email was sent, and any event fired.', + }, + { + name: 'send-product-event', + description: + 'Fire a Loops event for a user with structured properties to trigger lifecycle automations.', + content: + '# Send Product Event\n\nDrive Loops automations from real product behavior.\n\n## Steps\n1. Identify the contact by email or user ID and the event that occurred.\n2. Build event properties as a JSON object with the relevant values, such as plan and amount.\n3. Send Event with the event name, the contact identifier, and the properties.\n4. Optionally update mailing list subscriptions in the same call.\n\n## Output\nConfirmation the event was sent, the contact it was attributed to, and the properties included.', + }, + { + name: 'enrich-contact-properties', + description: + 'Find a Loops contact and update it with enriched custom properties and user group.', + content: + '# Enrich Contact Properties\n\nKeep Loops contact data complete and current.\n\n## Steps\n1. Find Contact by email or user ID to read existing fields and spot gaps.\n2. Gather the missing or stale values from your source or research.\n3. Update Contact with the new custom properties, user group, and any name fields.\n\n## Output\nThe updated contact ID and a summary of the properties that were set or changed.', + }, + { + name: 'send-transactional-email', + description: + 'Send a Loops transactional email from a template with personalized data variables.', + content: + '# Send Transactional Email\n\nDeliver a templated transactional email through Loops.\n\n## Steps\n1. Confirm the transactional email template ID to use.\n2. Build the data variables JSON to match the variable names in the template, such as name and a confirmation URL.\n3. Send Transactional Email with the recipient email, template ID, and data variables, attaching files if needed.\n\n## Output\nConfirmation of send success and the template ID and recipient used.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/loops.ts b/apps/sim/blocks/blocks/loops.ts index 0657f0f7f3b..643aa279da7 100644 --- a/apps/sim/blocks/blocks/loops.ts +++ b/apps/sim/blocks/blocks/loops.ts @@ -1,6 +1,5 @@ -import { LoopsIcon } from '@/components/icons' import { LoopsBlockDisplay } from '@/blocks/blocks/loops.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { LoopsResponse } from '@/tools/loops/types' @@ -527,103 +526,3 @@ Return ONLY the JSON object - no explanations, no extra text.`, }, }, } - -export const LoopsBlockMeta = { - tags: ['email-marketing', 'marketing', 'automation'], - url: 'https://loops.so', - templates: [ - { - icon: LoopsIcon, - title: 'Loops product event tracker', - prompt: - 'Build a workflow that listens for product events from my tables, sends matching Loops events for each user with structured properties, and updates contact properties so Loops automations can branch on real product behavior.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'product'], - }, - { - icon: LoopsIcon, - title: 'Loops list hygiene', - prompt: - 'Create a scheduled workflow that reads a Sim table of user activity to find accounts inactive for 90 days, updates each contact in Loops to the dormant user group and unsubscribes them from non-essential mailing lists, and writes a hygiene report to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'analysis'], - }, - { - icon: LoopsIcon, - title: 'Loops onboarding orchestrator', - prompt: - 'Build a workflow triggered on signup that creates a Loops contact, kicks off the onboarding event sequence, and updates user group as the user completes activation steps so the right Loops email goes out at every milestone.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - { - icon: LoopsIcon, - title: 'Loops contact property enricher', - prompt: - 'Create a scheduled workflow that reads a Sim table of contacts missing key custom properties, enriches each one using Clay or web research, updates the matching contact in Loops with the new properties, and tracks enrichment coverage in a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm', 'sync'], - alsoIntegrations: ['clay'], - }, - { - icon: LoopsIcon, - title: 'Loops signup welcome flow', - prompt: - 'Build a workflow that on a new product signup creates the contact in Loops with their plan and source, sends a transactional welcome email, and fires a signup event so the onboarding campaign starts automatically.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - { - icon: LoopsIcon, - title: 'Loops milestone event sender', - prompt: - 'Create a workflow that watches product usage in a table for key milestones — first integration, team invite, plan upgrade — and sends the matching Loops event for each so lifecycle emails fire on real behavior instead of guesses.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'product'], - }, - { - icon: LoopsIcon, - title: 'Loops churn win-back', - prompt: - 'Build a scheduled workflow that reads a Sim table of product-usage data to identify users who have gone inactive, sends each a personalized transactional win-back email through Loops, fires a re-engagement event, and logs who was contacted to a table for follow-up.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - ], - skills: [ - { - name: 'onboard-new-contact', - description: 'Create a Loops contact on signup and send a transactional welcome email.', - content: - '# Onboard New Contact\n\nAdd a new signup to Loops and welcome them.\n\n## Steps\n1. Create Contact with the email, first and last name, and any source or user group, plus custom properties like plan.\n2. Send Transactional Email using the welcome template ID, passing the contact data as data variables.\n3. Optionally Send Event with a signup event name so any onboarding automation begins.\n\n## Output\nThe created contact ID, confirmation the welcome email was sent, and any event fired.', - }, - { - name: 'send-product-event', - description: - 'Fire a Loops event for a user with structured properties to trigger lifecycle automations.', - content: - '# Send Product Event\n\nDrive Loops automations from real product behavior.\n\n## Steps\n1. Identify the contact by email or user ID and the event that occurred.\n2. Build event properties as a JSON object with the relevant values, such as plan and amount.\n3. Send Event with the event name, the contact identifier, and the properties.\n4. Optionally update mailing list subscriptions in the same call.\n\n## Output\nConfirmation the event was sent, the contact it was attributed to, and the properties included.', - }, - { - name: 'enrich-contact-properties', - description: - 'Find a Loops contact and update it with enriched custom properties and user group.', - content: - '# Enrich Contact Properties\n\nKeep Loops contact data complete and current.\n\n## Steps\n1. Find Contact by email or user ID to read existing fields and spot gaps.\n2. Gather the missing or stale values from your source or research.\n3. Update Contact with the new custom properties, user group, and any name fields.\n\n## Output\nThe updated contact ID and a summary of the properties that were set or changed.', - }, - { - name: 'send-transactional-email', - description: - 'Send a Loops transactional email from a template with personalized data variables.', - content: - '# Send Transactional Email\n\nDeliver a templated transactional email through Loops.\n\n## Steps\n1. Confirm the transactional email template ID to use.\n2. Build the data variables JSON to match the variable names in the template, such as name and a confirmation URL.\n3. Send Transactional Email with the recipient email, template ID, and data variables, attaching files if needed.\n\n## Output\nConfirmation of send success and the template ID and recipient used.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/luma.display.ts b/apps/sim/blocks/blocks/luma.display.ts index 6809101f94f..8f114cd0df9 100644 --- a/apps/sim/blocks/blocks/luma.display.ts +++ b/apps/sim/blocks/blocks/luma.display.ts @@ -1,6 +1,6 @@ import { LumaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const LumaBlockDisplay = { type: 'luma', @@ -14,3 +14,122 @@ export const LumaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/luma', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const LumaBlockMeta = { + tags: ['events', 'calendar', 'scheduling'], + url: 'https://luma.com', + templates: [ + { + icon: LumaIcon, + title: 'Luma event reminder cadence', + prompt: + 'Create a workflow that sends scheduled reminders to Luma event registrants — 7 days, 24 hours, 1 hour out — with personalized content based on RSVP type.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: LumaIcon, + title: 'Luma registrant enricher', + prompt: + 'Build a scheduled workflow that pulls the Luma event guest list, enriches each registrant with company data via Apollo, and pushes high-value attendees into HubSpot as leads.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['apollo', 'hubspot'], + }, + { + icon: LumaIcon, + title: 'Luma post-event followup', + prompt: + 'Create a scheduled workflow that runs the day after a Luma event, pulls the guest list, segments attendees from no-shows, sends each segment a tailored followup, and writes attendance to the CRM.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['gmail', 'hubspot'], + }, + { + icon: LumaIcon, + title: 'Luma calendar import', + prompt: + 'Build a scheduled workflow that pulls the Luma event guest list and creates a personalized Google Calendar invite for each new registrant with the event details, location, and prep links.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: LumaIcon, + title: 'Luma + Discord community sync', + prompt: + 'Create a scheduled workflow that pulls the Luma event guest list and adds each new registrant to the matching Discord community channel with the right role for event access.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['community', 'communication'], + alsoIntegrations: ['discord'], + }, + { + icon: LumaIcon, + title: 'Luma event-series analytics', + prompt: + 'Build a scheduled workflow that pulls Luma event-series data, calculates conversion from registration to attendance to next action, and writes the analytics to a report file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: LumaIcon, + title: 'Luma new-registrant welcome', + prompt: + 'Create a scheduled workflow that pulls the Luma event guest list, finds registrants added since the last run, and sends each a personalized welcome email with what to expect and how to prepare.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'create-event', + description: + 'Create a Luma event with a name, start time, timezone, description, and visibility.', + content: + '# Create Event\n\nSpin up a new Luma event ready to share.\n\n## Steps\n1. Decide the event name, start time as an ISO 8601 timestamp, and the IANA timezone.\n2. Create Event with those fields plus an optional end time or duration, a Markdown description, and a meeting URL for virtual events.\n3. Set visibility to public, members-only, or private as appropriate.\n\n## Output\nThe created event ID and URL, with its start time, timezone, and visibility.', + }, + { + name: 'add-guests-to-event', + description: 'Add a batch of guests to a Luma event from a list of emails and names.', + content: + '# Add Guests to Event\n\nBulk-register guests on a Luma event.\n\n## Steps\n1. Confirm the target event ID.\n2. Build the guests JSON array, one object per guest with an email and optional name or first and last name.\n3. Add Guests with the event ID and the guest array.\n\n## Output\nConfirmation of how many guests were added and the event ID they were added to.', + }, + { + name: 'export-guest-list', + description: + 'Pull a Luma event guest list, optionally filtered by approval status, for follow-up or enrichment.', + content: + '# Export Guest List\n\nRetrieve registrants for an event.\n\n## Steps\n1. Get Guests for the event ID, optionally filtering by approval status such as approved or waitlist.\n2. Page through results using the limit and pagination cursor until the full list is collected.\n3. Extract the fields you need, such as email, name, approval status, and registered or checked-in timestamps.\n\n## Output\nThe full guest list with key fields, ready to segment attendees from no-shows or feed into a CRM.', + }, + { + name: 'send-event-reminders', + description: + 'Pull the Luma guest list and prepare personalized reminders for upcoming registrants.', + content: + '# Send Event Reminders\n\nPrepare reminder content for an upcoming Luma event.\n\n## Steps\n1. Get Event to read the name, start time, timezone, and meeting or location details.\n2. Get Guests filtered to approved registrants, paging until complete.\n3. For each guest, draft a personalized reminder with the event time in their context and the join or location info.\n\n## Output\nA per-guest list of email addresses and drafted reminder messages, ready to hand to an email or messaging step.', + }, + { + name: 'triage-event-registrations', + description: + 'Review pending Luma registrations and approve, waitlist, or decline each guest.', + content: + '# Triage Event Registrations\n\nProcess pending registrations for an event with limited capacity.\n\n## Steps\n1. Get Guests filtered to the pending_approval status, paging until complete.\n2. Apply your approval criteria to each registrant (for example, work email domain or registration answers).\n3. Update Guest Status for each guest to approved, waitlist, or declined, identifying them by email or guest ID.\n\n## Output\nEach pending guest moved to a final approval status, with the applied status reported back per guest.', + }, + { + name: 'invite-guests-to-event', + description: + 'Email Luma event invitations to a list of prospects with an optional custom message.', + content: + '# Invite Guests to Event\n\nSend invitations that recipients can accept, rather than registering them outright.\n\n## Steps\n1. Confirm the target event ID.\n2. Build a guests JSON array, one object per invitee with an email and optional name.\n3. Send Invites with the event ID, the guest array, and an optional short message.\n\n## Output\nThe count of guests invited, ready to log or report.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/luma.ts b/apps/sim/blocks/blocks/luma.ts index d76f5b0b3d6..e06715b086b 100644 --- a/apps/sim/blocks/blocks/luma.ts +++ b/apps/sim/blocks/blocks/luma.ts @@ -1,6 +1,5 @@ -import { LumaIcon } from '@/components/icons' import { LumaBlockDisplay } from '@/blocks/blocks/luma.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' export const LumaBlock: BlockConfig = { ...LumaBlockDisplay, @@ -536,122 +535,3 @@ Return ONLY the ISO 8601 timestamp - no explanations, no quotes, no extra text.` apiId: { type: 'string', description: 'Resolved event API ID (Lookup Event operation)' }, }, } - -export const LumaBlockMeta = { - tags: ['events', 'calendar', 'scheduling'], - url: 'https://luma.com', - templates: [ - { - icon: LumaIcon, - title: 'Luma event reminder cadence', - prompt: - 'Create a workflow that sends scheduled reminders to Luma event registrants — 7 days, 24 hours, 1 hour out — with personalized content based on RSVP type.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: LumaIcon, - title: 'Luma registrant enricher', - prompt: - 'Build a scheduled workflow that pulls the Luma event guest list, enriches each registrant with company data via Apollo, and pushes high-value attendees into HubSpot as leads.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['apollo', 'hubspot'], - }, - { - icon: LumaIcon, - title: 'Luma post-event followup', - prompt: - 'Create a scheduled workflow that runs the day after a Luma event, pulls the guest list, segments attendees from no-shows, sends each segment a tailored followup, and writes attendance to the CRM.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['gmail', 'hubspot'], - }, - { - icon: LumaIcon, - title: 'Luma calendar import', - prompt: - 'Build a scheduled workflow that pulls the Luma event guest list and creates a personalized Google Calendar invite for each new registrant with the event details, location, and prep links.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: LumaIcon, - title: 'Luma + Discord community sync', - prompt: - 'Create a scheduled workflow that pulls the Luma event guest list and adds each new registrant to the matching Discord community channel with the right role for event access.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['community', 'communication'], - alsoIntegrations: ['discord'], - }, - { - icon: LumaIcon, - title: 'Luma event-series analytics', - prompt: - 'Build a scheduled workflow that pulls Luma event-series data, calculates conversion from registration to attendance to next action, and writes the analytics to a report file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: LumaIcon, - title: 'Luma new-registrant welcome', - prompt: - 'Create a scheduled workflow that pulls the Luma event guest list, finds registrants added since the last run, and sends each a personalized welcome email with what to expect and how to prepare.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'create-event', - description: - 'Create a Luma event with a name, start time, timezone, description, and visibility.', - content: - '# Create Event\n\nSpin up a new Luma event ready to share.\n\n## Steps\n1. Decide the event name, start time as an ISO 8601 timestamp, and the IANA timezone.\n2. Create Event with those fields plus an optional end time or duration, a Markdown description, and a meeting URL for virtual events.\n3. Set visibility to public, members-only, or private as appropriate.\n\n## Output\nThe created event ID and URL, with its start time, timezone, and visibility.', - }, - { - name: 'add-guests-to-event', - description: 'Add a batch of guests to a Luma event from a list of emails and names.', - content: - '# Add Guests to Event\n\nBulk-register guests on a Luma event.\n\n## Steps\n1. Confirm the target event ID.\n2. Build the guests JSON array, one object per guest with an email and optional name or first and last name.\n3. Add Guests with the event ID and the guest array.\n\n## Output\nConfirmation of how many guests were added and the event ID they were added to.', - }, - { - name: 'export-guest-list', - description: - 'Pull a Luma event guest list, optionally filtered by approval status, for follow-up or enrichment.', - content: - '# Export Guest List\n\nRetrieve registrants for an event.\n\n## Steps\n1. Get Guests for the event ID, optionally filtering by approval status such as approved or waitlist.\n2. Page through results using the limit and pagination cursor until the full list is collected.\n3. Extract the fields you need, such as email, name, approval status, and registered or checked-in timestamps.\n\n## Output\nThe full guest list with key fields, ready to segment attendees from no-shows or feed into a CRM.', - }, - { - name: 'send-event-reminders', - description: - 'Pull the Luma guest list and prepare personalized reminders for upcoming registrants.', - content: - '# Send Event Reminders\n\nPrepare reminder content for an upcoming Luma event.\n\n## Steps\n1. Get Event to read the name, start time, timezone, and meeting or location details.\n2. Get Guests filtered to approved registrants, paging until complete.\n3. For each guest, draft a personalized reminder with the event time in their context and the join or location info.\n\n## Output\nA per-guest list of email addresses and drafted reminder messages, ready to hand to an email or messaging step.', - }, - { - name: 'triage-event-registrations', - description: - 'Review pending Luma registrations and approve, waitlist, or decline each guest.', - content: - '# Triage Event Registrations\n\nProcess pending registrations for an event with limited capacity.\n\n## Steps\n1. Get Guests filtered to the pending_approval status, paging until complete.\n2. Apply your approval criteria to each registrant (for example, work email domain or registration answers).\n3. Update Guest Status for each guest to approved, waitlist, or declined, identifying them by email or guest ID.\n\n## Output\nEach pending guest moved to a final approval status, with the applied status reported back per guest.', - }, - { - name: 'invite-guests-to-event', - description: - 'Email Luma event invitations to a list of prospects with an optional custom message.', - content: - '# Invite Guests to Event\n\nSend invitations that recipients can accept, rather than registering them outright.\n\n## Steps\n1. Confirm the target event ID.\n2. Build a guests JSON array, one object per invitee with an email and optional name.\n3. Send Invites with the event ID, the guest array, and an optional short message.\n\n## Output\nThe count of guests invited, ready to log or report.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mailchimp.display.ts b/apps/sim/blocks/blocks/mailchimp.display.ts index 595b24daddd..ba5094da8b9 100644 --- a/apps/sim/blocks/blocks/mailchimp.display.ts +++ b/apps/sim/blocks/blocks/mailchimp.display.ts @@ -1,6 +1,7 @@ +import { Mail } from '@/components/emcn/icons' import { MailchimpIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MailchimpBlockDisplay = { type: 'mailchimp', @@ -14,3 +15,106 @@ export const MailchimpBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/mailchimp', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const MailchimpBlockMeta = { + tags: ['email-marketing', 'marketing', 'automation'], + url: 'https://mailchimp.com', + templates: [ + { + icon: Mail, + title: 'Newsletter curator', + prompt: + 'Create a scheduled weekly workflow that scrapes my favorite industry news sites and blogs, picks the top stories relevant to my audience, writes summaries for each, and drafts a ready-to-send newsletter in Mailchimp.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'communication'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp re-engagement campaign', + prompt: + 'Build a workflow that finds Mailchimp members who have not opened or clicked in 90 days, drafts a re-engagement campaign with a personalized subject line per segment, and schedules it to send to those members only.', + modules: ['agent', 'scheduled', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp + SendGrid hybrid sender', + prompt: + 'Create a workflow that uses Mailchimp for marketing audience management and segmentation but sends the actual campaign through SendGrid for deliverability, syncing send results, opens, and clicks back to the Mailchimp audience as merge fields.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'sync', 'enterprise'], + alsoIntegrations: ['sendgrid'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp campaign performance digest', + prompt: + 'Build a scheduled workflow that pulls the previous week of Mailchimp campaign reports, compares open and click rates against my benchmarks, and posts a Slack digest with the winners, losers, and one-line takeaways.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp + Loops audience sync', + prompt: + 'Create a workflow that keeps a Mailchimp audience and a Loops mailing list in sync: new Mailchimp subscribers create Loops contacts on the matching list, unsubscribes propagate both ways, and merge fields map cleanly to Loops contact properties.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'sync', 'automation'], + alsoIntegrations: ['loops'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp event-driven blast', + prompt: + 'Build a workflow that listens for a launch trigger from my tables, populates a Mailchimp campaign template with the launch details, schedules it to the right segment, and logs the campaign ID and recipient count back to the table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + { + icon: MailchimpIcon, + title: 'Mailchimp segment builder from HubSpot', + prompt: + 'Create a workflow that reads HubSpot lifecycle stage and ICP fields, upserts each contact into Mailchimp with the matching tags and merge fields, and recomputes named segments daily so marketing can target by CRM state.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm', 'sync'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'sync-contact-to-audience', + description: 'Add or update a contact in a Mailchimp audience with merge fields and tags.', + content: + '# Sync Contact to Audience\n\nKeep a Mailchimp audience in sync with your source of truth.\n\n## Steps\n1. If the audience is unknown, Get Audiences to find the right list ID.\n2. Use Add or Update Member with the email, subscription status, and merge fields like first and last name.\n3. Apply segmentation with Add Member Tags for lifecycle stage or ICP tags.\n\n## Output\nThe member ID and status in the audience, plus the merge fields and tags applied.', + }, + { + name: 'create-and-send-campaign', + description: + 'Create a Mailchimp campaign, set its content, and send or schedule it to an audience.', + content: + '# Create and Send Campaign\n\nLaunch an email campaign to an audience or segment.\n\n## Steps\n1. Create Campaign targeting the audience or a saved segment, with the subject line and from details.\n2. Set Campaign Content with the HTML or a template ID.\n3. Send Campaign immediately, or Schedule Campaign for a future send time.\n\n## Output\nThe campaign ID, the audience or segment targeted, and whether it was sent or scheduled with the send time.', + }, + { + name: 'build-targeted-segment', + description: + 'Create a Mailchimp segment from conditions so a campaign can target a specific slice of an audience.', + content: + '# Build Targeted Segment\n\nDefine a reusable audience segment for targeting.\n\n## Steps\n1. Identify the audience and the conditions that define the segment, such as tags, merge field values, or activity.\n2. Create Segment on that audience with the conditions and a clear name.\n3. Optionally Get Segment Members to verify the segment matches the intended contacts.\n\n## Output\nThe segment ID and name, the conditions used, and the count of matching members.', + }, + { + name: 'report-campaign-performance', + description: + 'Pull Mailchimp campaign reports and summarize open, click, and bounce performance.', + content: + '# Report Campaign Performance\n\nTurn Mailchimp report data into a readable summary.\n\n## Steps\n1. Get Campaign Reports for the recent window, or Get Campaign Report for a specific campaign ID.\n2. Extract opens, clicks, bounces, and unsubscribes per campaign.\n3. Compute open rate, click rate, and bounce rate and flag campaigns that underperformed.\n\n## Output\nA per-campaign metrics summary with rates and a short list of underperformers worth revisiting.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mailchimp.ts b/apps/sim/blocks/blocks/mailchimp.ts index 8b9075b160d..f37ab4484fd 100644 --- a/apps/sim/blocks/blocks/mailchimp.ts +++ b/apps/sim/blocks/blocks/mailchimp.ts @@ -1,7 +1,5 @@ -import { Mail } from '@/components/emcn/icons' -import { MailchimpIcon } from '@/components/icons' import { MailchimpBlockDisplay } from '@/blocks/blocks/mailchimp.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const MailchimpBlock: BlockConfig = { @@ -1452,106 +1450,3 @@ Return ONLY the JSON array - no explanations or markdown.`, output: { type: 'json', description: 'Operation result data' }, }, } - -export const MailchimpBlockMeta = { - tags: ['email-marketing', 'marketing', 'automation'], - url: 'https://mailchimp.com', - templates: [ - { - icon: Mail, - title: 'Newsletter curator', - prompt: - 'Create a scheduled weekly workflow that scrapes my favorite industry news sites and blogs, picks the top stories relevant to my audience, writes summaries for each, and drafts a ready-to-send newsletter in Mailchimp.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'communication'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp re-engagement campaign', - prompt: - 'Build a workflow that finds Mailchimp members who have not opened or clicked in 90 days, drafts a re-engagement campaign with a personalized subject line per segment, and schedules it to send to those members only.', - modules: ['agent', 'scheduled', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp + SendGrid hybrid sender', - prompt: - 'Create a workflow that uses Mailchimp for marketing audience management and segmentation but sends the actual campaign through SendGrid for deliverability, syncing send results, opens, and clicks back to the Mailchimp audience as merge fields.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'sync', 'enterprise'], - alsoIntegrations: ['sendgrid'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp campaign performance digest', - prompt: - 'Build a scheduled workflow that pulls the previous week of Mailchimp campaign reports, compares open and click rates against my benchmarks, and posts a Slack digest with the winners, losers, and one-line takeaways.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp + Loops audience sync', - prompt: - 'Create a workflow that keeps a Mailchimp audience and a Loops mailing list in sync: new Mailchimp subscribers create Loops contacts on the matching list, unsubscribes propagate both ways, and merge fields map cleanly to Loops contact properties.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'sync', 'automation'], - alsoIntegrations: ['loops'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp event-driven blast', - prompt: - 'Build a workflow that listens for a launch trigger from my tables, populates a Mailchimp campaign template with the launch details, schedules it to the right segment, and logs the campaign ID and recipient count back to the table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - { - icon: MailchimpIcon, - title: 'Mailchimp segment builder from HubSpot', - prompt: - 'Create a workflow that reads HubSpot lifecycle stage and ICP fields, upserts each contact into Mailchimp with the matching tags and merge fields, and recomputes named segments daily so marketing can target by CRM state.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm', 'sync'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'sync-contact-to-audience', - description: 'Add or update a contact in a Mailchimp audience with merge fields and tags.', - content: - '# Sync Contact to Audience\n\nKeep a Mailchimp audience in sync with your source of truth.\n\n## Steps\n1. If the audience is unknown, Get Audiences to find the right list ID.\n2. Use Add or Update Member with the email, subscription status, and merge fields like first and last name.\n3. Apply segmentation with Add Member Tags for lifecycle stage or ICP tags.\n\n## Output\nThe member ID and status in the audience, plus the merge fields and tags applied.', - }, - { - name: 'create-and-send-campaign', - description: - 'Create a Mailchimp campaign, set its content, and send or schedule it to an audience.', - content: - '# Create and Send Campaign\n\nLaunch an email campaign to an audience or segment.\n\n## Steps\n1. Create Campaign targeting the audience or a saved segment, with the subject line and from details.\n2. Set Campaign Content with the HTML or a template ID.\n3. Send Campaign immediately, or Schedule Campaign for a future send time.\n\n## Output\nThe campaign ID, the audience or segment targeted, and whether it was sent or scheduled with the send time.', - }, - { - name: 'build-targeted-segment', - description: - 'Create a Mailchimp segment from conditions so a campaign can target a specific slice of an audience.', - content: - '# Build Targeted Segment\n\nDefine a reusable audience segment for targeting.\n\n## Steps\n1. Identify the audience and the conditions that define the segment, such as tags, merge field values, or activity.\n2. Create Segment on that audience with the conditions and a clear name.\n3. Optionally Get Segment Members to verify the segment matches the intended contacts.\n\n## Output\nThe segment ID and name, the conditions used, and the count of matching members.', - }, - { - name: 'report-campaign-performance', - description: - 'Pull Mailchimp campaign reports and summarize open, click, and bounce performance.', - content: - '# Report Campaign Performance\n\nTurn Mailchimp report data into a readable summary.\n\n## Steps\n1. Get Campaign Reports for the recent window, or Get Campaign Report for a specific campaign ID.\n2. Extract opens, clicks, bounces, and unsubscribes per campaign.\n3. Compute open rate, click rate, and bounce rate and flag campaigns that underperformed.\n\n## Output\nA per-campaign metrics summary with rates and a short list of underperformers worth revisiting.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mailgun.display.ts b/apps/sim/blocks/blocks/mailgun.display.ts index be4d031187f..420ad234272 100644 --- a/apps/sim/blocks/blocks/mailgun.display.ts +++ b/apps/sim/blocks/blocks/mailgun.display.ts @@ -1,6 +1,6 @@ import { MailgunIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MailgunBlockDisplay = { type: 'mailgun', @@ -14,3 +14,105 @@ export const MailgunBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/mailgun', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const MailgunBlockMeta = { + tags: ['messaging', 'email-marketing'], + url: 'https://www.mailgun.com', + templates: [ + { + icon: MailgunIcon, + title: 'Mailgun mailing list builder', + prompt: + 'Create a scheduled workflow that watches a table of contact opt-ins, creates the matching Mailgun mailing lists by segment, adds each new opt-in as a member, and reports list health weekly to a tracking table.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'sync', 'automation'], + }, + { + icon: MailgunIcon, + title: 'Mailgun event analytics digest', + prompt: + 'Build a scheduled workflow that pulls Mailgun message events, aggregates deliveries, opens, clicks, and complaints by tag and domain, and posts a Slack digest with anomalies and the top-performing tags of the day.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: MailgunIcon, + title: 'Mailgun transactional sender', + prompt: + 'Create a workflow that receives a structured event from my application, picks the right Mailgun template and recipient, sends through Mailgun with tracking tags, then retrieves the stored message status for audit.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'communication'], + }, + { + icon: MailgunIcon, + title: 'Mailgun + Resend transactional fallback', + prompt: + 'Build a workflow that sends transactional emails through Mailgun by default and automatically falls back to Resend when Mailgun returns a send error or rate-limit response, normalizing the payload and writing every send and the provider used to a delivery table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'monitoring', 'enterprise'], + alsoIntegrations: ['resend'], + }, + { + icon: MailgunIcon, + title: 'Mailgun deliverability scorecard', + prompt: + 'Create a scheduled workflow that pulls Mailgun events for the previous week, computes per-domain deliverability, complaint rate, and bounce rate, and generates a scorecard file flagging any sending domain trending toward a deliverability problem.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting', 'monitoring'], + }, + { + icon: MailgunIcon, + title: 'Mailgun bounce list hygiene', + prompt: + 'Build a scheduled workflow that retrieves Mailgun bounce and complaint events, compiles the offending addresses into a suppression table, and posts a summary so the marketing team can audit and clean list hygiene.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'monitoring'], + }, + { + icon: MailgunIcon, + title: 'Mailgun domain verification monitor', + prompt: + 'Create a scheduled workflow that checks the status of each Mailgun sending domain, flags any domain whose SPF, DKIM, or tracking records fall out of verification, and pages the on-call engineer in Slack with the exact records that need fixing.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'send-transactional-email', + description: + 'Send a transactional email through a Mailgun sending domain to one or more recipients.', + content: + '# Send Transactional Email\n\nDeliver an email through Mailgun.\n\n## Steps\n1. Confirm the verified sending domain to use, listing domains first if unsure.\n2. Compose the message with from, to, subject, and an HTML or text body.\n3. Send Message with those fields, adding CC, BCC, or attachments as needed.\n\n## Output\nConfirmation of acceptance with the Mailgun message ID and the recipients it was queued to.', + }, + { + name: 'track-delivery-events', + description: + 'Pull Mailgun events filtered by type to see what was delivered, opened, clicked, or failed.', + content: + '# Track Delivery Events\n\nMonitor what happened to your Mailgun sends.\n\n## Steps\n1. List Messages or query events filtered by an event type such as delivered, failed, opened, or clicked.\n2. Group the events by recipient and by type to see delivery outcomes.\n3. Highlight failures and bounces that need attention.\n\n## Output\nA summary of event counts by type and a list of failed or bounced recipients.', + }, + { + name: 'sweep-bounces-and-complaints', + description: + 'Collect Mailgun failed and complained events and compile the offending addresses for suppression.', + content: + '# Sweep Bounces and Complaints\n\nKeep your list clean by capturing bad addresses.\n\n## Steps\n1. Query Mailgun events filtered to failed and complained types over the chosen window.\n2. Extract the recipient addresses and the reason for each.\n3. Compile a suppression list of addresses to stop mailing.\n\n## Output\nA list of bounced and complained addresses with reasons, ready to write to a suppression table.', + }, + { + name: 'add-member-to-list', + description: 'Create a Mailgun mailing list if needed and add a subscriber to it.', + content: + '# Add Member to List\n\nGrow a Mailgun mailing list.\n\n## Steps\n1. Get Mailing List to confirm the list exists, or Create Mailing List with the address and access level if it does not.\n2. Add List Member with the subscriber email and any name or variables.\n\n## Output\nConfirmation the member was added, the list address, and the member email.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mailgun.ts b/apps/sim/blocks/blocks/mailgun.ts index a95a7a886d9..c248739edb1 100644 --- a/apps/sim/blocks/blocks/mailgun.ts +++ b/apps/sim/blocks/blocks/mailgun.ts @@ -1,6 +1,5 @@ -import { MailgunIcon } from '@/components/icons' import { MailgunBlockDisplay } from '@/blocks/blocks/mailgun.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { SendMessageResult } from '@/tools/mailgun/types' export const MailgunBlock: BlockConfig = { @@ -402,105 +401,3 @@ Return ONLY the JSON object - no explanations or markdown.`, totalCount: { type: 'number', description: 'Total count of items' }, }, } - -export const MailgunBlockMeta = { - tags: ['messaging', 'email-marketing'], - url: 'https://www.mailgun.com', - templates: [ - { - icon: MailgunIcon, - title: 'Mailgun mailing list builder', - prompt: - 'Create a scheduled workflow that watches a table of contact opt-ins, creates the matching Mailgun mailing lists by segment, adds each new opt-in as a member, and reports list health weekly to a tracking table.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'sync', 'automation'], - }, - { - icon: MailgunIcon, - title: 'Mailgun event analytics digest', - prompt: - 'Build a scheduled workflow that pulls Mailgun message events, aggregates deliveries, opens, clicks, and complaints by tag and domain, and posts a Slack digest with anomalies and the top-performing tags of the day.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: MailgunIcon, - title: 'Mailgun transactional sender', - prompt: - 'Create a workflow that receives a structured event from my application, picks the right Mailgun template and recipient, sends through Mailgun with tracking tags, then retrieves the stored message status for audit.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'communication'], - }, - { - icon: MailgunIcon, - title: 'Mailgun + Resend transactional fallback', - prompt: - 'Build a workflow that sends transactional emails through Mailgun by default and automatically falls back to Resend when Mailgun returns a send error or rate-limit response, normalizing the payload and writing every send and the provider used to a delivery table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'monitoring', 'enterprise'], - alsoIntegrations: ['resend'], - }, - { - icon: MailgunIcon, - title: 'Mailgun deliverability scorecard', - prompt: - 'Create a scheduled workflow that pulls Mailgun events for the previous week, computes per-domain deliverability, complaint rate, and bounce rate, and generates a scorecard file flagging any sending domain trending toward a deliverability problem.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting', 'monitoring'], - }, - { - icon: MailgunIcon, - title: 'Mailgun bounce list hygiene', - prompt: - 'Build a scheduled workflow that retrieves Mailgun bounce and complaint events, compiles the offending addresses into a suppression table, and posts a summary so the marketing team can audit and clean list hygiene.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'monitoring'], - }, - { - icon: MailgunIcon, - title: 'Mailgun domain verification monitor', - prompt: - 'Create a scheduled workflow that checks the status of each Mailgun sending domain, flags any domain whose SPF, DKIM, or tracking records fall out of verification, and pages the on-call engineer in Slack with the exact records that need fixing.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'send-transactional-email', - description: - 'Send a transactional email through a Mailgun sending domain to one or more recipients.', - content: - '# Send Transactional Email\n\nDeliver an email through Mailgun.\n\n## Steps\n1. Confirm the verified sending domain to use, listing domains first if unsure.\n2. Compose the message with from, to, subject, and an HTML or text body.\n3. Send Message with those fields, adding CC, BCC, or attachments as needed.\n\n## Output\nConfirmation of acceptance with the Mailgun message ID and the recipients it was queued to.', - }, - { - name: 'track-delivery-events', - description: - 'Pull Mailgun events filtered by type to see what was delivered, opened, clicked, or failed.', - content: - '# Track Delivery Events\n\nMonitor what happened to your Mailgun sends.\n\n## Steps\n1. List Messages or query events filtered by an event type such as delivered, failed, opened, or clicked.\n2. Group the events by recipient and by type to see delivery outcomes.\n3. Highlight failures and bounces that need attention.\n\n## Output\nA summary of event counts by type and a list of failed or bounced recipients.', - }, - { - name: 'sweep-bounces-and-complaints', - description: - 'Collect Mailgun failed and complained events and compile the offending addresses for suppression.', - content: - '# Sweep Bounces and Complaints\n\nKeep your list clean by capturing bad addresses.\n\n## Steps\n1. Query Mailgun events filtered to failed and complained types over the chosen window.\n2. Extract the recipient addresses and the reason for each.\n3. Compile a suppression list of addresses to stop mailing.\n\n## Output\nA list of bounced and complained addresses with reasons, ready to write to a suppression table.', - }, - { - name: 'add-member-to-list', - description: 'Create a Mailgun mailing list if needed and add a subscriber to it.', - content: - '# Add Member to List\n\nGrow a Mailgun mailing list.\n\n## Steps\n1. Get Mailing List to confirm the list exists, or Create Mailing List with the address and access level if it does not.\n2. Add List Member with the subscriber email and any name or variables.\n\n## Output\nConfirmation the member was added, the list address, and the member email.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mem0.display.ts b/apps/sim/blocks/blocks/mem0.display.ts index 3fbc6468451..8f4cb390b4a 100644 --- a/apps/sim/blocks/blocks/mem0.display.ts +++ b/apps/sim/blocks/blocks/mem0.display.ts @@ -1,6 +1,6 @@ import { Mem0Icon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const Mem0BlockDisplay = { type: 'mem0', @@ -13,3 +13,100 @@ export const Mem0BlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/mem0', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const Mem0BlockMeta = { + tags: ['llm', 'knowledge-base', 'agentic'], + url: 'https://mem0.ai', + templates: [ + { + icon: Mem0Icon, + title: 'Mem0 long-term agent memory', + prompt: + 'Build an agent that uses Mem0 to remember user preferences and prior conversations across sessions, so follow-up requests reference real history instead of starting from scratch.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: Mem0Icon, + title: 'Mem0 sales-assistant memory', + prompt: + 'Create a sales agent that persists per-account context in Mem0 — last call notes, open objections, agreed next steps — so every rep starts a follow-up call already up to speed.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + }, + { + icon: Mem0Icon, + title: 'Mem0 + Zep hybrid memory agent', + prompt: + 'Create a chat agent that uses Mem0 for persistent user preferences and Zep for in-session continuity, so the agent recalls long-term context while staying coherent turn-to-turn.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + alsoIntegrations: ['zep'], + }, + { + icon: Mem0Icon, + title: 'Mem0 + Slack assistant memory', + prompt: + 'Build a Slack bot that uses Mem0 to remember user preferences and prior conversations, so each follow-up question lands in context instead of starting fresh.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: Mem0Icon, + title: 'Mem0 + Notion personal-knowledge agent', + prompt: + 'Create an agent that uses Mem0 to recall personal context and Notion as the source-of-truth knowledge base, answering questions with citations plus user-specific memory.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + alsoIntegrations: ['notion'], + }, + { + icon: Mem0Icon, + title: 'Mem0 customer-preference store', + prompt: + 'Build a workflow that captures customer preferences from support interactions into Mem0 keyed by account, so future automations reference the real preferences.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'crm'], + alsoIntegrations: ['zendesk'], + }, + { + icon: Mem0Icon, + title: 'Mem0 onboarding-context agent', + prompt: + 'Create an onboarding agent that adds each new user’s role, goals, and stack to Mem0 on first contact, then searches that memory on every later session so guidance stays tailored to the individual instead of generic.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation', 'onboarding'], + }, + ], + skills: [ + { + name: 'remember-user-context', + description: + 'Store new facts and preferences for a user in Mem0 from the latest conversation.', + content: + '# Remember User Context\n\nPersist what you learned about a user so future sessions stay informed.\n\n## Steps\n1. Identify the user ID this memory belongs to.\n2. Build the messages array from the relevant conversation turns as role and content objects.\n3. Add Memories with the user ID and messages so Mem0 extracts and stores the durable facts.\n\n## Output\nConfirmation the memories were added for the user, with the IDs of the facts created.', + }, + { + name: 'recall-relevant-memories', + description: + "Search a user's Mem0 memories for the facts relevant to the current request before answering.", + content: + '# Recall Relevant Memories\n\nGround a response in what Mem0 already knows about the user.\n\n## Steps\n1. Identify the user ID.\n2. Phrase a search query that captures the current request or topic.\n3. Search Memories with the user ID and query.\n4. Use the returned memories as context when drafting the answer.\n\n## Output\nThe most relevant memories for the user and a note of how they should shape the response.', + }, + { + name: 'review-stored-memories', + description: + "Retrieve a user's stored Mem0 memories, optionally within a date range, to audit what is known.", + content: + "# Review Stored Memories\n\nInspect what Mem0 holds for a user.\n\n## Steps\n1. Identify the user ID.\n2. Get Memories for that user, optionally bounding by a start and end date or a specific memory ID.\n3. Page through results if there are many.\n4. Summarize the stored facts and flag anything stale or contradictory.\n\n## Output\nA readable list of the user's stored memories with a short summary and any items worth updating.", + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mem0.ts b/apps/sim/blocks/blocks/mem0.ts index 347603428ea..e958565615a 100644 --- a/apps/sim/blocks/blocks/mem0.ts +++ b/apps/sim/blocks/blocks/mem0.ts @@ -1,7 +1,6 @@ import { toError } from '@sim/utils/errors' -import { Mem0Icon } from '@/components/icons' import { Mem0BlockDisplay } from '@/blocks/blocks/mem0.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { Mem0Response } from '@/tools/mem0/types' import { parseMem0Messages } from '@/tools/mem0/utils' @@ -264,100 +263,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n previous: { type: 'string', description: 'Previous page URL for get operations' }, }, } - -export const Mem0BlockMeta = { - tags: ['llm', 'knowledge-base', 'agentic'], - url: 'https://mem0.ai', - templates: [ - { - icon: Mem0Icon, - title: 'Mem0 long-term agent memory', - prompt: - 'Build an agent that uses Mem0 to remember user preferences and prior conversations across sessions, so follow-up requests reference real history instead of starting from scratch.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: Mem0Icon, - title: 'Mem0 sales-assistant memory', - prompt: - 'Create a sales agent that persists per-account context in Mem0 — last call notes, open objections, agreed next steps — so every rep starts a follow-up call already up to speed.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - }, - { - icon: Mem0Icon, - title: 'Mem0 + Zep hybrid memory agent', - prompt: - 'Create a chat agent that uses Mem0 for persistent user preferences and Zep for in-session continuity, so the agent recalls long-term context while staying coherent turn-to-turn.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - alsoIntegrations: ['zep'], - }, - { - icon: Mem0Icon, - title: 'Mem0 + Slack assistant memory', - prompt: - 'Build a Slack bot that uses Mem0 to remember user preferences and prior conversations, so each follow-up question lands in context instead of starting fresh.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: Mem0Icon, - title: 'Mem0 + Notion personal-knowledge agent', - prompt: - 'Create an agent that uses Mem0 to recall personal context and Notion as the source-of-truth knowledge base, answering questions with citations plus user-specific memory.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - alsoIntegrations: ['notion'], - }, - { - icon: Mem0Icon, - title: 'Mem0 customer-preference store', - prompt: - 'Build a workflow that captures customer preferences from support interactions into Mem0 keyed by account, so future automations reference the real preferences.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'crm'], - alsoIntegrations: ['zendesk'], - }, - { - icon: Mem0Icon, - title: 'Mem0 onboarding-context agent', - prompt: - 'Create an onboarding agent that adds each new user’s role, goals, and stack to Mem0 on first contact, then searches that memory on every later session so guidance stays tailored to the individual instead of generic.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation', 'onboarding'], - }, - ], - skills: [ - { - name: 'remember-user-context', - description: - 'Store new facts and preferences for a user in Mem0 from the latest conversation.', - content: - '# Remember User Context\n\nPersist what you learned about a user so future sessions stay informed.\n\n## Steps\n1. Identify the user ID this memory belongs to.\n2. Build the messages array from the relevant conversation turns as role and content objects.\n3. Add Memories with the user ID and messages so Mem0 extracts and stores the durable facts.\n\n## Output\nConfirmation the memories were added for the user, with the IDs of the facts created.', - }, - { - name: 'recall-relevant-memories', - description: - "Search a user's Mem0 memories for the facts relevant to the current request before answering.", - content: - '# Recall Relevant Memories\n\nGround a response in what Mem0 already knows about the user.\n\n## Steps\n1. Identify the user ID.\n2. Phrase a search query that captures the current request or topic.\n3. Search Memories with the user ID and query.\n4. Use the returned memories as context when drafting the answer.\n\n## Output\nThe most relevant memories for the user and a note of how they should shape the response.', - }, - { - name: 'review-stored-memories', - description: - "Retrieve a user's stored Mem0 memories, optionally within a date range, to audit what is known.", - content: - "# Review Stored Memories\n\nInspect what Mem0 holds for a user.\n\n## Steps\n1. Identify the user ID.\n2. Get Memories for that user, optionally bounding by a start and end date or a specific memory ID.\n3. Page through results if there are many.\n4. Summarize the stored facts and flag anything stale or contradictory.\n\n## Output\nA readable list of the user's stored memories with a short summary and any items worth updating.", - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_ad.display.ts b/apps/sim/blocks/blocks/microsoft_ad.display.ts index fc5827d0da5..c1d1f9406f5 100644 --- a/apps/sim/blocks/blocks/microsoft_ad.display.ts +++ b/apps/sim/blocks/blocks/microsoft_ad.display.ts @@ -1,6 +1,6 @@ import { AzureIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MicrosoftAdBlockDisplay = { type: 'microsoft_ad', @@ -14,3 +14,100 @@ export const MicrosoftAdBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/microsoft_ad', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const MicrosoftAdBlockMeta = { + tags: ['identity', 'microsoft-365'], + url: 'https://www.microsoft.com/security/business/identity-access/microsoft-entra-id', + templates: [ + { + icon: AzureIcon, + title: 'Azure AD provisioning', + prompt: + 'Build a workflow that on a Workday new-hire event creates the Azure AD user account, assigns the right group memberships, and writes the provisioning record to an audit table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: AzureIcon, + title: 'Azure AD offboarding sweep', + prompt: + 'Create a workflow that on a Workday termination disables the Azure AD account, removes its group memberships, and writes the security audit record.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: AzureIcon, + title: 'Azure AD access review', + prompt: + 'Build a scheduled quarterly workflow that lists Azure AD group memberships, requests owner attestation in Microsoft Teams, and writes the audit log to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: AzureIcon, + title: 'Azure AD password-age reminder', + prompt: + 'Create a scheduled workflow that lists Azure AD users, flags accounts whose last password change is older than the policy window, sends targeted reset reminders, and writes the compliance audit.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + }, + { + icon: AzureIcon, + title: 'Azure AD stale-account sweeper', + prompt: + 'Build a scheduled workflow that lists Azure AD accounts inactive for 90+ days, requests owner re-attestation, and disables accounts that fail attestation.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + }, + { + icon: AzureIcon, + title: 'Azure AD privileged-group auditor', + prompt: + 'Create a scheduled monthly workflow that lists the members of privileged Azure AD groups, requests owner attestation for each, and writes the review to an audit table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: AzureIcon, + title: 'Azure AD privileged-access monitor', + prompt: + 'Build a scheduled workflow that lists privileged Azure AD group members each run, compares against the last snapshot in a table, and pings the security Microsoft Teams channel on any add or removal.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['microsoft_teams'], + }, + ], + skills: [ + { + name: 'provision-new-user', + description: + 'Create a new Azure AD (Entra ID) user account and add it to the right groups. Use when onboarding an employee or contractor.', + content: + '# Provision New User\n\nCreate an Azure AD user and grant initial group access.\n\n## Steps\n1. Use Create User with the required fields: display name, mail nickname, user principal name (e.g. name@yourdomain.com), and an initial password. Set Account Enabled to Yes.\n2. Fill optional profile fields when available: first name, last name, job title, department, office location, and mobile phone.\n3. For each group the person should belong to, resolve the group with Get Group or List Groups, then call Add Group Member with the new user id.\n4. Confirm membership with List Group Members.\n\n## Output\nReturn the created user id, user principal name, and the list of groups they were added to. If a username collision or password-policy error occurs, report it clearly instead of retrying blindly.', + }, + { + name: 'offboard-user', + description: + 'Disable an Azure AD account and strip its group memberships when someone leaves. Use for secure offboarding.', + content: + '# Offboard User\n\nRevoke access for a departing user.\n\n## Steps\n1. Resolve the account with Get User by user principal name or id.\n2. Use Update User to set Account Enabled to No so the user can no longer sign in.\n3. Use List Group Members or the user record to enumerate the groups the user belongs to.\n4. For each group, call Remove Group Member with the user id.\n\n## Output\nReturn the disabled user id and the list of groups the user was removed from. Note any group where removal failed so it can be handled manually, and recommend writing the action to an audit record.', + }, + { + name: 'audit-group-membership', + description: + 'List the members of an Azure AD group for an access review. Use for periodic attestation of privileged or sensitive groups.', + content: + '# Audit Group Membership\n\nProduce a current membership snapshot for a group.\n\n## Steps\n1. Resolve the target group with Get Group or List Groups (filter or search by name).\n2. Call List Group Members for the group id, raising Max Results if the group is large.\n3. For each member, optionally call Get User to enrich with job title, department, and account-enabled status.\n\n## Output\nReturn a table of members with id, display name, email, department, and whether the account is enabled. Highlight disabled or stale accounts that still hold membership and should be reviewed for removal.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_ad.ts b/apps/sim/blocks/blocks/microsoft_ad.ts index 15fa52a1176..29d03a40a07 100644 --- a/apps/sim/blocks/blocks/microsoft_ad.ts +++ b/apps/sim/blocks/blocks/microsoft_ad.ts @@ -1,7 +1,6 @@ -import { AzureIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MicrosoftAdBlockDisplay } from '@/blocks/blocks/microsoft_ad.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { MicrosoftAdResponse } from '@/tools/microsoft_ad/types' @@ -386,100 +385,3 @@ export const MicrosoftAdBlock: BlockConfig = { }, }, } - -export const MicrosoftAdBlockMeta = { - tags: ['identity', 'microsoft-365'], - url: 'https://www.microsoft.com/security/business/identity-access/microsoft-entra-id', - templates: [ - { - icon: AzureIcon, - title: 'Azure AD provisioning', - prompt: - 'Build a workflow that on a Workday new-hire event creates the Azure AD user account, assigns the right group memberships, and writes the provisioning record to an audit table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: AzureIcon, - title: 'Azure AD offboarding sweep', - prompt: - 'Create a workflow that on a Workday termination disables the Azure AD account, removes its group memberships, and writes the security audit record.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: AzureIcon, - title: 'Azure AD access review', - prompt: - 'Build a scheduled quarterly workflow that lists Azure AD group memberships, requests owner attestation in Microsoft Teams, and writes the audit log to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: AzureIcon, - title: 'Azure AD password-age reminder', - prompt: - 'Create a scheduled workflow that lists Azure AD users, flags accounts whose last password change is older than the policy window, sends targeted reset reminders, and writes the compliance audit.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - }, - { - icon: AzureIcon, - title: 'Azure AD stale-account sweeper', - prompt: - 'Build a scheduled workflow that lists Azure AD accounts inactive for 90+ days, requests owner re-attestation, and disables accounts that fail attestation.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - }, - { - icon: AzureIcon, - title: 'Azure AD privileged-group auditor', - prompt: - 'Create a scheduled monthly workflow that lists the members of privileged Azure AD groups, requests owner attestation for each, and writes the review to an audit table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: AzureIcon, - title: 'Azure AD privileged-access monitor', - prompt: - 'Build a scheduled workflow that lists privileged Azure AD group members each run, compares against the last snapshot in a table, and pings the security Microsoft Teams channel on any add or removal.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['microsoft_teams'], - }, - ], - skills: [ - { - name: 'provision-new-user', - description: - 'Create a new Azure AD (Entra ID) user account and add it to the right groups. Use when onboarding an employee or contractor.', - content: - '# Provision New User\n\nCreate an Azure AD user and grant initial group access.\n\n## Steps\n1. Use Create User with the required fields: display name, mail nickname, user principal name (e.g. name@yourdomain.com), and an initial password. Set Account Enabled to Yes.\n2. Fill optional profile fields when available: first name, last name, job title, department, office location, and mobile phone.\n3. For each group the person should belong to, resolve the group with Get Group or List Groups, then call Add Group Member with the new user id.\n4. Confirm membership with List Group Members.\n\n## Output\nReturn the created user id, user principal name, and the list of groups they were added to. If a username collision or password-policy error occurs, report it clearly instead of retrying blindly.', - }, - { - name: 'offboard-user', - description: - 'Disable an Azure AD account and strip its group memberships when someone leaves. Use for secure offboarding.', - content: - '# Offboard User\n\nRevoke access for a departing user.\n\n## Steps\n1. Resolve the account with Get User by user principal name or id.\n2. Use Update User to set Account Enabled to No so the user can no longer sign in.\n3. Use List Group Members or the user record to enumerate the groups the user belongs to.\n4. For each group, call Remove Group Member with the user id.\n\n## Output\nReturn the disabled user id and the list of groups the user was removed from. Note any group where removal failed so it can be handled manually, and recommend writing the action to an audit record.', - }, - { - name: 'audit-group-membership', - description: - 'List the members of an Azure AD group for an access review. Use for periodic attestation of privileged or sensitive groups.', - content: - '# Audit Group Membership\n\nProduce a current membership snapshot for a group.\n\n## Steps\n1. Resolve the target group with Get Group or List Groups (filter or search by name).\n2. Call List Group Members for the group id, raising Max Results if the group is large.\n3. For each member, optionally call Get User to enrich with job title, department, and account-enabled status.\n\n## Output\nReturn a table of members with id, display name, email, department, and whether the account is enabled. Highlight disabled or stale accounts that still hold membership and should be reviewed for removal.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_dataverse.display.ts b/apps/sim/blocks/blocks/microsoft_dataverse.display.ts index 8b220fb9c69..96d577ad356 100644 --- a/apps/sim/blocks/blocks/microsoft_dataverse.display.ts +++ b/apps/sim/blocks/blocks/microsoft_dataverse.display.ts @@ -1,6 +1,6 @@ import { MicrosoftDataverseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MicrosoftDataverseBlockDisplay = { type: 'microsoft_dataverse', @@ -14,3 +14,104 @@ export const MicrosoftDataverseBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/microsoft_dataverse', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const MicrosoftDataverseBlockMeta = { + tags: ['microsoft-365', 'data-warehouse', 'cloud'], + url: 'https://www.microsoft.com/power-platform/dataverse', + templates: [ + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse record sync', + prompt: + 'Build a scheduled workflow that mirrors records between Microsoft Dataverse and a Sim table, normalizes schemas, and posts conflict reports to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + alsoIntegrations: ['slack'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse approval workflow', + prompt: + 'Create a scheduled workflow that polls Dataverse for new high-value records, posts an adaptive card approval to Microsoft Teams, captures the decision, and updates the record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse data-quality auditor', + prompt: + 'Build a scheduled workflow that scans Dataverse tables for missing required fields, format violations, and duplicates, and writes a remediation backlog to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse + Power BI feeder', + prompt: + 'Create a workflow that pulls Dataverse entity data daily, transforms it into BI-ready rows in a Sim table, and stages a refresh signal for downstream Power BI consumption.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse legacy CRM bridge', + prompt: + 'Build a workflow that mirrors Salesforce contacts into Microsoft Dataverse and back, mapping fields and resolving conflicts deterministically so both CRMs stay in sync during migration.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['crm', 'sync', 'enterprise'], + alsoIntegrations: ['salesforce'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse compliance archiver', + prompt: + 'Create a scheduled workflow that exports Dataverse records older than the retention horizon into long-term storage, removes them from the live table, and writes the archive manifest for auditors.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: MicrosoftDataverseIcon, + title: 'Dataverse case-routing agent', + prompt: + 'Build a workflow that runs a relevance search across Microsoft Dataverse case and account tables when a new support request arrives, classifies the issue, upserts the case record with the right owner and priority, and notifies the assigned team in Microsoft Teams.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'enterprise', 'automation'], + alsoIntegrations: ['microsoft_teams'], + }, + ], + skills: [ + { + name: 'upsert-record', + description: 'Create or update a record in a Dataverse table by its key without duplicating.', + content: + '# Upsert Record\n\nKeep a Dataverse table in sync from an external source without creating duplicates.\n\n## Steps\n1. Identify the target table and the key field that uniquely identifies the record.\n2. Map the incoming data to the table column names.\n3. Use Upsert Record so an existing match is updated and a new key creates a record.\n\n## Output\nThe record ID and whether it was created or updated, plus the fields written.', + }, + { + name: 'query-records', + description: 'List or query Dataverse records with filters and return the matching rows.', + content: + '# Query Records\n\nRetrieve a filtered set of rows from a Dataverse table.\n\n## Steps\n1. Choose the table to query.\n2. Use List Records with OData filters, selected columns, and ordering, or use a FetchXML Query for complex joins and aggregates.\n3. Page through results until the needed rows are collected.\n\n## Output\nThe matching records with the selected columns, ready for downstream processing.', + }, + { + name: 'relevance-search', + description: + 'Run a relevance search across Dataverse tables to find records matching a term.', + content: + '# Relevance Search\n\nFind records across Dataverse using full-text relevance search.\n\n## Steps\n1. Take the search term, such as a customer name or case keyword.\n2. Use Search with the term, choosing simple or Lucene query syntax and match-any or match-all behavior.\n3. Review the ranked matches and pick the relevant record.\n\n## Output\nA ranked list of matching records with their table and key fields.', + }, + { + name: 'bulk-write-records', + description: 'Create or update many Dataverse records in one batch operation.', + content: + '# Bulk Write Records\n\nWrite many Dataverse rows efficiently in a single call.\n\n## Steps\n1. Assemble the array of records, mapping each to the table column names.\n2. Use Create Multiple to insert new rows, or Update Multiple to change existing rows by ID.\n3. Verify the operation succeeded and capture any per-record errors.\n\n## Output\nThe count of records written, their IDs, and any rows that failed with their error.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_dataverse.ts b/apps/sim/blocks/blocks/microsoft_dataverse.ts index 9cfab9f99ca..e7af96609a0 100644 --- a/apps/sim/blocks/blocks/microsoft_dataverse.ts +++ b/apps/sim/blocks/blocks/microsoft_dataverse.ts @@ -1,7 +1,6 @@ -import { MicrosoftDataverseIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MicrosoftDataverseBlockDisplay } from '@/blocks/blocks/microsoft_dataverse.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { DataverseResponse } from '@/tools/microsoft_dataverse/types' @@ -583,104 +582,3 @@ Return ONLY the expand expression - no $expand= prefix, no explanations.`, fileColumn: { type: 'string', description: 'File column name' }, }, } - -export const MicrosoftDataverseBlockMeta = { - tags: ['microsoft-365', 'data-warehouse', 'cloud'], - url: 'https://www.microsoft.com/power-platform/dataverse', - templates: [ - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse record sync', - prompt: - 'Build a scheduled workflow that mirrors records between Microsoft Dataverse and a Sim table, normalizes schemas, and posts conflict reports to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - alsoIntegrations: ['slack'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse approval workflow', - prompt: - 'Create a scheduled workflow that polls Dataverse for new high-value records, posts an adaptive card approval to Microsoft Teams, captures the decision, and updates the record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse data-quality auditor', - prompt: - 'Build a scheduled workflow that scans Dataverse tables for missing required fields, format violations, and duplicates, and writes a remediation backlog to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse + Power BI feeder', - prompt: - 'Create a workflow that pulls Dataverse entity data daily, transforms it into BI-ready rows in a Sim table, and stages a refresh signal for downstream Power BI consumption.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse legacy CRM bridge', - prompt: - 'Build a workflow that mirrors Salesforce contacts into Microsoft Dataverse and back, mapping fields and resolving conflicts deterministically so both CRMs stay in sync during migration.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['crm', 'sync', 'enterprise'], - alsoIntegrations: ['salesforce'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse compliance archiver', - prompt: - 'Create a scheduled workflow that exports Dataverse records older than the retention horizon into long-term storage, removes them from the live table, and writes the archive manifest for auditors.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: MicrosoftDataverseIcon, - title: 'Dataverse case-routing agent', - prompt: - 'Build a workflow that runs a relevance search across Microsoft Dataverse case and account tables when a new support request arrives, classifies the issue, upserts the case record with the right owner and priority, and notifies the assigned team in Microsoft Teams.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'enterprise', 'automation'], - alsoIntegrations: ['microsoft_teams'], - }, - ], - skills: [ - { - name: 'upsert-record', - description: 'Create or update a record in a Dataverse table by its key without duplicating.', - content: - '# Upsert Record\n\nKeep a Dataverse table in sync from an external source without creating duplicates.\n\n## Steps\n1. Identify the target table and the key field that uniquely identifies the record.\n2. Map the incoming data to the table column names.\n3. Use Upsert Record so an existing match is updated and a new key creates a record.\n\n## Output\nThe record ID and whether it was created or updated, plus the fields written.', - }, - { - name: 'query-records', - description: 'List or query Dataverse records with filters and return the matching rows.', - content: - '# Query Records\n\nRetrieve a filtered set of rows from a Dataverse table.\n\n## Steps\n1. Choose the table to query.\n2. Use List Records with OData filters, selected columns, and ordering, or use a FetchXML Query for complex joins and aggregates.\n3. Page through results until the needed rows are collected.\n\n## Output\nThe matching records with the selected columns, ready for downstream processing.', - }, - { - name: 'relevance-search', - description: - 'Run a relevance search across Dataverse tables to find records matching a term.', - content: - '# Relevance Search\n\nFind records across Dataverse using full-text relevance search.\n\n## Steps\n1. Take the search term, such as a customer name or case keyword.\n2. Use Search with the term, choosing simple or Lucene query syntax and match-any or match-all behavior.\n3. Review the ranked matches and pick the relevant record.\n\n## Output\nA ranked list of matching records with their table and key fields.', - }, - { - name: 'bulk-write-records', - description: 'Create or update many Dataverse records in one batch operation.', - content: - '# Bulk Write Records\n\nWrite many Dataverse rows efficiently in a single call.\n\n## Steps\n1. Assemble the array of records, mapping each to the table column names.\n2. Use Create Multiple to insert new rows, or Update Multiple to change existing rows by ID.\n3. Verify the operation succeeded and capture any per-record errors.\n\n## Output\nThe count of records written, their IDs, and any rows that failed with their error.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_excel.display.ts b/apps/sim/blocks/blocks/microsoft_excel.display.ts index 4657ea12e06..ac7f43f0ddd 100644 --- a/apps/sim/blocks/blocks/microsoft_excel.display.ts +++ b/apps/sim/blocks/blocks/microsoft_excel.display.ts @@ -1,6 +1,6 @@ import { MicrosoftExcelIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MicrosoftExcelBlockDisplay = { type: 'microsoft_excel', @@ -29,3 +29,113 @@ export const MicrosoftExcelV2BlockDisplay = { integrationType: IntegrationType.Documents, hideFromToolbar: false, } satisfies BlockDisplay + +export const MicrosoftExcelBlockMeta = { + tags: ['spreadsheet', 'microsoft-365'], + url: 'https://www.microsoft.com/microsoft-365/excel', + templates: [ + { + icon: MicrosoftExcelIcon, + title: 'Excel financial close automator', + prompt: + 'Build a scheduled workflow that closes the books each period — pulls Stripe and accounting data, updates a Microsoft Excel close workbook, and emails the controller the reconciled file.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + alsoIntegrations: ['stripe', 'gmail'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel invoice generator', + prompt: + 'Create a workflow that reads a sales orders table, populates a Microsoft Excel invoice template per order, and saves the file to a SharePoint folder for finance review.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['sharepoint'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel pivot refresher', + prompt: + 'Build a scheduled workflow that refreshes a Microsoft Excel pivot table from a SQL source, exports the rendered snapshot, and posts the file link to a Microsoft Teams channel.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel + SharePoint forecast hub', + prompt: + 'Create a workflow that aggregates regional forecasts submitted in Microsoft Excel files on SharePoint, normalizes formats, and writes a consolidated forecast table for leadership.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + alsoIntegrations: ['sharepoint'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel commission calculator', + prompt: + 'Build a workflow that pulls closed Salesforce deals each month, computes commission per rep using a Microsoft Excel commission model, and emails the per-rep statements.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'finance'], + alsoIntegrations: ['salesforce', 'gmail'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel scenario modeler', + prompt: + 'Create a workflow that runs scenarios against a Microsoft Excel financial model — pessimistic, base, optimistic — captures outputs, and writes a comparison report to a finance file.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis'], + }, + { + icon: MicrosoftExcelIcon, + title: 'Excel + Power BI feeder', + prompt: + 'Build a scheduled workflow that updates a Microsoft Excel data table from a Sim source, refreshes the dependent Power BI dataset, and notifies BI consumers in Teams.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + ], + skills: [ + { + name: 'read-sheet-range', + description: 'Read data from a Microsoft Excel worksheet range and return the rows.', + content: + '# Read Sheet Range\n\nPull data out of an Excel workbook for analysis or downstream steps.\n\n## Steps\n1. Identify the workbook and the worksheet and range to read.\n2. Use Read Data with the spreadsheet ID and range.\n3. Parse the returned rows into a structured form for the next step.\n\n## Output\nThe values from the range as rows, plus the sheet and range they came from.', + }, + { + name: 'write-sheet-data', + description: + 'Write or update values in a Microsoft Excel worksheet range, with formula parsing control.', + content: + '# Write Sheet Data\n\nUpdate cells in an Excel workbook.\n\n## Steps\n1. Identify the workbook, worksheet, and target range.\n2. Prepare the values as rows matching the range shape.\n3. Use Write/Update Data, choosing User Entered to parse formulas or Raw to write values literally.\n\n## Output\nConfirmation of the cells updated and the range that was written.', + }, + { + name: 'append-table-row', + description: + 'Append a new row to a Microsoft Excel table so it stays structured and formatted.', + content: + '# Append Table Row\n\nAdd a record to an existing Excel table.\n\n## Steps\n1. Identify the workbook and the table to append to.\n2. Build the row values in the table column order.\n3. Use Add to Table to append the row so table formatting and references update automatically.\n\n## Output\nConfirmation the row was appended and the table it was added to.', + }, + { + name: 'add-worksheet', + description: + 'Add a new worksheet to a Microsoft Excel workbook to hold a new dataset or report.', + content: + '# Add Worksheet\n\nCreate a fresh worksheet inside a workbook.\n\n## Steps\n1. Identify the workbook to add the sheet to.\n2. Choose a name for the new worksheet.\n3. Use Add Worksheet to create it, then write headers or data with Write/Update Data if needed.\n\n## Output\nThe new worksheet name and confirmation it was created in the workbook.', + }, + ], +} as const satisfies BlockMeta + +export const MicrosoftExcelV2BlockMeta = { + tags: ['spreadsheet', 'microsoft-365'], + url: 'https://www.microsoft.com/microsoft-365/excel', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_excel.ts b/apps/sim/blocks/blocks/microsoft_excel.ts index 99e6be38430..2c1d8f5b8b7 100644 --- a/apps/sim/blocks/blocks/microsoft_excel.ts +++ b/apps/sim/blocks/blocks/microsoft_excel.ts @@ -1,10 +1,9 @@ -import { MicrosoftExcelIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MicrosoftExcelBlockDisplay, MicrosoftExcelV2BlockDisplay, } from '@/blocks/blocks/microsoft_excel.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { @@ -657,113 +656,3 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`, metadata: { type: 'json', description: 'Spreadsheet metadata including ID and URL' }, }, } - -export const MicrosoftExcelBlockMeta = { - tags: ['spreadsheet', 'microsoft-365'], - url: 'https://www.microsoft.com/microsoft-365/excel', - templates: [ - { - icon: MicrosoftExcelIcon, - title: 'Excel financial close automator', - prompt: - 'Build a scheduled workflow that closes the books each period — pulls Stripe and accounting data, updates a Microsoft Excel close workbook, and emails the controller the reconciled file.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - alsoIntegrations: ['stripe', 'gmail'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel invoice generator', - prompt: - 'Create a workflow that reads a sales orders table, populates a Microsoft Excel invoice template per order, and saves the file to a SharePoint folder for finance review.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['sharepoint'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel pivot refresher', - prompt: - 'Build a scheduled workflow that refreshes a Microsoft Excel pivot table from a SQL source, exports the rendered snapshot, and posts the file link to a Microsoft Teams channel.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel + SharePoint forecast hub', - prompt: - 'Create a workflow that aggregates regional forecasts submitted in Microsoft Excel files on SharePoint, normalizes formats, and writes a consolidated forecast table for leadership.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - alsoIntegrations: ['sharepoint'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel commission calculator', - prompt: - 'Build a workflow that pulls closed Salesforce deals each month, computes commission per rep using a Microsoft Excel commission model, and emails the per-rep statements.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'finance'], - alsoIntegrations: ['salesforce', 'gmail'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel scenario modeler', - prompt: - 'Create a workflow that runs scenarios against a Microsoft Excel financial model — pessimistic, base, optimistic — captures outputs, and writes a comparison report to a finance file.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis'], - }, - { - icon: MicrosoftExcelIcon, - title: 'Excel + Power BI feeder', - prompt: - 'Build a scheduled workflow that updates a Microsoft Excel data table from a Sim source, refreshes the dependent Power BI dataset, and notifies BI consumers in Teams.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - ], - skills: [ - { - name: 'read-sheet-range', - description: 'Read data from a Microsoft Excel worksheet range and return the rows.', - content: - '# Read Sheet Range\n\nPull data out of an Excel workbook for analysis or downstream steps.\n\n## Steps\n1. Identify the workbook and the worksheet and range to read.\n2. Use Read Data with the spreadsheet ID and range.\n3. Parse the returned rows into a structured form for the next step.\n\n## Output\nThe values from the range as rows, plus the sheet and range they came from.', - }, - { - name: 'write-sheet-data', - description: - 'Write or update values in a Microsoft Excel worksheet range, with formula parsing control.', - content: - '# Write Sheet Data\n\nUpdate cells in an Excel workbook.\n\n## Steps\n1. Identify the workbook, worksheet, and target range.\n2. Prepare the values as rows matching the range shape.\n3. Use Write/Update Data, choosing User Entered to parse formulas or Raw to write values literally.\n\n## Output\nConfirmation of the cells updated and the range that was written.', - }, - { - name: 'append-table-row', - description: - 'Append a new row to a Microsoft Excel table so it stays structured and formatted.', - content: - '# Append Table Row\n\nAdd a record to an existing Excel table.\n\n## Steps\n1. Identify the workbook and the table to append to.\n2. Build the row values in the table column order.\n3. Use Add to Table to append the row so table formatting and references update automatically.\n\n## Output\nConfirmation the row was appended and the table it was added to.', - }, - { - name: 'add-worksheet', - description: - 'Add a new worksheet to a Microsoft Excel workbook to hold a new dataset or report.', - content: - '# Add Worksheet\n\nCreate a fresh worksheet inside a workbook.\n\n## Steps\n1. Identify the workbook to add the sheet to.\n2. Choose a name for the new worksheet.\n3. Use Add Worksheet to create it, then write headers or data with Write/Update Data if needed.\n\n## Output\nThe new worksheet name and confirmation it was created in the workbook.', - }, - ], -} as const satisfies BlockMeta - -export const MicrosoftExcelV2BlockMeta = { - tags: ['spreadsheet', 'microsoft-365'], - url: 'https://www.microsoft.com/microsoft-365/excel', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_planner.display.ts b/apps/sim/blocks/blocks/microsoft_planner.display.ts index f1855742fb1..8c573c45da9 100644 --- a/apps/sim/blocks/blocks/microsoft_planner.display.ts +++ b/apps/sim/blocks/blocks/microsoft_planner.display.ts @@ -1,6 +1,6 @@ import { MicrosoftPlannerIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MicrosoftPlannerBlockDisplay = { type: 'microsoft_planner', @@ -14,3 +14,103 @@ export const MicrosoftPlannerBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/microsoft_planner', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const MicrosoftPlannerBlockMeta = { + tags: ['project-management', 'microsoft-365'], + url: 'https://www.microsoft.com/microsoft-365/business/task-management-software', + templates: [ + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner sprint digest', + prompt: + 'Create a scheduled weekly workflow that pulls Microsoft Planner bucket progress, computes completion rate per bucket, and posts a status digest to the project Microsoft Teams channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner SLA monitor', + prompt: + 'Build a workflow that watches Microsoft Planner tasks with due dates, sends reminders 24 hours before, and escalates to managers in Teams when items breach SLA.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'monitoring'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner Excel-import', + prompt: + 'Create a workflow that takes a Microsoft Excel task list, creates matching Planner tasks in the right bucket, and writes the planner IDs back to the spreadsheet for tracking.', + modules: ['files', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'sync'], + alsoIntegrations: ['microsoft_excel'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner blocker watcher', + prompt: + 'Build a scheduled workflow that scans Microsoft Planner tasks tagged blocked, identifies the blocking party, and posts a Teams ping with the context to unblock the work.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner template launcher', + prompt: + 'Create a scheduled workflow that polls Microsoft Dataverse for new projects and creates a Planner plan from the project template, populates the standard buckets, and assigns the right owners.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['microsoft_dataverse'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner retrospective', + prompt: + 'Build a scheduled workflow that runs at the end of a sprint, pulls completed Microsoft Planner tasks, summarizes wins and patterns, and writes the retro doc to a SharePoint page.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['sharepoint'], + }, + { + icon: MicrosoftPlannerIcon, + title: 'Microsoft Planner workload balancer', + prompt: + 'Create a scheduled weekly workflow that audits Microsoft Planner assignment load per team member, suggests rebalancing, and posts the recommendations to the manager in Teams.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'analysis'], + alsoIntegrations: ['microsoft_teams'], + }, + ], + skills: [ + { + name: 'create-task-in-bucket', + description: + 'Create a Microsoft Planner task in a specific plan and bucket with title, due date, and assignee.', + content: + '# Create Planner Task\n\nCreate a new task in a Microsoft Planner plan, placing it in the right bucket and setting a due date and owner.\n\n## Steps\n1. Use List Plans to find the target plan, then List Buckets for that plan to locate the bucket id.\n2. Run Create Task with the plan id, a clear title, and the bucket id so it lands in the right column.\n3. If a due date was described in natural language, convert it to ISO 8601 (YYYY-MM-DDTHH:MM:SSZ) before passing dueDateTime.\n4. Set assigneeUserId when an owner is known.\n\n## Output\nConfirm the created task id and report title, bucket, due date, and assignee. Surface the etag for any follow-up updates.', + }, + { + name: 'set-up-plan-buckets', + description: + 'Create a set of stage or phase buckets in a Planner plan to organize tasks by workflow column.', + content: + '# Set Up Plan Buckets\n\nStructure a Microsoft Planner plan into the workflow columns a team needs, such as To Do, In Progress, Review, and Done, or project phases.\n\n## Steps\n1. Use List Plans to find the target plan, then List Buckets to see which buckets already exist and avoid duplicates.\n2. Run Create Bucket once per desired column, passing the plan id and a clear bucket name.\n3. Keep names short and ordered so the board reads left to right as work progresses.\n\n## Output\nList every bucket id and name that now exists in the plan, marking which were newly created. Suggest the next bucket only if a stage is clearly missing.', + }, + { + name: 'add-task-checklist', + description: + 'Add a step-by-step checklist to a Planner task so each subtask can be tracked and checked off.', + content: + '# Add Task Checklist\n\nBreak a Microsoft Planner task into trackable subtasks using its checklist.\n\n## Steps\n1. Identify the target task id, using Read Task to confirm the title if needed.\n2. Use Get Task Details to read the current checklist and capture the etag required for updates.\n3. Run Update Task Details with the checklist items to add, passing the etag from the previous step.\n4. Set percentComplete on the task with Update Task when progress should reflect the checklist state.\n\n## Output\nConfirm the task id and list the checklist items now present. Note the refreshed etag for any further edits.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_planner.ts b/apps/sim/blocks/blocks/microsoft_planner.ts index 46bbf5984f9..c5e08d300a5 100644 --- a/apps/sim/blocks/blocks/microsoft_planner.ts +++ b/apps/sim/blocks/blocks/microsoft_planner.ts @@ -1,7 +1,6 @@ -import { MicrosoftPlannerIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MicrosoftPlannerBlockDisplay } from '@/blocks/blocks/microsoft_planner.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { MicrosoftPlannerResponse } from '@/tools/microsoft_planner/types' @@ -653,103 +652,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, }, }, } - -export const MicrosoftPlannerBlockMeta = { - tags: ['project-management', 'microsoft-365'], - url: 'https://www.microsoft.com/microsoft-365/business/task-management-software', - templates: [ - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner sprint digest', - prompt: - 'Create a scheduled weekly workflow that pulls Microsoft Planner bucket progress, computes completion rate per bucket, and posts a status digest to the project Microsoft Teams channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner SLA monitor', - prompt: - 'Build a workflow that watches Microsoft Planner tasks with due dates, sends reminders 24 hours before, and escalates to managers in Teams when items breach SLA.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'monitoring'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner Excel-import', - prompt: - 'Create a workflow that takes a Microsoft Excel task list, creates matching Planner tasks in the right bucket, and writes the planner IDs back to the spreadsheet for tracking.', - modules: ['files', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'sync'], - alsoIntegrations: ['microsoft_excel'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner blocker watcher', - prompt: - 'Build a scheduled workflow that scans Microsoft Planner tasks tagged blocked, identifies the blocking party, and posts a Teams ping with the context to unblock the work.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner template launcher', - prompt: - 'Create a scheduled workflow that polls Microsoft Dataverse for new projects and creates a Planner plan from the project template, populates the standard buckets, and assigns the right owners.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['microsoft_dataverse'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner retrospective', - prompt: - 'Build a scheduled workflow that runs at the end of a sprint, pulls completed Microsoft Planner tasks, summarizes wins and patterns, and writes the retro doc to a SharePoint page.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['sharepoint'], - }, - { - icon: MicrosoftPlannerIcon, - title: 'Microsoft Planner workload balancer', - prompt: - 'Create a scheduled weekly workflow that audits Microsoft Planner assignment load per team member, suggests rebalancing, and posts the recommendations to the manager in Teams.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'analysis'], - alsoIntegrations: ['microsoft_teams'], - }, - ], - skills: [ - { - name: 'create-task-in-bucket', - description: - 'Create a Microsoft Planner task in a specific plan and bucket with title, due date, and assignee.', - content: - '# Create Planner Task\n\nCreate a new task in a Microsoft Planner plan, placing it in the right bucket and setting a due date and owner.\n\n## Steps\n1. Use List Plans to find the target plan, then List Buckets for that plan to locate the bucket id.\n2. Run Create Task with the plan id, a clear title, and the bucket id so it lands in the right column.\n3. If a due date was described in natural language, convert it to ISO 8601 (YYYY-MM-DDTHH:MM:SSZ) before passing dueDateTime.\n4. Set assigneeUserId when an owner is known.\n\n## Output\nConfirm the created task id and report title, bucket, due date, and assignee. Surface the etag for any follow-up updates.', - }, - { - name: 'set-up-plan-buckets', - description: - 'Create a set of stage or phase buckets in a Planner plan to organize tasks by workflow column.', - content: - '# Set Up Plan Buckets\n\nStructure a Microsoft Planner plan into the workflow columns a team needs, such as To Do, In Progress, Review, and Done, or project phases.\n\n## Steps\n1. Use List Plans to find the target plan, then List Buckets to see which buckets already exist and avoid duplicates.\n2. Run Create Bucket once per desired column, passing the plan id and a clear bucket name.\n3. Keep names short and ordered so the board reads left to right as work progresses.\n\n## Output\nList every bucket id and name that now exists in the plan, marking which were newly created. Suggest the next bucket only if a stage is clearly missing.', - }, - { - name: 'add-task-checklist', - description: - 'Add a step-by-step checklist to a Planner task so each subtask can be tracked and checked off.', - content: - '# Add Task Checklist\n\nBreak a Microsoft Planner task into trackable subtasks using its checklist.\n\n## Steps\n1. Identify the target task id, using Read Task to confirm the title if needed.\n2. Use Get Task Details to read the current checklist and capture the etag required for updates.\n3. Run Update Task Details with the checklist items to add, passing the etag from the previous step.\n4. Set percentComplete on the task with Update Task when progress should reflect the checklist state.\n\n## Output\nConfirm the task id and list the checklist items now present. Note the refreshed etag for any further edits.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_teams.display.ts b/apps/sim/blocks/blocks/microsoft_teams.display.ts index 3c4b9c2d941..cd522eece5f 100644 --- a/apps/sim/blocks/blocks/microsoft_teams.display.ts +++ b/apps/sim/blocks/blocks/microsoft_teams.display.ts @@ -1,6 +1,6 @@ import { MicrosoftTeamsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MicrosoftTeamsBlockDisplay = { type: 'microsoft_teams', @@ -15,3 +15,105 @@ export const MicrosoftTeamsBlockDisplay = { integrationType: IntegrationType.Communication, triggerAllowed: true, } satisfies BlockDisplay + +export const MicrosoftTeamsBlockMeta = { + tags: ['messaging', 'microsoft-365'], + url: 'https://www.microsoft.com/microsoft-teams/group-chat-software', + templates: [ + { + icon: MicrosoftTeamsIcon, + title: 'Microsoft Teams daily brief', + prompt: + 'Build a scheduled workflow that pulls updates from your project tools — GitHub commits, Jira ticket status changes, and calendar events — and posts a formatted daily brief to your Microsoft Teams channel each morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting', 'enterprise'], + alsoIntegrations: ['github', 'jira'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams incident war room', + prompt: + 'Build a workflow triggered by a PagerDuty incident that creates a Microsoft Teams war-room channel, invites responders, posts the incident summary, and keeps the channel name in sync with incident state.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams sales-deal channel', + prompt: + 'Create a workflow that listens for new Salesforce opportunities above a threshold, creates a Microsoft Teams channel for the deal, invites the account team, and pins the opportunity link.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enterprise'], + alsoIntegrations: ['salesforce'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams approval router', + prompt: + 'Build a workflow that posts approval requests with quick-action buttons in Microsoft Teams, captures the decision, writes it back to the source record, and notifies the requester.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams weekly metrics digest', + prompt: + 'Create a scheduled weekly workflow that aggregates key business metrics from Stripe and HubSpot, formats them into a polished Microsoft Teams adaptive card, and posts to the leadership channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'enterprise'], + alsoIntegrations: ['stripe', 'hubspot'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams onboarding bot', + prompt: + 'Build a Microsoft Teams bot that greets new hires when added to the org, walks them through onboarding tasks with progress checkboxes, and writes completion status to an HR table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + }, + { + icon: MicrosoftTeamsIcon, + title: 'Teams ticket-bridge for Zendesk', + prompt: + 'Create a workflow that mirrors high-priority Zendesk tickets into Microsoft Teams channels, keeps replies synced both ways, and closes the Teams thread when the ticket is resolved.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'enterprise'], + alsoIntegrations: ['zendesk'], + }, + ], + skills: [ + { + name: 'post-channel-announcement', + description: 'Write a formatted message to a specific Microsoft Teams channel.', + content: + '# Post Channel Announcement\n\nSend an announcement or update to a Microsoft Teams channel.\n\n## Steps\n1. Identify the team and channel to post to, selecting the channel id.\n2. Compose the message body, using clear headings and bullets so it reads well in Teams.\n3. Run Write Channel Message with the channel id and the formatted content.\n4. If a thread already exists for the topic, use Reply to Channel Message instead to keep context together.\n\n## Output\nConfirm the posted message id and channel. Quote the first line of what was posted.', + }, + { + name: 'summarize-channel-activity', + description: + 'Read recent Microsoft Teams channel messages and produce a concise digest of decisions and action items.', + content: + '# Summarize Channel Activity\n\nTurn a busy Microsoft Teams channel into a short readable digest.\n\n## Steps\n1. Run Read Channel Messages for the target channel.\n2. Group messages by topic or thread and drop noise such as greetings and reactions.\n3. Extract decisions made, open questions, and any explicit action items with owners.\n4. Optionally post the digest back to the channel as a new message.\n\n## Output\nThree short sections: Decisions, Open Questions, Action Items. Each item one line with the person responsible when known.', + }, + { + name: 'acknowledge-with-reaction', + description: 'React to a specific Microsoft Teams message to acknowledge it.', + content: + '# Acknowledge with Reaction\n\nAdd or remove an emoji reaction on a Microsoft Teams message.\n\n## Steps\n1. Locate the message using Get Message or the known message id and channel/chat id.\n2. Run Add Reaction with the desired reactionType to acknowledge or signal status.\n3. Use Remove Reaction when the acknowledgment should be cleared.\n\n## Output\nConfirm the reaction applied and on which message. Keep the response to one line.', + }, + { + name: 'list-team-members', + description: 'List the members of a Microsoft Teams team or channel for routing or auditing.', + content: + '# List Team Members\n\nRetrieve who belongs to a Microsoft Teams team or channel.\n\n## Steps\n1. Decide whether you need team-wide membership or a single channel and pick List Team Members or List Channel Members.\n2. Run the operation with the team id (and channel id when needed).\n3. Normalize the result into a clean roster of names and roles.\n\n## Output\nA roster list with display name and role. Note the total count at the top.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/microsoft_teams.ts b/apps/sim/blocks/blocks/microsoft_teams.ts index 2d5ad5f6853..28583d9763e 100644 --- a/apps/sim/blocks/blocks/microsoft_teams.ts +++ b/apps/sim/blocks/blocks/microsoft_teams.ts @@ -1,7 +1,6 @@ -import { MicrosoftTeamsIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MicrosoftTeamsBlockDisplay } from '@/blocks/blocks/microsoft_teams.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { MicrosoftTeamsResponse } from '@/tools/microsoft_teams/types' @@ -471,105 +470,3 @@ export const MicrosoftTeamsBlock: BlockConfig = { available: ['microsoftteams_webhook'], }, } - -export const MicrosoftTeamsBlockMeta = { - tags: ['messaging', 'microsoft-365'], - url: 'https://www.microsoft.com/microsoft-teams/group-chat-software', - templates: [ - { - icon: MicrosoftTeamsIcon, - title: 'Microsoft Teams daily brief', - prompt: - 'Build a scheduled workflow that pulls updates from your project tools — GitHub commits, Jira ticket status changes, and calendar events — and posts a formatted daily brief to your Microsoft Teams channel each morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting', 'enterprise'], - alsoIntegrations: ['github', 'jira'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams incident war room', - prompt: - 'Build a workflow triggered by a PagerDuty incident that creates a Microsoft Teams war-room channel, invites responders, posts the incident summary, and keeps the channel name in sync with incident state.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams sales-deal channel', - prompt: - 'Create a workflow that listens for new Salesforce opportunities above a threshold, creates a Microsoft Teams channel for the deal, invites the account team, and pins the opportunity link.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enterprise'], - alsoIntegrations: ['salesforce'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams approval router', - prompt: - 'Build a workflow that posts approval requests with quick-action buttons in Microsoft Teams, captures the decision, writes it back to the source record, and notifies the requester.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams weekly metrics digest', - prompt: - 'Create a scheduled weekly workflow that aggregates key business metrics from Stripe and HubSpot, formats them into a polished Microsoft Teams adaptive card, and posts to the leadership channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'enterprise'], - alsoIntegrations: ['stripe', 'hubspot'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams onboarding bot', - prompt: - 'Build a Microsoft Teams bot that greets new hires when added to the org, walks them through onboarding tasks with progress checkboxes, and writes completion status to an HR table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - }, - { - icon: MicrosoftTeamsIcon, - title: 'Teams ticket-bridge for Zendesk', - prompt: - 'Create a workflow that mirrors high-priority Zendesk tickets into Microsoft Teams channels, keeps replies synced both ways, and closes the Teams thread when the ticket is resolved.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'enterprise'], - alsoIntegrations: ['zendesk'], - }, - ], - skills: [ - { - name: 'post-channel-announcement', - description: 'Write a formatted message to a specific Microsoft Teams channel.', - content: - '# Post Channel Announcement\n\nSend an announcement or update to a Microsoft Teams channel.\n\n## Steps\n1. Identify the team and channel to post to, selecting the channel id.\n2. Compose the message body, using clear headings and bullets so it reads well in Teams.\n3. Run Write Channel Message with the channel id and the formatted content.\n4. If a thread already exists for the topic, use Reply to Channel Message instead to keep context together.\n\n## Output\nConfirm the posted message id and channel. Quote the first line of what was posted.', - }, - { - name: 'summarize-channel-activity', - description: - 'Read recent Microsoft Teams channel messages and produce a concise digest of decisions and action items.', - content: - '# Summarize Channel Activity\n\nTurn a busy Microsoft Teams channel into a short readable digest.\n\n## Steps\n1. Run Read Channel Messages for the target channel.\n2. Group messages by topic or thread and drop noise such as greetings and reactions.\n3. Extract decisions made, open questions, and any explicit action items with owners.\n4. Optionally post the digest back to the channel as a new message.\n\n## Output\nThree short sections: Decisions, Open Questions, Action Items. Each item one line with the person responsible when known.', - }, - { - name: 'acknowledge-with-reaction', - description: 'React to a specific Microsoft Teams message to acknowledge it.', - content: - '# Acknowledge with Reaction\n\nAdd or remove an emoji reaction on a Microsoft Teams message.\n\n## Steps\n1. Locate the message using Get Message or the known message id and channel/chat id.\n2. Run Add Reaction with the desired reactionType to acknowledge or signal status.\n3. Use Remove Reaction when the acknowledgment should be cleared.\n\n## Output\nConfirm the reaction applied and on which message. Keep the response to one line.', - }, - { - name: 'list-team-members', - description: 'List the members of a Microsoft Teams team or channel for routing or auditing.', - content: - '# List Team Members\n\nRetrieve who belongs to a Microsoft Teams team or channel.\n\n## Steps\n1. Decide whether you need team-wide membership or a single channel and pick List Team Members or List Channel Members.\n2. Run the operation with the team id (and channel id when needed).\n3. Normalize the result into a clean roster of names and roles.\n\n## Output\nA roster list with display name and role. Note the total count at the top.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/millionverifier.display.ts b/apps/sim/blocks/blocks/millionverifier.display.ts index d0571fac424..2ae46c653f9 100644 --- a/apps/sim/blocks/blocks/millionverifier.display.ts +++ b/apps/sim/blocks/blocks/millionverifier.display.ts @@ -1,6 +1,6 @@ import { MillionVerifierIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MillionVerifierBlockDisplay = { type: 'millionverifier', @@ -14,3 +14,8 @@ export const MillionVerifierBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/millionverifier', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const MillionVerifierBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.millionverifier.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/millionverifier.ts b/apps/sim/blocks/blocks/millionverifier.ts index b4d336da59c..197b9ffb7fa 100644 --- a/apps/sim/blocks/blocks/millionverifier.ts +++ b/apps/sim/blocks/blocks/millionverifier.ts @@ -1,5 +1,5 @@ import { MillionVerifierBlockDisplay } from '@/blocks/blocks/millionverifier.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { MillionVerifierResponse } from '@/tools/millionverifier/types' export const MillionVerifierBlock: BlockConfig = { @@ -90,8 +90,3 @@ export const MillionVerifierBlock: BlockConfig = { credits: { type: 'number', description: 'Remaining verification credits' }, }, } - -export const MillionVerifierBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.millionverifier.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mistral_parse.display.ts b/apps/sim/blocks/blocks/mistral_parse.display.ts index e1c83a163a7..a30960419c7 100644 --- a/apps/sim/blocks/blocks/mistral_parse.display.ts +++ b/apps/sim/blocks/blocks/mistral_parse.display.ts @@ -1,6 +1,6 @@ import { MistralIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MistralParseBlockDisplay = { type: 'mistral_parse', @@ -30,3 +30,96 @@ export const MistralParseV3BlockDisplay = { description: 'Extract text from PDF documents', hideFromToolbar: false, } satisfies BlockDisplay + +export const MistralParseBlockMeta = { + tags: ['document-processing', 'ocr'], + url: 'https://mistral.ai', + templates: [ + { + icon: MistralIcon, + title: 'Mistral Parser for complex PDFs', + prompt: + 'Create a workflow that uses Mistral Parser to convert dense research PDFs into clean Markdown, saves the Markdown to files, and indexes them into a knowledge base for downstream agents.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'automation'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser bank statement reader', + prompt: + 'Create a workflow that uses Mistral Parser to extract structured transactions from uploaded bank statement PDFs, writes each transaction to a finance table, and classifies expense category.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser research-paper digester', + prompt: + 'Build a scheduled workflow that watches a research-paper folder, parses each PDF with Mistral Parser, and writes clean Markdown summaries for the knowledge base.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser legal-doc summarizer', + prompt: + 'Create a workflow that processes legal documents with Mistral Parser, extracts the key clauses and obligations into a table, and writes a one-pager summary file.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'analysis'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser invoice intake', + prompt: + 'Build a workflow that runs each incoming invoice PDF through Mistral Parser, extracts vendor, line items, totals, and due date into an accounts-payable table, and flags any invoice missing a PO number for the finance team in Slack.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser scanned-contract indexer', + prompt: + 'Create a workflow that parses scanned, image-only contracts with Mistral Parser OCR, converts them to searchable Markdown, and indexes the result into a knowledge base so legal can search obligations across every signed agreement.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'ocr', 'research'], + }, + { + icon: MistralIcon, + title: 'Mistral Parser resume screener', + prompt: + 'Build a workflow that parses uploaded resume PDFs with Mistral Parser, extracts candidate skills, experience, and contact details into a hiring table, and posts a shortlist summary to the recruiting channel in Slack.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hiring', 'automation', 'analysis'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'pdf-to-markdown', + description: 'Convert a PDF document into clean structured Markdown using Mistral OCR.', + content: + '# PDF to Markdown\n\nUse Mistral Parser to turn a PDF, including scanned image-only pages, into clean Markdown.\n\n## Steps\n1. Provide the PDF as a URL or uploaded file to the parser.\n2. Run the parse to extract text, headings, tables, and layout into Markdown.\n3. Review the Markdown for page-break artifacts and stray headers or footers and clean them.\n\n## Output\nReturn the full Markdown. Note the page count and flag any pages where OCR confidence looked low.', + }, + { + name: 'extract-document-fields', + description: + 'Parse a PDF and pull specific structured fields such as totals, dates, or names.', + content: + '# Extract Document Fields\n\nExtract a defined set of fields from a document such as an invoice, statement, or contract.\n\n## Steps\n1. Run Mistral Parser on the source PDF to get the text content.\n2. Locate the requested fields (for example vendor, total, due date, line items) within the parsed text.\n3. Return the fields as a structured object, leaving any field that is genuinely absent as null rather than guessing.\n\n## Output\nA JSON object keyed by the requested field names. List any fields that could not be found.', + }, + { + name: 'summarize-long-document', + description: 'Parse a long PDF and produce a concise summary of its key points.', + content: + '# Summarize Long Document\n\nProduce a readable summary from a long PDF such as a report, paper, or agreement.\n\n## Steps\n1. Parse the PDF with Mistral Parser to get its full text.\n2. Identify the main sections and the most important claims, findings, or obligations.\n3. Write a tight summary that preserves specifics like figures and dates.\n\n## Output\nA short summary with a few bullet highlights. Keep numbers and named entities exact.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mistral_parse.ts b/apps/sim/blocks/blocks/mistral_parse.ts index 972dd65a1a2..22f2e97bee6 100644 --- a/apps/sim/blocks/blocks/mistral_parse.ts +++ b/apps/sim/blocks/blocks/mistral_parse.ts @@ -1,11 +1,10 @@ import { toError } from '@sim/utils/errors' -import { MistralIcon } from '@/components/icons' import { MistralParseBlockDisplay, MistralParseV2BlockDisplay, MistralParseV3BlockDisplay, } from '@/blocks/blocks/mistral_parse.display' -import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' +import { AuthMode, type BlockConfig, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { MistralParserOutput } from '@/tools/mistral/types' @@ -387,96 +386,3 @@ export const MistralParseV3Block: BlockConfig = { document_annotation: { type: 'string', description: 'Structured annotation data' }, }, } - -export const MistralParseBlockMeta = { - tags: ['document-processing', 'ocr'], - url: 'https://mistral.ai', - templates: [ - { - icon: MistralIcon, - title: 'Mistral Parser for complex PDFs', - prompt: - 'Create a workflow that uses Mistral Parser to convert dense research PDFs into clean Markdown, saves the Markdown to files, and indexes them into a knowledge base for downstream agents.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'automation'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser bank statement reader', - prompt: - 'Create a workflow that uses Mistral Parser to extract structured transactions from uploaded bank statement PDFs, writes each transaction to a finance table, and classifies expense category.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser research-paper digester', - prompt: - 'Build a scheduled workflow that watches a research-paper folder, parses each PDF with Mistral Parser, and writes clean Markdown summaries for the knowledge base.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser legal-doc summarizer', - prompt: - 'Create a workflow that processes legal documents with Mistral Parser, extracts the key clauses and obligations into a table, and writes a one-pager summary file.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'analysis'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser invoice intake', - prompt: - 'Build a workflow that runs each incoming invoice PDF through Mistral Parser, extracts vendor, line items, totals, and due date into an accounts-payable table, and flags any invoice missing a PO number for the finance team in Slack.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser scanned-contract indexer', - prompt: - 'Create a workflow that parses scanned, image-only contracts with Mistral Parser OCR, converts them to searchable Markdown, and indexes the result into a knowledge base so legal can search obligations across every signed agreement.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'ocr', 'research'], - }, - { - icon: MistralIcon, - title: 'Mistral Parser resume screener', - prompt: - 'Build a workflow that parses uploaded resume PDFs with Mistral Parser, extracts candidate skills, experience, and contact details into a hiring table, and posts a shortlist summary to the recruiting channel in Slack.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hiring', 'automation', 'analysis'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'pdf-to-markdown', - description: 'Convert a PDF document into clean structured Markdown using Mistral OCR.', - content: - '# PDF to Markdown\n\nUse Mistral Parser to turn a PDF, including scanned image-only pages, into clean Markdown.\n\n## Steps\n1. Provide the PDF as a URL or uploaded file to the parser.\n2. Run the parse to extract text, headings, tables, and layout into Markdown.\n3. Review the Markdown for page-break artifacts and stray headers or footers and clean them.\n\n## Output\nReturn the full Markdown. Note the page count and flag any pages where OCR confidence looked low.', - }, - { - name: 'extract-document-fields', - description: - 'Parse a PDF and pull specific structured fields such as totals, dates, or names.', - content: - '# Extract Document Fields\n\nExtract a defined set of fields from a document such as an invoice, statement, or contract.\n\n## Steps\n1. Run Mistral Parser on the source PDF to get the text content.\n2. Locate the requested fields (for example vendor, total, due date, line items) within the parsed text.\n3. Return the fields as a structured object, leaving any field that is genuinely absent as null rather than guessing.\n\n## Output\nA JSON object keyed by the requested field names. List any fields that could not be found.', - }, - { - name: 'summarize-long-document', - description: 'Parse a long PDF and produce a concise summary of its key points.', - content: - '# Summarize Long Document\n\nProduce a readable summary from a long PDF such as a report, paper, or agreement.\n\n## Steps\n1. Parse the PDF with Mistral Parser to get its full text.\n2. Identify the main sections and the most important claims, findings, or obligations.\n3. Write a tight summary that preserves specifics like figures and dates.\n\n## Output\nA short summary with a few bullet highlights. Keep numbers and named entities exact.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/monday.display.ts b/apps/sim/blocks/blocks/monday.display.ts index da18c6538fc..6682f29985f 100644 --- a/apps/sim/blocks/blocks/monday.display.ts +++ b/apps/sim/blocks/blocks/monday.display.ts @@ -1,6 +1,6 @@ import { MondayIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MondayBlockDisplay = { type: 'monday', @@ -14,3 +14,98 @@ export const MondayBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/monday', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const MondayBlockMeta = { + tags: ['project-management', 'ticketing'], + url: 'https://monday.com', + templates: [ + { + icon: MondayIcon, + title: 'Monday status digest', + prompt: + 'Create a scheduled weekly workflow that pulls Monday board progress, computes completion rate, and posts a status update to leadership Slack with the at-risk items highlighted.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: MondayIcon, + title: 'Monday board automator', + prompt: + 'Build a workflow that watches Monday boards for status changes, applies branching automations — assign owners, set due dates, post Slack updates — based on a rules table.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: MondayIcon, + title: 'Monday client portal', + prompt: + 'Create a workflow that mirrors a Monday project board into a client-facing summary table, refreshes hourly, and emails the client a snapshot link each week.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: MondayIcon, + title: 'Monday SLA enforcer', + prompt: + 'Build a workflow that watches Monday items with due dates, sends reminders 24 hours before, and escalates to managers when items breach SLA.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'monitoring'], + }, + { + icon: MondayIcon, + title: 'Monday + CRM sync', + prompt: + 'Create a workflow that mirrors Monday CRM board items into Salesforce as opportunities, keeps stage and amount synced, and writes the Salesforce ID back to the Monday item.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'sync'], + alsoIntegrations: ['salesforce'], + }, + { + icon: MondayIcon, + title: 'Monday workspace audit', + prompt: + 'Build a scheduled monthly workflow that audits Monday boards for unused columns, stale automations, and missing owners, and writes a cleanup plan to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + }, + { + icon: MondayIcon, + title: 'Monday onboarding kickoff', + prompt: + 'Create a workflow that on a new hire in Workday creates a personalized Monday onboarding board, seeds the role-specific tasks, and invites the new hire and buddy.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + ], + skills: [ + { + name: 'create-board-item', + description: 'Create a new item on a Monday board in the right group with column values set.', + content: + '# Create Board Item\n\nAdd an item to a Monday.com board and populate its columns.\n\n## Steps\n1. Use List Boards to find the board, then Get Board to read its groups and column ids.\n2. Run Create Item with the board id, item name, and the target group.\n3. Map the requested fields to the correct column ids, formatting status and date columns as Monday expects.\n4. Add a follow-up Create Update if a comment or context note is needed on the item.\n\n## Output\nConfirm the new item id, board, and group. List the column values that were set.', + }, + { + name: 'find-items-by-criteria', + description: 'Search a Monday board for items matching a value such as status or owner.', + content: + '# Find Items by Criteria\n\nLocate Monday.com items that match a given condition.\n\n## Steps\n1. Identify the board and the column to filter on with Get Board.\n2. Use Search Items or Get Items to retrieve candidates.\n3. Filter to the items whose column value matches the requested criteria.\n\n## Output\nA list of matching items with name, group, and the relevant column values. Note the total match count.', + }, + { + name: 'progress-item-status', + description: 'Move a Monday item forward by updating its status column and group.', + content: + '# Progress Item Status\n\nAdvance a Monday.com item through its workflow.\n\n## Steps\n1. Get the item with Get Item to read its current status and group.\n2. Run Update Item to set the new status column value.\n3. If the stage maps to a different group, use Move Item to Group to keep the board organized.\n4. Optionally post a Create Update noting the transition.\n\n## Output\nConfirm the item id, the old and new status, and the group it now sits in.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/monday.ts b/apps/sim/blocks/blocks/monday.ts index da5e1cd4337..822f48c4bfb 100644 --- a/apps/sim/blocks/blocks/monday.ts +++ b/apps/sim/blocks/blocks/monday.ts @@ -1,7 +1,6 @@ -import { MondayIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { MondayBlockDisplay } from '@/blocks/blocks/monday.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { MondayArchiveItemResponse, @@ -472,98 +471,3 @@ export const MondayBlock: BlockConfig = { ], }, } - -export const MondayBlockMeta = { - tags: ['project-management', 'ticketing'], - url: 'https://monday.com', - templates: [ - { - icon: MondayIcon, - title: 'Monday status digest', - prompt: - 'Create a scheduled weekly workflow that pulls Monday board progress, computes completion rate, and posts a status update to leadership Slack with the at-risk items highlighted.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: MondayIcon, - title: 'Monday board automator', - prompt: - 'Build a workflow that watches Monday boards for status changes, applies branching automations — assign owners, set due dates, post Slack updates — based on a rules table.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: MondayIcon, - title: 'Monday client portal', - prompt: - 'Create a workflow that mirrors a Monday project board into a client-facing summary table, refreshes hourly, and emails the client a snapshot link each week.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: MondayIcon, - title: 'Monday SLA enforcer', - prompt: - 'Build a workflow that watches Monday items with due dates, sends reminders 24 hours before, and escalates to managers when items breach SLA.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'monitoring'], - }, - { - icon: MondayIcon, - title: 'Monday + CRM sync', - prompt: - 'Create a workflow that mirrors Monday CRM board items into Salesforce as opportunities, keeps stage and amount synced, and writes the Salesforce ID back to the Monday item.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'sync'], - alsoIntegrations: ['salesforce'], - }, - { - icon: MondayIcon, - title: 'Monday workspace audit', - prompt: - 'Build a scheduled monthly workflow that audits Monday boards for unused columns, stale automations, and missing owners, and writes a cleanup plan to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - }, - { - icon: MondayIcon, - title: 'Monday onboarding kickoff', - prompt: - 'Create a workflow that on a new hire in Workday creates a personalized Monday onboarding board, seeds the role-specific tasks, and invites the new hire and buddy.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - ], - skills: [ - { - name: 'create-board-item', - description: 'Create a new item on a Monday board in the right group with column values set.', - content: - '# Create Board Item\n\nAdd an item to a Monday.com board and populate its columns.\n\n## Steps\n1. Use List Boards to find the board, then Get Board to read its groups and column ids.\n2. Run Create Item with the board id, item name, and the target group.\n3. Map the requested fields to the correct column ids, formatting status and date columns as Monday expects.\n4. Add a follow-up Create Update if a comment or context note is needed on the item.\n\n## Output\nConfirm the new item id, board, and group. List the column values that were set.', - }, - { - name: 'find-items-by-criteria', - description: 'Search a Monday board for items matching a value such as status or owner.', - content: - '# Find Items by Criteria\n\nLocate Monday.com items that match a given condition.\n\n## Steps\n1. Identify the board and the column to filter on with Get Board.\n2. Use Search Items or Get Items to retrieve candidates.\n3. Filter to the items whose column value matches the requested criteria.\n\n## Output\nA list of matching items with name, group, and the relevant column values. Note the total match count.', - }, - { - name: 'progress-item-status', - description: 'Move a Monday item forward by updating its status column and group.', - content: - '# Progress Item Status\n\nAdvance a Monday.com item through its workflow.\n\n## Steps\n1. Get the item with Get Item to read its current status and group.\n2. Run Update Item to set the new status column value.\n3. If the stage maps to a different group, use Move Item to Group to keep the board organized.\n4. Optionally post a Create Update noting the transition.\n\n## Output\nConfirm the item id, the old and new status, and the group it now sits in.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mongodb.display.ts b/apps/sim/blocks/blocks/mongodb.display.ts index 169e43c4d91..68865b93420 100644 --- a/apps/sim/blocks/blocks/mongodb.display.ts +++ b/apps/sim/blocks/blocks/mongodb.display.ts @@ -1,6 +1,6 @@ import { MongoDBIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const MongoDBBlockDisplay = { type: 'mongodb', @@ -14,3 +14,99 @@ export const MongoDBBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/mongodb', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const MongoDBBlockMeta = { + tags: ['data-warehouse', 'cloud'], + url: 'https://www.mongodb.com', + templates: [ + { + icon: MongoDBIcon, + title: 'MongoDB to data lake export', + prompt: + 'Build a scheduled workflow that runs each night, exports MongoDB collections to S3 with partitioned Parquet files, and registers them in an Athena-queryable catalog.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB index health monitor', + prompt: + 'Create a scheduled workflow that scans MongoDB collections for slow queries and missing indexes, writes a remediation table, and opens Linear tickets for the worst offenders.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + alsoIntegrations: ['linear'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB to vector enrichment', + prompt: + 'Build a scheduled workflow that polls a MongoDB collection for new documents, generates OpenAI embeddings, and upserts them into Pinecone with the source document ID for retrieval.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['pinecone', 'openai'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB user-event triage', + prompt: + 'Create a scheduled workflow that polls a MongoDB user-events collection for new records, classifies events as engagement or risk signals, and writes high-priority items to a triage table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['product', 'analysis'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB orphaned-doc cleaner', + prompt: + 'Build a scheduled workflow that runs weekly, finds orphaned references in MongoDB, dry-runs the cleanup plan, posts to Slack for approval, and executes once approved.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB query digest', + prompt: + 'Create a scheduled daily workflow that aggregates MongoDB query telemetry from the profiler, identifies the top-cost queries, and posts a Slack engineering digest.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: MongoDBIcon, + title: 'MongoDB + Tinybird feeder', + prompt: + 'Build a scheduled workflow that batches new MongoDB records into a Tinybird pipe on a short interval, exposes the data to downstream apps, and writes the load metrics to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + alsoIntegrations: ['tinybird'], + }, + ], + skills: [ + { + name: 'find-documents', + description: 'Query a MongoDB collection with a filter and return the matching documents.', + content: + '# Find Documents\n\nRetrieve documents from a MongoDB collection that match a filter.\n\n## Steps\n1. If the collection shape is unknown, run Introspect Database first to learn the fields.\n2. Build a MongoDB filter document for the requested condition, using operators like $gte, $in, and $regex as needed.\n3. Run Find Documents against the target collection with the filter, plus projection and limit when appropriate.\n\n## Output\nReturn the matching documents. State the filter used and the number of results. Suggest an index if a scan looks slow.', + }, + { + name: 'aggregate-report', + description: 'Run a MongoDB aggregation pipeline to group and summarize collection data.', + content: + '# Aggregate Report\n\nProduce a summary from a MongoDB collection using an aggregation pipeline.\n\n## Steps\n1. Introspect the collection to confirm the fields to group and measure on.\n2. Compose a pipeline with stages such as $match, $group, $sort, and $limit to compute the requested metric.\n3. Run the Aggregate Pipeline operation and read back the grouped results.\n\n## Output\nA compact table of the grouped metrics. Include the pipeline used so the query can be rerun.', + }, + { + name: 'upsert-document', + description: 'Insert a new MongoDB document or update an existing one matched by a key.', + content: + '# Upsert Document\n\nWrite a document to MongoDB, creating it or updating the existing match.\n\n## Steps\n1. Determine the key field that identifies the record uniquely.\n2. Run Find Documents on that key to see whether a record already exists.\n3. If it exists, run Update Documents with the new values; otherwise run Insert Documents.\n\n## Output\nReport whether a document was inserted or updated and echo the key value. Confirm the affected count.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/mongodb.ts b/apps/sim/blocks/blocks/mongodb.ts index 063b754fc03..f8c4f04d49f 100644 --- a/apps/sim/blocks/blocks/mongodb.ts +++ b/apps/sim/blocks/blocks/mongodb.ts @@ -1,7 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { MongoDBIcon } from '@/components/icons' import { MongoDBBlockDisplay } from '@/blocks/blocks/mongodb.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { MongoDBIntrospectResponse, MongoDBResponse } from '@/tools/mongodb/types' export const MongoDBBlock: BlockConfig = { @@ -953,99 +952,3 @@ Return ONLY the MongoDB query filter as valid JSON - no explanations, no markdow }, }, } - -export const MongoDBBlockMeta = { - tags: ['data-warehouse', 'cloud'], - url: 'https://www.mongodb.com', - templates: [ - { - icon: MongoDBIcon, - title: 'MongoDB to data lake export', - prompt: - 'Build a scheduled workflow that runs each night, exports MongoDB collections to S3 with partitioned Parquet files, and registers them in an Athena-queryable catalog.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB index health monitor', - prompt: - 'Create a scheduled workflow that scans MongoDB collections for slow queries and missing indexes, writes a remediation table, and opens Linear tickets for the worst offenders.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - alsoIntegrations: ['linear'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB to vector enrichment', - prompt: - 'Build a scheduled workflow that polls a MongoDB collection for new documents, generates OpenAI embeddings, and upserts them into Pinecone with the source document ID for retrieval.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['pinecone', 'openai'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB user-event triage', - prompt: - 'Create a scheduled workflow that polls a MongoDB user-events collection for new records, classifies events as engagement or risk signals, and writes high-priority items to a triage table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['product', 'analysis'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB orphaned-doc cleaner', - prompt: - 'Build a scheduled workflow that runs weekly, finds orphaned references in MongoDB, dry-runs the cleanup plan, posts to Slack for approval, and executes once approved.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB query digest', - prompt: - 'Create a scheduled daily workflow that aggregates MongoDB query telemetry from the profiler, identifies the top-cost queries, and posts a Slack engineering digest.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: MongoDBIcon, - title: 'MongoDB + Tinybird feeder', - prompt: - 'Build a scheduled workflow that batches new MongoDB records into a Tinybird pipe on a short interval, exposes the data to downstream apps, and writes the load metrics to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - alsoIntegrations: ['tinybird'], - }, - ], - skills: [ - { - name: 'find-documents', - description: 'Query a MongoDB collection with a filter and return the matching documents.', - content: - '# Find Documents\n\nRetrieve documents from a MongoDB collection that match a filter.\n\n## Steps\n1. If the collection shape is unknown, run Introspect Database first to learn the fields.\n2. Build a MongoDB filter document for the requested condition, using operators like $gte, $in, and $regex as needed.\n3. Run Find Documents against the target collection with the filter, plus projection and limit when appropriate.\n\n## Output\nReturn the matching documents. State the filter used and the number of results. Suggest an index if a scan looks slow.', - }, - { - name: 'aggregate-report', - description: 'Run a MongoDB aggregation pipeline to group and summarize collection data.', - content: - '# Aggregate Report\n\nProduce a summary from a MongoDB collection using an aggregation pipeline.\n\n## Steps\n1. Introspect the collection to confirm the fields to group and measure on.\n2. Compose a pipeline with stages such as $match, $group, $sort, and $limit to compute the requested metric.\n3. Run the Aggregate Pipeline operation and read back the grouped results.\n\n## Output\nA compact table of the grouped metrics. Include the pipeline used so the query can be rerun.', - }, - { - name: 'upsert-document', - description: 'Insert a new MongoDB document or update an existing one matched by a key.', - content: - '# Upsert Document\n\nWrite a document to MongoDB, creating it or updating the existing match.\n\n## Steps\n1. Determine the key field that identifies the record uniquely.\n2. Run Find Documents on that key to see whether a record already exists.\n3. If it exists, run Update Documents with the new values; otherwise run Insert Documents.\n\n## Output\nReport whether a document was inserted or updated and echo the key value. Confirm the affected count.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/neo4j.display.ts b/apps/sim/blocks/blocks/neo4j.display.ts index 9f1e3d2d1ba..9b5004ed4f2 100644 --- a/apps/sim/blocks/blocks/neo4j.display.ts +++ b/apps/sim/blocks/blocks/neo4j.display.ts @@ -1,6 +1,6 @@ import { Neo4jIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const Neo4jBlockDisplay = { type: 'neo4j', @@ -14,3 +14,96 @@ export const Neo4jBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/neo4j', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const Neo4jBlockMeta = { + tags: ['data-warehouse', 'data-analytics'], + url: 'https://neo4j.com', + templates: [ + { + icon: Neo4jIcon, + title: 'Neo4j relationship exporter', + prompt: + 'Build a workflow that queries Neo4j for a chosen entity graph, writes the nodes and edges to a structured JSON adjacency file, and shares the file link for a downstream tool to visualize.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['analysis', 'research'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j fraud-ring detector', + prompt: + 'Create a scheduled workflow that queries Neo4j for suspicious connection patterns — shared devices, overlapping addresses — writes risk-scored clusters to a fraud table, and pings Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j org-chart sync', + prompt: + 'Build a workflow that pulls Workday or Rippling worker data, upserts employees and reporting relationships into Neo4j, and exposes a queryable org graph for downstream tools.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'sync'], + alsoIntegrations: ['workday', 'rippling'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j knowledge-graph builder', + prompt: + 'Create a workflow that processes documents from a knowledge base, extracts entities and relationships with an agent, and writes the graph into Neo4j for cross-document insights.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['research', 'enterprise'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j recommendation engine', + prompt: + 'Build a workflow that runs Neo4j graph algorithms — collaborative filtering, PageRank — on product-purchase data and writes per-user recommendations to a personalization table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j data lineage tracker', + prompt: + 'Create a workflow that ingests dbt manifest metadata into Neo4j, tracks lineage across tables and pipelines, and queries impact when a source schema changes.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: Neo4jIcon, + title: 'Neo4j natural-language graph explorer', + prompt: + 'Build a chat agent that introspects the Neo4j schema, translates plain-English questions like “which customers share a support agent with churned accounts?” into Cypher queries, runs them, and returns a readable answer with the matching nodes.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'research', 'automation'], + }, + ], + skills: [ + { + name: 'answer-graph-question', + description: + 'Translate a plain-English question into Cypher, run it on Neo4j, and explain the result.', + content: + '# Answer Graph Question\n\nTurn a natural-language question into a Cypher query against the Neo4j graph.\n\n## Steps\n1. Run Introspect Schema to learn the node labels, relationship types, and properties.\n2. Translate the question into a Cypher MATCH that uses the real labels and relationships from the schema.\n3. Run the Query operation and read the returned rows.\n4. If the query returns nothing, relax the pattern and explain what was tried.\n\n## Output\nA plain-language answer plus the Cypher used and the key matching nodes or paths.', + }, + { + name: 'create-graph-relationship', + description: 'Create or merge nodes and connect them with a relationship in Neo4j.', + content: + '# Create Graph Relationship\n\nAdd nodes and a relationship between them without creating duplicates.\n\n## Steps\n1. Introspect Schema to confirm the labels and relationship type to use.\n2. Use Merge (Find or Create) for each node so existing nodes are reused rather than duplicated.\n3. Create the relationship between them with the requested direction and any properties.\n\n## Output\nConfirm the nodes involved and the relationship created, noting whether each node was found or newly created.', + }, + { + name: 'find-connected-nodes', + description: 'Traverse the Neo4j graph from a starting node to find related entities.', + content: + '# Find Connected Nodes\n\nExplore the neighborhood of a node to find connected entities.\n\n## Steps\n1. Introspect Schema to know the relationship types available.\n2. Build a Cypher MATCH that starts at the given node and traverses the relevant relationships to the desired depth.\n3. Run the Query operation and collect the connected nodes.\n\n## Output\nA list of connected nodes grouped by relationship type, with the traversal path described in one line.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/neo4j.ts b/apps/sim/blocks/blocks/neo4j.ts index 34a39bd78cd..bcedccb022d 100644 --- a/apps/sim/blocks/blocks/neo4j.ts +++ b/apps/sim/blocks/blocks/neo4j.ts @@ -1,7 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { Neo4jIcon } from '@/components/icons' import { Neo4jBlockDisplay } from '@/blocks/blocks/neo4j.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { Neo4jIntrospectResponse, Neo4jResponse } from '@/tools/neo4j/types' export const Neo4jBlock: BlockConfig = { @@ -691,96 +690,3 @@ Return ONLY valid JSON.`, }, }, } - -export const Neo4jBlockMeta = { - tags: ['data-warehouse', 'data-analytics'], - url: 'https://neo4j.com', - templates: [ - { - icon: Neo4jIcon, - title: 'Neo4j relationship exporter', - prompt: - 'Build a workflow that queries Neo4j for a chosen entity graph, writes the nodes and edges to a structured JSON adjacency file, and shares the file link for a downstream tool to visualize.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['analysis', 'research'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j fraud-ring detector', - prompt: - 'Create a scheduled workflow that queries Neo4j for suspicious connection patterns — shared devices, overlapping addresses — writes risk-scored clusters to a fraud table, and pings Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j org-chart sync', - prompt: - 'Build a workflow that pulls Workday or Rippling worker data, upserts employees and reporting relationships into Neo4j, and exposes a queryable org graph for downstream tools.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'sync'], - alsoIntegrations: ['workday', 'rippling'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j knowledge-graph builder', - prompt: - 'Create a workflow that processes documents from a knowledge base, extracts entities and relationships with an agent, and writes the graph into Neo4j for cross-document insights.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['research', 'enterprise'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j recommendation engine', - prompt: - 'Build a workflow that runs Neo4j graph algorithms — collaborative filtering, PageRank — on product-purchase data and writes per-user recommendations to a personalization table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j data lineage tracker', - prompt: - 'Create a workflow that ingests dbt manifest metadata into Neo4j, tracks lineage across tables and pipelines, and queries impact when a source schema changes.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: Neo4jIcon, - title: 'Neo4j natural-language graph explorer', - prompt: - 'Build a chat agent that introspects the Neo4j schema, translates plain-English questions like “which customers share a support agent with churned accounts?” into Cypher queries, runs them, and returns a readable answer with the matching nodes.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'research', 'automation'], - }, - ], - skills: [ - { - name: 'answer-graph-question', - description: - 'Translate a plain-English question into Cypher, run it on Neo4j, and explain the result.', - content: - '# Answer Graph Question\n\nTurn a natural-language question into a Cypher query against the Neo4j graph.\n\n## Steps\n1. Run Introspect Schema to learn the node labels, relationship types, and properties.\n2. Translate the question into a Cypher MATCH that uses the real labels and relationships from the schema.\n3. Run the Query operation and read the returned rows.\n4. If the query returns nothing, relax the pattern and explain what was tried.\n\n## Output\nA plain-language answer plus the Cypher used and the key matching nodes or paths.', - }, - { - name: 'create-graph-relationship', - description: 'Create or merge nodes and connect them with a relationship in Neo4j.', - content: - '# Create Graph Relationship\n\nAdd nodes and a relationship between them without creating duplicates.\n\n## Steps\n1. Introspect Schema to confirm the labels and relationship type to use.\n2. Use Merge (Find or Create) for each node so existing nodes are reused rather than duplicated.\n3. Create the relationship between them with the requested direction and any properties.\n\n## Output\nConfirm the nodes involved and the relationship created, noting whether each node was found or newly created.', - }, - { - name: 'find-connected-nodes', - description: 'Traverse the Neo4j graph from a starting node to find related entities.', - content: - '# Find Connected Nodes\n\nExplore the neighborhood of a node to find connected entities.\n\n## Steps\n1. Introspect Schema to know the relationship types available.\n2. Build a Cypher MATCH that starts at the given node and traverses the relevant relationships to the desired depth.\n3. Run the Query operation and collect the connected nodes.\n\n## Output\nA list of connected nodes grouped by relationship type, with the traversal path described in one line.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/neverbounce.display.ts b/apps/sim/blocks/blocks/neverbounce.display.ts index c5846c3b008..43ff9e37383 100644 --- a/apps/sim/blocks/blocks/neverbounce.display.ts +++ b/apps/sim/blocks/blocks/neverbounce.display.ts @@ -1,6 +1,6 @@ import { NeverBounceIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const NeverBounceBlockDisplay = { type: 'neverbounce', @@ -14,3 +14,8 @@ export const NeverBounceBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/neverbounce', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const NeverBounceBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.neverbounce.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/neverbounce.ts b/apps/sim/blocks/blocks/neverbounce.ts index e3fda9f92b2..45d39abd89b 100644 --- a/apps/sim/blocks/blocks/neverbounce.ts +++ b/apps/sim/blocks/blocks/neverbounce.ts @@ -1,5 +1,5 @@ import { NeverBounceBlockDisplay } from '@/blocks/blocks/neverbounce.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { NeverBounceResponse } from '@/tools/neverbounce/types' export const NeverBounceBlock: BlockConfig = { @@ -91,8 +91,3 @@ export const NeverBounceBlock: BlockConfig = { freeCredits: { type: 'number', description: 'Remaining free verification credits' }, }, } - -export const NeverBounceBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.neverbounce.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/new_relic.display.ts b/apps/sim/blocks/blocks/new_relic.display.ts index d4c21066179..c52bf2421cb 100644 --- a/apps/sim/blocks/blocks/new_relic.display.ts +++ b/apps/sim/blocks/blocks/new_relic.display.ts @@ -1,6 +1,6 @@ import { NewRelicIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const NewRelicBlockDisplay = { type: 'new_relic', @@ -14,3 +14,101 @@ export const NewRelicBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/new_relic', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const NewRelicBlockMeta = { + tags: ['monitoring', 'error-tracking', 'incident-management'], + url: 'https://newrelic.com', + templates: [ + { + icon: NewRelicIcon, + title: 'New Relic health report', + prompt: + 'Create a scheduled daily workflow that runs NRQL queries against New Relic for error rate, latency percentiles, and throughput, logs the results to a table for trend tracking, and Slacks a morning summary highlighting any degradations.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: NewRelicIcon, + title: 'New Relic deployment tracker', + prompt: + 'Build a workflow that fires after each production release, records a New Relic deployment change event for the affected entity, and posts a Slack note linking the deployment to the dashboard for the on-call engineer.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: NewRelicIcon, + title: 'New Relic anomaly investigator', + prompt: + 'Create a workflow triggered by an alert that runs targeted NRQL queries to pull the surrounding error and latency data, searches related New Relic entities for blast radius, summarizes likely causes, and opens a Linear ticket.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: NewRelicIcon, + title: 'New Relic entity inventory', + prompt: + 'Build a scheduled weekly workflow that searches New Relic for all monitored entities, fetches details for each, logs them into an inventory table, and Slacks a diff of newly added or removed services.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: NewRelicIcon, + title: 'New Relic SLO weekly review', + prompt: + 'Create a scheduled weekly workflow that runs NRQL queries to compute error budget burn for each service, writes a narrative review file for the SRE team, and links the supporting dashboards.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + }, + { + icon: NewRelicIcon, + title: 'New Relic cost-by-service breakdown', + prompt: + 'Build a scheduled monthly workflow that runs NRQL queries to attribute data ingest and compute to each New Relic entity, writes a per-team cost breakdown to a table, and emails finance the services trending over budget.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'finance', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: NewRelicIcon, + title: 'New Relic incident war-room kickoff', + prompt: + 'Create a workflow triggered by a PagerDuty incident that runs NRQL queries for the impacted service, pulls the latest deployment change event from New Relic, and posts a war-room summary with golden-signal charts to the incident Slack channel.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'incident-management'], + alsoIntegrations: ['pagerduty', 'slack'], + }, + ], + skills: [ + { + name: 'query-golden-signals', + description: + 'Run NRQL to pull latency, error rate, and throughput for a service over a time window.', + content: + '# Query Golden Signals\n\nUse New Relic NRQL to read the golden signals for a service.\n\n## Steps\n1. Identify the service or application name, using Search Entities if it is unknown.\n2. Build NRQL queries for throughput, average and p95 latency, and error rate over the requested window using SELECT ... FROM Transaction WHERE appName = ... SINCE ...\n3. Run NRQL Query for each signal and collect the values.\n\n## Output\nA short table of throughput, latency p50/p95, and error rate with the time window stated. Flag any signal that looks anomalous.', + }, + { + name: 'investigate-error-spike', + description: + 'Use NRQL to break down a New Relic error spike by type and impacted transaction.', + content: + '# Investigate Error Spike\n\nDrill into an error spike for a service in New Relic.\n\n## Steps\n1. Run an NRQL query counting errors over time to confirm and bound the spike window.\n2. Break the errors down by error.class, message, and transactionName using FACET.\n3. Use Get Entity to add context such as the service health and recent alerts.\n4. Check for a recent Create Deployment Event near the spike start to correlate with a release.\n\n## Output\nThe top error types by count, the most impacted transactions, and whether a recent deployment lines up with the spike.', + }, + { + name: 'record-deployment-marker', + description: 'Create a New Relic deployment event so releases line up with metric changes.', + content: + '# Record Deployment Marker\n\nMark a deployment in New Relic to correlate releases with performance.\n\n## Steps\n1. Identify the target entity with Search Entities to get its GUID.\n2. Run Create Deployment Event with the version, and include the commit or changelog and the user who deployed.\n3. Confirm the marker is associated with the right entity.\n\n## Output\nConfirm the deployment event created, with the entity name, version, and timestamp.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/new_relic.ts b/apps/sim/blocks/blocks/new_relic.ts index 53fd3d031dd..7c01fd8f59d 100644 --- a/apps/sim/blocks/blocks/new_relic.ts +++ b/apps/sim/blocks/blocks/new_relic.ts @@ -1,6 +1,5 @@ -import { NewRelicIcon } from '@/components/icons' import { NewRelicBlockDisplay } from '@/blocks/blocks/new_relic.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { NewRelicCustomAttributes, NewRelicResponse } from '@/tools/new_relic/types' @@ -344,101 +343,3 @@ Return ONLY the numeric timestamp - no explanations, no extra text.`, messages: { type: 'json', description: 'New Relic change tracking messages' }, }, } - -export const NewRelicBlockMeta = { - tags: ['monitoring', 'error-tracking', 'incident-management'], - url: 'https://newrelic.com', - templates: [ - { - icon: NewRelicIcon, - title: 'New Relic health report', - prompt: - 'Create a scheduled daily workflow that runs NRQL queries against New Relic for error rate, latency percentiles, and throughput, logs the results to a table for trend tracking, and Slacks a morning summary highlighting any degradations.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: NewRelicIcon, - title: 'New Relic deployment tracker', - prompt: - 'Build a workflow that fires after each production release, records a New Relic deployment change event for the affected entity, and posts a Slack note linking the deployment to the dashboard for the on-call engineer.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: NewRelicIcon, - title: 'New Relic anomaly investigator', - prompt: - 'Create a workflow triggered by an alert that runs targeted NRQL queries to pull the surrounding error and latency data, searches related New Relic entities for blast radius, summarizes likely causes, and opens a Linear ticket.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: NewRelicIcon, - title: 'New Relic entity inventory', - prompt: - 'Build a scheduled weekly workflow that searches New Relic for all monitored entities, fetches details for each, logs them into an inventory table, and Slacks a diff of newly added or removed services.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: NewRelicIcon, - title: 'New Relic SLO weekly review', - prompt: - 'Create a scheduled weekly workflow that runs NRQL queries to compute error budget burn for each service, writes a narrative review file for the SRE team, and links the supporting dashboards.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - }, - { - icon: NewRelicIcon, - title: 'New Relic cost-by-service breakdown', - prompt: - 'Build a scheduled monthly workflow that runs NRQL queries to attribute data ingest and compute to each New Relic entity, writes a per-team cost breakdown to a table, and emails finance the services trending over budget.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'finance', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: NewRelicIcon, - title: 'New Relic incident war-room kickoff', - prompt: - 'Create a workflow triggered by a PagerDuty incident that runs NRQL queries for the impacted service, pulls the latest deployment change event from New Relic, and posts a war-room summary with golden-signal charts to the incident Slack channel.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'incident-management'], - alsoIntegrations: ['pagerduty', 'slack'], - }, - ], - skills: [ - { - name: 'query-golden-signals', - description: - 'Run NRQL to pull latency, error rate, and throughput for a service over a time window.', - content: - '# Query Golden Signals\n\nUse New Relic NRQL to read the golden signals for a service.\n\n## Steps\n1. Identify the service or application name, using Search Entities if it is unknown.\n2. Build NRQL queries for throughput, average and p95 latency, and error rate over the requested window using SELECT ... FROM Transaction WHERE appName = ... SINCE ...\n3. Run NRQL Query for each signal and collect the values.\n\n## Output\nA short table of throughput, latency p50/p95, and error rate with the time window stated. Flag any signal that looks anomalous.', - }, - { - name: 'investigate-error-spike', - description: - 'Use NRQL to break down a New Relic error spike by type and impacted transaction.', - content: - '# Investigate Error Spike\n\nDrill into an error spike for a service in New Relic.\n\n## Steps\n1. Run an NRQL query counting errors over time to confirm and bound the spike window.\n2. Break the errors down by error.class, message, and transactionName using FACET.\n3. Use Get Entity to add context such as the service health and recent alerts.\n4. Check for a recent Create Deployment Event near the spike start to correlate with a release.\n\n## Output\nThe top error types by count, the most impacted transactions, and whether a recent deployment lines up with the spike.', - }, - { - name: 'record-deployment-marker', - description: 'Create a New Relic deployment event so releases line up with metric changes.', - content: - '# Record Deployment Marker\n\nMark a deployment in New Relic to correlate releases with performance.\n\n## Steps\n1. Identify the target entity with Search Entities to get its GUID.\n2. Run Create Deployment Event with the version, and include the commit or changelog and the user who deployed.\n3. Confirm the marker is associated with the right entity.\n\n## Output\nConfirm the deployment event created, with the entity name, version, and timestamp.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/notion.display.ts b/apps/sim/blocks/blocks/notion.display.ts index 8f4772dee60..97eac43da3e 100644 --- a/apps/sim/blocks/blocks/notion.display.ts +++ b/apps/sim/blocks/blocks/notion.display.ts @@ -1,6 +1,7 @@ +import { Send } from '@/components/emcn/icons' import { NotionIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const NotionBlockDisplay = { type: 'notion', @@ -29,3 +30,112 @@ export const NotionV2BlockDisplay = { integrationType: IntegrationType.Documents, hideFromToolbar: false, } satisfies BlockDisplay + +export const NotionBlockMeta = { + tags: ['note-taking', 'knowledge-base', 'content-management'], + url: 'https://www.notion.com', + templates: [ + { + icon: Send, + title: 'Customer support bot', + prompt: + 'Create a knowledge base and connect it to my Notion or Google Docs so it stays synced with my product documentation automatically. Then build an agent that answers customer questions using it with sourced citations and deploy it as a chat endpoint.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + alsoIntegrations: ['google_docs'], + }, + { + icon: NotionIcon, + title: 'Notion knowledge search', + prompt: + 'Create a knowledge base connected to my Notion workspace so all pages, databases, meeting notes, and wikis are automatically synced and searchable. Then build an agent I can ask things like "what\'s our refund policy?" or "what was decided in the Q3 planning doc?" and get instant answers with page links.', + modules: ['knowledge-base', 'agent'], + category: 'productivity', + tags: ['team', 'research'], + }, + + { + icon: NotionIcon, + title: 'Notify your team from Notion', + prompt: + 'Build a workflow that watches Notion for new or updated pages and automatically posts a Slack message so your team stays aligned without manual check-ins.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + { + icon: NotionIcon, + title: 'Notion meeting-notes capture', + prompt: + 'Build a workflow that runs after a Google Meet call, fetches the transcript, and creates a structured Notion page under the right project with attendees, decisions, and action items.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'note-taking', 'automation'], + alsoIntegrations: ['google_meet'], + }, + { + icon: NotionIcon, + title: 'Notion CRM enrichment', + prompt: + 'Create a workflow that watches a Notion database of companies, researches each new entry for funding, headcount, and industry, and appends the enriched fields back to the Notion page so the pipeline stays current.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enrichment', 'automation'], + }, + { + icon: NotionIcon, + title: 'Notion content calendar publisher', + prompt: + 'Build a scheduled workflow that queries a Notion content-calendar database for posts marked ready today, formats each one, and publishes it to the blog while updating the Notion page status to published.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content-management', 'automation'], + alsoIntegrations: ['wordpress'], + }, + { + icon: NotionIcon, + title: 'Notion weekly digest builder', + prompt: + 'Create a scheduled weekly workflow that queries a Notion project database for items completed this week, appends a summary section to a Notion review page, and posts the highlights to Slack for the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'create-structured-page', + description: + 'Create a Notion page under a parent with headings, bullets, and a clean layout.', + content: + '# Create Structured Page\n\nCreate a well-formatted Notion page, such as meeting notes or a project brief.\n\n## Steps\n1. Identify the parent page or database, using Search Workspace if the destination is not known.\n2. Run Create Page with the title and parent.\n3. Use Append Content to add the body as Notion blocks: headings for sections, bulleted lists for items, and to-do blocks for action items.\n\n## Output\nReturn the new page URL and id. Summarize the sections that were added.', + }, + { + name: 'add-database-entry', + description: 'Add a row to a Notion database with the correct property values.', + content: + '# Add Database Entry\n\nInsert a new row into a Notion database with its properties set.\n\n## Steps\n1. Run Read Database on the target database to learn its property names and types.\n2. Map the requested values to the matching properties, formatting select, date, and relation fields correctly.\n3. Run Add Database Row with the property values.\n\n## Output\nConfirm the new row id and URL, and list the property values that were written.', + }, + { + name: 'query-database', + description: 'Filter and sort a Notion database to return matching entries.', + content: + '# Query Database\n\nRetrieve entries from a Notion database that match a condition.\n\n## Steps\n1. Read the database with Read Database to confirm the property to filter on.\n2. Build a filter and optional sort for the requested condition (for example Status equals Done, sorted by date).\n3. Run Query Database and collect the matching pages.\n\n## Output\nA list of matching entries with their key properties and page links. Note the total count.', + }, + { + name: 'search-and-summarize', + description: 'Search the Notion workspace for a topic and summarize the relevant pages.', + content: + '# Search and Summarize\n\nFind and summarize Notion content on a given topic.\n\n## Steps\n1. Run Search Workspace with the topic keywords.\n2. Read the most relevant pages with Read Page.\n3. Synthesize the key points across the pages, citing each source page by title and link.\n\n## Output\nA short synthesized answer with citations to the Notion pages used. Note if the workspace had no relevant content.', + }, + ], +} as const satisfies BlockMeta + +export const NotionV2BlockMeta = { + tags: ['note-taking', 'knowledge-base', 'content-management'], + url: 'https://www.notion.com', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/notion.ts b/apps/sim/blocks/blocks/notion.ts index 191b49081e3..fbdb1998415 100644 --- a/apps/sim/blocks/blocks/notion.ts +++ b/apps/sim/blocks/blocks/notion.ts @@ -1,8 +1,6 @@ import { toError } from '@sim/utils/errors' -import { Send } from '@/components/emcn/icons' -import { NotionIcon } from '@/components/icons' import { NotionBlockDisplay, NotionV2BlockDisplay } from '@/blocks/blocks/notion.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { createVersionedToolSelector } from '@/blocks/utils' import type { NotionResponse } from '@/tools/notion/types' @@ -536,112 +534,3 @@ export const NotionV2Block: BlockConfig = { }, }, } - -export const NotionBlockMeta = { - tags: ['note-taking', 'knowledge-base', 'content-management'], - url: 'https://www.notion.com', - templates: [ - { - icon: Send, - title: 'Customer support bot', - prompt: - 'Create a knowledge base and connect it to my Notion or Google Docs so it stays synced with my product documentation automatically. Then build an agent that answers customer questions using it with sourced citations and deploy it as a chat endpoint.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - alsoIntegrations: ['google_docs'], - }, - { - icon: NotionIcon, - title: 'Notion knowledge search', - prompt: - 'Create a knowledge base connected to my Notion workspace so all pages, databases, meeting notes, and wikis are automatically synced and searchable. Then build an agent I can ask things like "what\'s our refund policy?" or "what was decided in the Q3 planning doc?" and get instant answers with page links.', - modules: ['knowledge-base', 'agent'], - category: 'productivity', - tags: ['team', 'research'], - }, - - { - icon: NotionIcon, - title: 'Notify your team from Notion', - prompt: - 'Build a workflow that watches Notion for new or updated pages and automatically posts a Slack message so your team stays aligned without manual check-ins.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - { - icon: NotionIcon, - title: 'Notion meeting-notes capture', - prompt: - 'Build a workflow that runs after a Google Meet call, fetches the transcript, and creates a structured Notion page under the right project with attendees, decisions, and action items.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'note-taking', 'automation'], - alsoIntegrations: ['google_meet'], - }, - { - icon: NotionIcon, - title: 'Notion CRM enrichment', - prompt: - 'Create a workflow that watches a Notion database of companies, researches each new entry for funding, headcount, and industry, and appends the enriched fields back to the Notion page so the pipeline stays current.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enrichment', 'automation'], - }, - { - icon: NotionIcon, - title: 'Notion content calendar publisher', - prompt: - 'Build a scheduled workflow that queries a Notion content-calendar database for posts marked ready today, formats each one, and publishes it to the blog while updating the Notion page status to published.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content-management', 'automation'], - alsoIntegrations: ['wordpress'], - }, - { - icon: NotionIcon, - title: 'Notion weekly digest builder', - prompt: - 'Create a scheduled weekly workflow that queries a Notion project database for items completed this week, appends a summary section to a Notion review page, and posts the highlights to Slack for the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'create-structured-page', - description: - 'Create a Notion page under a parent with headings, bullets, and a clean layout.', - content: - '# Create Structured Page\n\nCreate a well-formatted Notion page, such as meeting notes or a project brief.\n\n## Steps\n1. Identify the parent page or database, using Search Workspace if the destination is not known.\n2. Run Create Page with the title and parent.\n3. Use Append Content to add the body as Notion blocks: headings for sections, bulleted lists for items, and to-do blocks for action items.\n\n## Output\nReturn the new page URL and id. Summarize the sections that were added.', - }, - { - name: 'add-database-entry', - description: 'Add a row to a Notion database with the correct property values.', - content: - '# Add Database Entry\n\nInsert a new row into a Notion database with its properties set.\n\n## Steps\n1. Run Read Database on the target database to learn its property names and types.\n2. Map the requested values to the matching properties, formatting select, date, and relation fields correctly.\n3. Run Add Database Row with the property values.\n\n## Output\nConfirm the new row id and URL, and list the property values that were written.', - }, - { - name: 'query-database', - description: 'Filter and sort a Notion database to return matching entries.', - content: - '# Query Database\n\nRetrieve entries from a Notion database that match a condition.\n\n## Steps\n1. Read the database with Read Database to confirm the property to filter on.\n2. Build a filter and optional sort for the requested condition (for example Status equals Done, sorted by date).\n3. Run Query Database and collect the matching pages.\n\n## Output\nA list of matching entries with their key properties and page links. Note the total count.', - }, - { - name: 'search-and-summarize', - description: 'Search the Notion workspace for a topic and summarize the relevant pages.', - content: - '# Search and Summarize\n\nFind and summarize Notion content on a given topic.\n\n## Steps\n1. Run Search Workspace with the topic keywords.\n2. Read the most relevant pages with Read Page.\n3. Synthesize the key points across the pages, citing each source page by title and link.\n\n## Output\nA short synthesized answer with citations to the Notion pages used. Note if the workspace had no relevant content.', - }, - ], -} as const satisfies BlockMeta - -export const NotionV2BlockMeta = { - tags: ['note-taking', 'knowledge-base', 'content-management'], - url: 'https://www.notion.com', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/obsidian.display.ts b/apps/sim/blocks/blocks/obsidian.display.ts index 9ec48e9a0b9..1964d73dd26 100644 --- a/apps/sim/blocks/blocks/obsidian.display.ts +++ b/apps/sim/blocks/blocks/obsidian.display.ts @@ -1,6 +1,6 @@ import { ObsidianIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ObsidianBlockDisplay = { type: 'obsidian', @@ -14,3 +14,96 @@ export const ObsidianBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/obsidian', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const ObsidianBlockMeta = { + tags: ['note-taking', 'knowledge-base'], + url: 'https://obsidian.md', + templates: [ + { + icon: ObsidianIcon, + title: 'Obsidian daily journal agent', + prompt: + 'Build a workflow that pulls calendar events, completed tasks, and journal prompts, and generates a daily Obsidian note draft for the user to review and annotate.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'content'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian backlink builder', + prompt: + 'Create a workflow that processes new Obsidian notes, identifies entities and concepts that should be wikilinks, and rewrites the note with proper backlinks plus a hub note for new tags.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian web clipper', + prompt: + 'Build a workflow that accepts a URL from a form, scrapes the page with Firecrawl, summarizes with an agent, and writes the clip as a new Obsidian note with source metadata.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + alsoIntegrations: ['firecrawl'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian knowledge-base sync', + prompt: + 'Create a workflow that mirrors an Obsidian vault into a Sim knowledge base so an agent can answer questions over personal notes with citations.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'research'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian smart review', + prompt: + 'Build a scheduled weekly workflow that surfaces stale Obsidian notes due for spaced-repetition review, scores their freshness, and writes a review queue note for the user.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian meeting-note autopopulator', + prompt: + 'Create a workflow that runs after a Google Meet meeting, fetches the transcript, and appends a structured meeting note to an Obsidian vault under the right project folder.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'team'], + alsoIntegrations: ['google_meet'], + }, + { + icon: ObsidianIcon, + title: 'Obsidian reading-list digester', + prompt: + 'Build a scheduled workflow that reads the links saved in an Obsidian "to read" note, summarizes each article with an agent, and appends the key takeaways back into the vault as individual literature notes with source links.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'research', 'automation'], + }, + ], + skills: [ + { + name: 'capture-note', + description: 'Create a new Obsidian note with Markdown content at a chosen vault path.', + content: + '# Capture Note\n\nWrite a new note into the Obsidian vault.\n\n## Steps\n1. Decide the vault path and filename for the note, keeping folder conventions consistent.\n2. Compose the Markdown body with a clear title heading and any tags or frontmatter wanted.\n3. Run Create Note with the path and content. If the note may already exist, use Append to Note instead to avoid overwriting.\n\n## Output\nConfirm the note path created and summarize what was captured.', + }, + { + name: 'append-to-daily-note', + description: 'Append an entry to the Obsidian periodic daily note.', + content: + '# Append to Daily Note\n\nAdd a timestamped entry to the current daily note.\n\n## Steps\n1. Use Get Periodic Note to confirm the daily note exists and read its current content if needed.\n2. Format the entry as a Markdown bullet or section, including a timestamp where useful.\n3. Run Append to Periodic Note to add it to the day.\n\n## Output\nConfirm the entry was appended to the daily note and quote the line added.', + }, + { + name: 'search-vault', + description: 'Search the Obsidian vault for notes matching a query and summarize matches.', + content: + '# Search Vault\n\nFind notes in the Obsidian vault that mention a topic.\n\n## Steps\n1. Run Search with the query terms.\n2. Open the most relevant results with Get Note to read their content.\n3. Summarize the findings, linking each note by its path.\n\n## Output\nA short synthesis of what the vault says about the topic, with the source note paths listed.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/obsidian.ts b/apps/sim/blocks/blocks/obsidian.ts index bbfa692767c..35d62d1b41f 100644 --- a/apps/sim/blocks/blocks/obsidian.ts +++ b/apps/sim/blocks/blocks/obsidian.ts @@ -1,6 +1,5 @@ -import { ObsidianIcon } from '@/components/icons' import { ObsidianBlockDisplay } from '@/blocks/blocks/obsidian.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const ObsidianBlock: BlockConfig = { @@ -261,96 +260,3 @@ export const ObsidianBlock: BlockConfig = { period: { type: 'string', description: 'Period type of the periodic note' }, }, } - -export const ObsidianBlockMeta = { - tags: ['note-taking', 'knowledge-base'], - url: 'https://obsidian.md', - templates: [ - { - icon: ObsidianIcon, - title: 'Obsidian daily journal agent', - prompt: - 'Build a workflow that pulls calendar events, completed tasks, and journal prompts, and generates a daily Obsidian note draft for the user to review and annotate.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'content'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian backlink builder', - prompt: - 'Create a workflow that processes new Obsidian notes, identifies entities and concepts that should be wikilinks, and rewrites the note with proper backlinks plus a hub note for new tags.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian web clipper', - prompt: - 'Build a workflow that accepts a URL from a form, scrapes the page with Firecrawl, summarizes with an agent, and writes the clip as a new Obsidian note with source metadata.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - alsoIntegrations: ['firecrawl'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian knowledge-base sync', - prompt: - 'Create a workflow that mirrors an Obsidian vault into a Sim knowledge base so an agent can answer questions over personal notes with citations.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'research'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian smart review', - prompt: - 'Build a scheduled weekly workflow that surfaces stale Obsidian notes due for spaced-repetition review, scores their freshness, and writes a review queue note for the user.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian meeting-note autopopulator', - prompt: - 'Create a workflow that runs after a Google Meet meeting, fetches the transcript, and appends a structured meeting note to an Obsidian vault under the right project folder.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'team'], - alsoIntegrations: ['google_meet'], - }, - { - icon: ObsidianIcon, - title: 'Obsidian reading-list digester', - prompt: - 'Build a scheduled workflow that reads the links saved in an Obsidian "to read" note, summarizes each article with an agent, and appends the key takeaways back into the vault as individual literature notes with source links.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'research', 'automation'], - }, - ], - skills: [ - { - name: 'capture-note', - description: 'Create a new Obsidian note with Markdown content at a chosen vault path.', - content: - '# Capture Note\n\nWrite a new note into the Obsidian vault.\n\n## Steps\n1. Decide the vault path and filename for the note, keeping folder conventions consistent.\n2. Compose the Markdown body with a clear title heading and any tags or frontmatter wanted.\n3. Run Create Note with the path and content. If the note may already exist, use Append to Note instead to avoid overwriting.\n\n## Output\nConfirm the note path created and summarize what was captured.', - }, - { - name: 'append-to-daily-note', - description: 'Append an entry to the Obsidian periodic daily note.', - content: - '# Append to Daily Note\n\nAdd a timestamped entry to the current daily note.\n\n## Steps\n1. Use Get Periodic Note to confirm the daily note exists and read its current content if needed.\n2. Format the entry as a Markdown bullet or section, including a timestamp where useful.\n3. Run Append to Periodic Note to add it to the day.\n\n## Output\nConfirm the entry was appended to the daily note and quote the line added.', - }, - { - name: 'search-vault', - description: 'Search the Obsidian vault for notes matching a query and summarize matches.', - content: - '# Search Vault\n\nFind notes in the Obsidian vault that mention a topic.\n\n## Steps\n1. Run Search with the query terms.\n2. Open the most relevant results with Get Note to read their content.\n3. Summarize the findings, linking each note by its path.\n\n## Output\nA short synthesis of what the vault says about the topic, with the source note paths listed.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/okta.display.ts b/apps/sim/blocks/blocks/okta.display.ts index aa6ee04b653..0010d3d24a6 100644 --- a/apps/sim/blocks/blocks/okta.display.ts +++ b/apps/sim/blocks/blocks/okta.display.ts @@ -1,6 +1,6 @@ import { OktaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const OktaBlockDisplay = { type: 'okta', @@ -15,3 +15,104 @@ export const OktaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/okta', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const OktaBlockMeta = { + tags: ['identity', 'automation'], + url: 'https://www.okta.com', + templates: [ + { + icon: OktaIcon, + title: 'Okta quarterly access review', + prompt: + 'Build a scheduled quarterly workflow that pulls Okta group memberships per app, posts an attestation thread to each owner in Slack, captures confirmations, and writes the audit log to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: OktaIcon, + title: 'Okta orphan-account sweeper', + prompt: + 'Create a scheduled workflow that compares Okta users against HRIS data, finds accounts for departed employees, disables them, and writes the sweep log to an audit table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: OktaIcon, + title: 'Okta new-hire provisioning', + prompt: + 'Build a workflow that polls Workday for new hires, creates the matching Okta user, adds them to the right groups for their role, and emails IT a provisioning summary.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday', 'gmail'], + }, + { + icon: OktaIcon, + title: 'Okta compromised-account responder', + prompt: + 'Create a workflow triggered by a CrowdStrike detection on a user that suspends the matching Okta account, resets their password, and pings the security Slack channel with the action taken.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['crowdstrike', 'slack'], + }, + { + icon: OktaIcon, + title: 'Okta access-group provisioner', + prompt: + 'Build a workflow that reads an access-request table, creates the Okta group if it is missing, adds the approved users to it, and writes the grant record back to the table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + }, + { + icon: OktaIcon, + title: 'Okta SSO group sync', + prompt: + 'Create a scheduled workflow that mirrors org structure from Workday into Okta groups, ensuring group memberships stay in sync as employees change roles.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'sync'], + alsoIntegrations: ['workday'], + }, + { + icon: OktaIcon, + title: 'Okta group membership audit', + prompt: + 'Build a scheduled monthly workflow that lists every Okta group and its members, flags privileged groups with unexpected membership, and writes a review report for the security team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + ], + skills: [ + { + name: 'onboard-user', + description: 'Create an Okta user, set their profile, and add them to the right groups.', + content: + '# Onboard User\n\nProvision a new user in Okta and grant their group access.\n\n## Steps\n1. Run Create User with the profile fields: first name, last name, email, and login.\n2. Determine the groups the role requires, using List Groups to resolve group ids.\n3. Run Add User to Group for each required group.\n4. Activate the user if it was created in a staged state.\n\n## Output\nConfirm the new user id and login, and list the groups they were added to.', + }, + { + name: 'offboard-user', + description: 'Deactivate an Okta user and remove their group memberships during offboarding.', + content: + '# Offboard User\n\nRevoke access for a departing user in Okta.\n\n## Steps\n1. Find the user with List Users or Get User to confirm the user id.\n2. Run Deactivate User (or Suspend User for a temporary hold) to block sign-in.\n3. Remove the user from sensitive groups with Remove User from Group.\n4. Only run Delete User when permanent removal is explicitly requested, since it is irreversible.\n\n## Output\nConfirm the user status and the groups removed. State clearly whether the account was deactivated or deleted.', + }, + { + name: 'audit-group-membership', + description: 'List Okta groups and their members to audit access for a security review.', + content: + '# Audit Group Membership\n\nReview who belongs to Okta groups, focusing on privileged access.\n\n## Steps\n1. Run List Groups to enumerate the groups, or Get Group for a specific one.\n2. For each group of interest, run List Group Members.\n3. Highlight privileged or admin groups and call out any unexpected members.\n\n## Output\nA per-group roster with member counts, and a short list of access concerns to review.', + }, + { + name: 'reset-user-password', + description: 'Trigger an Okta password reset for a user who is locked out.', + content: + '# Reset User Password\n\nHelp a user regain access by resetting their Okta password.\n\n## Steps\n1. Locate the user with Get User to confirm identity.\n2. Run Reset Password to start the reset flow for that user.\n3. If the account is suspended, run Unsuspend User first so the reset can proceed.\n\n## Output\nConfirm the reset was initiated for the named user and note any prerequisite step that was taken.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/okta.ts b/apps/sim/blocks/blocks/okta.ts index b876b6fe1ca..25e0facb1dd 100644 --- a/apps/sim/blocks/blocks/okta.ts +++ b/apps/sim/blocks/blocks/okta.ts @@ -1,6 +1,5 @@ -import { OktaIcon } from '@/components/icons' import { OktaBlockDisplay } from '@/blocks/blocks/okta.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { OktaResponse } from '@/tools/okta/types' export const OktaBlock: BlockConfig = { @@ -374,104 +373,3 @@ export const OktaBlock: BlockConfig = { success: { type: 'boolean', description: 'Operation success status' }, }, } - -export const OktaBlockMeta = { - tags: ['identity', 'automation'], - url: 'https://www.okta.com', - templates: [ - { - icon: OktaIcon, - title: 'Okta quarterly access review', - prompt: - 'Build a scheduled quarterly workflow that pulls Okta group memberships per app, posts an attestation thread to each owner in Slack, captures confirmations, and writes the audit log to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: OktaIcon, - title: 'Okta orphan-account sweeper', - prompt: - 'Create a scheduled workflow that compares Okta users against HRIS data, finds accounts for departed employees, disables them, and writes the sweep log to an audit table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: OktaIcon, - title: 'Okta new-hire provisioning', - prompt: - 'Build a workflow that polls Workday for new hires, creates the matching Okta user, adds them to the right groups for their role, and emails IT a provisioning summary.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday', 'gmail'], - }, - { - icon: OktaIcon, - title: 'Okta compromised-account responder', - prompt: - 'Create a workflow triggered by a CrowdStrike detection on a user that suspends the matching Okta account, resets their password, and pings the security Slack channel with the action taken.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['crowdstrike', 'slack'], - }, - { - icon: OktaIcon, - title: 'Okta access-group provisioner', - prompt: - 'Build a workflow that reads an access-request table, creates the Okta group if it is missing, adds the approved users to it, and writes the grant record back to the table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - }, - { - icon: OktaIcon, - title: 'Okta SSO group sync', - prompt: - 'Create a scheduled workflow that mirrors org structure from Workday into Okta groups, ensuring group memberships stay in sync as employees change roles.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'sync'], - alsoIntegrations: ['workday'], - }, - { - icon: OktaIcon, - title: 'Okta group membership audit', - prompt: - 'Build a scheduled monthly workflow that lists every Okta group and its members, flags privileged groups with unexpected membership, and writes a review report for the security team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - ], - skills: [ - { - name: 'onboard-user', - description: 'Create an Okta user, set their profile, and add them to the right groups.', - content: - '# Onboard User\n\nProvision a new user in Okta and grant their group access.\n\n## Steps\n1. Run Create User with the profile fields: first name, last name, email, and login.\n2. Determine the groups the role requires, using List Groups to resolve group ids.\n3. Run Add User to Group for each required group.\n4. Activate the user if it was created in a staged state.\n\n## Output\nConfirm the new user id and login, and list the groups they were added to.', - }, - { - name: 'offboard-user', - description: 'Deactivate an Okta user and remove their group memberships during offboarding.', - content: - '# Offboard User\n\nRevoke access for a departing user in Okta.\n\n## Steps\n1. Find the user with List Users or Get User to confirm the user id.\n2. Run Deactivate User (or Suspend User for a temporary hold) to block sign-in.\n3. Remove the user from sensitive groups with Remove User from Group.\n4. Only run Delete User when permanent removal is explicitly requested, since it is irreversible.\n\n## Output\nConfirm the user status and the groups removed. State clearly whether the account was deactivated or deleted.', - }, - { - name: 'audit-group-membership', - description: 'List Okta groups and their members to audit access for a security review.', - content: - '# Audit Group Membership\n\nReview who belongs to Okta groups, focusing on privileged access.\n\n## Steps\n1. Run List Groups to enumerate the groups, or Get Group for a specific one.\n2. For each group of interest, run List Group Members.\n3. Highlight privileged or admin groups and call out any unexpected members.\n\n## Output\nA per-group roster with member counts, and a short list of access concerns to review.', - }, - { - name: 'reset-user-password', - description: 'Trigger an Okta password reset for a user who is locked out.', - content: - '# Reset User Password\n\nHelp a user regain access by resetting their Okta password.\n\n## Steps\n1. Locate the user with Get User to confirm identity.\n2. Run Reset Password to start the reset flow for that user.\n3. If the account is suspended, run Unsuspend User first so the reset can proceed.\n\n## Output\nConfirm the reset was initiated for the named user and note any prerequisite step that was taken.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/onedrive.display.ts b/apps/sim/blocks/blocks/onedrive.display.ts index 7a87de41f4f..0a12ec1daee 100644 --- a/apps/sim/blocks/blocks/onedrive.display.ts +++ b/apps/sim/blocks/blocks/onedrive.display.ts @@ -1,6 +1,6 @@ import { MicrosoftOneDriveIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const OneDriveBlockDisplay = { type: 'onedrive', @@ -14,3 +14,99 @@ export const OneDriveBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/onedrive', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const OneDriveBlockMeta = { + tags: ['microsoft-365', 'cloud', 'document-processing'], + url: 'https://www.microsoft.com/microsoft-365/onedrive', + templates: [ + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive contract intake', + prompt: + 'Create a scheduled workflow that polls a OneDrive intake folder for new contract PDFs, extracts clauses with Reducto, writes the structured terms to a table, and pings legal in Teams.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + alsoIntegrations: ['reducto', 'microsoft_teams'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive sharing audit', + prompt: + 'Build a scheduled weekly workflow that lists OneDrive files shared externally, flags ones above a sensitivity score, and writes a security review report.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive to knowledge base sync', + prompt: + 'Create a workflow that mirrors OneDrive folders into a knowledge base, chunks and embeds new content on change, and removes deleted files so retrieval stays accurate.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive backup verifier', + prompt: + 'Build a scheduled workflow that verifies OneDrive backups by sampling files and comparing checksums against the originating SharePoint copy, writing the report to an SRE table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['sharepoint'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive retention cleaner', + prompt: + 'Create a scheduled workflow that finds OneDrive files older than the retention horizon, requires manager approval through Teams, and archives or deletes per the policy.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive Excel-pipeline opener', + prompt: + 'Build a scheduled workflow that polls OneDrive for new Excel data drops, normalizes each, writes to a downstream table, and emails the analyst that the latest file is ready.', + modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'sync'], + alsoIntegrations: ['microsoft_excel', 'gmail'], + }, + { + icon: MicrosoftOneDriveIcon, + title: 'OneDrive new-hire kit deployer', + prompt: + 'Create a workflow triggered by a Workday new hire that creates a OneDrive new-hire folder, uploads the standard onboarding documents into it, and writes the folder link into the onboarding tracker.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + ], + skills: [ + { + name: 'upload-file-to-folder', + description: 'Upload a file to a specific OneDrive folder, creating the folder if needed.', + content: + '# Upload File to Folder\n\nPlace a file into the right OneDrive folder.\n\n## Steps\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\n2. Run Upload File with the file content and the target folder.\n3. Use a clear, consistent filename so the document is easy to find later.\n\n## Output\nConfirm the uploaded file name, its folder, and the file id or link.', + }, + { + name: 'find-and-download-file', + description: 'Locate a file in OneDrive by name and download its contents.', + content: + '# Find and Download File\n\nRetrieve a file from OneDrive for processing.\n\n## Steps\n1. Run List Files in the likely folder to find the file and its id.\n2. Run Download File with the matched file id.\n3. Pass the downloaded content to the next step, such as a parser or summarizer.\n\n## Output\nConfirm the file downloaded with its name and size, and hand off the content.', + }, + { + name: 'save-generated-document', + description: + 'Create a new text or document file in OneDrive from generated content, in the right folder.', + content: + '# Save Generated Document\n\nWrite generated content, such as a report or notes, into OneDrive as a new file.\n\n## Steps\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\n2. Compose the document content and choose a clear filename and type.\n3. Run Create File with the content, filename, and target folder.\n\n## Output\nConfirm the created file name, its folder, and the file id or link.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/onedrive.ts b/apps/sim/blocks/blocks/onedrive.ts index fc635f292d8..15b94a29e50 100644 --- a/apps/sim/blocks/blocks/onedrive.ts +++ b/apps/sim/blocks/blocks/onedrive.ts @@ -1,8 +1,7 @@ import { createLogger } from '@sim/logger' -import { MicrosoftOneDriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { OneDriveBlockDisplay } from '@/blocks/blocks/onedrive.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { OneDriveResponse } from '@/tools/onedrive/types' @@ -422,99 +421,3 @@ export const OneDriveBlock: BlockConfig = { }, }, } - -export const OneDriveBlockMeta = { - tags: ['microsoft-365', 'cloud', 'document-processing'], - url: 'https://www.microsoft.com/microsoft-365/onedrive', - templates: [ - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive contract intake', - prompt: - 'Create a scheduled workflow that polls a OneDrive intake folder for new contract PDFs, extracts clauses with Reducto, writes the structured terms to a table, and pings legal in Teams.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - alsoIntegrations: ['reducto', 'microsoft_teams'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive sharing audit', - prompt: - 'Build a scheduled weekly workflow that lists OneDrive files shared externally, flags ones above a sensitivity score, and writes a security review report.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive to knowledge base sync', - prompt: - 'Create a workflow that mirrors OneDrive folders into a knowledge base, chunks and embeds new content on change, and removes deleted files so retrieval stays accurate.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive backup verifier', - prompt: - 'Build a scheduled workflow that verifies OneDrive backups by sampling files and comparing checksums against the originating SharePoint copy, writing the report to an SRE table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['sharepoint'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive retention cleaner', - prompt: - 'Create a scheduled workflow that finds OneDrive files older than the retention horizon, requires manager approval through Teams, and archives or deletes per the policy.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive Excel-pipeline opener', - prompt: - 'Build a scheduled workflow that polls OneDrive for new Excel data drops, normalizes each, writes to a downstream table, and emails the analyst that the latest file is ready.', - modules: ['scheduled', 'files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'sync'], - alsoIntegrations: ['microsoft_excel', 'gmail'], - }, - { - icon: MicrosoftOneDriveIcon, - title: 'OneDrive new-hire kit deployer', - prompt: - 'Create a workflow triggered by a Workday new hire that creates a OneDrive new-hire folder, uploads the standard onboarding documents into it, and writes the folder link into the onboarding tracker.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - ], - skills: [ - { - name: 'upload-file-to-folder', - description: 'Upload a file to a specific OneDrive folder, creating the folder if needed.', - content: - '# Upload File to Folder\n\nPlace a file into the right OneDrive folder.\n\n## Steps\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\n2. Run Upload File with the file content and the target folder.\n3. Use a clear, consistent filename so the document is easy to find later.\n\n## Output\nConfirm the uploaded file name, its folder, and the file id or link.', - }, - { - name: 'find-and-download-file', - description: 'Locate a file in OneDrive by name and download its contents.', - content: - '# Find and Download File\n\nRetrieve a file from OneDrive for processing.\n\n## Steps\n1. Run List Files in the likely folder to find the file and its id.\n2. Run Download File with the matched file id.\n3. Pass the downloaded content to the next step, such as a parser or summarizer.\n\n## Output\nConfirm the file downloaded with its name and size, and hand off the content.', - }, - { - name: 'save-generated-document', - description: - 'Create a new text or document file in OneDrive from generated content, in the right folder.', - content: - '# Save Generated Document\n\nWrite generated content, such as a report or notes, into OneDrive as a new file.\n\n## Steps\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\n2. Compose the document content and choose a clear filename and type.\n3. Run Create File with the content, filename, and target folder.\n\n## Output\nConfirm the created file name, its folder, and the file id or link.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/onepassword.display.ts b/apps/sim/blocks/blocks/onepassword.display.ts index f5531fd60ac..18eb51d625e 100644 --- a/apps/sim/blocks/blocks/onepassword.display.ts +++ b/apps/sim/blocks/blocks/onepassword.display.ts @@ -1,6 +1,6 @@ import { OnePasswordIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const OnePasswordBlockDisplay = { type: 'onepassword', @@ -14,3 +14,101 @@ export const OnePasswordBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/onepassword', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const OnePasswordBlockMeta = { + tags: ['secrets-management', 'identity'], + url: 'https://1password.com', + templates: [ + { + icon: OnePasswordIcon, + title: '1Password vault audit', + prompt: + 'Build a scheduled monthly workflow that scans 1Password vaults for weak or reused passwords, expired items, and unused secrets, and writes a remediation queue.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + }, + { + icon: OnePasswordIcon, + title: '1Password offboarding sweep', + prompt: + 'Create a workflow that on a Workday termination rotates the shared 1Password secrets the departing employee had access to, updates the affected items, and writes the action log.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: OnePasswordIcon, + title: '1Password access-review automator', + prompt: + 'Build a scheduled quarterly workflow that inventories 1Password items per vault, requires owner re-attestation in Slack, and writes the audit log to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: OnePasswordIcon, + title: '1Password secret rotation watcher', + prompt: + 'Create a scheduled workflow that finds 1Password items older than the rotation policy, opens a Linear ticket per item to rotate, and writes the rotation status back.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: OnePasswordIcon, + title: '1Password onboarding kit', + prompt: + 'Build a workflow that when a new hire is provisioned creates their starter 1Password items based on role and team, and writes the access record to the onboarding table.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + { + icon: OnePasswordIcon, + title: '1Password Slack secret-share guard', + prompt: + 'Create a workflow that monitors Slack for accidental secret sharing, redacts the message, and posts a polite reminder to use 1Password Secret Sharing instead.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: OnePasswordIcon, + title: '1Password compliance reporter', + prompt: + 'Build a scheduled workflow that produces a 1Password compliance report — item counts, ages, and categories per vault — and writes the report file for auditors.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + ], + skills: [ + { + name: 'fetch-secret-for-runtime', + description: + 'Retrieve a secret (API key, token, or credential) from a 1Password vault to pass into a downstream step.', + content: + '# Fetch Secret for Runtime\n\nSecurely read a credential from 1Password so a later step can authenticate without hardcoding it.\n\n## Steps\n1. Identify the vault and item that holds the needed secret.\n2. Read the specific field (password, token, or key) from that item.\n3. Pass the value to the downstream tool or request that needs it.\n\n## Output\nConfirm the secret was retrieved without printing its value. Never echo, log, or include the raw secret in any summary or message.', + }, + { + name: 'audit-vault-items', + description: + 'List items in a 1Password vault and report metadata like titles, categories, and last-updated dates.', + content: + '# Audit Vault Items\n\nProduce an inventory of items in a 1Password vault for review.\n\n## Steps\n1. List the items in the specified vault.\n2. For each item collect non-sensitive metadata: title, category, tags, and last-updated date.\n3. Flag items that look stale or duplicated based on titles and dates.\n\n## Output\nA table of items with metadata only. Do not retrieve or display any secret values, just the item references.', + }, + { + name: 'create-credential-item', + description: + 'Store a new credential (login, API key, or token) as an item in a 1Password vault.', + content: + '# Create Credential Item\n\nSave a new secret into 1Password so it is centrally managed.\n\n## Steps\n1. Determine the target vault and the item category (login, API credential, secure note).\n2. Set the title and the secret fields from the provided values.\n3. Create the item in the vault.\n\n## Output\nConfirm the item was created with its title and vault. Do not repeat the secret value back in the response.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/onepassword.ts b/apps/sim/blocks/blocks/onepassword.ts index dd814de8b11..ae1f3dd92fd 100644 --- a/apps/sim/blocks/blocks/onepassword.ts +++ b/apps/sim/blocks/blocks/onepassword.ts @@ -1,6 +1,5 @@ -import { OnePasswordIcon } from '@/components/icons' import { OnePasswordBlockDisplay } from '@/blocks/blocks/onepassword.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' export const OnePasswordBlock: BlockConfig = { ...OnePasswordBlockDisplay, @@ -259,101 +258,3 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, }, }, } - -export const OnePasswordBlockMeta = { - tags: ['secrets-management', 'identity'], - url: 'https://1password.com', - templates: [ - { - icon: OnePasswordIcon, - title: '1Password vault audit', - prompt: - 'Build a scheduled monthly workflow that scans 1Password vaults for weak or reused passwords, expired items, and unused secrets, and writes a remediation queue.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - }, - { - icon: OnePasswordIcon, - title: '1Password offboarding sweep', - prompt: - 'Create a workflow that on a Workday termination rotates the shared 1Password secrets the departing employee had access to, updates the affected items, and writes the action log.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: OnePasswordIcon, - title: '1Password access-review automator', - prompt: - 'Build a scheduled quarterly workflow that inventories 1Password items per vault, requires owner re-attestation in Slack, and writes the audit log to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: OnePasswordIcon, - title: '1Password secret rotation watcher', - prompt: - 'Create a scheduled workflow that finds 1Password items older than the rotation policy, opens a Linear ticket per item to rotate, and writes the rotation status back.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: OnePasswordIcon, - title: '1Password onboarding kit', - prompt: - 'Build a workflow that when a new hire is provisioned creates their starter 1Password items based on role and team, and writes the access record to the onboarding table.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - { - icon: OnePasswordIcon, - title: '1Password Slack secret-share guard', - prompt: - 'Create a workflow that monitors Slack for accidental secret sharing, redacts the message, and posts a polite reminder to use 1Password Secret Sharing instead.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: OnePasswordIcon, - title: '1Password compliance reporter', - prompt: - 'Build a scheduled workflow that produces a 1Password compliance report — item counts, ages, and categories per vault — and writes the report file for auditors.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - ], - skills: [ - { - name: 'fetch-secret-for-runtime', - description: - 'Retrieve a secret (API key, token, or credential) from a 1Password vault to pass into a downstream step.', - content: - '# Fetch Secret for Runtime\n\nSecurely read a credential from 1Password so a later step can authenticate without hardcoding it.\n\n## Steps\n1. Identify the vault and item that holds the needed secret.\n2. Read the specific field (password, token, or key) from that item.\n3. Pass the value to the downstream tool or request that needs it.\n\n## Output\nConfirm the secret was retrieved without printing its value. Never echo, log, or include the raw secret in any summary or message.', - }, - { - name: 'audit-vault-items', - description: - 'List items in a 1Password vault and report metadata like titles, categories, and last-updated dates.', - content: - '# Audit Vault Items\n\nProduce an inventory of items in a 1Password vault for review.\n\n## Steps\n1. List the items in the specified vault.\n2. For each item collect non-sensitive metadata: title, category, tags, and last-updated date.\n3. Flag items that look stale or duplicated based on titles and dates.\n\n## Output\nA table of items with metadata only. Do not retrieve or display any secret values, just the item references.', - }, - { - name: 'create-credential-item', - description: - 'Store a new credential (login, API key, or token) as an item in a 1Password vault.', - content: - '# Create Credential Item\n\nSave a new secret into 1Password so it is centrally managed.\n\n## Steps\n1. Determine the target vault and the item category (login, API credential, secure note).\n2. Set the title and the secret fields from the provided values.\n3. Create the item in the vault.\n\n## Output\nConfirm the item was created with its title and vault. Do not repeat the secret value back in the response.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/openai.display.ts b/apps/sim/blocks/blocks/openai.display.ts index 8b3a278e7c3..21d47e5ae6b 100644 --- a/apps/sim/blocks/blocks/openai.display.ts +++ b/apps/sim/blocks/blocks/openai.display.ts @@ -1,6 +1,6 @@ import { OpenAIIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const OpenAIBlockDisplay = { type: 'openai', @@ -13,3 +13,100 @@ export const OpenAIBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/openai', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const OpenAIBlockMeta = { + tags: ['llm', 'vector-search'], + url: 'https://openai.com', + templates: [ + { + icon: OpenAIIcon, + title: 'Document embedding pipeline', + prompt: + 'Build a workflow that watches a files folder, chunks each new document, generates embeddings with OpenAI, and upserts vectors into Pinecone with rich metadata for retrieval.', + modules: ['files', 'knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'sync'], + alsoIntegrations: ['pinecone'], + }, + { + icon: OpenAIIcon, + title: 'Knowledge base re-embedder', + prompt: + 'Create a scheduled workflow that finds documents whose embeddings are stale, regenerates them with OpenAI, and re-upserts the vectors into Pinecone so retrieval stays current.', + modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'sync', 'vector-search'], + alsoIntegrations: ['pinecone'], + }, + { + icon: OpenAIIcon, + title: 'Semantic duplicate detector', + prompt: + 'Build a workflow that reads new rows from a table, generates OpenAI embeddings for each, compares them against existing rows by cosine similarity, and flags near-duplicates in an evaluation table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis', 'vector-search'], + }, + { + icon: OpenAIIcon, + title: 'Product catalog semantic search', + prompt: + 'Create a workflow that embeds each product description from a table with OpenAI, upserts the vectors into Pinecone, and lets an incoming query return the closest matching products by similarity.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'vector-search'], + alsoIntegrations: ['pinecone'], + }, + { + icon: OpenAIIcon, + title: 'Semantic ticket deduplication', + prompt: + 'Build a workflow that embeds each new support ticket with OpenAI, searches a Pinecone index of past tickets for near-duplicates, and links the new ticket to the matching thread instead of opening a fresh one.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'vector-search'], + alsoIntegrations: ['pinecone'], + }, + { + icon: OpenAIIcon, + title: 'FAQ semantic router', + prompt: + 'Create a workflow that generates OpenAI embeddings for an incoming question, compares it against embedded FAQ entries to find the closest match, and returns the canned answer when similarity is high or escalates to an agent when it is not.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'vector-search'], + }, + { + icon: OpenAIIcon, + title: 'Embedding-based content clustering', + prompt: + 'Build a scheduled workflow that pulls recent feedback from a table, generates OpenAI embeddings for each entry, clusters them by semantic similarity, and writes the themed groups with representative quotes back to a summary table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['analysis', 'automation', 'vector-search'], + }, + ], + skills: [ + { + name: 'embed-text', + description: + 'Generate an OpenAI embedding vector for a piece of text to use in semantic search or similarity.', + content: + '# Embed Text\n\nConvert text into an OpenAI embedding vector.\n\n## Steps\n1. Take the input text. If it is long, ensure it fits the model context; otherwise chunk it first.\n2. Choose the model — text-embedding-3-small for cost-efficient general use or text-embedding-3-large for higher accuracy. Keep the model consistent with any existing vectors it will be compared against.\n3. Generate the embedding.\n\n## Output\nReturn the embedding vector, the model used, and token usage. Note the vector dimensionality so it can be matched to the destination vector index.', + }, + { + name: 'embed-documents-for-retrieval', + description: + 'Chunk and embed a set of documents so they can be upserted into a vector store for retrieval.', + content: + '# Embed Documents for Retrieval\n\nPrepare documents for semantic retrieval by chunking and embedding them.\n\n## Steps\n1. Split each document into reasonably sized chunks with light overlap so context is preserved.\n2. Embed each chunk with a single consistent OpenAI model (e.g., text-embedding-3-small).\n3. Pair each vector with its source metadata (document ID, chunk index, title) ready for upsert into the vector store.\n\n## Output\nReturn the embeddings with their associated metadata and the model used. Report how many chunks were produced and flag any chunk that failed to embed.', + }, + { + name: 'find-semantic-duplicates', + description: + 'Embed items and compare vectors by cosine similarity to flag near-duplicate content.', + content: + '# Find Semantic Duplicates\n\nDetect items that mean the same thing even when worded differently.\n\n## Steps\n1. Embed each candidate item with the same OpenAI model used for the existing set.\n2. Compare each new vector against existing vectors using cosine similarity.\n3. Flag pairs above a similarity threshold (e.g., 0.9) as likely duplicates; treat lower scores as distinct.\n\n## Output\nReturn the flagged duplicate pairs with their similarity scores, sorted highest first, so they can be merged or deduplicated.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/openai.ts b/apps/sim/blocks/blocks/openai.ts index bd63287ca63..bfa42a35768 100644 --- a/apps/sim/blocks/blocks/openai.ts +++ b/apps/sim/blocks/blocks/openai.ts @@ -1,6 +1,5 @@ -import { OpenAIIcon } from '@/components/icons' import { OpenAIBlockDisplay } from '@/blocks/blocks/openai.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const OpenAIBlock: BlockConfig = { @@ -48,100 +47,3 @@ export const OpenAIBlock: BlockConfig = { usage: { type: 'json', description: 'Token usage' }, }, } - -export const OpenAIBlockMeta = { - tags: ['llm', 'vector-search'], - url: 'https://openai.com', - templates: [ - { - icon: OpenAIIcon, - title: 'Document embedding pipeline', - prompt: - 'Build a workflow that watches a files folder, chunks each new document, generates embeddings with OpenAI, and upserts vectors into Pinecone with rich metadata for retrieval.', - modules: ['files', 'knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'sync'], - alsoIntegrations: ['pinecone'], - }, - { - icon: OpenAIIcon, - title: 'Knowledge base re-embedder', - prompt: - 'Create a scheduled workflow that finds documents whose embeddings are stale, regenerates them with OpenAI, and re-upserts the vectors into Pinecone so retrieval stays current.', - modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'sync', 'vector-search'], - alsoIntegrations: ['pinecone'], - }, - { - icon: OpenAIIcon, - title: 'Semantic duplicate detector', - prompt: - 'Build a workflow that reads new rows from a table, generates OpenAI embeddings for each, compares them against existing rows by cosine similarity, and flags near-duplicates in an evaluation table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis', 'vector-search'], - }, - { - icon: OpenAIIcon, - title: 'Product catalog semantic search', - prompt: - 'Create a workflow that embeds each product description from a table with OpenAI, upserts the vectors into Pinecone, and lets an incoming query return the closest matching products by similarity.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'vector-search'], - alsoIntegrations: ['pinecone'], - }, - { - icon: OpenAIIcon, - title: 'Semantic ticket deduplication', - prompt: - 'Build a workflow that embeds each new support ticket with OpenAI, searches a Pinecone index of past tickets for near-duplicates, and links the new ticket to the matching thread instead of opening a fresh one.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'vector-search'], - alsoIntegrations: ['pinecone'], - }, - { - icon: OpenAIIcon, - title: 'FAQ semantic router', - prompt: - 'Create a workflow that generates OpenAI embeddings for an incoming question, compares it against embedded FAQ entries to find the closest match, and returns the canned answer when similarity is high or escalates to an agent when it is not.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'vector-search'], - }, - { - icon: OpenAIIcon, - title: 'Embedding-based content clustering', - prompt: - 'Build a scheduled workflow that pulls recent feedback from a table, generates OpenAI embeddings for each entry, clusters them by semantic similarity, and writes the themed groups with representative quotes back to a summary table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['analysis', 'automation', 'vector-search'], - }, - ], - skills: [ - { - name: 'embed-text', - description: - 'Generate an OpenAI embedding vector for a piece of text to use in semantic search or similarity.', - content: - '# Embed Text\n\nConvert text into an OpenAI embedding vector.\n\n## Steps\n1. Take the input text. If it is long, ensure it fits the model context; otherwise chunk it first.\n2. Choose the model — text-embedding-3-small for cost-efficient general use or text-embedding-3-large for higher accuracy. Keep the model consistent with any existing vectors it will be compared against.\n3. Generate the embedding.\n\n## Output\nReturn the embedding vector, the model used, and token usage. Note the vector dimensionality so it can be matched to the destination vector index.', - }, - { - name: 'embed-documents-for-retrieval', - description: - 'Chunk and embed a set of documents so they can be upserted into a vector store for retrieval.', - content: - '# Embed Documents for Retrieval\n\nPrepare documents for semantic retrieval by chunking and embedding them.\n\n## Steps\n1. Split each document into reasonably sized chunks with light overlap so context is preserved.\n2. Embed each chunk with a single consistent OpenAI model (e.g., text-embedding-3-small).\n3. Pair each vector with its source metadata (document ID, chunk index, title) ready for upsert into the vector store.\n\n## Output\nReturn the embeddings with their associated metadata and the model used. Report how many chunks were produced and flag any chunk that failed to embed.', - }, - { - name: 'find-semantic-duplicates', - description: - 'Embed items and compare vectors by cosine similarity to flag near-duplicate content.', - content: - '# Find Semantic Duplicates\n\nDetect items that mean the same thing even when worded differently.\n\n## Steps\n1. Embed each candidate item with the same OpenAI model used for the existing set.\n2. Compare each new vector against existing vectors using cosine similarity.\n3. Flag pairs above a similarity threshold (e.g., 0.9) as likely duplicates; treat lower scores as distinct.\n\n## Output\nReturn the flagged duplicate pairs with their similarity scores, sorted highest first, so they can be merged or deduplicated.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/outlook.display.ts b/apps/sim/blocks/blocks/outlook.display.ts index 65ccddca500..84c6b580fc7 100644 --- a/apps/sim/blocks/blocks/outlook.display.ts +++ b/apps/sim/blocks/blocks/outlook.display.ts @@ -1,6 +1,6 @@ import { OutlookIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const OutlookBlockDisplay = { type: 'outlook', @@ -15,3 +15,112 @@ export const OutlookBlockDisplay = { integrationType: IntegrationType.Email, triggerAllowed: true, } satisfies BlockDisplay + +export const OutlookBlockMeta = { + tags: ['microsoft-365', 'messaging', 'automation'], + url: 'https://www.microsoft.com/microsoft-365/outlook', + templates: [ + { + icon: OutlookIcon, + title: 'Outlook auto-responder', + prompt: + 'Build a workflow that monitors my Outlook inbox, drafts a contextual reply for every email that needs a response using my recent threads as tone reference, and saves each reply as an Outlook draft for me to review and send.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'communication', 'automation'], + }, + { + icon: OutlookIcon, + title: 'Outlook customer escalation to Zendesk', + prompt: + 'Create a workflow that reads new Outlook emails from customers, classifies whether each one is a support issue, and when it is, creates a Zendesk ticket with the email body, attachments, and contact details, then replies from Outlook with the ticket number.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + alsoIntegrations: ['zendesk'], + }, + { + icon: OutlookIcon, + title: 'Outlook executive triage', + prompt: + 'Build a scheduled workflow that scans Outlook every hour, ranks new emails by urgency, summarizes the top items, and posts a prioritized digest to a Slack channel so executives can act without opening the inbox.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['founder', 'communication', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: OutlookIcon, + title: 'Outlook invoice extractor', + prompt: + 'Build a workflow that monitors Outlook for invoice attachments, extracts vendor, amount, due date, and line items from each PDF, and logs the results to a tracking table while moving the original email to an Invoices folder.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + }, + { + icon: OutlookIcon, + title: 'Outlook follow-up reminder', + prompt: + 'Create a workflow that scans Outlook for sent emails awaiting a reply older than three business days, drafts a polite follow-up email per thread, and saves each one as a draft in Outlook ready to send.', + modules: ['agent', 'scheduled', 'workflows'], + category: 'productivity', + tags: ['sales', 'communication', 'automation'], + }, + { + icon: OutlookIcon, + title: 'Outlook to JSM ticket router', + prompt: + 'Build a workflow that reads support requests arriving in a shared Outlook mailbox, classifies the request type, and creates a Jira Service Management request in the correct service desk with the right request type, then replies from Outlook with the JSM portal link.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'enterprise'], + alsoIntegrations: ['jira_service_management'], + }, + { + icon: OutlookIcon, + title: 'Outlook newsletter clipper', + prompt: + 'Create a workflow that reads newsletters arriving in Outlook, summarizes each one into key takeaways, and appends the digest to a daily Notion page so the inbox stays clean and the insights stay searchable.', + modules: ['agent', 'scheduled', 'workflows'], + category: 'productivity', + tags: ['individual', 'research', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: OutlookIcon, + title: 'Outlook contract clause flagger', + prompt: + 'Build a workflow that scans Outlook for inbound contracts and amendments, extracts key clauses (payment terms, liability, termination, renewal), flags deviations from my standard terms, and replies internally with a summary and red-flag list.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'analysis', 'automation'], + }, + ], + skills: [ + { + name: 'send-email', + description: 'Compose and send an Outlook email to one or more recipients.', + content: + '# Send Email\n\nSend a message from the connected Outlook account.\n\n## Steps\n1. Gather the recipients, subject, and the body content.\n2. Write a clear subject and a concise, well-structured body.\n3. Run Send Email with the recipients, subject, and body. Use Draft Email instead when the message should be reviewed before sending.\n\n## Output\nConfirm the email was sent, listing recipients and subject. If drafted, note that it awaits review.', + }, + { + name: 'triage-inbox', + description: 'Read recent Outlook emails and summarize which ones need a reply or action.', + content: + '# Triage Inbox\n\nTurn a noisy Outlook inbox into a short action list.\n\n## Steps\n1. Run Read Email to pull recent unread messages.\n2. Classify each as needs reply, needs action, FYI, or ignore.\n3. For handled messages, run Mark as Read; leave items that still need a reply unread.\n\n## Output\nA prioritized list of emails that need attention, each with sender, subject, and the suggested next action.', + }, + { + name: 'forward-with-context', + description: 'Forward an Outlook email to the right person with an added note.', + content: + '# Forward with Context\n\nRoute an email to the correct owner with a short explanation.\n\n## Steps\n1. Read the target email to capture its content with Read Email.\n2. Identify the correct recipient for the topic.\n3. Run Forward Email to that recipient, adding a brief note on why it is being forwarded and what is needed.\n\n## Output\nConfirm the email was forwarded, to whom, and the note that was added.', + }, + { + name: 'file-email-to-folder', + description: 'Move an Outlook email to the appropriate folder to keep the inbox clean.', + content: + '# File Email to Folder\n\nOrganize the inbox by moving a message into the right folder.\n\n## Steps\n1. Identify the email and the destination folder.\n2. Run Move Email to relocate the message.\n3. Optionally run Mark as Read so it does not linger as unread.\n\n## Output\nConfirm the email moved, naming the source and destination folders.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/outlook.ts b/apps/sim/blocks/blocks/outlook.ts index 120fd98d81a..01de3a87d98 100644 --- a/apps/sim/blocks/blocks/outlook.ts +++ b/apps/sim/blocks/blocks/outlook.ts @@ -1,7 +1,6 @@ -import { OutlookIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { OutlookBlockDisplay } from '@/blocks/blocks/outlook.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { OutlookResponse } from '@/tools/outlook/types' @@ -447,112 +446,3 @@ export const OutlookBlock: BlockConfig = { available: ['outlook_poller'], }, } - -export const OutlookBlockMeta = { - tags: ['microsoft-365', 'messaging', 'automation'], - url: 'https://www.microsoft.com/microsoft-365/outlook', - templates: [ - { - icon: OutlookIcon, - title: 'Outlook auto-responder', - prompt: - 'Build a workflow that monitors my Outlook inbox, drafts a contextual reply for every email that needs a response using my recent threads as tone reference, and saves each reply as an Outlook draft for me to review and send.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'communication', 'automation'], - }, - { - icon: OutlookIcon, - title: 'Outlook customer escalation to Zendesk', - prompt: - 'Create a workflow that reads new Outlook emails from customers, classifies whether each one is a support issue, and when it is, creates a Zendesk ticket with the email body, attachments, and contact details, then replies from Outlook with the ticket number.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - alsoIntegrations: ['zendesk'], - }, - { - icon: OutlookIcon, - title: 'Outlook executive triage', - prompt: - 'Build a scheduled workflow that scans Outlook every hour, ranks new emails by urgency, summarizes the top items, and posts a prioritized digest to a Slack channel so executives can act without opening the inbox.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['founder', 'communication', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: OutlookIcon, - title: 'Outlook invoice extractor', - prompt: - 'Build a workflow that monitors Outlook for invoice attachments, extracts vendor, amount, due date, and line items from each PDF, and logs the results to a tracking table while moving the original email to an Invoices folder.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - }, - { - icon: OutlookIcon, - title: 'Outlook follow-up reminder', - prompt: - 'Create a workflow that scans Outlook for sent emails awaiting a reply older than three business days, drafts a polite follow-up email per thread, and saves each one as a draft in Outlook ready to send.', - modules: ['agent', 'scheduled', 'workflows'], - category: 'productivity', - tags: ['sales', 'communication', 'automation'], - }, - { - icon: OutlookIcon, - title: 'Outlook to JSM ticket router', - prompt: - 'Build a workflow that reads support requests arriving in a shared Outlook mailbox, classifies the request type, and creates a Jira Service Management request in the correct service desk with the right request type, then replies from Outlook with the JSM portal link.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'enterprise'], - alsoIntegrations: ['jira_service_management'], - }, - { - icon: OutlookIcon, - title: 'Outlook newsletter clipper', - prompt: - 'Create a workflow that reads newsletters arriving in Outlook, summarizes each one into key takeaways, and appends the digest to a daily Notion page so the inbox stays clean and the insights stay searchable.', - modules: ['agent', 'scheduled', 'workflows'], - category: 'productivity', - tags: ['individual', 'research', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: OutlookIcon, - title: 'Outlook contract clause flagger', - prompt: - 'Build a workflow that scans Outlook for inbound contracts and amendments, extracts key clauses (payment terms, liability, termination, renewal), flags deviations from my standard terms, and replies internally with a summary and red-flag list.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'analysis', 'automation'], - }, - ], - skills: [ - { - name: 'send-email', - description: 'Compose and send an Outlook email to one or more recipients.', - content: - '# Send Email\n\nSend a message from the connected Outlook account.\n\n## Steps\n1. Gather the recipients, subject, and the body content.\n2. Write a clear subject and a concise, well-structured body.\n3. Run Send Email with the recipients, subject, and body. Use Draft Email instead when the message should be reviewed before sending.\n\n## Output\nConfirm the email was sent, listing recipients and subject. If drafted, note that it awaits review.', - }, - { - name: 'triage-inbox', - description: 'Read recent Outlook emails and summarize which ones need a reply or action.', - content: - '# Triage Inbox\n\nTurn a noisy Outlook inbox into a short action list.\n\n## Steps\n1. Run Read Email to pull recent unread messages.\n2. Classify each as needs reply, needs action, FYI, or ignore.\n3. For handled messages, run Mark as Read; leave items that still need a reply unread.\n\n## Output\nA prioritized list of emails that need attention, each with sender, subject, and the suggested next action.', - }, - { - name: 'forward-with-context', - description: 'Forward an Outlook email to the right person with an added note.', - content: - '# Forward with Context\n\nRoute an email to the correct owner with a short explanation.\n\n## Steps\n1. Read the target email to capture its content with Read Email.\n2. Identify the correct recipient for the topic.\n3. Run Forward Email to that recipient, adding a brief note on why it is being forwarded and what is needed.\n\n## Output\nConfirm the email was forwarded, to whom, and the note that was added.', - }, - { - name: 'file-email-to-folder', - description: 'Move an Outlook email to the appropriate folder to keep the inbox clean.', - content: - '# File Email to Folder\n\nOrganize the inbox by moving a message into the right folder.\n\n## Steps\n1. Identify the email and the destination folder.\n2. Run Move Email to relocate the message.\n3. Optionally run Mark as Read so it does not linger as unread.\n\n## Output\nConfirm the email moved, naming the source and destination folders.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pagerduty.display.ts b/apps/sim/blocks/blocks/pagerduty.display.ts index 8e21c8edbc7..b9e96771fa7 100644 --- a/apps/sim/blocks/blocks/pagerduty.display.ts +++ b/apps/sim/blocks/blocks/pagerduty.display.ts @@ -1,6 +1,6 @@ import { PagerDutyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PagerDutyBlockDisplay = { type: 'pagerduty', @@ -16,3 +16,108 @@ export const PagerDutyBlockDisplay = { integrationType: IntegrationType.Observability, triggerAllowed: true, } satisfies BlockDisplay + +export const PagerDutyBlockMeta = { + tags: ['incident-management', 'monitoring'], + url: 'https://www.pagerduty.com', + templates: [ + { + icon: PagerDutyIcon, + title: 'PagerDuty incident war room', + prompt: + 'Build a scheduled workflow that polls PagerDuty for new severity-1 incidents, opens a Slack war-room channel, invites responders, posts the incident summary, and updates the channel topic with status.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty on-call digest', + prompt: + 'Create a scheduled daily workflow that summarizes the past 24 hours of PagerDuty incidents, MTTR, and on-call load by responder, and posts a Slack digest to the SRE channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty escalation auditor', + prompt: + 'Build a scheduled weekly workflow that audits PagerDuty escalation policies, on-call schedules, and gaps in coverage, and writes a remediation backlog to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty postmortem starter', + prompt: + 'Create a scheduled workflow that polls PagerDuty for newly resolved incidents and opens a postmortem doc for each with the timeline, responders, and Slack thread linked, ready for the team to fill in root cause.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['google_docs'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty auto-triage enricher', + prompt: + 'Build a scheduled workflow that polls PagerDuty for new incidents, pulls the affected service details, queries recent logs and the latest deploy, and posts an enriched triage summary with likely cause back as an incident note for the responder.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'incident-management', 'automation'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty customer-impact notifier', + prompt: + 'Create a scheduled workflow that polls PagerDuty for incidents on customer-facing services, looks up affected accounts in Salesforce, and drafts a status-page update plus a Slack alert to the customer success team for high-impact outages.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'incident-management', 'communication'], + alsoIntegrations: ['slack', 'salesforce'], + }, + { + icon: PagerDutyIcon, + title: 'PagerDuty alert-to-ticket bridge', + prompt: + 'Build a workflow that creates a PagerDuty incident from inbound monitoring alerts, opens a matching Linear issue with the same severity and links the two, and logs the pairing in a table so engineering can track alert-to-fix time.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'incident-management', 'ticketing'], + alsoIntegrations: ['linear'], + }, + ], + skills: [ + { + name: 'open-incident', + description: + 'Create a PagerDuty incident on a service with a title, urgency, and description so responders get paged.', + content: + '# Open Incident\n\nCreate a new PagerDuty incident and page the on-call responder.\n\n## Steps\n1. Use the Create Incident operation with the target Service ID and a clear, specific Title summarizing the problem.\n2. Set Urgency (high or low) based on customer impact and add a Description with affected systems, symptoms, and any error signatures.\n3. Optionally set an Escalation Policy ID or Assignee User ID to route the page directly.\n4. Capture the returned incident ID, number, and web URL for follow-up.\n\n## Output\nReport the new incident number, urgency, assigned service, and the PagerDuty URL so the team can jump straight to the incident.', + }, + { + name: 'triage-active-incidents', + description: + 'List triggered and acknowledged PagerDuty incidents and produce a prioritized triage summary.', + content: + '# Triage Active Incidents\n\nReview what is currently on fire and summarize it for the team.\n\n## Steps\n1. Use List Incidents filtered to Triggered then Acknowledged statuses, sorted by created at (newest first).\n2. Optionally scope to specific Service IDs or a Since window to focus on a team or recent activity.\n3. Group results by service and urgency, flagging high-urgency triggered incidents that are still unacknowledged.\n4. For each, note title, age, status, and the responsible service.\n\n## Output\nA prioritized list leading with unacknowledged high-urgency incidents, including incident number, service, age, and URL.', + }, + { + name: 'resolve-and-note-incident', + description: + 'Update a PagerDuty incident status and add a resolution note documenting what was done.', + content: + '# Resolve and Note Incident\n\nClose out an incident with a clear audit trail.\n\n## Steps\n1. Use Update Incident with the Incident ID and set Status to acknowledged or resolved as appropriate.\n2. Use Add Note on the same Incident ID to record the root cause, the fix applied, and any follow-up actions.\n3. Provide a valid From Email (a real PagerDuty user) since these write operations require it.\n4. Confirm the new status from the response.\n\n## Output\nState the incident number, its new status, and a one-line summary of the note that was attached.', + }, + { + name: 'check-whos-on-call', + description: + 'List current PagerDuty on-call assignments for given schedules or escalation policies.', + content: + '# Check Who Is On Call\n\nFind the right person to reach right now.\n\n## Steps\n1. Use List On-Calls, optionally scoped by Escalation Policy IDs or Schedule IDs.\n2. Set a Since and Until window to look at the current or an upcoming shift.\n3. Map each on-call entry to its escalation level so primary versus backup responders are clear.\n\n## Output\nA concise roster: who is on call at level 1 (primary) and level 2 (backup) per schedule, with the time window covered.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pagerduty.ts b/apps/sim/blocks/blocks/pagerduty.ts index 1c07505dfda..0d8fd67de61 100644 --- a/apps/sim/blocks/blocks/pagerduty.ts +++ b/apps/sim/blocks/blocks/pagerduty.ts @@ -1,6 +1,5 @@ -import { PagerDutyIcon } from '@/components/icons' import { PagerDutyBlockDisplay } from '@/blocks/blocks/pagerduty.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const PagerDutyBlock: BlockConfig = { @@ -492,108 +491,3 @@ export const PagerDutyBlock: BlockConfig = { ], }, } - -export const PagerDutyBlockMeta = { - tags: ['incident-management', 'monitoring'], - url: 'https://www.pagerduty.com', - templates: [ - { - icon: PagerDutyIcon, - title: 'PagerDuty incident war room', - prompt: - 'Build a scheduled workflow that polls PagerDuty for new severity-1 incidents, opens a Slack war-room channel, invites responders, posts the incident summary, and updates the channel topic with status.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty on-call digest', - prompt: - 'Create a scheduled daily workflow that summarizes the past 24 hours of PagerDuty incidents, MTTR, and on-call load by responder, and posts a Slack digest to the SRE channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty escalation auditor', - prompt: - 'Build a scheduled weekly workflow that audits PagerDuty escalation policies, on-call schedules, and gaps in coverage, and writes a remediation backlog to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty postmortem starter', - prompt: - 'Create a scheduled workflow that polls PagerDuty for newly resolved incidents and opens a postmortem doc for each with the timeline, responders, and Slack thread linked, ready for the team to fill in root cause.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['google_docs'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty auto-triage enricher', - prompt: - 'Build a scheduled workflow that polls PagerDuty for new incidents, pulls the affected service details, queries recent logs and the latest deploy, and posts an enriched triage summary with likely cause back as an incident note for the responder.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'incident-management', 'automation'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty customer-impact notifier', - prompt: - 'Create a scheduled workflow that polls PagerDuty for incidents on customer-facing services, looks up affected accounts in Salesforce, and drafts a status-page update plus a Slack alert to the customer success team for high-impact outages.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'incident-management', 'communication'], - alsoIntegrations: ['slack', 'salesforce'], - }, - { - icon: PagerDutyIcon, - title: 'PagerDuty alert-to-ticket bridge', - prompt: - 'Build a workflow that creates a PagerDuty incident from inbound monitoring alerts, opens a matching Linear issue with the same severity and links the two, and logs the pairing in a table so engineering can track alert-to-fix time.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'incident-management', 'ticketing'], - alsoIntegrations: ['linear'], - }, - ], - skills: [ - { - name: 'open-incident', - description: - 'Create a PagerDuty incident on a service with a title, urgency, and description so responders get paged.', - content: - '# Open Incident\n\nCreate a new PagerDuty incident and page the on-call responder.\n\n## Steps\n1. Use the Create Incident operation with the target Service ID and a clear, specific Title summarizing the problem.\n2. Set Urgency (high or low) based on customer impact and add a Description with affected systems, symptoms, and any error signatures.\n3. Optionally set an Escalation Policy ID or Assignee User ID to route the page directly.\n4. Capture the returned incident ID, number, and web URL for follow-up.\n\n## Output\nReport the new incident number, urgency, assigned service, and the PagerDuty URL so the team can jump straight to the incident.', - }, - { - name: 'triage-active-incidents', - description: - 'List triggered and acknowledged PagerDuty incidents and produce a prioritized triage summary.', - content: - '# Triage Active Incidents\n\nReview what is currently on fire and summarize it for the team.\n\n## Steps\n1. Use List Incidents filtered to Triggered then Acknowledged statuses, sorted by created at (newest first).\n2. Optionally scope to specific Service IDs or a Since window to focus on a team or recent activity.\n3. Group results by service and urgency, flagging high-urgency triggered incidents that are still unacknowledged.\n4. For each, note title, age, status, and the responsible service.\n\n## Output\nA prioritized list leading with unacknowledged high-urgency incidents, including incident number, service, age, and URL.', - }, - { - name: 'resolve-and-note-incident', - description: - 'Update a PagerDuty incident status and add a resolution note documenting what was done.', - content: - '# Resolve and Note Incident\n\nClose out an incident with a clear audit trail.\n\n## Steps\n1. Use Update Incident with the Incident ID and set Status to acknowledged or resolved as appropriate.\n2. Use Add Note on the same Incident ID to record the root cause, the fix applied, and any follow-up actions.\n3. Provide a valid From Email (a real PagerDuty user) since these write operations require it.\n4. Confirm the new status from the response.\n\n## Output\nState the incident number, its new status, and a one-line summary of the note that was attached.', - }, - { - name: 'check-whos-on-call', - description: - 'List current PagerDuty on-call assignments for given schedules or escalation policies.', - content: - '# Check Who Is On Call\n\nFind the right person to reach right now.\n\n## Steps\n1. Use List On-Calls, optionally scoped by Escalation Policy IDs or Schedule IDs.\n2. Set a Since and Until window to look at the current or an upcoming shift.\n3. Map each on-call entry to its escalation level so primary versus backup responders are clear.\n\n## Output\nA concise roster: who is on call at level 1 (primary) and level 2 (backup) per schedule, with the time window covered.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/parallel.display.ts b/apps/sim/blocks/blocks/parallel.display.ts index b56525a26c6..b93c2db4758 100644 --- a/apps/sim/blocks/blocks/parallel.display.ts +++ b/apps/sim/blocks/blocks/parallel.display.ts @@ -1,6 +1,6 @@ import { ParallelIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ParallelBlockDisplay = { type: 'parallel_ai', @@ -14,3 +14,106 @@ export const ParallelBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/parallel_ai', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const ParallelBlockMeta = { + tags: ['web-scraping', 'llm', 'agentic'], + url: 'https://parallel.ai', + templates: [ + { + icon: ParallelIcon, + title: 'Parallel AI account research agent', + prompt: + 'Build a workflow that takes a company name, runs Parallel AI deep research for recent funding, leadership changes, and product launches, and writes a structured account brief with citations back to the matching CRM record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI competitor monitor', + prompt: + 'Create a scheduled workflow that uses Parallel AI search to find new announcements from a list of competitors, extracts the key details from each source URL, and posts a cited digest to Slack for the product team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['research', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI URL fact extractor', + prompt: + 'Build a workflow that reads a table of source URLs, uses Parallel AI extract to pull the structured facts requested for each page, and writes the normalized results back to the table for review.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['research', 'automation', 'enrichment'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI market landscape report', + prompt: + 'Create a workflow that runs Parallel AI deep research on a market category, synthesizes the players, pricing, and trends into a Markdown report file, and shares the link with the strategy team.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['research', 'analysis', 'reporting'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI lead enrichment pipeline', + prompt: + 'Build a workflow that runs Parallel AI search and extract on each new inbound lead to find company size, industry, and tech stack, scores fit against the ICP, and updates the lead record with the enriched profile.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enrichment', 'automation'], + alsoIntegrations: ['hubspot'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI due-diligence brief', + prompt: + 'Create a workflow that runs Parallel AI deep research on a target company for litigation, leadership, and financial signals, extracts supporting detail from each cited source, and writes a due-diligence brief file for the deal team.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['research', 'enterprise', 'analysis'], + }, + { + icon: ParallelIcon, + title: 'Parallel AI daily topic digest', + prompt: + 'Build a scheduled daily workflow that uses Parallel AI search across the topics a team follows, extracts the key facts from the top results, and emails a concise cited digest each morning.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting', 'automation'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'research-company-brief', + description: + 'Run Parallel AI deep research on a company and produce a cited brief covering funding, leadership, and product.', + content: + '# Research Company Brief\n\nGenerate a sourced account brief for a target company.\n\n## Steps\n1. Use the Deep Research operation with a Research Query naming the company and the angles to cover: recent funding, leadership changes, product launches, and notable news.\n2. Choose a processor tier (Pro for balance, Ultra for depth) and optionally constrain Include or Exclude Domains.\n3. Read the structured content plus the basis field for citations and confidence per claim.\n\n## Output\nA brief organized by topic, where every claim links to its source URL from the basis, and note any low-confidence items that need verification.', + }, + { + name: 'web-search-with-objective', + description: + 'Use Parallel AI search to answer a question across the web and return ranked, cited results.', + content: + '# Web Search With Objective\n\nAnswer a factual question grounded in fresh web sources.\n\n## Steps\n1. Use the Search operation and state a clear Objective describing what you want to know and which sources to prefer.\n2. Optionally add specific Search Queries, set a Search Mode (one-shot, agentic, or fast), and limit results with Include or Exclude Domains.\n3. Tune Max Results and Max Chars Per Result for breadth versus depth.\n\n## Output\nA direct answer to the objective followed by the supporting results, each with title, URL, and the relevant excerpt.', + }, + { + name: 'extract-facts-from-urls', + description: 'Use Parallel AI extract to pull structured facts from a list of source URLs.', + content: + '# Extract Facts From URLs\n\nTurn a set of pages into structured data.\n\n## Steps\n1. Use the Extract operation and provide the comma-separated URLs to read.\n2. Set an Extract Objective describing exactly which fields to pull from each page.\n3. Enable Include Excerpts for supporting snippets and Include Full Content only when the whole page text is needed.\n\n## Output\nA normalized record per URL with the requested fields and an excerpt backing each value, plus a note on any URL that could not be parsed.', + }, + { + name: 'monitor-competitor-news', + description: + 'Search Parallel AI for recent announcements from named competitors and summarize the changes.', + content: + '# Monitor Competitor News\n\nTrack what rivals shipped or announced recently.\n\n## Steps\n1. Use the Search operation with an Objective naming the competitors and the timeframe of interest.\n2. Optionally restrict Include Domains to the competitors official sites and reputable news outlets.\n3. For high-signal hits, follow up with the Extract operation to pull the specific details from each announcement URL.\n\n## Output\nA dated digest grouped by competitor, each item a one-line summary with its source URL and why it matters.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/parallel.ts b/apps/sim/blocks/blocks/parallel.ts index b3416ad20a1..646282fb88f 100644 --- a/apps/sim/blocks/blocks/parallel.ts +++ b/apps/sim/blocks/blocks/parallel.ts @@ -1,6 +1,5 @@ -import { ParallelIcon } from '@/components/icons' import { ParallelBlockDisplay } from '@/blocks/blocks/parallel.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' export const ParallelBlock: BlockConfig = { @@ -266,106 +265,3 @@ export const ParallelBlock: BlockConfig = { }, }, } - -export const ParallelBlockMeta = { - tags: ['web-scraping', 'llm', 'agentic'], - url: 'https://parallel.ai', - templates: [ - { - icon: ParallelIcon, - title: 'Parallel AI account research agent', - prompt: - 'Build a workflow that takes a company name, runs Parallel AI deep research for recent funding, leadership changes, and product launches, and writes a structured account brief with citations back to the matching CRM record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI competitor monitor', - prompt: - 'Create a scheduled workflow that uses Parallel AI search to find new announcements from a list of competitors, extracts the key details from each source URL, and posts a cited digest to Slack for the product team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['research', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI URL fact extractor', - prompt: - 'Build a workflow that reads a table of source URLs, uses Parallel AI extract to pull the structured facts requested for each page, and writes the normalized results back to the table for review.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['research', 'automation', 'enrichment'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI market landscape report', - prompt: - 'Create a workflow that runs Parallel AI deep research on a market category, synthesizes the players, pricing, and trends into a Markdown report file, and shares the link with the strategy team.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['research', 'analysis', 'reporting'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI lead enrichment pipeline', - prompt: - 'Build a workflow that runs Parallel AI search and extract on each new inbound lead to find company size, industry, and tech stack, scores fit against the ICP, and updates the lead record with the enriched profile.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enrichment', 'automation'], - alsoIntegrations: ['hubspot'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI due-diligence brief', - prompt: - 'Create a workflow that runs Parallel AI deep research on a target company for litigation, leadership, and financial signals, extracts supporting detail from each cited source, and writes a due-diligence brief file for the deal team.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['research', 'enterprise', 'analysis'], - }, - { - icon: ParallelIcon, - title: 'Parallel AI daily topic digest', - prompt: - 'Build a scheduled daily workflow that uses Parallel AI search across the topics a team follows, extracts the key facts from the top results, and emails a concise cited digest each morning.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting', 'automation'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'research-company-brief', - description: - 'Run Parallel AI deep research on a company and produce a cited brief covering funding, leadership, and product.', - content: - '# Research Company Brief\n\nGenerate a sourced account brief for a target company.\n\n## Steps\n1. Use the Deep Research operation with a Research Query naming the company and the angles to cover: recent funding, leadership changes, product launches, and notable news.\n2. Choose a processor tier (Pro for balance, Ultra for depth) and optionally constrain Include or Exclude Domains.\n3. Read the structured content plus the basis field for citations and confidence per claim.\n\n## Output\nA brief organized by topic, where every claim links to its source URL from the basis, and note any low-confidence items that need verification.', - }, - { - name: 'web-search-with-objective', - description: - 'Use Parallel AI search to answer a question across the web and return ranked, cited results.', - content: - '# Web Search With Objective\n\nAnswer a factual question grounded in fresh web sources.\n\n## Steps\n1. Use the Search operation and state a clear Objective describing what you want to know and which sources to prefer.\n2. Optionally add specific Search Queries, set a Search Mode (one-shot, agentic, or fast), and limit results with Include or Exclude Domains.\n3. Tune Max Results and Max Chars Per Result for breadth versus depth.\n\n## Output\nA direct answer to the objective followed by the supporting results, each with title, URL, and the relevant excerpt.', - }, - { - name: 'extract-facts-from-urls', - description: 'Use Parallel AI extract to pull structured facts from a list of source URLs.', - content: - '# Extract Facts From URLs\n\nTurn a set of pages into structured data.\n\n## Steps\n1. Use the Extract operation and provide the comma-separated URLs to read.\n2. Set an Extract Objective describing exactly which fields to pull from each page.\n3. Enable Include Excerpts for supporting snippets and Include Full Content only when the whole page text is needed.\n\n## Output\nA normalized record per URL with the requested fields and an excerpt backing each value, plus a note on any URL that could not be parsed.', - }, - { - name: 'monitor-competitor-news', - description: - 'Search Parallel AI for recent announcements from named competitors and summarize the changes.', - content: - '# Monitor Competitor News\n\nTrack what rivals shipped or announced recently.\n\n## Steps\n1. Use the Search operation with an Objective naming the competitors and the timeframe of interest.\n2. Optionally restrict Include Domains to the competitors official sites and reputable news outlets.\n3. For high-signal hits, follow up with the Extract operation to pull the specific details from each announcement URL.\n\n## Output\nA dated digest grouped by competitor, each item a one-line summary with its source URL and why it matters.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/peopledatalabs.display.ts b/apps/sim/blocks/blocks/peopledatalabs.display.ts index 2f6adb42939..691f8cfcdd9 100644 --- a/apps/sim/blocks/blocks/peopledatalabs.display.ts +++ b/apps/sim/blocks/blocks/peopledatalabs.display.ts @@ -1,6 +1,6 @@ import { PeopleDataLabsIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PeopleDataLabsBlockDisplay = { type: 'peopledatalabs', @@ -15,3 +15,109 @@ export const PeopleDataLabsBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/peopledatalabs', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const PeopleDataLabsBlockMeta = { + tags: ['enrichment'], + url: 'https://www.peopledatalabs.com', + templates: [ + { + icon: PeopleDataLabsIcon, + title: 'PDL person enricher', + prompt: + 'Build a workflow that watches CRM contacts, enriches each via People Data Labs with role, seniority, and company signals, and writes the enriched data back.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['hubspot'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL company enricher', + prompt: + 'Create a workflow that takes a list of company domains, runs People Data Labs company-search, and writes firmographics, employee count, and tech stack into a tables-based research base.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL ICP scorer', + prompt: + 'Build a workflow that scores inbound leads against the ICP using People Data Labs enrichment fields, routes high-fit leads to sales, and writes the score back to the CRM.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL CRM gap-filler', + prompt: + 'Create a scheduled workflow that finds CRM contacts missing key fields, runs People Data Labs to fill gaps, and writes coverage metrics to a hygiene table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL lookalike expander', + prompt: + 'Build a workflow that derives firmographic attributes from a seed account list and uses People Data Labs company-search to find similar companies, expanding the TAM and writing the new prospects into Salesforce.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL hiring-signal alerter', + prompt: + 'Create a scheduled workflow that runs People Data Labs person-search for new hires in relevant roles at tracked accounts and posts a Slack alert when a match appears.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PeopleDataLabsIcon, + title: 'PDL + Email Bison outbound', + prompt: + 'Build a workflow that runs People Data Labs on prospects, drafts a personalized first-touch email based on enrichment fields, and sends via Email Bison.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + ], + skills: [ + { + name: 'enrich-person', + description: + 'Enrich a single person from an email, LinkedIn URL, or name plus company using People Data Labs.', + content: + '# Enrich Person\n\nFill in a full profile for one contact.\n\n## Steps\n1. Use the Person Enrich operation and provide the strongest identifier available: Email or LinkedIn URL first, otherwise First and Last Name plus Company.\n2. Set a Min Likelihood (for example 6) to avoid weak matches.\n3. Read the matched person record for job title, seniority, company, location, and contact fields, and check the likelihood score.\n\n## Output\nThe enriched profile (title, seniority, company, location, emails) plus the match likelihood; if not matched, say so and list which identifiers were tried.', + }, + { + name: 'search-people-by-criteria', + description: + 'Search the People Data Labs person dataset by role, location, or company using SQL or Elasticsearch DSL.', + content: + '# Search People By Criteria\n\nFind people matching a target profile.\n\n## Steps\n1. Use the Person Search operation and write a SQL query (for example filter on job_title and location_country) or an Elasticsearch DSL query for finer control.\n2. Set Result Size for the page, and optionally a Dataset filter (such as email or mobile_phone) to require certain coverage.\n3. To page through more results, pass the returned scroll token on the next call.\n\n## Output\nThe list of matched people with key fields, the total dataset match count, and the scroll token to fetch the next page.', + }, + { + name: 'enrich-company', + description: + 'Enrich a company from a name, website, or LinkedIn URL to get firmographics with People Data Labs.', + content: + '# Enrich Company\n\nBuild a firmographic profile for one company.\n\n## Steps\n1. Use the Company Enrich operation and provide a Website (most reliable), Company Name, ticker, or LinkedIn URL.\n2. Optionally add a Location or PDL Company ID to disambiguate common names, and set Min Likelihood.\n3. Read the matched company record for industry, employee count, headquarters, and tech-related signals.\n\n## Output\nThe company firmographics (industry, size, location, founded, website) with the match confidence noted.', + }, + { + name: 'bulk-enrich-contacts', + description: + 'Enrich many people or companies in one call with People Data Labs bulk enrichment.', + content: + '# Bulk Enrich Contacts\n\nEnrich a batch of records efficiently.\n\n## Steps\n1. Use Bulk Person Enrich (or Bulk Company Enrich) and pass a JSON array of request objects, each with its own params such as a LinkedIn URL, email, or website.\n2. Optionally set a Required Fields expression (for example emails AND job_title) so only records with that coverage are returned.\n3. Iterate the results array in order, matching each result back to its input record.\n\n## Output\nA per-record summary listing which inputs matched, the enriched fields returned, and which inputs had no match for follow-up.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/peopledatalabs.ts b/apps/sim/blocks/blocks/peopledatalabs.ts index b62d0fd3268..cdcf7171c2b 100644 --- a/apps/sim/blocks/blocks/peopledatalabs.ts +++ b/apps/sim/blocks/blocks/peopledatalabs.ts @@ -1,6 +1,5 @@ -import { PeopleDataLabsIcon } from '@/components/icons' import { PeopleDataLabsBlockDisplay } from '@/blocks/blocks/peopledatalabs.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { PdlPersonEnrichResponse } from '@/tools/peopledatalabs/types' @@ -620,109 +619,3 @@ export const PeopleDataLabsBlock: BlockConfig = { suggestions: { type: 'json', description: 'Autocomplete suggestions' }, }, } - -export const PeopleDataLabsBlockMeta = { - tags: ['enrichment'], - url: 'https://www.peopledatalabs.com', - templates: [ - { - icon: PeopleDataLabsIcon, - title: 'PDL person enricher', - prompt: - 'Build a workflow that watches CRM contacts, enriches each via People Data Labs with role, seniority, and company signals, and writes the enriched data back.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['hubspot'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL company enricher', - prompt: - 'Create a workflow that takes a list of company domains, runs People Data Labs company-search, and writes firmographics, employee count, and tech stack into a tables-based research base.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL ICP scorer', - prompt: - 'Build a workflow that scores inbound leads against the ICP using People Data Labs enrichment fields, routes high-fit leads to sales, and writes the score back to the CRM.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL CRM gap-filler', - prompt: - 'Create a scheduled workflow that finds CRM contacts missing key fields, runs People Data Labs to fill gaps, and writes coverage metrics to a hygiene table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL lookalike expander', - prompt: - 'Build a workflow that derives firmographic attributes from a seed account list and uses People Data Labs company-search to find similar companies, expanding the TAM and writing the new prospects into Salesforce.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL hiring-signal alerter', - prompt: - 'Create a scheduled workflow that runs People Data Labs person-search for new hires in relevant roles at tracked accounts and posts a Slack alert when a match appears.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PeopleDataLabsIcon, - title: 'PDL + Email Bison outbound', - prompt: - 'Build a workflow that runs People Data Labs on prospects, drafts a personalized first-touch email based on enrichment fields, and sends via Email Bison.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - ], - skills: [ - { - name: 'enrich-person', - description: - 'Enrich a single person from an email, LinkedIn URL, or name plus company using People Data Labs.', - content: - '# Enrich Person\n\nFill in a full profile for one contact.\n\n## Steps\n1. Use the Person Enrich operation and provide the strongest identifier available: Email or LinkedIn URL first, otherwise First and Last Name plus Company.\n2. Set a Min Likelihood (for example 6) to avoid weak matches.\n3. Read the matched person record for job title, seniority, company, location, and contact fields, and check the likelihood score.\n\n## Output\nThe enriched profile (title, seniority, company, location, emails) plus the match likelihood; if not matched, say so and list which identifiers were tried.', - }, - { - name: 'search-people-by-criteria', - description: - 'Search the People Data Labs person dataset by role, location, or company using SQL or Elasticsearch DSL.', - content: - '# Search People By Criteria\n\nFind people matching a target profile.\n\n## Steps\n1. Use the Person Search operation and write a SQL query (for example filter on job_title and location_country) or an Elasticsearch DSL query for finer control.\n2. Set Result Size for the page, and optionally a Dataset filter (such as email or mobile_phone) to require certain coverage.\n3. To page through more results, pass the returned scroll token on the next call.\n\n## Output\nThe list of matched people with key fields, the total dataset match count, and the scroll token to fetch the next page.', - }, - { - name: 'enrich-company', - description: - 'Enrich a company from a name, website, or LinkedIn URL to get firmographics with People Data Labs.', - content: - '# Enrich Company\n\nBuild a firmographic profile for one company.\n\n## Steps\n1. Use the Company Enrich operation and provide a Website (most reliable), Company Name, ticker, or LinkedIn URL.\n2. Optionally add a Location or PDL Company ID to disambiguate common names, and set Min Likelihood.\n3. Read the matched company record for industry, employee count, headquarters, and tech-related signals.\n\n## Output\nThe company firmographics (industry, size, location, founded, website) with the match confidence noted.', - }, - { - name: 'bulk-enrich-contacts', - description: - 'Enrich many people or companies in one call with People Data Labs bulk enrichment.', - content: - '# Bulk Enrich Contacts\n\nEnrich a batch of records efficiently.\n\n## Steps\n1. Use Bulk Person Enrich (or Bulk Company Enrich) and pass a JSON array of request objects, each with its own params such as a LinkedIn URL, email, or website.\n2. Optionally set a Required Fields expression (for example emails AND job_title) so only records with that coverage are returned.\n3. Iterate the results array in order, matching each result back to its input record.\n\n## Output\nA per-record summary listing which inputs matched, the enriched fields returned, and which inputs had no match for follow-up.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/perplexity.display.ts b/apps/sim/blocks/blocks/perplexity.display.ts index c6f52c63024..a12beeae724 100644 --- a/apps/sim/blocks/blocks/perplexity.display.ts +++ b/apps/sim/blocks/blocks/perplexity.display.ts @@ -1,6 +1,6 @@ import { PerplexityIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PerplexityBlockDisplay = { type: 'perplexity', @@ -15,3 +15,102 @@ export const PerplexityBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/perplexity', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const PerplexityBlockMeta = { + tags: ['llm', 'web-scraping', 'agentic'], + url: 'https://www.perplexity.ai', + templates: [ + { + icon: PerplexityIcon, + title: 'Perplexity research briefer', + prompt: + 'Build an agent that takes a topic or company name, runs deep web research via Perplexity with citations, and saves a structured brief file with sources, key findings, and open questions.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + { + icon: PerplexityIcon, + title: 'Daily news brief via Perplexity', + prompt: + 'Create a scheduled daily workflow that queries Perplexity for the latest news on topics I follow, summarizes each thread with citations, and posts the digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: PerplexityIcon, + title: 'Multi-source research agent', + prompt: + 'Create an agent that triangulates a topic across Perplexity, Exa, and Tavily, deduplicates findings, and produces a consensus brief with confidence scores per claim.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'enterprise'], + alsoIntegrations: ['exa', 'tavily'], + }, + { + icon: PerplexityIcon, + title: 'Perplexity sales account refresh', + prompt: + 'Create a scheduled workflow that walks accounts in my CRM, runs Perplexity research on each for new funding, headcount changes, or product launches, and writes the digest back to the account record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: PerplexityIcon, + title: 'Perplexity + DSPy structured-output evaluator', + prompt: + 'Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['dspy', 'huggingface', 'mistral_parse'], + }, + { + icon: PerplexityIcon, + title: 'Perplexity + Hugging Face semantic dedup', + prompt: + 'Build a workflow that runs Perplexity research, embeds findings with a Hugging Face encoder, deduplicates near-identical claims, and writes a clean research file.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + alsoIntegrations: ['huggingface'], + }, + { + icon: PerplexityIcon, + title: 'Perplexity competitor-watch monitor', + prompt: + 'Build a scheduled workflow that asks Perplexity for any new launches, pricing changes, or announcements from a list of competitors, summarizes what changed since last run, and posts a cited digest to a Slack channel for the product team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['research', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'answer-with-citations', + description: + 'Ask Perplexity a question and get an answer grounded in current web sources with citations.', + content: + '# Answer With Citations\n\nGet a current, sourced answer to a question.\n\n## Steps\n1. Use the Chat operation and write the question as the User Prompt. Add a System Prompt to set tone and require inline citations.\n2. Pick a model: sonar for quick answers, sonar-pro for harder questions, or sonar-deep-research for thorough multi-source work.\n3. Keep temperature low (around 0.2) for factual tasks and set Max Tokens to cap length.\n\n## Output\nThe answer with its supporting sources, and a note flagging anything the model could not confirm.', + }, + { + name: 'search-recent-news', + description: + 'Use Perplexity search with a recency filter to find the latest results on a topic.', + content: + '# Search Recent News\n\nFind the freshest sources on a topic.\n\n## Steps\n1. Use the Search operation and enter the topic as the Search Query.\n2. Set a Recency Filter (hour, day, week, month, or year) or pin an After Date and Before Date window.\n3. Optionally constrain a Domain Filter to trusted outlets and set a Country code for regional results.\n4. Adjust Max Results for breadth.\n\n## Output\nA dated list of results, each with title, URL, and a one-line summary, ordered by relevance and recency.', + }, + { + name: 'domain-restricted-research', + description: + 'Run a Perplexity search restricted to specific authoritative domains and summarize findings.', + content: + '# Domain-Restricted Research\n\nResearch a topic using only trusted sources.\n\n## Steps\n1. Use the Search operation with a precise Search Query.\n2. Set the Domain Filter to the allowed domains (comma-separated, up to twenty) such as official, academic, or .gov sites.\n3. Tune Max Page Tokens to control how much text is pulled per source.\n4. Synthesize the returned results into a short summary.\n\n## Output\nA concise summary drawn only from the allowed domains, with each finding attributed to its source URL.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/perplexity.ts b/apps/sim/blocks/blocks/perplexity.ts index 924db15eef5..6ee8da8f58d 100644 --- a/apps/sim/blocks/blocks/perplexity.ts +++ b/apps/sim/blocks/blocks/perplexity.ts @@ -1,6 +1,5 @@ -import { PerplexityIcon } from '@/components/icons' import { PerplexityBlockDisplay } from '@/blocks/blocks/perplexity.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { PerplexityChatResponse, PerplexitySearchResponse } from '@/tools/perplexity/types' type PerplexityResponse = PerplexityChatResponse | PerplexitySearchResponse @@ -251,102 +250,3 @@ Return ONLY the date string in MM/DD/YYYY format - no explanations, no quotes, n results: { type: 'json', description: 'Search results array' }, }, } - -export const PerplexityBlockMeta = { - tags: ['llm', 'web-scraping', 'agentic'], - url: 'https://www.perplexity.ai', - templates: [ - { - icon: PerplexityIcon, - title: 'Perplexity research briefer', - prompt: - 'Build an agent that takes a topic or company name, runs deep web research via Perplexity with citations, and saves a structured brief file with sources, key findings, and open questions.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - { - icon: PerplexityIcon, - title: 'Daily news brief via Perplexity', - prompt: - 'Create a scheduled daily workflow that queries Perplexity for the latest news on topics I follow, summarizes each thread with citations, and posts the digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: PerplexityIcon, - title: 'Multi-source research agent', - prompt: - 'Create an agent that triangulates a topic across Perplexity, Exa, and Tavily, deduplicates findings, and produces a consensus brief with confidence scores per claim.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'enterprise'], - alsoIntegrations: ['exa', 'tavily'], - }, - { - icon: PerplexityIcon, - title: 'Perplexity sales account refresh', - prompt: - 'Create a scheduled workflow that walks accounts in my CRM, runs Perplexity research on each for new funding, headcount changes, or product launches, and writes the digest back to the account record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: PerplexityIcon, - title: 'Perplexity + DSPy structured-output evaluator', - prompt: - 'Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['dspy', 'huggingface', 'mistral_parse'], - }, - { - icon: PerplexityIcon, - title: 'Perplexity + Hugging Face semantic dedup', - prompt: - 'Build a workflow that runs Perplexity research, embeds findings with a Hugging Face encoder, deduplicates near-identical claims, and writes a clean research file.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - alsoIntegrations: ['huggingface'], - }, - { - icon: PerplexityIcon, - title: 'Perplexity competitor-watch monitor', - prompt: - 'Build a scheduled workflow that asks Perplexity for any new launches, pricing changes, or announcements from a list of competitors, summarizes what changed since last run, and posts a cited digest to a Slack channel for the product team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['research', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'answer-with-citations', - description: - 'Ask Perplexity a question and get an answer grounded in current web sources with citations.', - content: - '# Answer With Citations\n\nGet a current, sourced answer to a question.\n\n## Steps\n1. Use the Chat operation and write the question as the User Prompt. Add a System Prompt to set tone and require inline citations.\n2. Pick a model: sonar for quick answers, sonar-pro for harder questions, or sonar-deep-research for thorough multi-source work.\n3. Keep temperature low (around 0.2) for factual tasks and set Max Tokens to cap length.\n\n## Output\nThe answer with its supporting sources, and a note flagging anything the model could not confirm.', - }, - { - name: 'search-recent-news', - description: - 'Use Perplexity search with a recency filter to find the latest results on a topic.', - content: - '# Search Recent News\n\nFind the freshest sources on a topic.\n\n## Steps\n1. Use the Search operation and enter the topic as the Search Query.\n2. Set a Recency Filter (hour, day, week, month, or year) or pin an After Date and Before Date window.\n3. Optionally constrain a Domain Filter to trusted outlets and set a Country code for regional results.\n4. Adjust Max Results for breadth.\n\n## Output\nA dated list of results, each with title, URL, and a one-line summary, ordered by relevance and recency.', - }, - { - name: 'domain-restricted-research', - description: - 'Run a Perplexity search restricted to specific authoritative domains and summarize findings.', - content: - '# Domain-Restricted Research\n\nResearch a topic using only trusted sources.\n\n## Steps\n1. Use the Search operation with a precise Search Query.\n2. Set the Domain Filter to the allowed domains (comma-separated, up to twenty) such as official, academic, or .gov sites.\n3. Tune Max Page Tokens to control how much text is pulled per source.\n4. Synthesize the returned results into a short summary.\n\n## Output\nA concise summary drawn only from the allowed domains, with each finding attributed to its source URL.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/persona.display.ts b/apps/sim/blocks/blocks/persona.display.ts index 5f6445006dc..24feb110d98 100644 --- a/apps/sim/blocks/blocks/persona.display.ts +++ b/apps/sim/blocks/blocks/persona.display.ts @@ -1,6 +1,6 @@ import { PersonaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PersonaBlockDisplay = { type: 'persona', @@ -14,3 +14,130 @@ export const PersonaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/persona', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const PersonaBlockMeta = { + tags: ['identity'], + url: 'https://withpersona.com', + templates: [ + { + icon: PersonaIcon, + title: 'Customer onboarding identity verification', + prompt: + 'Build a workflow triggered when a new customer signs up that creates a Persona inquiry from our KYC template with their name and email pre-filled, generates a one-time verification link, and emails it to the customer.', + modules: ['workflows', 'agent'], + category: 'operations', + tags: ['onboarding', 'compliance'], + alsoIntegrations: ['gmail'], + }, + { + icon: PersonaIcon, + title: 'Verification decision router', + prompt: + 'Build a workflow that takes an inquiry ID, fetches the inquiry from Persona, and routes on its status: approved customers get a welcome email, needs-review inquiries post to a compliance Slack channel with a summary, and declined inquiries update our CRM.', + modules: ['workflows', 'agent'], + category: 'operations', + tags: ['compliance', 'automation'], + alsoIntegrations: ['slack', 'gmail'], + }, + { + icon: PersonaIcon, + title: 'Daily pending-review digest', + prompt: + 'Build a scheduled workflow that runs every morning, lists Persona inquiries with needs_review status from the last 24 hours, summarizes each one, and posts a digest to the compliance team in Slack.', + modules: ['scheduled', 'workflows', 'agent'], + category: 'operations', + tags: ['compliance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PersonaIcon, + title: 'Watchlist screening on signup', + prompt: + "Build a workflow that takes a new user's name and birthdate, runs a Persona watchlist report against them, polls until the report is ready, and creates a case in our tracking table if the report has a match.", + modules: ['workflows', 'tables', 'agent'], + category: 'operations', + tags: ['compliance', 'screening'], + }, + { + icon: PersonaIcon, + title: 'Bulk account import from CRM export', + prompt: + 'Build a workflow that takes an uploaded CSV export of customers, imports them into Persona as accounts using the account importer, polls the importer status, and reports how many rows succeeded, errored, or were duplicates.', + modules: ['files', 'workflows', 'agent'], + category: 'operations', + tags: ['migration', 'automation'], + }, + { + icon: PersonaIcon, + title: 'Compliance audit PDF archive', + prompt: + 'Build a workflow that takes an approved inquiry ID, downloads the inquiry summary PDF from Persona, and uploads it to a compliance archive folder in Google Drive named by customer reference ID.', + modules: ['workflows', 'files', 'agent'], + category: 'operations', + tags: ['compliance', 'audit'], + alsoIntegrations: ['google_drive'], + }, + { + icon: PersonaIcon, + title: 'Manual review case triage agent', + prompt: + 'Build an agent that lists open Persona cases, fetches the linked inquiry and verification details for each, drafts a recommended approve/decline decision with reasoning, and posts the triage summary to Slack for a human reviewer.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['compliance', 'triage'], + alsoIntegrations: ['slack'], + }, + { + icon: PersonaIcon, + title: 'Re-verification campaign for stale accounts', + prompt: + 'Build a scheduled workflow that lists Persona accounts, finds ones whose latest approved inquiry is older than a year, creates a new inquiry for each from our re-verification template, and emails customers a one-time verification link.', + modules: ['scheduled', 'workflows', 'agent'], + category: 'operations', + tags: ['compliance', 'lifecycle'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'verify-customer-identity', + description: + 'Create a Persona inquiry for a customer and send them a one-time verification link.', + content: + '# Verify Customer Identity\n\nStart an identity verification for a customer using Persona.\n\n## Steps\n1. Use the Create Inquiry operation with your inquiry template ID. Pass the customer reference ID so the inquiry links to an account in your user model, and pre-fill known fields (e.g. {"name-first": "Jane", "name-last": "Doe"}).\n2. Use the Generate Inquiry Link operation with the new inquiry ID to mint a one-time verification link. Set a custom expiry only if the default (24 hours) does not fit.\n3. Deliver the one-time link to the customer (email, SMS, or chat).\n\n## Output\nReturn the inquiry ID, its status, and the one-time link. Note when the link expires so follow-ups can be scheduled.', + }, + { + name: 'check-verification-status', + description: + 'Look up a Persona inquiry and report whether the individual passed, failed, or needs review.', + content: + '# Check Verification Status\n\nRead the current state of an identity verification from Persona.\n\n## Steps\n1. Use the Get Inquiry operation with the inquiry ID (or List Inquiries filtered by reference ID to find it).\n2. Read the status: approved or completed means verified; needs_review means a human should look; failed, expired, or declined means not verified.\n3. For deeper detail, use Get Verification with a verification ID to inspect the individual checks that ran.\n\n## Output\nReturn the status, decision timestamps, and collected fields. Recommend the next action (proceed, route to review, or re-verify).', + }, + { + name: 'screen-against-watchlists', + description: + 'Run a Persona watchlist, adverse media, or PEP report on a person and surface matches.', + content: + '# Screen Against Watchlists\n\nScreen an individual for sanctions, adverse media, or political exposure using Persona reports.\n\n## Steps\n1. Use the Create Report operation with the report type (watchlist, adverse-media, or politically-exposed-person) and your report template ID. Provide the name parts or a full-name term, plus birthdate and country code when known to reduce false positives.\n2. Reports run asynchronously: poll Get Report with the report ID until the status is ready.\n3. Check hasMatch and the report attributes for matched lists and match details.\n\n## Output\nReturn whether the screening found matches, the matched lists, and the report ID for the audit trail.', + }, + { + name: 'triage-pending-reviews', + description: + 'List Persona inquiries awaiting manual review and approve or decline them after assessment.', + content: + '# Triage Pending Reviews\n\nWork through identity verifications that need a manual decision in Persona.\n\n## Steps\n1. Use the List Inquiries operation with status needs_review (optionally bounded by created-after/created-before).\n2. For each inquiry, use Get Inquiry for collected fields and List Cases / Get Case to see any linked review case.\n3. After assessment, use Approve Inquiry or Decline Inquiry. Both are final: they prevent further progress and trigger associated workflows and webhooks.\n\n## Output\nReturn a summary of inquiries reviewed and the decision taken for each, with inquiry IDs for the audit trail.', + }, + { + name: 'import-accounts-from-csv', + description: 'Bulk-import existing users into Persona as accounts from a CSV file.', + content: + '# Import Accounts from CSV\n\nMigrate an existing user base into Persona using the account importer.\n\n## Steps\n1. Prepare a CSV of users (one row per account, with reference IDs and account fields).\n2. Use the Import Accounts (CSV) operation with the file.\n3. The importer runs asynchronously and returns pending at first; report the importer ID and counts once available.\n\n## Output\nReturn the importer ID, status, and the successful, errored, and duplicate row counts.', + }, + { + name: 'archive-verification-pdf', + description: 'Download the PDF summary of a Persona inquiry for compliance record-keeping.', + content: + '# Archive Verification PDF\n\nKeep a permanent record of an identity verification decision.\n\n## Steps\n1. Use the Print Inquiry PDF operation with the inquiry ID.\n2. The PDF lands in execution files; pass it to a storage integration (Google Drive, S3, SharePoint) named by customer reference ID and date.\n\n## Output\nReturn the stored file and where it was archived.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/persona.ts b/apps/sim/blocks/blocks/persona.ts index b88fa8159c3..fbebe7d093f 100644 --- a/apps/sim/blocks/blocks/persona.ts +++ b/apps/sim/blocks/blocks/persona.ts @@ -1,6 +1,5 @@ -import { PersonaIcon } from '@/components/icons' import { PersonaBlockDisplay } from '@/blocks/blocks/persona.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { PersonaResponse } from '@/tools/persona/types' @@ -554,130 +553,3 @@ export const PersonaBlock: BlockConfig = { nextCursor: { type: 'string', description: 'Cursor for the next page of list results' }, }, } - -export const PersonaBlockMeta = { - tags: ['identity'], - url: 'https://withpersona.com', - templates: [ - { - icon: PersonaIcon, - title: 'Customer onboarding identity verification', - prompt: - 'Build a workflow triggered when a new customer signs up that creates a Persona inquiry from our KYC template with their name and email pre-filled, generates a one-time verification link, and emails it to the customer.', - modules: ['workflows', 'agent'], - category: 'operations', - tags: ['onboarding', 'compliance'], - alsoIntegrations: ['gmail'], - }, - { - icon: PersonaIcon, - title: 'Verification decision router', - prompt: - 'Build a workflow that takes an inquiry ID, fetches the inquiry from Persona, and routes on its status: approved customers get a welcome email, needs-review inquiries post to a compliance Slack channel with a summary, and declined inquiries update our CRM.', - modules: ['workflows', 'agent'], - category: 'operations', - tags: ['compliance', 'automation'], - alsoIntegrations: ['slack', 'gmail'], - }, - { - icon: PersonaIcon, - title: 'Daily pending-review digest', - prompt: - 'Build a scheduled workflow that runs every morning, lists Persona inquiries with needs_review status from the last 24 hours, summarizes each one, and posts a digest to the compliance team in Slack.', - modules: ['scheduled', 'workflows', 'agent'], - category: 'operations', - tags: ['compliance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PersonaIcon, - title: 'Watchlist screening on signup', - prompt: - "Build a workflow that takes a new user's name and birthdate, runs a Persona watchlist report against them, polls until the report is ready, and creates a case in our tracking table if the report has a match.", - modules: ['workflows', 'tables', 'agent'], - category: 'operations', - tags: ['compliance', 'screening'], - }, - { - icon: PersonaIcon, - title: 'Bulk account import from CRM export', - prompt: - 'Build a workflow that takes an uploaded CSV export of customers, imports them into Persona as accounts using the account importer, polls the importer status, and reports how many rows succeeded, errored, or were duplicates.', - modules: ['files', 'workflows', 'agent'], - category: 'operations', - tags: ['migration', 'automation'], - }, - { - icon: PersonaIcon, - title: 'Compliance audit PDF archive', - prompt: - 'Build a workflow that takes an approved inquiry ID, downloads the inquiry summary PDF from Persona, and uploads it to a compliance archive folder in Google Drive named by customer reference ID.', - modules: ['workflows', 'files', 'agent'], - category: 'operations', - tags: ['compliance', 'audit'], - alsoIntegrations: ['google_drive'], - }, - { - icon: PersonaIcon, - title: 'Manual review case triage agent', - prompt: - 'Build an agent that lists open Persona cases, fetches the linked inquiry and verification details for each, drafts a recommended approve/decline decision with reasoning, and posts the triage summary to Slack for a human reviewer.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['compliance', 'triage'], - alsoIntegrations: ['slack'], - }, - { - icon: PersonaIcon, - title: 'Re-verification campaign for stale accounts', - prompt: - 'Build a scheduled workflow that lists Persona accounts, finds ones whose latest approved inquiry is older than a year, creates a new inquiry for each from our re-verification template, and emails customers a one-time verification link.', - modules: ['scheduled', 'workflows', 'agent'], - category: 'operations', - tags: ['compliance', 'lifecycle'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'verify-customer-identity', - description: - 'Create a Persona inquiry for a customer and send them a one-time verification link.', - content: - '# Verify Customer Identity\n\nStart an identity verification for a customer using Persona.\n\n## Steps\n1. Use the Create Inquiry operation with your inquiry template ID. Pass the customer reference ID so the inquiry links to an account in your user model, and pre-fill known fields (e.g. {"name-first": "Jane", "name-last": "Doe"}).\n2. Use the Generate Inquiry Link operation with the new inquiry ID to mint a one-time verification link. Set a custom expiry only if the default (24 hours) does not fit.\n3. Deliver the one-time link to the customer (email, SMS, or chat).\n\n## Output\nReturn the inquiry ID, its status, and the one-time link. Note when the link expires so follow-ups can be scheduled.', - }, - { - name: 'check-verification-status', - description: - 'Look up a Persona inquiry and report whether the individual passed, failed, or needs review.', - content: - '# Check Verification Status\n\nRead the current state of an identity verification from Persona.\n\n## Steps\n1. Use the Get Inquiry operation with the inquiry ID (or List Inquiries filtered by reference ID to find it).\n2. Read the status: approved or completed means verified; needs_review means a human should look; failed, expired, or declined means not verified.\n3. For deeper detail, use Get Verification with a verification ID to inspect the individual checks that ran.\n\n## Output\nReturn the status, decision timestamps, and collected fields. Recommend the next action (proceed, route to review, or re-verify).', - }, - { - name: 'screen-against-watchlists', - description: - 'Run a Persona watchlist, adverse media, or PEP report on a person and surface matches.', - content: - '# Screen Against Watchlists\n\nScreen an individual for sanctions, adverse media, or political exposure using Persona reports.\n\n## Steps\n1. Use the Create Report operation with the report type (watchlist, adverse-media, or politically-exposed-person) and your report template ID. Provide the name parts or a full-name term, plus birthdate and country code when known to reduce false positives.\n2. Reports run asynchronously: poll Get Report with the report ID until the status is ready.\n3. Check hasMatch and the report attributes for matched lists and match details.\n\n## Output\nReturn whether the screening found matches, the matched lists, and the report ID for the audit trail.', - }, - { - name: 'triage-pending-reviews', - description: - 'List Persona inquiries awaiting manual review and approve or decline them after assessment.', - content: - '# Triage Pending Reviews\n\nWork through identity verifications that need a manual decision in Persona.\n\n## Steps\n1. Use the List Inquiries operation with status needs_review (optionally bounded by created-after/created-before).\n2. For each inquiry, use Get Inquiry for collected fields and List Cases / Get Case to see any linked review case.\n3. After assessment, use Approve Inquiry or Decline Inquiry. Both are final: they prevent further progress and trigger associated workflows and webhooks.\n\n## Output\nReturn a summary of inquiries reviewed and the decision taken for each, with inquiry IDs for the audit trail.', - }, - { - name: 'import-accounts-from-csv', - description: 'Bulk-import existing users into Persona as accounts from a CSV file.', - content: - '# Import Accounts from CSV\n\nMigrate an existing user base into Persona using the account importer.\n\n## Steps\n1. Prepare a CSV of users (one row per account, with reference IDs and account fields).\n2. Use the Import Accounts (CSV) operation with the file.\n3. The importer runs asynchronously and returns pending at first; report the importer ID and counts once available.\n\n## Output\nReturn the importer ID, status, and the successful, errored, and duplicate row counts.', - }, - { - name: 'archive-verification-pdf', - description: 'Download the PDF summary of a Persona inquiry for compliance record-keeping.', - content: - '# Archive Verification PDF\n\nKeep a permanent record of an identity verification decision.\n\n## Steps\n1. Use the Print Inquiry PDF operation with the inquiry ID.\n2. The PDF lands in execution files; pass it to a storage integration (Google Drive, S3, SharePoint) named by customer reference ID and date.\n\n## Output\nReturn the stored file and where it was archived.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pinecone.display.ts b/apps/sim/blocks/blocks/pinecone.display.ts index 011be489c36..dd2646b67a2 100644 --- a/apps/sim/blocks/blocks/pinecone.display.ts +++ b/apps/sim/blocks/blocks/pinecone.display.ts @@ -1,6 +1,6 @@ import { PineconeIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PineconeBlockDisplay = { type: 'pinecone', @@ -14,3 +14,108 @@ export const PineconeBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/pinecone', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const PineconeBlockMeta = { + tags: ['vector-search', 'knowledge-base'], + url: 'https://www.pinecone.io', + templates: [ + { + icon: PineconeIcon, + title: 'Pinecone reindex pipeline', + prompt: + 'Build a scheduled workflow that regenerates embeddings with OpenAI for new or changed source documents and upserts the vectors into a Pinecone index so retrieval stays current.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['openai'], + }, + { + icon: PineconeIcon, + title: 'Pinecone semantic search agent', + prompt: + 'Create an agent that takes a natural-language query, embeds it with OpenAI, retrieves top-k matches from Pinecone, and answers with cited passages plus a confidence score.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'enterprise'], + alsoIntegrations: ['openai'], + }, + { + icon: PineconeIcon, + title: 'Pinecone retrieval-quality monitor', + prompt: + 'Build a scheduled weekly workflow that runs a fixed set of benchmark queries against a Pinecone index, records top-k similarity scores per namespace to a table, and pings Slack when retrieval quality regresses.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PineconeIcon, + title: 'Pinecone duplicate detector', + prompt: + 'Create a workflow that reads a table of candidate records, embeds each with OpenAI, searches a Pinecone index for matches above a similarity threshold, and writes the near-duplicates to a cleanup queue.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + alsoIntegrations: ['openai'], + }, + { + icon: PineconeIcon, + title: 'Pinecone tenant isolation auditor', + prompt: + 'Build a workflow that verifies Pinecone namespace isolation by sampling cross-namespace queries, ensuring no leakage, and writing a compliance audit report each week.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'enterprise'], + }, + { + icon: PineconeIcon, + title: 'Pinecone FAQ deflection bot', + prompt: + 'Create a workflow that embeds an incoming question with OpenAI, searches a Pinecone index of FAQ entries for the closest match, and returns the answer when similarity is high or escalates when it is not.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + alsoIntegrations: ['openai'], + }, + { + icon: PineconeIcon, + title: 'Pinecone support knowledge retriever', + prompt: + 'Build a workflow that fetches each new Zendesk ticket, embeds the question with OpenAI, queries a Pinecone index of resolved tickets and docs, and drafts a suggested reply citing the most relevant matches for the agent to approve.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'vector-search', 'automation'], + alsoIntegrations: ['openai', 'zendesk'], + }, + ], + skills: [ + { + name: 'upsert-text-records', + description: + 'Embed and upsert text records into a Pinecone namespace using integrated embeddings.', + content: + '# Upsert Text Records\n\nLoad documents into a Pinecone index for retrieval.\n\n## Steps\n1. Use the Upsert Text operation and provide the Index Host and target Namespace.\n2. Pass newline-delimited JSON Records, each with a unique _id, a text or chunk_text field, and any metadata fields such as category for later filtering.\n3. Keep chunks reasonably sized so each record carries one coherent idea.\n4. Confirm the upsert status from the response.\n\n## Output\nReport how many records were upserted into which namespace and surface any records that failed validation.', + }, + { + name: 'semantic-search', + description: + 'Run a text query against a Pinecone index with metadata filtering and optional reranking.', + content: + '# Semantic Search\n\nRetrieve the most relevant records for a query.\n\n## Steps\n1. Use the Search With Text operation with the Index Host, Namespace, and a natural-language Search Query.\n2. Set Top K for how many matches to return and list the Fields to Return.\n3. Optionally apply a metadata Filter (operators like $eq, $in, $gte) to scope the search, and pass Rerank Options to reorder by a cross-encoder for higher precision.\n\n## Output\nThe top matches with their scores, returned fields, and IDs, ordered by relevance after any reranking.', + }, + { + name: 'generate-embeddings', + description: + 'Generate vector embeddings for a set of texts with a Pinecone-hosted embedding model.', + content: + '# Generate Embeddings\n\nTurn text into vectors for storage or comparison.\n\n## Steps\n1. Use the Generate Embeddings operation and choose a model such as multilingual-e5-large or llama-text-embed-v2.\n2. Provide the Text Inputs as a JSON array of objects each with a text field.\n3. Use the returned vectors for downstream upserts or similarity work.\n\n## Output\nThe embedding vector per input, the model used, and the usage statistics for cost tracking.', + }, + { + name: 'fetch-vectors-by-id', + description: 'Fetch specific vectors and their metadata from a Pinecone namespace by ID.', + content: + '# Fetch Vectors By ID\n\nLook up known records directly.\n\n## Steps\n1. Use the Fetch Vectors operation with the Index Host and Namespace.\n2. Provide the Vector IDs as a JSON array of the records to retrieve.\n3. Inspect the returned values and metadata to confirm content or debug retrieval.\n\n## Output\nThe requested records with their stored metadata, and a note listing any IDs that were not found.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pinecone.ts b/apps/sim/blocks/blocks/pinecone.ts index 97df02be4f9..cd8f2e5aa08 100644 --- a/apps/sim/blocks/blocks/pinecone.ts +++ b/apps/sim/blocks/blocks/pinecone.ts @@ -1,6 +1,5 @@ -import { PineconeIcon } from '@/components/icons' import { PineconeBlockDisplay } from '@/blocks/blocks/pinecone.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { PineconeResponse } from '@/tools/pinecone/types' @@ -319,108 +318,3 @@ export const PineconeBlock: BlockConfig = { usage: { type: 'json', description: 'Usage statistics' }, }, } - -export const PineconeBlockMeta = { - tags: ['vector-search', 'knowledge-base'], - url: 'https://www.pinecone.io', - templates: [ - { - icon: PineconeIcon, - title: 'Pinecone reindex pipeline', - prompt: - 'Build a scheduled workflow that regenerates embeddings with OpenAI for new or changed source documents and upserts the vectors into a Pinecone index so retrieval stays current.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['openai'], - }, - { - icon: PineconeIcon, - title: 'Pinecone semantic search agent', - prompt: - 'Create an agent that takes a natural-language query, embeds it with OpenAI, retrieves top-k matches from Pinecone, and answers with cited passages plus a confidence score.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'enterprise'], - alsoIntegrations: ['openai'], - }, - { - icon: PineconeIcon, - title: 'Pinecone retrieval-quality monitor', - prompt: - 'Build a scheduled weekly workflow that runs a fixed set of benchmark queries against a Pinecone index, records top-k similarity scores per namespace to a table, and pings Slack when retrieval quality regresses.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PineconeIcon, - title: 'Pinecone duplicate detector', - prompt: - 'Create a workflow that reads a table of candidate records, embeds each with OpenAI, searches a Pinecone index for matches above a similarity threshold, and writes the near-duplicates to a cleanup queue.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - alsoIntegrations: ['openai'], - }, - { - icon: PineconeIcon, - title: 'Pinecone tenant isolation auditor', - prompt: - 'Build a workflow that verifies Pinecone namespace isolation by sampling cross-namespace queries, ensuring no leakage, and writing a compliance audit report each week.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'enterprise'], - }, - { - icon: PineconeIcon, - title: 'Pinecone FAQ deflection bot', - prompt: - 'Create a workflow that embeds an incoming question with OpenAI, searches a Pinecone index of FAQ entries for the closest match, and returns the answer when similarity is high or escalates when it is not.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - alsoIntegrations: ['openai'], - }, - { - icon: PineconeIcon, - title: 'Pinecone support knowledge retriever', - prompt: - 'Build a workflow that fetches each new Zendesk ticket, embeds the question with OpenAI, queries a Pinecone index of resolved tickets and docs, and drafts a suggested reply citing the most relevant matches for the agent to approve.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'vector-search', 'automation'], - alsoIntegrations: ['openai', 'zendesk'], - }, - ], - skills: [ - { - name: 'upsert-text-records', - description: - 'Embed and upsert text records into a Pinecone namespace using integrated embeddings.', - content: - '# Upsert Text Records\n\nLoad documents into a Pinecone index for retrieval.\n\n## Steps\n1. Use the Upsert Text operation and provide the Index Host and target Namespace.\n2. Pass newline-delimited JSON Records, each with a unique _id, a text or chunk_text field, and any metadata fields such as category for later filtering.\n3. Keep chunks reasonably sized so each record carries one coherent idea.\n4. Confirm the upsert status from the response.\n\n## Output\nReport how many records were upserted into which namespace and surface any records that failed validation.', - }, - { - name: 'semantic-search', - description: - 'Run a text query against a Pinecone index with metadata filtering and optional reranking.', - content: - '# Semantic Search\n\nRetrieve the most relevant records for a query.\n\n## Steps\n1. Use the Search With Text operation with the Index Host, Namespace, and a natural-language Search Query.\n2. Set Top K for how many matches to return and list the Fields to Return.\n3. Optionally apply a metadata Filter (operators like $eq, $in, $gte) to scope the search, and pass Rerank Options to reorder by a cross-encoder for higher precision.\n\n## Output\nThe top matches with their scores, returned fields, and IDs, ordered by relevance after any reranking.', - }, - { - name: 'generate-embeddings', - description: - 'Generate vector embeddings for a set of texts with a Pinecone-hosted embedding model.', - content: - '# Generate Embeddings\n\nTurn text into vectors for storage or comparison.\n\n## Steps\n1. Use the Generate Embeddings operation and choose a model such as multilingual-e5-large or llama-text-embed-v2.\n2. Provide the Text Inputs as a JSON array of objects each with a text field.\n3. Use the returned vectors for downstream upserts or similarity work.\n\n## Output\nThe embedding vector per input, the model used, and the usage statistics for cost tracking.', - }, - { - name: 'fetch-vectors-by-id', - description: 'Fetch specific vectors and their metadata from a Pinecone namespace by ID.', - content: - '# Fetch Vectors By ID\n\nLook up known records directly.\n\n## Steps\n1. Use the Fetch Vectors operation with the Index Host and Namespace.\n2. Provide the Vector IDs as a JSON array of the records to retrieve.\n3. Inspect the returned values and metadata to confirm content or debug retrieval.\n\n## Output\nThe requested records with their stored metadata, and a note listing any IDs that were not found.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pipedrive.display.ts b/apps/sim/blocks/blocks/pipedrive.display.ts index 0e19a033700..f93d12ccda1 100644 --- a/apps/sim/blocks/blocks/pipedrive.display.ts +++ b/apps/sim/blocks/blocks/pipedrive.display.ts @@ -1,6 +1,6 @@ import { PipedriveIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PipedriveBlockDisplay = { type: 'pipedrive', @@ -15,3 +15,109 @@ export const PipedriveBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/pipedrive', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const PipedriveBlockMeta = { + tags: ['sales-engagement', 'project-management'], + url: 'https://www.pipedrive.com', + templates: [ + { + icon: PipedriveIcon, + title: 'Pipedrive deal pipeline tracker', + prompt: + 'Create a scheduled workflow that mirrors Pipedrive deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive lead enrichment pipeline', + prompt: + 'Build a scheduled workflow that polls Pipedrive for new leads, enriches each via Apollo with role, seniority, and tech stack, and updates the lead with the enriched details.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['apollo'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive activity-from-email logger', + prompt: + 'Create a workflow that watches Gmail for emails to or from Pipedrive contacts, logs each as an activity, and creates a follow-up task if next steps are mentioned.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive call-summary updater', + prompt: + 'Build a workflow that runs after a Fireflies sales call, summarizes the transcript, and updates the matching Pipedrive deal with the call summary and next steps.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['fireflies'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive win/loss analyzer', + prompt: + 'Create a scheduled monthly workflow that pulls closed Pipedrive deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'analysis'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive renewal forecast', + prompt: + 'Build a workflow that pulls Pipedrive customer renewals due in the next 90 days, generates a personalized renewal-prep brief, and emails the account owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['gmail'], + }, + { + icon: PipedriveIcon, + title: 'Pipedrive Slack channel-per-deal', + prompt: + 'Create a workflow that for Pipedrive deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'create-deal', + description: + 'Create a Pipedrive deal with a title, value, pipeline stage, and linked person or organization.', + content: + '# Create Deal\n\nAdd a new opportunity to the sales pipeline.\n\n## Steps\n1. Use the Create Deal operation with a clear Title.\n2. Set Value and Currency, the target Pipeline and Stage ID, and Status (open, won, or lost).\n3. Link the deal to a Person ID or Organization ID, and set an Expected Close Date.\n4. Capture the returned deal ID for follow-up activities.\n\n## Output\nConfirm the new deal title, value, pipeline stage, and ID so it can be referenced in later steps.', + }, + { + name: 'review-pipeline', + description: + 'List Pipedrive deals in a pipeline and summarize stage distribution and deals at risk.', + content: + '# Review Pipeline\n\nGet a snapshot of the current sales pipeline.\n\n## Steps\n1. Use Get All Deals (or Get Pipeline Deals for one pipeline) filtered to open status.\n2. Optionally scope by Pipeline, Person ID, or Organization ID and set Updated Since to focus on recent movement.\n3. Group deals by stage and total their value, flagging stale deals with no recent update.\n4. Page with the cursor or start offset for large pipelines.\n\n## Output\nA stage-by-stage breakdown with deal counts and total value, plus a short list of at-risk deals that have gone quiet.', + }, + { + name: 'log-activity', + description: + 'Create a Pipedrive activity such as a call, meeting, or task linked to a deal or contact.', + content: + '# Log Activity\n\nSchedule or record follow-up work against a record.\n\n## Steps\n1. Use the Create Activity operation with a Subject and an activity Type (call, meeting, task, deadline, email, or lunch).\n2. Set the Due Date and optional Due Time, Duration, and Notes.\n3. Link the activity to the relevant Deal ID, Person ID, or Organization ID.\n4. Use Update Activity later to mark it done.\n\n## Output\nConfirm the activity subject, type, due date, and the record it is linked to.', + }, + { + name: 'manage-leads', + description: + 'Create or update Pipedrive leads with value, contacts, and expected close date.', + content: + '# Manage Leads\n\nCapture and maintain top-of-funnel leads.\n\n## Steps\n1. Use Create Lead with a Title and link a Person ID or Organization ID and an Owner ID.\n2. Set the Value Amount and Value Currency and an Expected Close Date.\n3. Use Update Lead to revise details or archive a lead once it converts or goes cold.\n4. Use Get Leads to review active or archived leads.\n\n## Output\nThe lead title, linked contact, value, and current state (active or archived) with its ID.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pipedrive.ts b/apps/sim/blocks/blocks/pipedrive.ts index 4e6abed8c76..5ede91cca10 100644 --- a/apps/sim/blocks/blocks/pipedrive.ts +++ b/apps/sim/blocks/blocks/pipedrive.ts @@ -1,7 +1,6 @@ -import { PipedriveIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { PipedriveBlockDisplay } from '@/blocks/blocks/pipedrive.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { PipedriveResponse } from '@/tools/pipedrive/types' @@ -829,109 +828,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n success: { type: 'boolean', description: 'Operation success status' }, }, } - -export const PipedriveBlockMeta = { - tags: ['sales-engagement', 'project-management'], - url: 'https://www.pipedrive.com', - templates: [ - { - icon: PipedriveIcon, - title: 'Pipedrive deal pipeline tracker', - prompt: - 'Create a scheduled workflow that mirrors Pipedrive deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive lead enrichment pipeline', - prompt: - 'Build a scheduled workflow that polls Pipedrive for new leads, enriches each via Apollo with role, seniority, and tech stack, and updates the lead with the enriched details.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['apollo'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive activity-from-email logger', - prompt: - 'Create a workflow that watches Gmail for emails to or from Pipedrive contacts, logs each as an activity, and creates a follow-up task if next steps are mentioned.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive call-summary updater', - prompt: - 'Build a workflow that runs after a Fireflies sales call, summarizes the transcript, and updates the matching Pipedrive deal with the call summary and next steps.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['fireflies'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive win/loss analyzer', - prompt: - 'Create a scheduled monthly workflow that pulls closed Pipedrive deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'analysis'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive renewal forecast', - prompt: - 'Build a workflow that pulls Pipedrive customer renewals due in the next 90 days, generates a personalized renewal-prep brief, and emails the account owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['gmail'], - }, - { - icon: PipedriveIcon, - title: 'Pipedrive Slack channel-per-deal', - prompt: - 'Create a workflow that for Pipedrive deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'create-deal', - description: - 'Create a Pipedrive deal with a title, value, pipeline stage, and linked person or organization.', - content: - '# Create Deal\n\nAdd a new opportunity to the sales pipeline.\n\n## Steps\n1. Use the Create Deal operation with a clear Title.\n2. Set Value and Currency, the target Pipeline and Stage ID, and Status (open, won, or lost).\n3. Link the deal to a Person ID or Organization ID, and set an Expected Close Date.\n4. Capture the returned deal ID for follow-up activities.\n\n## Output\nConfirm the new deal title, value, pipeline stage, and ID so it can be referenced in later steps.', - }, - { - name: 'review-pipeline', - description: - 'List Pipedrive deals in a pipeline and summarize stage distribution and deals at risk.', - content: - '# Review Pipeline\n\nGet a snapshot of the current sales pipeline.\n\n## Steps\n1. Use Get All Deals (or Get Pipeline Deals for one pipeline) filtered to open status.\n2. Optionally scope by Pipeline, Person ID, or Organization ID and set Updated Since to focus on recent movement.\n3. Group deals by stage and total their value, flagging stale deals with no recent update.\n4. Page with the cursor or start offset for large pipelines.\n\n## Output\nA stage-by-stage breakdown with deal counts and total value, plus a short list of at-risk deals that have gone quiet.', - }, - { - name: 'log-activity', - description: - 'Create a Pipedrive activity such as a call, meeting, or task linked to a deal or contact.', - content: - '# Log Activity\n\nSchedule or record follow-up work against a record.\n\n## Steps\n1. Use the Create Activity operation with a Subject and an activity Type (call, meeting, task, deadline, email, or lunch).\n2. Set the Due Date and optional Due Time, Duration, and Notes.\n3. Link the activity to the relevant Deal ID, Person ID, or Organization ID.\n4. Use Update Activity later to mark it done.\n\n## Output\nConfirm the activity subject, type, due date, and the record it is linked to.', - }, - { - name: 'manage-leads', - description: - 'Create or update Pipedrive leads with value, contacts, and expected close date.', - content: - '# Manage Leads\n\nCapture and maintain top-of-funnel leads.\n\n## Steps\n1. Use Create Lead with a Title and link a Person ID or Organization ID and an Owner ID.\n2. Set the Value Amount and Value Currency and an Expected Close Date.\n3. Use Update Lead to revise details or archive a lead once it converts or goes cold.\n4. Use Get Leads to review active or archived leads.\n\n## Output\nThe lead title, linked contact, value, and current state (active or archived) with its ID.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/polymarket.display.ts b/apps/sim/blocks/blocks/polymarket.display.ts index 4ad48d02099..8f54944ce79 100644 --- a/apps/sim/blocks/blocks/polymarket.display.ts +++ b/apps/sim/blocks/blocks/polymarket.display.ts @@ -1,6 +1,6 @@ import { PolymarketIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PolymarketBlockDisplay = { type: 'polymarket', @@ -15,3 +15,108 @@ export const PolymarketBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/polymarket', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const PolymarketBlockMeta = { + tags: ['prediction-markets', 'data-analytics'], + url: 'https://polymarket.com', + templates: [ + { + icon: PolymarketIcon, + title: 'Polymarket position monitor', + prompt: + 'Create a scheduled workflow that fetches Polymarket prices for tracked markets, computes price changes vs entry, writes the portfolio to a table, and pings Slack when any position swings beyond a threshold.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket research digest', + prompt: + 'Build a scheduled weekly workflow that pulls top-volume Polymarket markets, summarizes the implied odds and recent moves, and writes a markdown research file for the trading group.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'research'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket price-move alerter', + prompt: + 'Build a scheduled workflow that polls Polymarket prices for tracked markets, detects sharp moves since the last run, and writes the price reactions to a research table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['research', 'analysis'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket + Similarweb event volume tracker', + prompt: + 'Create a workflow that overlays Polymarket market activity with Similarweb traffic for the involved entities, identifies volume-driving news, and writes the analysis.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'research'], + alsoIntegrations: ['similarweb'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket large-order tracker', + prompt: + 'Build a scheduled workflow that pulls Polymarket order book activity, identifies unusually large orders on tracked markets, and pings Slack on whale activity.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket position digest', + prompt: + 'Create a scheduled daily workflow that summarizes Polymarket holdings, PnL per market, and notable movements, and emails the report to the trading team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: PolymarketIcon, + title: 'Polymarket arbitrage scanner', + prompt: + 'Build a scheduled workflow that fetches prices for related Polymarket markets, detects when complementary outcomes sum away from fair value, writes the mispriced pairs to a table, and pings Slack with the implied edge for each opportunity.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'find-market-odds', + description: + 'Look up a Polymarket market and report the current implied odds and price for each outcome.', + content: + '# Find Market Odds\n\nGet the live implied probability for a question.\n\n## Steps\n1. Use Search or Get Markets to locate the market, or Get Market with a known market ID or slug.\n2. Read the outcome token IDs from the market, then use Get Price or Get Midpoint per token to get the current price.\n3. Treat the price (0 to 1) as the implied probability of that outcome.\n\n## Output\nFor the market, list each outcome with its current price as a percentage probability, plus the market volume and whether it is still open.', + }, + { + name: 'list-top-markets', + description: + 'List the highest-volume or most-liquid Polymarket markets, optionally filtered by category tag.', + content: + '# List Top Markets\n\nSurface the markets attracting the most attention.\n\n## Steps\n1. Use Get Markets (or Get Events) sorted by Volume or Liquidity in descending order.\n2. Optionally filter by a Tag ID for a category and set Closed Status to open only.\n3. Set a Limit and use the offset to page through results.\n\n## Output\nA ranked list of markets with title, volume, liquidity, and current implied odds for the leading outcome.', + }, + { + name: 'track-price-history', + description: + 'Pull Polymarket price history for an outcome token over an interval and summarize the trend.', + content: + '# Track Price History\n\nSee how an outcome moved over time.\n\n## Steps\n1. Identify the outcome token ID from the market.\n2. Use Get Price History with that Token ID and either a preset Interval (1h, 6h, 1d, 1w, max) or a Start and End timestamp with a Fidelity in minutes.\n3. Compare the latest price against the start of the window to compute the move.\n\n## Output\nThe price at the start and end of the window, the net change, and a one-line read on the trend (rising, falling, or flat).', + }, + { + name: 'analyze-wallet-positions', + description: + "Fetch a Polymarket wallet's open positions and summarize value and profit and loss.", + content: + '# Analyze Wallet Positions\n\nReview what a trader holds and how it is performing.\n\n## Steps\n1. Use Get Positions with the User Wallet Address, optionally sorted by Cash P&L or Current Value.\n2. Filter with a Size Threshold or by redeemable status to focus on meaningful holdings.\n3. Optionally use Get Activity for the same wallet to see recent trades and redemptions.\n\n## Output\nA summary of the wallet positions: total current value, aggregate profit and loss, and the largest winners and losers by market.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/polymarket.ts b/apps/sim/blocks/blocks/polymarket.ts index b61deb35f6e..c8aa32c7282 100644 --- a/apps/sim/blocks/blocks/polymarket.ts +++ b/apps/sim/blocks/blocks/polymarket.ts @@ -1,6 +1,5 @@ -import { PolymarketIcon } from '@/components/icons' import { PolymarketBlockDisplay } from '@/blocks/blocks/polymarket.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' export const PolymarketBlock: BlockConfig = { ...PolymarketBlockDisplay, @@ -895,108 +894,3 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr holders: { type: 'json', description: 'Array of market holder groups (get_holders)' }, }, } - -export const PolymarketBlockMeta = { - tags: ['prediction-markets', 'data-analytics'], - url: 'https://polymarket.com', - templates: [ - { - icon: PolymarketIcon, - title: 'Polymarket position monitor', - prompt: - 'Create a scheduled workflow that fetches Polymarket prices for tracked markets, computes price changes vs entry, writes the portfolio to a table, and pings Slack when any position swings beyond a threshold.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket research digest', - prompt: - 'Build a scheduled weekly workflow that pulls top-volume Polymarket markets, summarizes the implied odds and recent moves, and writes a markdown research file for the trading group.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'research'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket price-move alerter', - prompt: - 'Build a scheduled workflow that polls Polymarket prices for tracked markets, detects sharp moves since the last run, and writes the price reactions to a research table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['research', 'analysis'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket + Similarweb event volume tracker', - prompt: - 'Create a workflow that overlays Polymarket market activity with Similarweb traffic for the involved entities, identifies volume-driving news, and writes the analysis.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'research'], - alsoIntegrations: ['similarweb'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket large-order tracker', - prompt: - 'Build a scheduled workflow that pulls Polymarket order book activity, identifies unusually large orders on tracked markets, and pings Slack on whale activity.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket position digest', - prompt: - 'Create a scheduled daily workflow that summarizes Polymarket holdings, PnL per market, and notable movements, and emails the report to the trading team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: PolymarketIcon, - title: 'Polymarket arbitrage scanner', - prompt: - 'Build a scheduled workflow that fetches prices for related Polymarket markets, detects when complementary outcomes sum away from fair value, writes the mispriced pairs to a table, and pings Slack with the implied edge for each opportunity.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'find-market-odds', - description: - 'Look up a Polymarket market and report the current implied odds and price for each outcome.', - content: - '# Find Market Odds\n\nGet the live implied probability for a question.\n\n## Steps\n1. Use Search or Get Markets to locate the market, or Get Market with a known market ID or slug.\n2. Read the outcome token IDs from the market, then use Get Price or Get Midpoint per token to get the current price.\n3. Treat the price (0 to 1) as the implied probability of that outcome.\n\n## Output\nFor the market, list each outcome with its current price as a percentage probability, plus the market volume and whether it is still open.', - }, - { - name: 'list-top-markets', - description: - 'List the highest-volume or most-liquid Polymarket markets, optionally filtered by category tag.', - content: - '# List Top Markets\n\nSurface the markets attracting the most attention.\n\n## Steps\n1. Use Get Markets (or Get Events) sorted by Volume or Liquidity in descending order.\n2. Optionally filter by a Tag ID for a category and set Closed Status to open only.\n3. Set a Limit and use the offset to page through results.\n\n## Output\nA ranked list of markets with title, volume, liquidity, and current implied odds for the leading outcome.', - }, - { - name: 'track-price-history', - description: - 'Pull Polymarket price history for an outcome token over an interval and summarize the trend.', - content: - '# Track Price History\n\nSee how an outcome moved over time.\n\n## Steps\n1. Identify the outcome token ID from the market.\n2. Use Get Price History with that Token ID and either a preset Interval (1h, 6h, 1d, 1w, max) or a Start and End timestamp with a Fidelity in minutes.\n3. Compare the latest price against the start of the window to compute the move.\n\n## Output\nThe price at the start and end of the window, the net change, and a one-line read on the trend (rising, falling, or flat).', - }, - { - name: 'analyze-wallet-positions', - description: - "Fetch a Polymarket wallet's open positions and summarize value and profit and loss.", - content: - '# Analyze Wallet Positions\n\nReview what a trader holds and how it is performing.\n\n## Steps\n1. Use Get Positions with the User Wallet Address, optionally sorted by Cash P&L or Current Value.\n2. Filter with a Size Threshold or by redeemable status to focus on meaningful holdings.\n3. Optionally use Get Activity for the same wallet to see recent trades and redemptions.\n\n## Output\nA summary of the wallet positions: total current value, aggregate profit and loss, and the largest winners and losers by market.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/posthog.display.ts b/apps/sim/blocks/blocks/posthog.display.ts index abe2c238973..525006dcf39 100644 --- a/apps/sim/blocks/blocks/posthog.display.ts +++ b/apps/sim/blocks/blocks/posthog.display.ts @@ -1,6 +1,6 @@ import { PosthogIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PostHogBlockDisplay = { type: 'posthog', @@ -14,3 +14,113 @@ export const PostHogBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/posthog', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const PostHogBlockMeta = { + tags: ['data-analytics', 'monitoring', 'feature-flags'], + url: 'https://posthog.com', + templates: [ + { + icon: PosthogIcon, + title: 'PostHog insight digest', + prompt: + 'Create a scheduled daily workflow that pulls key PostHog insights — DAU, top events, funnels — and posts a digest to Slack with week-over-week deltas and emoji indicators.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: PosthogIcon, + title: 'PostHog feature flag flip notifier', + prompt: + 'Build a scheduled workflow that polls PostHog feature flags, detects status changes since the last run, and posts a Slack notification with the old and new state for each changed flag.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: PosthogIcon, + title: 'PostHog session replay triage', + prompt: + 'Create a scheduled workflow that lists PostHog session recordings with rage clicks or dead clicks, scores each for severity, and creates a Linear ticket for the worst sessions.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['product', 'engineering'], + alsoIntegrations: ['linear'], + }, + { + icon: PosthogIcon, + title: 'PostHog event taxonomy enforcer', + prompt: + 'Build a workflow that scans PostHog events daily, flags any new event names that violate the naming convention, and opens a Linear ticket for the engineer to clean up tracking debt.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: PosthogIcon, + title: 'PostHog cohort enrichment', + prompt: + 'Create a workflow that pulls a PostHog cohort, enriches each user with HubSpot lifecycle stage and Stripe LTV, and writes the enriched cohort to a tables-based targeting view.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['product', 'crm', 'sync'], + alsoIntegrations: ['hubspot', 'stripe'], + }, + { + icon: PosthogIcon, + title: 'PostHog + Profound user-journey enricher', + prompt: + 'Build a scheduled weekly workflow that joins PostHog user journeys with Profound AI brand signal to identify how AI-driven discovery converts, and writes a report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + alsoIntegrations: ['profound'], + }, + { + icon: PosthogIcon, + title: 'PostHog survey response analyzer', + prompt: + 'Create a scheduled workflow that lists active PostHog surveys, pulls their responses with a query, runs sentiment and theme analysis across the open-text answers, and posts a summary of top themes and NPS movement to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'capture-event', + description: 'Send a product analytics event to PostHog for a user with custom properties.', + content: + '# Capture Event\n\nRecord a user action in PostHog.\n\n## Steps\n1. Use the Capture Event operation with the Project API Key and Project ID.\n2. Set the Event Name (for example purchase_completed) and the Distinct ID identifying the user.\n3. Add Properties as a JSON object with relevant context such as plan, price, or page, and optionally a Timestamp.\n4. For many events at once, use Batch Events with a JSON array instead.\n\n## Output\nConfirm the event name and user it was captured for, and report success or any validation error returned.', + }, + { + name: 'query-product-data', + description: 'Run a HogQL query against PostHog to answer a product analytics question.', + content: + '# Query Product Data\n\nPull custom analytics with HogQL.\n\n## Steps\n1. Use the Run Query operation with your Personal API Key, Project ID, and Region.\n2. Write the HogQL Query (SQL-like) to compute the metric, for example daily active users or top events over a window.\n3. Pass Query Values for any parameters.\n4. Aggregate or format the returned rows for the answer.\n\n## Output\nThe query result rows summarized into a direct answer, noting the time window and any assumptions in the query.', + }, + { + name: 'manage-feature-flag', + description: 'Create, update, or toggle a PostHog feature flag and control its rollout.', + content: + '# Manage Feature Flag\n\nControl a feature rollout in PostHog.\n\n## Steps\n1. Use Create Feature Flag with a Flag Key, Name, and a Rollout Percentage, or Update Feature Flag by Feature Flag ID to change state.\n2. Set Active on or off and supply Filters as JSON to target specific cohorts or person properties.\n3. Provide the Personal API Key, Project ID, and Region.\n4. Use List Feature Flags to confirm the current state.\n\n## Output\nReport the flag key, whether it is active, and the rollout percentage or targeting now in effect.', + }, + { + name: 'analyze-survey-responses', + description: 'List PostHog surveys and pull responses to summarize themes and satisfaction.', + content: + '# Analyze Survey Responses\n\nTurn survey feedback into insight.\n\n## Steps\n1. Use List Surveys to find the active survey, then Get Survey for its definition.\n2. Use Run Query (HogQL) to pull the survey response events for that survey over a date window.\n3. Group open-text answers by theme and compute the rating or NPS distribution.\n\n## Output\nA short summary of the top themes from open responses plus the rating or NPS breakdown and any notable movement.', + }, + { + name: 'add-release-annotation', + description: + 'Create a PostHog annotation marking a deploy or release on the analytics timeline.', + content: + '# Add Release Annotation\n\nMark an event on the PostHog timeline for context.\n\n## Steps\n1. Use the Create Annotation operation with the Personal API Key, Project ID, and Region.\n2. Provide the Content describing what happened (for example a deploy or campaign launch) and a Date Marker timestamp.\n3. Set the Scope to project or dashboard item.\n\n## Output\nConfirm the annotation content and the date it was placed on so charts show the marker.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/posthog.ts b/apps/sim/blocks/blocks/posthog.ts index 5bf8adb6cd3..17059e22c55 100644 --- a/apps/sim/blocks/blocks/posthog.ts +++ b/apps/sim/blocks/blocks/posthog.ts @@ -1,6 +1,5 @@ -import { PosthogIcon } from '@/components/icons' import { PostHogBlockDisplay } from '@/blocks/blocks/posthog.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { PostHogResponse } from '@/tools/posthog/types' @@ -1317,113 +1316,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, error: { type: 'string', description: 'Error message if operation failed' }, }, } - -export const PostHogBlockMeta = { - tags: ['data-analytics', 'monitoring', 'feature-flags'], - url: 'https://posthog.com', - templates: [ - { - icon: PosthogIcon, - title: 'PostHog insight digest', - prompt: - 'Create a scheduled daily workflow that pulls key PostHog insights — DAU, top events, funnels — and posts a digest to Slack with week-over-week deltas and emoji indicators.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: PosthogIcon, - title: 'PostHog feature flag flip notifier', - prompt: - 'Build a scheduled workflow that polls PostHog feature flags, detects status changes since the last run, and posts a Slack notification with the old and new state for each changed flag.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: PosthogIcon, - title: 'PostHog session replay triage', - prompt: - 'Create a scheduled workflow that lists PostHog session recordings with rage clicks or dead clicks, scores each for severity, and creates a Linear ticket for the worst sessions.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['product', 'engineering'], - alsoIntegrations: ['linear'], - }, - { - icon: PosthogIcon, - title: 'PostHog event taxonomy enforcer', - prompt: - 'Build a workflow that scans PostHog events daily, flags any new event names that violate the naming convention, and opens a Linear ticket for the engineer to clean up tracking debt.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: PosthogIcon, - title: 'PostHog cohort enrichment', - prompt: - 'Create a workflow that pulls a PostHog cohort, enriches each user with HubSpot lifecycle stage and Stripe LTV, and writes the enriched cohort to a tables-based targeting view.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['product', 'crm', 'sync'], - alsoIntegrations: ['hubspot', 'stripe'], - }, - { - icon: PosthogIcon, - title: 'PostHog + Profound user-journey enricher', - prompt: - 'Build a scheduled weekly workflow that joins PostHog user journeys with Profound AI brand signal to identify how AI-driven discovery converts, and writes a report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - alsoIntegrations: ['profound'], - }, - { - icon: PosthogIcon, - title: 'PostHog survey response analyzer', - prompt: - 'Create a scheduled workflow that lists active PostHog surveys, pulls their responses with a query, runs sentiment and theme analysis across the open-text answers, and posts a summary of top themes and NPS movement to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'capture-event', - description: 'Send a product analytics event to PostHog for a user with custom properties.', - content: - '# Capture Event\n\nRecord a user action in PostHog.\n\n## Steps\n1. Use the Capture Event operation with the Project API Key and Project ID.\n2. Set the Event Name (for example purchase_completed) and the Distinct ID identifying the user.\n3. Add Properties as a JSON object with relevant context such as plan, price, or page, and optionally a Timestamp.\n4. For many events at once, use Batch Events with a JSON array instead.\n\n## Output\nConfirm the event name and user it was captured for, and report success or any validation error returned.', - }, - { - name: 'query-product-data', - description: 'Run a HogQL query against PostHog to answer a product analytics question.', - content: - '# Query Product Data\n\nPull custom analytics with HogQL.\n\n## Steps\n1. Use the Run Query operation with your Personal API Key, Project ID, and Region.\n2. Write the HogQL Query (SQL-like) to compute the metric, for example daily active users or top events over a window.\n3. Pass Query Values for any parameters.\n4. Aggregate or format the returned rows for the answer.\n\n## Output\nThe query result rows summarized into a direct answer, noting the time window and any assumptions in the query.', - }, - { - name: 'manage-feature-flag', - description: 'Create, update, or toggle a PostHog feature flag and control its rollout.', - content: - '# Manage Feature Flag\n\nControl a feature rollout in PostHog.\n\n## Steps\n1. Use Create Feature Flag with a Flag Key, Name, and a Rollout Percentage, or Update Feature Flag by Feature Flag ID to change state.\n2. Set Active on or off and supply Filters as JSON to target specific cohorts or person properties.\n3. Provide the Personal API Key, Project ID, and Region.\n4. Use List Feature Flags to confirm the current state.\n\n## Output\nReport the flag key, whether it is active, and the rollout percentage or targeting now in effect.', - }, - { - name: 'analyze-survey-responses', - description: 'List PostHog surveys and pull responses to summarize themes and satisfaction.', - content: - '# Analyze Survey Responses\n\nTurn survey feedback into insight.\n\n## Steps\n1. Use List Surveys to find the active survey, then Get Survey for its definition.\n2. Use Run Query (HogQL) to pull the survey response events for that survey over a date window.\n3. Group open-text answers by theme and compute the rating or NPS distribution.\n\n## Output\nA short summary of the top themes from open responses plus the rating or NPS breakdown and any notable movement.', - }, - { - name: 'add-release-annotation', - description: - 'Create a PostHog annotation marking a deploy or release on the analytics timeline.', - content: - '# Add Release Annotation\n\nMark an event on the PostHog timeline for context.\n\n## Steps\n1. Use the Create Annotation operation with the Personal API Key, Project ID, and Region.\n2. Provide the Content describing what happened (for example a deploy or campaign launch) and a Date Marker timestamp.\n3. Set the Scope to project or dashboard item.\n\n## Output\nConfirm the annotation content and the date it was placed on so charts show the marker.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/profound.display.ts b/apps/sim/blocks/blocks/profound.display.ts index 42da7f1c098..c4e2fc537e7 100644 --- a/apps/sim/blocks/blocks/profound.display.ts +++ b/apps/sim/blocks/blocks/profound.display.ts @@ -1,6 +1,6 @@ import { ProfoundIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ProfoundBlockDisplay = { type: 'profound', @@ -14,3 +14,107 @@ export const ProfoundBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/profound', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const ProfoundBlockMeta = { + tags: ['seo', 'data-analytics'], + url: 'https://www.tryprofound.com', + templates: [ + { + icon: ProfoundIcon, + title: 'Profound AI-visibility tracker', + prompt: + 'Create a scheduled weekly workflow that pulls Profound brand-visibility scores across AI search engines, tracks how my brand surfaces in answers for tracked prompts, and reports week-over-week shifts to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ProfoundIcon, + title: 'Profound competitor share-of-voice', + prompt: + 'Build a workflow that pulls Profound competitor share-of-voice across AI engines, writes the leaderboard to a tracking table, and flags when a competitor jumps more than two positions.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: ProfoundIcon, + title: 'Profound prompt-coverage audit', + prompt: + "Build a scheduled weekly workflow that reads Profound's tracked-prompt coverage and prompt answers to monitor how my brand surfaces in AI answers across engines, and writes the coverage scorecard to a tables-based report.", + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: ProfoundIcon, + title: 'Profound citation-source tracker', + prompt: + 'Build a scheduled workflow that pulls the sources Profound reports AI engines cite when answering brand prompts, logs the citing domains and pages to a table, and flags new sources the content team should target.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'seo', 'analysis'], + }, + { + icon: ProfoundIcon, + title: 'Profound visibility-drop alerter', + prompt: + 'Create a workflow that checks Profound brand-visibility scores daily, compares each tracked prompt against its baseline, and immediately pages the marketing on-call in Slack when visibility drops sharply on a high-priority prompt.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ProfoundIcon, + title: 'Profound content-gap planner', + prompt: + 'Build a workflow that pulls the prompts where Profound shows my brand is absent from AI answers, has an agent draft a prioritized content brief for each gap, and creates the briefs as Notion pages for the content team.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'seo', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: ProfoundIcon, + title: 'Profound executive AI-search digest', + prompt: + 'Create a scheduled monthly workflow that aggregates Profound visibility, share-of-voice, and citation trends into a Markdown report file with commentary, and emails the AI-search performance digest to leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting', 'analysis'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'check-brand-visibility', + description: + 'Pull a Profound visibility report to see how a brand surfaces in AI answers for tracked prompts.', + content: + '# Check Brand Visibility\n\nMeasure how often a brand appears in AI engine answers.\n\n## Steps\n1. Use the Visibility Report operation with the Category ID and a Start Date and End Date.\n2. Set Metrics such as share_of_voice, visibility_score, and mentions_count.\n3. Optionally break the data out by Dimensions (date, model) and set a Date Interval.\n4. Compare the latest period against the prior one.\n\n## Output\nThe visibility and share-of-voice scores for the period, broken down by model where requested, with the change versus the previous window.', + }, + { + name: 'track-citation-sources', + description: + 'Pull a Profound citations report to see which sources AI engines cite for brand prompts.', + content: + '# Track Citation Sources\n\nFind the sources AI engines cite when answering about a brand.\n\n## Steps\n1. Use the Citations Report operation with the Category ID, Start Date, and End Date, and set Metrics such as count and citation_share.\n2. For a specific domain, use Citation Prompts with the Domain to see which prompts cite it.\n3. Optionally add Dimensions to group by source domain or page.\n\n## Output\nA ranked list of citing domains and pages with their citation share, highlighting any new sources the content team should target.', + }, + { + name: 'compare-competitor-share', + description: + 'Use Profound visibility metrics to compare a brand against competitors in AI answers.', + content: + '# Compare Competitor Share\n\nBenchmark share-of-voice across competitors.\n\n## Steps\n1. Use the Visibility Report operation for the Category ID over a date window with the share_of_voice metric.\n2. Add Dimensions to break results out by asset or brand name, and apply Filters as JSON to scope to the competitor set.\n3. Rank the brands by share-of-voice.\n\n## Output\nA leaderboard of brands by share-of-voice in AI answers, flagging any competitor that gained or lost notable ground.', + }, + { + name: 'find-content-gaps', + description: + 'Use Profound prompt and answer data to find prompts where the brand is absent from AI answers.', + content: + '# Find Content Gaps\n\nSurface prompts where the brand is missing from AI answers.\n\n## Steps\n1. Use Category Prompts with the Category ID to list tracked prompts, paging with the cursor.\n2. Use Prompt Answers over a date window to see how the brand appears (or does not) for each prompt.\n3. Flag prompts with low or zero visibility as content gaps.\n\n## Output\nA prioritized list of prompts where the brand is absent or weak in AI answers, ready to drive content briefs.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/profound.ts b/apps/sim/blocks/blocks/profound.ts index 1f0dd638ec5..a49bdad3550 100644 --- a/apps/sim/blocks/blocks/profound.ts +++ b/apps/sim/blocks/blocks/profound.ts @@ -1,6 +1,5 @@ -import { ProfoundIcon } from '@/components/icons' import { ProfoundBlockDisplay } from '@/blocks/blocks/profound.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' const CATEGORY_REPORT_OPS = [ @@ -395,107 +394,3 @@ export const ProfoundBlock: BlockConfig = { }, }, } - -export const ProfoundBlockMeta = { - tags: ['seo', 'data-analytics'], - url: 'https://www.tryprofound.com', - templates: [ - { - icon: ProfoundIcon, - title: 'Profound AI-visibility tracker', - prompt: - 'Create a scheduled weekly workflow that pulls Profound brand-visibility scores across AI search engines, tracks how my brand surfaces in answers for tracked prompts, and reports week-over-week shifts to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ProfoundIcon, - title: 'Profound competitor share-of-voice', - prompt: - 'Build a workflow that pulls Profound competitor share-of-voice across AI engines, writes the leaderboard to a tracking table, and flags when a competitor jumps more than two positions.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: ProfoundIcon, - title: 'Profound prompt-coverage audit', - prompt: - "Build a scheduled weekly workflow that reads Profound's tracked-prompt coverage and prompt answers to monitor how my brand surfaces in AI answers across engines, and writes the coverage scorecard to a tables-based report.", - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: ProfoundIcon, - title: 'Profound citation-source tracker', - prompt: - 'Build a scheduled workflow that pulls the sources Profound reports AI engines cite when answering brand prompts, logs the citing domains and pages to a table, and flags new sources the content team should target.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'seo', 'analysis'], - }, - { - icon: ProfoundIcon, - title: 'Profound visibility-drop alerter', - prompt: - 'Create a workflow that checks Profound brand-visibility scores daily, compares each tracked prompt against its baseline, and immediately pages the marketing on-call in Slack when visibility drops sharply on a high-priority prompt.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ProfoundIcon, - title: 'Profound content-gap planner', - prompt: - 'Build a workflow that pulls the prompts where Profound shows my brand is absent from AI answers, has an agent draft a prioritized content brief for each gap, and creates the briefs as Notion pages for the content team.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'seo', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: ProfoundIcon, - title: 'Profound executive AI-search digest', - prompt: - 'Create a scheduled monthly workflow that aggregates Profound visibility, share-of-voice, and citation trends into a Markdown report file with commentary, and emails the AI-search performance digest to leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting', 'analysis'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'check-brand-visibility', - description: - 'Pull a Profound visibility report to see how a brand surfaces in AI answers for tracked prompts.', - content: - '# Check Brand Visibility\n\nMeasure how often a brand appears in AI engine answers.\n\n## Steps\n1. Use the Visibility Report operation with the Category ID and a Start Date and End Date.\n2. Set Metrics such as share_of_voice, visibility_score, and mentions_count.\n3. Optionally break the data out by Dimensions (date, model) and set a Date Interval.\n4. Compare the latest period against the prior one.\n\n## Output\nThe visibility and share-of-voice scores for the period, broken down by model where requested, with the change versus the previous window.', - }, - { - name: 'track-citation-sources', - description: - 'Pull a Profound citations report to see which sources AI engines cite for brand prompts.', - content: - '# Track Citation Sources\n\nFind the sources AI engines cite when answering about a brand.\n\n## Steps\n1. Use the Citations Report operation with the Category ID, Start Date, and End Date, and set Metrics such as count and citation_share.\n2. For a specific domain, use Citation Prompts with the Domain to see which prompts cite it.\n3. Optionally add Dimensions to group by source domain or page.\n\n## Output\nA ranked list of citing domains and pages with their citation share, highlighting any new sources the content team should target.', - }, - { - name: 'compare-competitor-share', - description: - 'Use Profound visibility metrics to compare a brand against competitors in AI answers.', - content: - '# Compare Competitor Share\n\nBenchmark share-of-voice across competitors.\n\n## Steps\n1. Use the Visibility Report operation for the Category ID over a date window with the share_of_voice metric.\n2. Add Dimensions to break results out by asset or brand name, and apply Filters as JSON to scope to the competitor set.\n3. Rank the brands by share-of-voice.\n\n## Output\nA leaderboard of brands by share-of-voice in AI answers, flagging any competitor that gained or lost notable ground.', - }, - { - name: 'find-content-gaps', - description: - 'Use Profound prompt and answer data to find prompts where the brand is absent from AI answers.', - content: - '# Find Content Gaps\n\nSurface prompts where the brand is missing from AI answers.\n\n## Steps\n1. Use Category Prompts with the Category ID to list tracked prompts, paging with the cursor.\n2. Use Prompt Answers over a date window to see how the brand appears (or does not) for each prompt.\n3. Flag prompts with low or zero visibility as content gaps.\n\n## Output\nA prioritized list of prompts where the brand is absent or weak in AI answers, ready to drive content briefs.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/prospeo.display.ts b/apps/sim/blocks/blocks/prospeo.display.ts index 92d63efe414..34e8ad4a595 100644 --- a/apps/sim/blocks/blocks/prospeo.display.ts +++ b/apps/sim/blocks/blocks/prospeo.display.ts @@ -1,6 +1,6 @@ import { ProspeoIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ProspeoBlockDisplay = { type: 'prospeo', @@ -14,3 +14,105 @@ export const ProspeoBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/prospeo', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const ProspeoBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://prospeo.io', + templates: [ + { + icon: ProspeoIcon, + title: 'Prospeo email finder', + prompt: + 'Build a workflow that takes a prospect name and company from a table, runs Prospeo to find and verify their work email, and writes the deliverable contact back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo person enricher', + prompt: + 'Create a workflow that watches CRM contacts, runs Prospeo enrichment to fill in title, company, and verified contact details, and writes the enriched fields back.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['hubspot'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo ICP search', + prompt: + 'Build a workflow that runs a Prospeo people search against my ICP filters, reveals verified emails and mobile numbers, and writes the prospect list into a sender table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo + Email Bison outbound', + prompt: + 'Create a workflow that uses Prospeo to find and verify prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo CRM gap-filler', + prompt: + 'Build a scheduled workflow that finds Salesforce contacts missing email addresses, runs Prospeo to find and verify them, and updates each contact record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo bulk list enrichment', + prompt: + 'Build a workflow that reads a large prospect list from a table, runs Prospeo bulk person enrichment in batches to reveal verified emails and titles, and writes the enriched results back row by row with a status column for any that could not be matched.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: ProspeoIcon, + title: 'Prospeo company enrichment', + prompt: + 'Create a workflow that takes a list of target company domains, runs Prospeo company enrichment to pull firmographics like size, industry, and location, and writes the structured company profiles into an account table for territory planning.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + ], + skills: [ + { + name: 'find-work-email', + description: + "Find and verify a prospect's work email and optional mobile number with Prospeo.", + content: + '# Find Work Email\n\nGet a deliverable work email for a prospect.\n\n## Steps\n1. Use the Enrich Person operation and provide the strongest match key: a LinkedIn URL, or First and Last Name plus Company Name or Company Website.\n2. Set Only Verified Email to Yes when deliverability matters, and Enrich Mobile to also reveal a phone number.\n3. Read the enriched person object for the email, its verification status, and the mobile if requested.\n\n## Output\nThe verified work email (and mobile if requested) with its status, or a clear note that no match was found and which keys were tried.', + }, + { + name: 'search-prospects', + description: + 'Search Prospeo for people matching an ICP using seniority, title, industry, and company filters.', + content: + '# Search Prospects\n\nBuild a targeted prospect list from the B2B database.\n\n## Steps\n1. Use the Search Person operation and supply a Filters JSON object using documented keys such as person_seniority, person_job_title, company_industry, and company_headcount_range with include or exclude lists.\n2. Avoid using only exclude filters; always include at least one positive filter.\n3. Page through results with the Page field.\n\n## Output\nThe matching prospects with names, titles, and companies, plus the pagination details so the list can be fully retrieved.', + }, + { + name: 'enrich-company', + description: + 'Enrich a company from its website or LinkedIn URL to get Prospeo firmographics.', + content: + '# Enrich Company\n\nPull firmographics for a target account.\n\n## Steps\n1. Use the Enrich Company operation and provide the Company Website or Company LinkedIn URL (most reliable), or a Company Name.\n2. Read the returned company object for size, industry, location, and other firmographic fields.\n3. For many accounts, use Bulk Enrich Company with a JSON array of records, each with an identifier and a match key.\n\n## Output\nThe company firmographics (size, industry, location) for the account, or the matched and not-matched breakdown when running in bulk.', + }, + { + name: 'bulk-enrich-list', + description: 'Enrich a list of people or companies in batches with Prospeo bulk enrichment.', + content: + '# Bulk Enrich List\n\nEnrich up to fifty records per call efficiently.\n\n## Steps\n1. Use Bulk Enrich Person (or Bulk Enrich Company) and pass a JSON array of records, each with a unique identifier and one valid match key set.\n2. Set Only Verified Email or Enrich Mobile as needed for the person variant.\n3. Map results back to inputs using the identifier, and check the not-matched and invalid-datapoints lists.\n\n## Output\nA per-identifier summary of matched records with their enriched fields, the total credit cost, and the identifiers that did not match for retry.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/prospeo.ts b/apps/sim/blocks/blocks/prospeo.ts index 8a30573d443..7a9a2c85c37 100644 --- a/apps/sim/blocks/blocks/prospeo.ts +++ b/apps/sim/blocks/blocks/prospeo.ts @@ -1,6 +1,5 @@ -import { ProspeoIcon } from '@/components/icons' import { ProspeoBlockDisplay } from '@/blocks/blocks/prospeo.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ProspeoResponse } from '@/tools/prospeo/types' export const ProspeoBlock: BlockConfig = { @@ -525,105 +524,3 @@ export const ProspeoBlock: BlockConfig = { }, }, } - -export const ProspeoBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://prospeo.io', - templates: [ - { - icon: ProspeoIcon, - title: 'Prospeo email finder', - prompt: - 'Build a workflow that takes a prospect name and company from a table, runs Prospeo to find and verify their work email, and writes the deliverable contact back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo person enricher', - prompt: - 'Create a workflow that watches CRM contacts, runs Prospeo enrichment to fill in title, company, and verified contact details, and writes the enriched fields back.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['hubspot'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo ICP search', - prompt: - 'Build a workflow that runs a Prospeo people search against my ICP filters, reveals verified emails and mobile numbers, and writes the prospect list into a sender table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo + Email Bison outbound', - prompt: - 'Create a workflow that uses Prospeo to find and verify prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo CRM gap-filler', - prompt: - 'Build a scheduled workflow that finds Salesforce contacts missing email addresses, runs Prospeo to find and verify them, and updates each contact record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo bulk list enrichment', - prompt: - 'Build a workflow that reads a large prospect list from a table, runs Prospeo bulk person enrichment in batches to reveal verified emails and titles, and writes the enriched results back row by row with a status column for any that could not be matched.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: ProspeoIcon, - title: 'Prospeo company enrichment', - prompt: - 'Create a workflow that takes a list of target company domains, runs Prospeo company enrichment to pull firmographics like size, industry, and location, and writes the structured company profiles into an account table for territory planning.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - ], - skills: [ - { - name: 'find-work-email', - description: - "Find and verify a prospect's work email and optional mobile number with Prospeo.", - content: - '# Find Work Email\n\nGet a deliverable work email for a prospect.\n\n## Steps\n1. Use the Enrich Person operation and provide the strongest match key: a LinkedIn URL, or First and Last Name plus Company Name or Company Website.\n2. Set Only Verified Email to Yes when deliverability matters, and Enrich Mobile to also reveal a phone number.\n3. Read the enriched person object for the email, its verification status, and the mobile if requested.\n\n## Output\nThe verified work email (and mobile if requested) with its status, or a clear note that no match was found and which keys were tried.', - }, - { - name: 'search-prospects', - description: - 'Search Prospeo for people matching an ICP using seniority, title, industry, and company filters.', - content: - '# Search Prospects\n\nBuild a targeted prospect list from the B2B database.\n\n## Steps\n1. Use the Search Person operation and supply a Filters JSON object using documented keys such as person_seniority, person_job_title, company_industry, and company_headcount_range with include or exclude lists.\n2. Avoid using only exclude filters; always include at least one positive filter.\n3. Page through results with the Page field.\n\n## Output\nThe matching prospects with names, titles, and companies, plus the pagination details so the list can be fully retrieved.', - }, - { - name: 'enrich-company', - description: - 'Enrich a company from its website or LinkedIn URL to get Prospeo firmographics.', - content: - '# Enrich Company\n\nPull firmographics for a target account.\n\n## Steps\n1. Use the Enrich Company operation and provide the Company Website or Company LinkedIn URL (most reliable), or a Company Name.\n2. Read the returned company object for size, industry, location, and other firmographic fields.\n3. For many accounts, use Bulk Enrich Company with a JSON array of records, each with an identifier and a match key.\n\n## Output\nThe company firmographics (size, industry, location) for the account, or the matched and not-matched breakdown when running in bulk.', - }, - { - name: 'bulk-enrich-list', - description: 'Enrich a list of people or companies in batches with Prospeo bulk enrichment.', - content: - '# Bulk Enrich List\n\nEnrich up to fifty records per call efficiently.\n\n## Steps\n1. Use Bulk Enrich Person (or Bulk Enrich Company) and pass a JSON array of records, each with a unique identifier and one valid match key set.\n2. Set Only Verified Email or Enrich Mobile as needed for the person variant.\n3. Map results back to inputs using the identifier, and check the not-matched and invalid-datapoints lists.\n\n## Output\nA per-identifier summary of matched records with their enriched fields, the total credit cost, and the identifiers that did not match for retry.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pulse.display.ts b/apps/sim/blocks/blocks/pulse.display.ts index 07be9fcef25..343d7d9bcc3 100644 --- a/apps/sim/blocks/blocks/pulse.display.ts +++ b/apps/sim/blocks/blocks/pulse.display.ts @@ -1,6 +1,6 @@ import { PulseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const PulseBlockDisplay = { type: 'pulse', @@ -24,3 +24,96 @@ export const PulseV2BlockDisplay = { 'Integrate Pulse into the workflow. Extract text from PDF documents, images, and Office files via upload or file references.', hideFromToolbar: false, } satisfies BlockDisplay + +export const PulseBlockMeta = { + tags: ['document-processing', 'ocr'], + url: 'https://www.runpulse.com', + templates: [ + { + icon: PulseIcon, + title: 'Pulse invoice extractor', + prompt: + 'Create a workflow that runs each uploaded invoice PDF through Pulse OCR, extracts vendor, line items, and totals into structured fields, and writes the parsed records to an accounts-payable table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['document-processing', 'automation'], + }, + { + icon: PulseIcon, + title: 'Pulse contract clause extractor', + prompt: + 'Build a workflow that extracts the full text of uploaded contract PDFs with Pulse OCR, has an agent pull out key clauses, parties, and renewal dates, and writes a structured summary to a table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['document-processing', 'analysis'], + }, + { + icon: PulseIcon, + title: 'Pulse scanned-document indexer', + prompt: + 'Create a workflow that runs each scanned image or PDF through Pulse OCR, chunks the extracted markdown, and indexes the cleaned content into a knowledge base so agents can search across every document.', + modules: ['files', 'knowledge-base', 'agent', 'workflows'], + category: 'operations', + tags: ['ocr', 'knowledge-base'], + }, + { + icon: PulseIcon, + title: 'Pulse form data extractor', + prompt: + 'Build a workflow that extracts text from uploaded form PDFs and images with Pulse OCR, maps the values into structured fields with an agent, and writes each submission to a table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ocr', 'automation'], + }, + { + icon: PulseIcon, + title: 'Pulse table-to-spreadsheet extractor', + prompt: + 'Create a workflow that runs uploaded reports through Pulse OCR, pulls the embedded tables into structured rows, and writes the consolidated data to a tracking table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['document-processing', 'automation'], + }, + { + icon: PulseIcon, + title: 'Pulse document summarizer', + prompt: + 'Build a workflow that extracts the text of an uploaded PDF or Office file with Pulse OCR, has an agent write a concise summary, and posts it to Slack.', + modules: ['files', 'agent', 'workflows'], + category: 'productivity', + tags: ['document-processing', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: PulseIcon, + title: 'Pulse document OCR pipeline', + prompt: + 'Build a workflow that runs each uploaded PDF, image, or Office file through Pulse OCR, extracts the text into structured rows in a table, and indexes the cleaned content into a knowledge base so agents can search across every scanned document.', + modules: ['files', 'tables', 'knowledge-base', 'agent', 'workflows'], + category: 'operations', + tags: ['ocr', 'document-processing', 'automation'], + }, + ], + skills: [ + { + name: 'extract-document-text', + description: 'Run a PDF, image, or Office file through Pulse OCR and return clean markdown.', + content: + '# Extract Document Text\n\nTurn a document into structured markdown text.\n\n## Steps\n1. Upload the Document (PDF, image, DOCX, PPTX, or XLSX) or provide a file reference.\n2. Optionally set Specific Pages (for example 1-3,5) to limit extraction to part of the document.\n3. Provide the Pulse API Key.\n4. Use the returned markdown as the source for downstream summarization or parsing.\n\n## Output\nThe extracted markdown text and the page count, plus any bounding-box or figure data when available.', + }, + { + name: 'extract-structured-fields', + description: + 'Use Pulse OCR output to pull structured fields like vendor, totals, or dates from a document.', + content: + '# Extract Structured Fields\n\nPull specific data points out of a scanned document.\n\n## Steps\n1. Run the document through Pulse OCR to get the markdown text.\n2. In a following agent step, map the markdown to the target fields (for example invoice vendor, line items, totals, or contract parties and renewal dates).\n3. Validate the parsed values against the source text before using them.\n\n## Output\nA structured record of the requested fields, with a note on any field that could not be confidently extracted from the document.', + }, + { + name: 'chunk-for-knowledge-base', + description: + 'Extract and chunk a document with Pulse OCR so it can be indexed for retrieval.', + content: + '# Chunk For Knowledge Base\n\nPrepare a document for vector indexing.\n\n## Steps\n1. Upload the Document and provide the Pulse API Key.\n2. Set a Chunking Strategy (semantic, header, page, or recursive) and a Chunk Size in characters.\n3. Use the returned chunks as the units to embed and index into a knowledge base.\n\n## Output\nThe chunked content ready for embedding, with each chunk sized per the strategy, plus the total page count for reference.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/pulse.ts b/apps/sim/blocks/blocks/pulse.ts index f9ca933a644..875647b91d2 100644 --- a/apps/sim/blocks/blocks/pulse.ts +++ b/apps/sim/blocks/blocks/pulse.ts @@ -1,6 +1,5 @@ -import { PulseIcon } from '@/components/icons' import { PulseBlockDisplay, PulseV2BlockDisplay } from '@/blocks/blocks/pulse.display' -import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' +import { AuthMode, type BlockConfig, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { PulseParserOutput } from '@/tools/pulse/types' @@ -189,96 +188,3 @@ export const PulseV2Block: BlockConfig = { }, inputs: pulseV2Inputs, } - -export const PulseBlockMeta = { - tags: ['document-processing', 'ocr'], - url: 'https://www.runpulse.com', - templates: [ - { - icon: PulseIcon, - title: 'Pulse invoice extractor', - prompt: - 'Create a workflow that runs each uploaded invoice PDF through Pulse OCR, extracts vendor, line items, and totals into structured fields, and writes the parsed records to an accounts-payable table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['document-processing', 'automation'], - }, - { - icon: PulseIcon, - title: 'Pulse contract clause extractor', - prompt: - 'Build a workflow that extracts the full text of uploaded contract PDFs with Pulse OCR, has an agent pull out key clauses, parties, and renewal dates, and writes a structured summary to a table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['document-processing', 'analysis'], - }, - { - icon: PulseIcon, - title: 'Pulse scanned-document indexer', - prompt: - 'Create a workflow that runs each scanned image or PDF through Pulse OCR, chunks the extracted markdown, and indexes the cleaned content into a knowledge base so agents can search across every document.', - modules: ['files', 'knowledge-base', 'agent', 'workflows'], - category: 'operations', - tags: ['ocr', 'knowledge-base'], - }, - { - icon: PulseIcon, - title: 'Pulse form data extractor', - prompt: - 'Build a workflow that extracts text from uploaded form PDFs and images with Pulse OCR, maps the values into structured fields with an agent, and writes each submission to a table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ocr', 'automation'], - }, - { - icon: PulseIcon, - title: 'Pulse table-to-spreadsheet extractor', - prompt: - 'Create a workflow that runs uploaded reports through Pulse OCR, pulls the embedded tables into structured rows, and writes the consolidated data to a tracking table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['document-processing', 'automation'], - }, - { - icon: PulseIcon, - title: 'Pulse document summarizer', - prompt: - 'Build a workflow that extracts the text of an uploaded PDF or Office file with Pulse OCR, has an agent write a concise summary, and posts it to Slack.', - modules: ['files', 'agent', 'workflows'], - category: 'productivity', - tags: ['document-processing', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: PulseIcon, - title: 'Pulse document OCR pipeline', - prompt: - 'Build a workflow that runs each uploaded PDF, image, or Office file through Pulse OCR, extracts the text into structured rows in a table, and indexes the cleaned content into a knowledge base so agents can search across every scanned document.', - modules: ['files', 'tables', 'knowledge-base', 'agent', 'workflows'], - category: 'operations', - tags: ['ocr', 'document-processing', 'automation'], - }, - ], - skills: [ - { - name: 'extract-document-text', - description: 'Run a PDF, image, or Office file through Pulse OCR and return clean markdown.', - content: - '# Extract Document Text\n\nTurn a document into structured markdown text.\n\n## Steps\n1. Upload the Document (PDF, image, DOCX, PPTX, or XLSX) or provide a file reference.\n2. Optionally set Specific Pages (for example 1-3,5) to limit extraction to part of the document.\n3. Provide the Pulse API Key.\n4. Use the returned markdown as the source for downstream summarization or parsing.\n\n## Output\nThe extracted markdown text and the page count, plus any bounding-box or figure data when available.', - }, - { - name: 'extract-structured-fields', - description: - 'Use Pulse OCR output to pull structured fields like vendor, totals, or dates from a document.', - content: - '# Extract Structured Fields\n\nPull specific data points out of a scanned document.\n\n## Steps\n1. Run the document through Pulse OCR to get the markdown text.\n2. In a following agent step, map the markdown to the target fields (for example invoice vendor, line items, totals, or contract parties and renewal dates).\n3. Validate the parsed values against the source text before using them.\n\n## Output\nA structured record of the requested fields, with a note on any field that could not be confidently extracted from the document.', - }, - { - name: 'chunk-for-knowledge-base', - description: - 'Extract and chunk a document with Pulse OCR so it can be indexed for retrieval.', - content: - '# Chunk For Knowledge Base\n\nPrepare a document for vector indexing.\n\n## Steps\n1. Upload the Document and provide the Pulse API Key.\n2. Set a Chunking Strategy (semantic, header, page, or recursive) and a Chunk Size in characters.\n3. Use the returned chunks as the units to embed and index into a knowledge base.\n\n## Output\nThe chunked content ready for embedding, with each chunk sized per the strategy, plus the total page count for reference.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/qdrant.display.ts b/apps/sim/blocks/blocks/qdrant.display.ts index 98e1e824875..72356be84c7 100644 --- a/apps/sim/blocks/blocks/qdrant.display.ts +++ b/apps/sim/blocks/blocks/qdrant.display.ts @@ -1,6 +1,6 @@ import { QdrantIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const QdrantBlockDisplay = { type: 'qdrant', @@ -13,3 +13,96 @@ export const QdrantBlockDisplay = { docsLink: 'https://qdrant.tech/documentation/', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const QdrantBlockMeta = { + tags: ['vector-search', 'knowledge-base'], + url: 'https://qdrant.tech', + templates: [ + { + icon: QdrantIcon, + title: 'Qdrant document ingestion', + prompt: + 'Build a workflow that watches a Google Drive folder for new docs, chunks each, generates embeddings, and upserts the vectors into a Qdrant collection with rich metadata.', + modules: ['files', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['google_drive', 'openai'], + }, + { + icon: QdrantIcon, + title: 'Qdrant retrieval agent', + prompt: + 'Create an agent that performs hybrid search against a Qdrant collection — semantic + filter conditions — and answers user questions with the matched documents cited.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'enterprise'], + }, + { + icon: QdrantIcon, + title: 'Qdrant payload schema migrator', + prompt: + 'Build a workflow that scans a Qdrant collection, migrates payload schema to a new version with backfilled fields, and writes the migration plan and outcome to an audit table.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: QdrantIcon, + title: 'Qdrant + knowledge base sync', + prompt: + 'Create a workflow that mirrors a Sim knowledge base into a Qdrant collection so downstream applications outside Sim can perform retrieval against the same vectors.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + }, + { + icon: QdrantIcon, + title: 'Qdrant snapshot manager', + prompt: + 'Build a scheduled workflow that takes a Qdrant collection snapshot each night, uploads it to S3 with retention rotation, and writes the snapshot manifest to a tracking table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['s3'], + }, + { + icon: QdrantIcon, + title: 'Qdrant abandoned-document detector', + prompt: + 'Create a workflow that scans a Qdrant collection for vectors whose source document no longer exists, deletes the orphans, and writes a hygiene report each week.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: QdrantIcon, + title: 'Qdrant support-answer retriever', + prompt: + 'Build a workflow that embeds each new Zendesk ticket with OpenAI, runs a filtered Qdrant search scoped to the customer’s product, and drafts a cited reply from the closest matching resolved tickets for the agent to approve.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'vector-search', 'automation'], + alsoIntegrations: ['openai', 'zendesk'], + }, + ], + skills: [ + { + name: 'upsert-points', + description: 'Insert or update vector points with payload metadata into a Qdrant collection.', + content: + '# Upsert Points\n\nLoad vectors into a Qdrant collection.\n\n## Steps\n1. Use the Upsert operation with the Qdrant URL, Collection name, and API Key.\n2. Provide Points as a JSON array, each with an id, a vector matching the collection dimension, and an optional payload of metadata for later filtering.\n3. Confirm the upserted count from the response.\n\n## Output\nReport how many points were upserted into which collection and surface any payload validation issues.', + }, + { + name: 'search-vectors', + description: 'Run a vector similarity search in Qdrant with optional payload filters.', + content: + '# Search Vectors\n\nFind the nearest points to a query vector.\n\n## Steps\n1. Use the Search operation with the Qdrant URL, Collection, and the Query Vector.\n2. Set the Limit for how many matches to return and choose what Return Data you need (payload only, vector only, both, or none).\n3. Optionally pass a Filter JSON object using must, should, or must_not conditions to scope the search by payload fields.\n\n## Output\nThe top matches with their scores and requested payload or vector data, ordered by similarity.', + }, + { + name: 'fetch-points-by-id', + description: 'Retrieve specific Qdrant points and their payloads by ID.', + content: + '# Fetch Points By ID\n\nLook up known points directly.\n\n## Steps\n1. Use the Fetch operation with the Qdrant URL, Collection, and API Key.\n2. Provide the IDs as a JSON array of the points to retrieve.\n3. Choose the Return Data option to control whether payloads and vectors are included.\n\n## Output\nThe requested points with their payloads (and vectors if requested), plus a note on any IDs that were not found.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/qdrant.ts b/apps/sim/blocks/blocks/qdrant.ts index ff8143a3fa4..93f7434a179 100644 --- a/apps/sim/blocks/blocks/qdrant.ts +++ b/apps/sim/blocks/blocks/qdrant.ts @@ -1,6 +1,5 @@ -import { QdrantIcon } from '@/components/icons' import { QdrantBlockDisplay } from '@/blocks/blocks/qdrant.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { QdrantResponse } from '@/tools/qdrant/types' @@ -239,96 +238,3 @@ Return ONLY the JSON object.`, status: { type: 'string', description: 'Operation status' }, }, } - -export const QdrantBlockMeta = { - tags: ['vector-search', 'knowledge-base'], - url: 'https://qdrant.tech', - templates: [ - { - icon: QdrantIcon, - title: 'Qdrant document ingestion', - prompt: - 'Build a workflow that watches a Google Drive folder for new docs, chunks each, generates embeddings, and upserts the vectors into a Qdrant collection with rich metadata.', - modules: ['files', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['google_drive', 'openai'], - }, - { - icon: QdrantIcon, - title: 'Qdrant retrieval agent', - prompt: - 'Create an agent that performs hybrid search against a Qdrant collection — semantic + filter conditions — and answers user questions with the matched documents cited.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'enterprise'], - }, - { - icon: QdrantIcon, - title: 'Qdrant payload schema migrator', - prompt: - 'Build a workflow that scans a Qdrant collection, migrates payload schema to a new version with backfilled fields, and writes the migration plan and outcome to an audit table.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: QdrantIcon, - title: 'Qdrant + knowledge base sync', - prompt: - 'Create a workflow that mirrors a Sim knowledge base into a Qdrant collection so downstream applications outside Sim can perform retrieval against the same vectors.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - }, - { - icon: QdrantIcon, - title: 'Qdrant snapshot manager', - prompt: - 'Build a scheduled workflow that takes a Qdrant collection snapshot each night, uploads it to S3 with retention rotation, and writes the snapshot manifest to a tracking table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['s3'], - }, - { - icon: QdrantIcon, - title: 'Qdrant abandoned-document detector', - prompt: - 'Create a workflow that scans a Qdrant collection for vectors whose source document no longer exists, deletes the orphans, and writes a hygiene report each week.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: QdrantIcon, - title: 'Qdrant support-answer retriever', - prompt: - 'Build a workflow that embeds each new Zendesk ticket with OpenAI, runs a filtered Qdrant search scoped to the customer’s product, and drafts a cited reply from the closest matching resolved tickets for the agent to approve.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'vector-search', 'automation'], - alsoIntegrations: ['openai', 'zendesk'], - }, - ], - skills: [ - { - name: 'upsert-points', - description: 'Insert or update vector points with payload metadata into a Qdrant collection.', - content: - '# Upsert Points\n\nLoad vectors into a Qdrant collection.\n\n## Steps\n1. Use the Upsert operation with the Qdrant URL, Collection name, and API Key.\n2. Provide Points as a JSON array, each with an id, a vector matching the collection dimension, and an optional payload of metadata for later filtering.\n3. Confirm the upserted count from the response.\n\n## Output\nReport how many points were upserted into which collection and surface any payload validation issues.', - }, - { - name: 'search-vectors', - description: 'Run a vector similarity search in Qdrant with optional payload filters.', - content: - '# Search Vectors\n\nFind the nearest points to a query vector.\n\n## Steps\n1. Use the Search operation with the Qdrant URL, Collection, and the Query Vector.\n2. Set the Limit for how many matches to return and choose what Return Data you need (payload only, vector only, both, or none).\n3. Optionally pass a Filter JSON object using must, should, or must_not conditions to scope the search by payload fields.\n\n## Output\nThe top matches with their scores and requested payload or vector data, ordered by similarity.', - }, - { - name: 'fetch-points-by-id', - description: 'Retrieve specific Qdrant points and their payloads by ID.', - content: - '# Fetch Points By ID\n\nLook up known points directly.\n\n## Steps\n1. Use the Fetch operation with the Qdrant URL, Collection, and API Key.\n2. Provide the IDs as a JSON array of the points to retrieve.\n3. Choose the Return Data option to control whether payloads and vectors are included.\n\n## Output\nThe requested points with their payloads (and vectors if requested), plus a note on any IDs that were not found.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/quartr.display.ts b/apps/sim/blocks/blocks/quartr.display.ts index 3af8e97cfce..882a8e6952e 100644 --- a/apps/sim/blocks/blocks/quartr.display.ts +++ b/apps/sim/blocks/blocks/quartr.display.ts @@ -1,6 +1,6 @@ import { QuartrIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const QuartrBlockDisplay = { type: 'quartr', @@ -14,3 +14,113 @@ export const QuartrBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/quartr', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const QuartrBlockMeta = { + tags: ['data-analytics', 'enrichment', 'document-processing'], + url: 'https://quartr.com', + templates: [ + { + icon: QuartrIcon, + title: 'Quartr earnings call digest', + prompt: + 'Create a scheduled workflow that lists yesterday’s Quartr events for my watchlist tickers, fetches the AI-generated summary for each event, and posts a digest with source links to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: QuartrIcon, + title: 'Quartr transcript knowledge base', + prompt: + 'Build a scheduled workflow that lists new Quartr earnings call transcripts for companies I follow, downloads each transcript file, and indexes the content into a knowledge base so agents can answer questions about past calls.', + modules: ['scheduled', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research', 'knowledge-base'], + }, + { + icon: QuartrIcon, + title: 'Quartr filing watcher', + prompt: + 'Create a scheduled workflow that checks Quartr daily for new annual and interim reports from my portfolio companies, downloads each report PDF to Files, and emails me a summary of what was filed.', + modules: ['scheduled', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: QuartrIcon, + title: 'Quartr slide deck analyst', + prompt: + 'Build a workflow that fetches the latest Quartr slide deck for a given ticker, has an agent extract guidance, KPIs, and notable changes from the deck, and writes the analysis to a table.', + modules: ['agent', 'tables', 'workflows'], + category: 'productivity', + tags: ['research', 'document-processing'], + }, + { + icon: QuartrIcon, + title: 'Quartr live earnings monitor', + prompt: + 'Create a scheduled workflow that polls Quartr live events for my watchlist, and when a company goes live, posts the live audio and transcript stream links to a Slack channel.', + modules: ['scheduled', 'workflows'], + category: 'operations', + tags: ['monitoring', 'events'], + alsoIntegrations: ['slack'], + }, + { + icon: QuartrIcon, + title: 'Quartr competitor earnings tracker', + prompt: + 'Build a workflow that reads competitor tickers from a table, lists each company’s recent Quartr events and event summaries, and logs revenue and guidance highlights back to the table for quarter-over-quarter comparison.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['research', 'sales'], + }, + { + icon: QuartrIcon, + title: 'Quartr earnings Q&A agent', + prompt: + 'Create an agent that answers questions about a company’s earnings by looking up the company on Quartr, finding its latest earnings call event, and grounding answers in the event summary and transcript.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'agentic'], + }, + ], + skills: [ + { + name: 'summarize-earnings-call', + description: + 'Find a company’s latest earnings call on Quartr and return its AI-generated summary with sources.', + content: + '# Summarize an Earnings Call\n\nTurn a ticker into a sourced summary of the company’s most recent earnings call.\n\n## Steps\n1. Use the List Companies operation with the ticker in Tickers to resolve the Quartr company ID.\n2. Use List Events with that ID in Company IDs, Sort By set to Date, and Sort Direction set to Descending to find the latest earnings event.\n3. Use Get Event Summary with the event ID. Pick Summary Length: One Line for a headline, Short for a digest, or Long for full detail.\n4. Keep Plain Text Summary off if you want the embedded source tags, and use the sources output to cite documents.\n\n## Output\nReturn the summary text followed by the event title, date, and the source document IDs it references.', + }, + { + name: 'download-earnings-transcript', + description: + 'Download the structured transcript JSON for a company’s earnings call for downstream analysis.', + content: + '# Download an Earnings Call Transcript\n\nFetch a transcript with timestamps and speaker identification as a workflow file.\n\n## Steps\n1. Resolve the company with List Companies (ticker, ISIN, or CIK).\n2. Use List Transcripts with the company ID in Company IDs and a date range to find the right transcript document.\n3. Use Get Transcript with that document ID. The transcript JSON is downloaded and stored as an execution file.\n4. Pass the file to an agent or knowledge base to analyze paragraphs, sentences, timestamps, and speakers.\n\n## Output\nReturn the transcript file plus the document metadata (event title, fiscal period, and date).', + }, + { + name: 'fetch-latest-filings', + description: + 'List a company’s recent filings and reports on Quartr and download the report PDFs.', + content: + '# Fetch the Latest Filings and Reports\n\nPull recent 10-Ks, 10-Qs, earnings releases, or annual reports for a company.\n\n## Steps\n1. Resolve the company with List Companies using its ticker or CIK.\n2. Use List Reports with the company ID in Company IDs. Narrow with Document Group IDs (1 = Earnings Release, 3 = Interim Report, 4 = Annual Report) or a date range.\n3. Use Get Report with each document ID to download the PDF into execution files.\n4. Optionally use List Document Types to map type IDs to filing forms like 10-Q.\n\n## Output\nReturn the report files with each document’s type, event, and filing date.', + }, + { + name: 'monitor-live-earnings', + description: + 'Check which companies are live on Quartr right now and surface their audio and transcript streams.', + content: + '# Monitor Live Earnings Calls\n\nWatch for companies going live and grab their stream URLs.\n\n## Steps\n1. Use List Live Events with Live States set to live (or willBeLive to see what is coming up).\n2. Filter to your watchlist with Company IDs or Tickers.\n3. Read each live event’s state, audio stream URL, and transcript stream URL from the output.\n4. Run the workflow on a schedule and alert when a watched company’s state changes to live.\n\n## Output\nReturn the live companies with their event IDs, states, and audio/transcript stream URLs.', + }, + { + name: 'analyze-investor-slides', + description: + 'Download a company’s latest investor presentation from Quartr and extract key takeaways.', + content: + '# Analyze an Investor Slide Deck\n\nGet the latest presentation PDF and have an agent extract what matters.\n\n## Steps\n1. Resolve the company with List Companies and find the relevant event with List Events.\n2. Use List Slide Decks with the event ID in Event IDs (or the company ID and a date range) to find the deck.\n3. Use Get Slide Deck with the document ID to download the PDF into execution files.\n4. Pass the file to an agent to extract guidance, KPIs, and notable changes.\n\n## Output\nReturn the slide deck file plus the extracted highlights.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/quartr.ts b/apps/sim/blocks/blocks/quartr.ts index 996542bbff2..3db5516f8ed 100644 --- a/apps/sim/blocks/blocks/quartr.ts +++ b/apps/sim/blocks/blocks/quartr.ts @@ -1,6 +1,5 @@ -import { QuartrIcon } from '@/components/icons' import { QuartrBlockDisplay } from '@/blocks/blocks/quartr.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' @@ -528,113 +527,3 @@ export const QuartrBlock: BlockConfig = { }, }, } - -export const QuartrBlockMeta = { - tags: ['data-analytics', 'enrichment', 'document-processing'], - url: 'https://quartr.com', - templates: [ - { - icon: QuartrIcon, - title: 'Quartr earnings call digest', - prompt: - 'Create a scheduled workflow that lists yesterday’s Quartr events for my watchlist tickers, fetches the AI-generated summary for each event, and posts a digest with source links to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: QuartrIcon, - title: 'Quartr transcript knowledge base', - prompt: - 'Build a scheduled workflow that lists new Quartr earnings call transcripts for companies I follow, downloads each transcript file, and indexes the content into a knowledge base so agents can answer questions about past calls.', - modules: ['scheduled', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research', 'knowledge-base'], - }, - { - icon: QuartrIcon, - title: 'Quartr filing watcher', - prompt: - 'Create a scheduled workflow that checks Quartr daily for new annual and interim reports from my portfolio companies, downloads each report PDF to Files, and emails me a summary of what was filed.', - modules: ['scheduled', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: QuartrIcon, - title: 'Quartr slide deck analyst', - prompt: - 'Build a workflow that fetches the latest Quartr slide deck for a given ticker, has an agent extract guidance, KPIs, and notable changes from the deck, and writes the analysis to a table.', - modules: ['agent', 'tables', 'workflows'], - category: 'productivity', - tags: ['research', 'document-processing'], - }, - { - icon: QuartrIcon, - title: 'Quartr live earnings monitor', - prompt: - 'Create a scheduled workflow that polls Quartr live events for my watchlist, and when a company goes live, posts the live audio and transcript stream links to a Slack channel.', - modules: ['scheduled', 'workflows'], - category: 'operations', - tags: ['monitoring', 'events'], - alsoIntegrations: ['slack'], - }, - { - icon: QuartrIcon, - title: 'Quartr competitor earnings tracker', - prompt: - 'Build a workflow that reads competitor tickers from a table, lists each company’s recent Quartr events and event summaries, and logs revenue and guidance highlights back to the table for quarter-over-quarter comparison.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['research', 'sales'], - }, - { - icon: QuartrIcon, - title: 'Quartr earnings Q&A agent', - prompt: - 'Create an agent that answers questions about a company’s earnings by looking up the company on Quartr, finding its latest earnings call event, and grounding answers in the event summary and transcript.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'agentic'], - }, - ], - skills: [ - { - name: 'summarize-earnings-call', - description: - 'Find a company’s latest earnings call on Quartr and return its AI-generated summary with sources.', - content: - '# Summarize an Earnings Call\n\nTurn a ticker into a sourced summary of the company’s most recent earnings call.\n\n## Steps\n1. Use the List Companies operation with the ticker in Tickers to resolve the Quartr company ID.\n2. Use List Events with that ID in Company IDs, Sort By set to Date, and Sort Direction set to Descending to find the latest earnings event.\n3. Use Get Event Summary with the event ID. Pick Summary Length: One Line for a headline, Short for a digest, or Long for full detail.\n4. Keep Plain Text Summary off if you want the embedded source tags, and use the sources output to cite documents.\n\n## Output\nReturn the summary text followed by the event title, date, and the source document IDs it references.', - }, - { - name: 'download-earnings-transcript', - description: - 'Download the structured transcript JSON for a company’s earnings call for downstream analysis.', - content: - '# Download an Earnings Call Transcript\n\nFetch a transcript with timestamps and speaker identification as a workflow file.\n\n## Steps\n1. Resolve the company with List Companies (ticker, ISIN, or CIK).\n2. Use List Transcripts with the company ID in Company IDs and a date range to find the right transcript document.\n3. Use Get Transcript with that document ID. The transcript JSON is downloaded and stored as an execution file.\n4. Pass the file to an agent or knowledge base to analyze paragraphs, sentences, timestamps, and speakers.\n\n## Output\nReturn the transcript file plus the document metadata (event title, fiscal period, and date).', - }, - { - name: 'fetch-latest-filings', - description: - 'List a company’s recent filings and reports on Quartr and download the report PDFs.', - content: - '# Fetch the Latest Filings and Reports\n\nPull recent 10-Ks, 10-Qs, earnings releases, or annual reports for a company.\n\n## Steps\n1. Resolve the company with List Companies using its ticker or CIK.\n2. Use List Reports with the company ID in Company IDs. Narrow with Document Group IDs (1 = Earnings Release, 3 = Interim Report, 4 = Annual Report) or a date range.\n3. Use Get Report with each document ID to download the PDF into execution files.\n4. Optionally use List Document Types to map type IDs to filing forms like 10-Q.\n\n## Output\nReturn the report files with each document’s type, event, and filing date.', - }, - { - name: 'monitor-live-earnings', - description: - 'Check which companies are live on Quartr right now and surface their audio and transcript streams.', - content: - '# Monitor Live Earnings Calls\n\nWatch for companies going live and grab their stream URLs.\n\n## Steps\n1. Use List Live Events with Live States set to live (or willBeLive to see what is coming up).\n2. Filter to your watchlist with Company IDs or Tickers.\n3. Read each live event’s state, audio stream URL, and transcript stream URL from the output.\n4. Run the workflow on a schedule and alert when a watched company’s state changes to live.\n\n## Output\nReturn the live companies with their event IDs, states, and audio/transcript stream URLs.', - }, - { - name: 'analyze-investor-slides', - description: - 'Download a company’s latest investor presentation from Quartr and extract key takeaways.', - content: - '# Analyze an Investor Slide Deck\n\nGet the latest presentation PDF and have an agent extract what matters.\n\n## Steps\n1. Resolve the company with List Companies and find the relevant event with List Events.\n2. Use List Slide Decks with the event ID in Event IDs (or the company ID and a date range) to find the deck.\n3. Use Get Slide Deck with the document ID to download the PDF into execution files.\n4. Pass the file to an agent to extract guidance, KPIs, and notable changes.\n\n## Output\nReturn the slide deck file plus the extracted highlights.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/quiver.display.ts b/apps/sim/blocks/blocks/quiver.display.ts index d247b589f0b..c356fce72fd 100644 --- a/apps/sim/blocks/blocks/quiver.display.ts +++ b/apps/sim/blocks/blocks/quiver.display.ts @@ -1,6 +1,6 @@ import { QuiverIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const QuiverBlockDisplay = { type: 'quiver', @@ -14,3 +14,57 @@ export const QuiverBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/quiver', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const QuiverBlockMeta = { + tags: ['image-generation'], + url: 'https://quiver.ai', + templates: [ + { + icon: QuiverIcon, + title: 'Quiver SVG icon generator', + prompt: + 'Build a workflow that takes a product name and brand color as inputs, generates a matching SVG icon with Quiver, and saves it to the files store.', + modules: ['files', 'agent', 'workflows'], + category: 'marketing', + tags: ['design', 'automation'], + }, + { + icon: QuiverIcon, + title: 'Quiver diagram creator', + prompt: + 'Create a workflow that reads structured data from a table and uses Quiver to generate a clean SVG diagram visualizing the data, then attaches it to a Slack message.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['design', 'reporting'], + }, + { + icon: QuiverIcon, + title: 'Quiver image vectorizer', + prompt: + 'Build a workflow that accepts a raster image upload, vectorizes it to SVG with Quiver, and returns the clean SVG for use in presentations or exports.', + modules: ['files', 'workflows'], + category: 'operations', + tags: ['design', 'automation'], + }, + ], + skills: [ + { + name: 'generate-brand-icon', + description: 'Generate a clean SVG icon from a text prompt and save it to the files store.', + content: + '# Generate Brand Icon\n\nTurn a text description into a production-ready SVG icon using Quiver text-to-SVG.\n\n## Steps\n1. Collect the icon concept (for example, a product name plus a brand color and style cues).\n2. Run the text_to_svg operation with a focused prompt that names the subject, color palette, and visual style (flat, line, filled).\n3. Optionally set n greater than 1 to generate several variations to choose from.\n4. Save the returned SVG file to the files store, or pass svgContent downstream for embedding.\n\n## Output\nReport the saved file location and the request id. When multiple variations are generated, list each so the user can pick one.', + }, + { + name: 'vectorize-raster-image', + description: 'Convert an uploaded raster image (PNG or JPG) into a clean editable SVG.', + content: + '# Vectorize Raster Image\n\nConvert a bitmap logo or graphic into a scalable SVG with Quiver image-to-SVG.\n\n## Steps\n1. Accept the raster image upload and pass it as the image input.\n2. Run the image_to_svg operation, optionally setting auto_crop and a target_size to tighten the output.\n3. Inspect svgContent for fidelity; rerun with adjusted instructions if details are lost.\n4. Save the SVG file for use in presentations, exports, or the web.\n\n## Output\nReturn the vectorized SVG file and confirm dimensions. Note any visual elements that did not vectorize cleanly.', + }, + { + name: 'create-data-diagram', + description: 'Generate an SVG diagram that visualizes structured data, then share it.', + content: + '# Create Data Diagram\n\nProduce a clean SVG diagram from structured data and attach it to a message.\n\n## Steps\n1. Read the structured data (for example, rows from a table) that should be visualized.\n2. Summarize the data into a precise prompt describing the diagram type and relationships.\n3. Run the text_to_svg operation to generate the diagram.\n4. Save the SVG file and attach it to the target channel or document.\n\n## Output\nShare the generated diagram file and a one-line description of what it depicts.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/quiver.ts b/apps/sim/blocks/blocks/quiver.ts index 84476b05937..2bd32d3d9d0 100644 --- a/apps/sim/blocks/blocks/quiver.ts +++ b/apps/sim/blocks/blocks/quiver.ts @@ -1,6 +1,5 @@ -import { QuiverIcon } from '@/components/icons' import { QuiverBlockDisplay } from '@/blocks/blocks/quiver.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { QuiverSvgResponse } from '@/tools/quiver/types' @@ -228,57 +227,3 @@ export const QuiverBlock: BlockConfig = { }, }, } - -export const QuiverBlockMeta = { - tags: ['image-generation'], - url: 'https://quiver.ai', - templates: [ - { - icon: QuiverIcon, - title: 'Quiver SVG icon generator', - prompt: - 'Build a workflow that takes a product name and brand color as inputs, generates a matching SVG icon with Quiver, and saves it to the files store.', - modules: ['files', 'agent', 'workflows'], - category: 'marketing', - tags: ['design', 'automation'], - }, - { - icon: QuiverIcon, - title: 'Quiver diagram creator', - prompt: - 'Create a workflow that reads structured data from a table and uses Quiver to generate a clean SVG diagram visualizing the data, then attaches it to a Slack message.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['design', 'reporting'], - }, - { - icon: QuiverIcon, - title: 'Quiver image vectorizer', - prompt: - 'Build a workflow that accepts a raster image upload, vectorizes it to SVG with Quiver, and returns the clean SVG for use in presentations or exports.', - modules: ['files', 'workflows'], - category: 'operations', - tags: ['design', 'automation'], - }, - ], - skills: [ - { - name: 'generate-brand-icon', - description: 'Generate a clean SVG icon from a text prompt and save it to the files store.', - content: - '# Generate Brand Icon\n\nTurn a text description into a production-ready SVG icon using Quiver text-to-SVG.\n\n## Steps\n1. Collect the icon concept (for example, a product name plus a brand color and style cues).\n2. Run the text_to_svg operation with a focused prompt that names the subject, color palette, and visual style (flat, line, filled).\n3. Optionally set n greater than 1 to generate several variations to choose from.\n4. Save the returned SVG file to the files store, or pass svgContent downstream for embedding.\n\n## Output\nReport the saved file location and the request id. When multiple variations are generated, list each so the user can pick one.', - }, - { - name: 'vectorize-raster-image', - description: 'Convert an uploaded raster image (PNG or JPG) into a clean editable SVG.', - content: - '# Vectorize Raster Image\n\nConvert a bitmap logo or graphic into a scalable SVG with Quiver image-to-SVG.\n\n## Steps\n1. Accept the raster image upload and pass it as the image input.\n2. Run the image_to_svg operation, optionally setting auto_crop and a target_size to tighten the output.\n3. Inspect svgContent for fidelity; rerun with adjusted instructions if details are lost.\n4. Save the SVG file for use in presentations, exports, or the web.\n\n## Output\nReturn the vectorized SVG file and confirm dimensions. Note any visual elements that did not vectorize cleanly.', - }, - { - name: 'create-data-diagram', - description: 'Generate an SVG diagram that visualizes structured data, then share it.', - content: - '# Create Data Diagram\n\nProduce a clean SVG diagram from structured data and attach it to a message.\n\n## Steps\n1. Read the structured data (for example, rows from a table) that should be visualized.\n2. Summarize the data into a precise prompt describing the diagram type and relationships.\n3. Run the text_to_svg operation to generate the diagram.\n4. Save the SVG file and attach it to the target channel or document.\n\n## Output\nShare the generated diagram file and a one-line description of what it depicts.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/railway.display.ts b/apps/sim/blocks/blocks/railway.display.ts index 894c80bc67c..10500757697 100644 --- a/apps/sim/blocks/blocks/railway.display.ts +++ b/apps/sim/blocks/blocks/railway.display.ts @@ -1,6 +1,6 @@ import { RailwayIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RailwayBlockDisplay = { type: 'railway', @@ -14,3 +14,118 @@ export const RailwayBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/railway', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const RailwayBlockMeta = { + tags: ['cloud', 'ci-cd'], + url: 'https://railway.com', + templates: [ + { + icon: RailwayIcon, + title: 'Railway deployment monitor', + prompt: + 'Build a scheduled workflow that lists the latest Railway deployments across my services every few minutes, detects failed or crashed deployments, summarizes the failure with an agent, and posts an actionable Slack alert with a link to the service.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['slack'], + }, + { + icon: RailwayIcon, + title: 'Railway deploy on merge', + prompt: + 'Create a workflow that watches GitHub for merges to the main branch, triggers a Railway service deployment for the matching environment, and posts the deployment status back as a Slack notification.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'ci-cd', 'automation'], + alsoIntegrations: ['github', 'slack'], + }, + { + icon: RailwayIcon, + title: 'Railway environment variable auditor', + prompt: + 'Build a scheduled weekly workflow that lists environment variables across every Railway project, compares them to a reference list in a table, flags drift and missing keys, and emails a remediation report to the platform team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'monitoring'], + }, + { + icon: RailwayIcon, + title: 'Railway project inventory', + prompt: + 'Create a scheduled workflow that lists every Railway project, its services, and environments weekly, logs them into a tracking table, and Slacks a diff of any added or removed resources so infrastructure changes never go unnoticed.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: RailwayIcon, + title: 'Railway config sync', + prompt: + 'Build a workflow that reads service configuration from a table and upserts the matching Railway environment variables for each service, then posts a Slack summary of every variable that was created or changed.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: RailwayIcon, + title: 'Railway preview environment provisioner', + prompt: + 'Create a workflow that watches GitHub for new pull requests, creates a fresh Railway environment for the branch, upserts the required environment variables, deploys the service, and comments the live preview URL back on the PR.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'ci-cd', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: RailwayIcon, + title: 'Railway project onboarding kit', + prompt: + 'Build a workflow that takes a new service name, creates a Railway project, sets up staging and production environments, seeds baseline environment variables from a table, and posts the project members and access summary to Slack for the team.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'monitor-failed-deployments', + description: 'List recent Railway deployments, detect failures, and alert with a summary.', + content: + '# Monitor Failed Deployments\n\nWatch Railway deployments and surface failures fast.\n\n## Steps\n1. Run list_deployments for the target project, service, and environment.\n2. Identify deployments with a failed or crashed status from the returned list.\n3. For each failure, run get_deployment_logs to pull the runtime logs and determine the likely cause.\n4. Summarize each failure: service, environment, status, and the diagnosed cause.\n5. Post an actionable alert (for example to Slack) with a link to the affected service.\n\n## Output\nReturn the count of failed deployments and a concise summary of each. If all healthy, report a clean status.', + }, + { + name: 'deploy-service', + description: 'Trigger a Railway service deployment for a given environment and commit.', + content: + '# Deploy Service\n\nTrigger a deployment of a Railway service.\n\n## Steps\n1. Identify the service id and environment id to deploy (use get_project to look them up if needed).\n2. Run deploy_service, optionally pinning a specific commitSha.\n3. Capture the returned deploymentId.\n4. Optionally poll list_deployments to confirm the deployment reaches a success state.\n\n## Output\nReport the deploymentId, target environment, and final status.', + }, + { + name: 'sync-environment-variables', + description: + 'Upsert Railway environment variables from a reference source and report changes.', + content: + '# Sync Environment Variables\n\nKeep Railway environment variables aligned with a reference list.\n\n## Steps\n1. Read the desired variable set (for example from a table) for each service.\n2. Run list_variables to capture the current state for the project, environment, and service.\n3. For each variable that is missing or differs, run upsert_variable. Use skipDeploys when batching multiple changes.\n4. Trigger a single deploy at the end if needed.\n\n## Output\nReturn a summary of every variable created or changed, grouped by service.', + }, + { + name: 'provision-preview-environment', + description: 'Create an ephemeral Railway environment, seed variables, and deploy it.', + content: + '# Provision Preview Environment\n\nSpin up a fresh Railway environment for a branch or pull request.\n\n## Steps\n1. Run create_environment for the project, optionally cloning from a source environment and marking it ephemeral.\n2. Upsert the required environment variables for the new environment.\n3. Run deploy_service to bring the preview online.\n4. Capture the deployment status and the preview URL.\n\n## Output\nReturn the new environment id and the live preview URL so it can be shared on the PR.', + }, + { + name: 'audit-project-inventory', + description: 'List every Railway project with services and environments for tracking.', + content: + '# Audit Project Inventory\n\nBuild a current inventory of Railway resources.\n\n## Steps\n1. Run list_projects, paginating with first and after until complete.\n2. For each project, run get_project to capture its services and environments.\n3. Optionally run list_project_members to record access.\n4. Compare against a prior snapshot to detect added or removed resources.\n\n## Output\nReturn the full inventory and a diff of any changes since the last run.', + }, + { + name: 'rollback-failed-deployment', + description: 'Detect a bad Railway deployment and roll back or restart to recover.', + content: + '# Roll Back Failed Deployment\n\nRecover a Railway service automatically when a deployment goes bad.\n\n## Steps\n1. Run list_deployments for the service and environment to find the most recent deployment and its status.\n2. If the latest deployment failed or crashed, optionally run get_deployment_logs to confirm and capture the cause.\n3. To revert: pick the most recent healthy deployment with canRollback true (from list_deployments) and run rollback_deployment with its id.\n4. To recover a locked-up but otherwise healthy deployment instead, run restart_deployment with the deployment id.\n5. Run get_deployment on the resulting deployment to confirm it reaches a healthy status.\n\n## Output\nReport whether a rollback or restart was performed, the target deployment id, and the final status.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/railway.ts b/apps/sim/blocks/blocks/railway.ts index 2f5ae367f05..6e2c56a67f9 100644 --- a/apps/sim/blocks/blocks/railway.ts +++ b/apps/sim/blocks/blocks/railway.ts @@ -1,6 +1,5 @@ -import { RailwayIcon } from '@/components/icons' import { RailwayBlockDisplay } from '@/blocks/blocks/railway.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RailwayResponse } from '@/tools/railway/types' @@ -843,118 +842,3 @@ export const RailwayBlock: BlockConfig = { pageInfo: { type: 'json', description: 'Pagination information (hasNextPage, endCursor)' }, }, } - -export const RailwayBlockMeta = { - tags: ['cloud', 'ci-cd'], - url: 'https://railway.com', - templates: [ - { - icon: RailwayIcon, - title: 'Railway deployment monitor', - prompt: - 'Build a scheduled workflow that lists the latest Railway deployments across my services every few minutes, detects failed or crashed deployments, summarizes the failure with an agent, and posts an actionable Slack alert with a link to the service.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['slack'], - }, - { - icon: RailwayIcon, - title: 'Railway deploy on merge', - prompt: - 'Create a workflow that watches GitHub for merges to the main branch, triggers a Railway service deployment for the matching environment, and posts the deployment status back as a Slack notification.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'ci-cd', 'automation'], - alsoIntegrations: ['github', 'slack'], - }, - { - icon: RailwayIcon, - title: 'Railway environment variable auditor', - prompt: - 'Build a scheduled weekly workflow that lists environment variables across every Railway project, compares them to a reference list in a table, flags drift and missing keys, and emails a remediation report to the platform team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'monitoring'], - }, - { - icon: RailwayIcon, - title: 'Railway project inventory', - prompt: - 'Create a scheduled workflow that lists every Railway project, its services, and environments weekly, logs them into a tracking table, and Slacks a diff of any added or removed resources so infrastructure changes never go unnoticed.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: RailwayIcon, - title: 'Railway config sync', - prompt: - 'Build a workflow that reads service configuration from a table and upserts the matching Railway environment variables for each service, then posts a Slack summary of every variable that was created or changed.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: RailwayIcon, - title: 'Railway preview environment provisioner', - prompt: - 'Create a workflow that watches GitHub for new pull requests, creates a fresh Railway environment for the branch, upserts the required environment variables, deploys the service, and comments the live preview URL back on the PR.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'ci-cd', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: RailwayIcon, - title: 'Railway project onboarding kit', - prompt: - 'Build a workflow that takes a new service name, creates a Railway project, sets up staging and production environments, seeds baseline environment variables from a table, and posts the project members and access summary to Slack for the team.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'monitor-failed-deployments', - description: 'List recent Railway deployments, detect failures, and alert with a summary.', - content: - '# Monitor Failed Deployments\n\nWatch Railway deployments and surface failures fast.\n\n## Steps\n1. Run list_deployments for the target project, service, and environment.\n2. Identify deployments with a failed or crashed status from the returned list.\n3. For each failure, run get_deployment_logs to pull the runtime logs and determine the likely cause.\n4. Summarize each failure: service, environment, status, and the diagnosed cause.\n5. Post an actionable alert (for example to Slack) with a link to the affected service.\n\n## Output\nReturn the count of failed deployments and a concise summary of each. If all healthy, report a clean status.', - }, - { - name: 'deploy-service', - description: 'Trigger a Railway service deployment for a given environment and commit.', - content: - '# Deploy Service\n\nTrigger a deployment of a Railway service.\n\n## Steps\n1. Identify the service id and environment id to deploy (use get_project to look them up if needed).\n2. Run deploy_service, optionally pinning a specific commitSha.\n3. Capture the returned deploymentId.\n4. Optionally poll list_deployments to confirm the deployment reaches a success state.\n\n## Output\nReport the deploymentId, target environment, and final status.', - }, - { - name: 'sync-environment-variables', - description: - 'Upsert Railway environment variables from a reference source and report changes.', - content: - '# Sync Environment Variables\n\nKeep Railway environment variables aligned with a reference list.\n\n## Steps\n1. Read the desired variable set (for example from a table) for each service.\n2. Run list_variables to capture the current state for the project, environment, and service.\n3. For each variable that is missing or differs, run upsert_variable. Use skipDeploys when batching multiple changes.\n4. Trigger a single deploy at the end if needed.\n\n## Output\nReturn a summary of every variable created or changed, grouped by service.', - }, - { - name: 'provision-preview-environment', - description: 'Create an ephemeral Railway environment, seed variables, and deploy it.', - content: - '# Provision Preview Environment\n\nSpin up a fresh Railway environment for a branch or pull request.\n\n## Steps\n1. Run create_environment for the project, optionally cloning from a source environment and marking it ephemeral.\n2. Upsert the required environment variables for the new environment.\n3. Run deploy_service to bring the preview online.\n4. Capture the deployment status and the preview URL.\n\n## Output\nReturn the new environment id and the live preview URL so it can be shared on the PR.', - }, - { - name: 'audit-project-inventory', - description: 'List every Railway project with services and environments for tracking.', - content: - '# Audit Project Inventory\n\nBuild a current inventory of Railway resources.\n\n## Steps\n1. Run list_projects, paginating with first and after until complete.\n2. For each project, run get_project to capture its services and environments.\n3. Optionally run list_project_members to record access.\n4. Compare against a prior snapshot to detect added or removed resources.\n\n## Output\nReturn the full inventory and a diff of any changes since the last run.', - }, - { - name: 'rollback-failed-deployment', - description: 'Detect a bad Railway deployment and roll back or restart to recover.', - content: - '# Roll Back Failed Deployment\n\nRecover a Railway service automatically when a deployment goes bad.\n\n## Steps\n1. Run list_deployments for the service and environment to find the most recent deployment and its status.\n2. If the latest deployment failed or crashed, optionally run get_deployment_logs to confirm and capture the cause.\n3. To revert: pick the most recent healthy deployment with canRollback true (from list_deployments) and run rollback_deployment with its id.\n4. To recover a locked-up but otherwise healthy deployment instead, run restart_deployment with the deployment id.\n5. Run get_deployment on the resulting deployment to confirm it reaches a healthy status.\n\n## Output\nReport whether a rollback or restart was performed, the target deployment id, and the final status.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rb2b.display.ts b/apps/sim/blocks/blocks/rb2b.display.ts index fd5fff7163d..70b681eb75b 100644 --- a/apps/sim/blocks/blocks/rb2b.display.ts +++ b/apps/sim/blocks/blocks/rb2b.display.ts @@ -1,6 +1,6 @@ import { RB2BIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RB2BBlockDisplay = { type: 'rb2b', @@ -14,3 +14,104 @@ export const RB2BBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/rb2b', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const RB2BBlockMeta = { + tags: ['enrichment', 'sales-engagement', 'identity'], + url: 'https://rb2b.com', + templates: [ + { + icon: RB2BIcon, + title: 'Website visitor de-anonymizer', + prompt: + 'Build a workflow that takes the IP addresses of anonymous website visitors, uses RB2B to resolve each IP to a hashed email and company domain, and writes the identified visitors into a table for the sales team.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'identity', 'enrichment'], + }, + { + icon: RB2BIcon, + title: 'Visitor IP to LinkedIn profile', + prompt: + 'Create a workflow that resolves a visitor IP to a hashed email with RB2B, then enriches that hashed email into a LinkedIn profile and business profile so reps know exactly who visited.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'identity', 'research'], + }, + { + icon: RB2BIcon, + title: 'Hashed email enrichment pipeline', + prompt: + 'Build a workflow that reads hashed emails from a table, uses RB2B to enrich each into a full business profile with name, title, seniority, and company details, and writes the enriched records back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enrichment', 'research'], + }, + { + icon: RB2BIcon, + title: 'LinkedIn to mobile phone finder', + prompt: + "Create a workflow that takes a list of LinkedIn profile slugs, uses RB2B to look up each prospect's mobile phone and best personal email, and writes a ready-to-contact table for outbound calling.", + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enrichment', 'research'], + }, + { + icon: RB2BIcon, + title: 'Intent-to-CRM identity sync', + prompt: + 'Build a workflow that resolves visitor IPs to company domains with RB2B, enriches the matched person into a business profile, and creates or updates the matching contact and company in HubSpot.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'identity', 'crm'], + alsoIntegrations: ['hubspot'], + }, + { + icon: RB2BIcon, + title: 'High-intent visitor Slack alerts', + prompt: + 'Create a workflow that reads a list of website visitor IPs, uses RB2B to resolve each person and their company, and posts an alert with the identified LinkedIn profile and company to the sales Slack channel.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'identity', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: RB2BIcon, + title: 'LinkedIn slug resolver', + prompt: + 'Build a workflow that takes a first name, last name, and company domain, uses RB2B LinkedIn slug search to resolve the matching profile, and enriches it into a business profile written to a prospect table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: RB2BIcon, + title: 'Account engagement freshness sweep', + prompt: + 'Create a scheduled workflow that runs my list of prospect emails through RB2B email-to-last-active-date lookups, flags recently active contacts, and logs the engagement snapshot to a table for prioritized follow-up.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'enrichment', 'automation'], + }, + ], + skills: [ + { + name: 'identify-website-visitor', + description: 'Resolve a visitor IP into a person and company profile for sales follow-up.', + content: + '# Identify Website Visitor\n\nTurn an anonymous visit into a named, enrichable lead.\n\n## Steps\n1. Take the visitor ip_address and run ip_to_company to resolve the firmographic match.\n2. Run ip_to_hem to obtain the hashed email identifier for the person.\n3. Run hem_to_business_profile and hem_to_best_linkedin to build a full contact profile.\n4. Score the lead by company fit and route high-intent matches to sales.\n\n## Output\nReturn the resolved company, person name, title, and LinkedIn. Flag whether the match clears your fit threshold.', + }, + { + name: 'enrich-linkedin-contact', + description: 'Enrich a LinkedIn profile with business email and phone for outreach.', + content: + '# Enrich LinkedIn Contact\n\nTurn a LinkedIn profile into reachable contact details.\n\n## Steps\n1. Provide the LinkedIn URL or slug; use linkedin_slug_search first if you only have a name.\n2. Run linkedin_to_business_profile to capture role and company.\n3. Run linkedin_to_best_personal_email and linkedin_to_mobile_phone for direct contact points.\n4. Push the enriched record into the CRM or an outreach sequence.\n\n## Output\nReturn the contact name, company, best email, and phone. Note any field that could not be resolved.', + }, + { + name: 'check-credit-balance', + description: 'Check the RB2B credit balance before running a batch of enrichment lookups.', + content: + '# Check Credit Balance\n\nVerify enrichment credits remain before a batch run.\n\n## Steps\n1. Run credit_check to read the current balance.\n2. Estimate the credits needed for the planned lookups.\n3. If the balance is insufficient, alert the team rather than starting a partial run.\n\n## Output\nReturn the remaining credit balance and whether the planned batch can proceed.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rb2b.ts b/apps/sim/blocks/blocks/rb2b.ts index 7cf9695d811..2039eb3f8be 100644 --- a/apps/sim/blocks/blocks/rb2b.ts +++ b/apps/sim/blocks/blocks/rb2b.ts @@ -1,6 +1,5 @@ -import { RB2BIcon } from '@/components/icons' import { RB2BBlockDisplay } from '@/blocks/blocks/rb2b.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { Rb2bResponse } from '@/tools/rb2b/types' @@ -208,104 +207,3 @@ export const RB2BBlock: BlockConfig = { md5: { type: 'string', description: 'MD5 hash of the resolved email' }, }, } - -export const RB2BBlockMeta = { - tags: ['enrichment', 'sales-engagement', 'identity'], - url: 'https://rb2b.com', - templates: [ - { - icon: RB2BIcon, - title: 'Website visitor de-anonymizer', - prompt: - 'Build a workflow that takes the IP addresses of anonymous website visitors, uses RB2B to resolve each IP to a hashed email and company domain, and writes the identified visitors into a table for the sales team.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'identity', 'enrichment'], - }, - { - icon: RB2BIcon, - title: 'Visitor IP to LinkedIn profile', - prompt: - 'Create a workflow that resolves a visitor IP to a hashed email with RB2B, then enriches that hashed email into a LinkedIn profile and business profile so reps know exactly who visited.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'identity', 'research'], - }, - { - icon: RB2BIcon, - title: 'Hashed email enrichment pipeline', - prompt: - 'Build a workflow that reads hashed emails from a table, uses RB2B to enrich each into a full business profile with name, title, seniority, and company details, and writes the enriched records back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enrichment', 'research'], - }, - { - icon: RB2BIcon, - title: 'LinkedIn to mobile phone finder', - prompt: - "Create a workflow that takes a list of LinkedIn profile slugs, uses RB2B to look up each prospect's mobile phone and best personal email, and writes a ready-to-contact table for outbound calling.", - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enrichment', 'research'], - }, - { - icon: RB2BIcon, - title: 'Intent-to-CRM identity sync', - prompt: - 'Build a workflow that resolves visitor IPs to company domains with RB2B, enriches the matched person into a business profile, and creates or updates the matching contact and company in HubSpot.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'identity', 'crm'], - alsoIntegrations: ['hubspot'], - }, - { - icon: RB2BIcon, - title: 'High-intent visitor Slack alerts', - prompt: - 'Create a workflow that reads a list of website visitor IPs, uses RB2B to resolve each person and their company, and posts an alert with the identified LinkedIn profile and company to the sales Slack channel.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'identity', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: RB2BIcon, - title: 'LinkedIn slug resolver', - prompt: - 'Build a workflow that takes a first name, last name, and company domain, uses RB2B LinkedIn slug search to resolve the matching profile, and enriches it into a business profile written to a prospect table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: RB2BIcon, - title: 'Account engagement freshness sweep', - prompt: - 'Create a scheduled workflow that runs my list of prospect emails through RB2B email-to-last-active-date lookups, flags recently active contacts, and logs the engagement snapshot to a table for prioritized follow-up.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'enrichment', 'automation'], - }, - ], - skills: [ - { - name: 'identify-website-visitor', - description: 'Resolve a visitor IP into a person and company profile for sales follow-up.', - content: - '# Identify Website Visitor\n\nTurn an anonymous visit into a named, enrichable lead.\n\n## Steps\n1. Take the visitor ip_address and run ip_to_company to resolve the firmographic match.\n2. Run ip_to_hem to obtain the hashed email identifier for the person.\n3. Run hem_to_business_profile and hem_to_best_linkedin to build a full contact profile.\n4. Score the lead by company fit and route high-intent matches to sales.\n\n## Output\nReturn the resolved company, person name, title, and LinkedIn. Flag whether the match clears your fit threshold.', - }, - { - name: 'enrich-linkedin-contact', - description: 'Enrich a LinkedIn profile with business email and phone for outreach.', - content: - '# Enrich LinkedIn Contact\n\nTurn a LinkedIn profile into reachable contact details.\n\n## Steps\n1. Provide the LinkedIn URL or slug; use linkedin_slug_search first if you only have a name.\n2. Run linkedin_to_business_profile to capture role and company.\n3. Run linkedin_to_best_personal_email and linkedin_to_mobile_phone for direct contact points.\n4. Push the enriched record into the CRM or an outreach sequence.\n\n## Output\nReturn the contact name, company, best email, and phone. Note any field that could not be resolved.', - }, - { - name: 'check-credit-balance', - description: 'Check the RB2B credit balance before running a batch of enrichment lookups.', - content: - '# Check Credit Balance\n\nVerify enrichment credits remain before a batch run.\n\n## Steps\n1. Run credit_check to read the current balance.\n2. Estimate the credits needed for the planned lookups.\n3. If the balance is insufficient, alert the team rather than starting a partial run.\n\n## Output\nReturn the remaining credit balance and whether the planned batch can proceed.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rds.display.ts b/apps/sim/blocks/blocks/rds.display.ts index 0699c9e915f..3c8beeb7e7b 100644 --- a/apps/sim/blocks/blocks/rds.display.ts +++ b/apps/sim/blocks/blocks/rds.display.ts @@ -1,6 +1,6 @@ import { RDSIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RDSBlockDisplay = { type: 'rds', @@ -15,3 +15,100 @@ export const RDSBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/rds', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const RDSBlockMeta = { + tags: ['cloud'], + url: 'https://aws.amazon.com/rds', + templates: [ + { + icon: RDSIcon, + title: 'RDS daily metrics digest', + prompt: + 'Build a scheduled workflow that runs an aggregate SQL query against my Amazon RDS database each morning, summarizes the key numbers with an agent, and posts the digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: RDSIcon, + title: 'RDS natural-language query agent', + prompt: + 'Create an agent that introspects my Amazon RDS schema, turns plain-English questions into SQL, runs the query through the Data API, and returns the results in a readable answer.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'analysis'], + }, + { + icon: RDSIcon, + title: 'RDS lead capture', + prompt: + 'Build a workflow triggered by a form submission that validates the payload and inserts a new lead row into my Amazon RDS database, then confirms the write back to the submitter.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'forms'], + }, + { + icon: RDSIcon, + title: 'RDS to spreadsheet export', + prompt: + 'Create a scheduled workflow that queries Amazon RDS for the latest records, writes the rows into a Sim table, and keeps a running export the operations team can review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'sync'], + }, + { + icon: RDSIcon, + title: 'RDS record updater from Slack', + prompt: + 'Build a workflow that reads update requests posted in a Slack channel, parses the target record and fields with an agent, and runs the matching UPDATE against Amazon RDS with the conditions applied.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: RDSIcon, + title: 'RDS row-change alerter', + prompt: + 'Create a scheduled workflow that queries Amazon RDS for rows matching a watch condition, compares them to the previous run stored in a table, and posts a Slack alert when a tracked record changes.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: RDSIcon, + title: 'RDS + BigQuery analytics mirror', + prompt: + 'Build a scheduled workflow that queries analytical tables from Amazon RDS, loads the rows into BigQuery for downstream BI, and writes a sync log to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + alsoIntegrations: ['google_bigquery'], + }, + ], + skills: [ + { + name: 'run-readonly-query', + description: + 'Run a parameterized SELECT against Amazon RDS via the Data API and return the rows.', + content: + '# Run Read-only Query\n\nQuery an RDS database through the Data API to answer a question.\n\n## Steps\n1. Write a SELECT statement that returns only the columns needed.\n2. Use parameters for any user-supplied values instead of string concatenation.\n3. Execute the statement and collect the result rows.\n\n## Output\nThe returned rows in a readable table plus a row count. If the result is large, summarize and note that it was limited.', + }, + { + name: 'lookup-record', + description: + 'Fetch a specific record from Amazon RDS by an identifier and return its fields.', + content: + '# Lookup Record\n\nRetrieve one row from an RDS table by a key.\n\n## Steps\n1. Identify the table and the unique identifier (id, email, order number).\n2. Run a parameterized SELECT filtered by that identifier.\n3. Return the matching row, or report that no record was found.\n\n## Output\nThe record fields if found, or a clear "not found" result. Do not invent field values.', + }, + { + name: 'insert-record', + description: + 'Insert a new row into an Amazon RDS table from provided field values via the Data API.', + content: + '# Insert Record\n\nWrite a new record into an RDS table through the Data API.\n\n## Steps\n1. Identify the target table and map the input values to its columns as key-value pairs.\n2. Run the insert operation with that data object.\n3. To load several rows, repeat the insert for each item, or use the Execute Raw SQL operation with a multi-row INSERT statement.\n\n## Output\nConfirm the table written to and how many rows were inserted. Flag any items skipped for missing required fields.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rds.ts b/apps/sim/blocks/blocks/rds.ts index 738a7f27ea3..9414568f173 100644 --- a/apps/sim/blocks/blocks/rds.ts +++ b/apps/sim/blocks/blocks/rds.ts @@ -1,7 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { RDSIcon } from '@/components/icons' import { RDSBlockDisplay } from '@/blocks/blocks/rds.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { RdsIntrospectResponse, RdsResponse } from '@/tools/rds/types' export const RDSBlock: BlockConfig = { @@ -475,100 +474,3 @@ Return ONLY the JSON object.`, }, }, } - -export const RDSBlockMeta = { - tags: ['cloud'], - url: 'https://aws.amazon.com/rds', - templates: [ - { - icon: RDSIcon, - title: 'RDS daily metrics digest', - prompt: - 'Build a scheduled workflow that runs an aggregate SQL query against my Amazon RDS database each morning, summarizes the key numbers with an agent, and posts the digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: RDSIcon, - title: 'RDS natural-language query agent', - prompt: - 'Create an agent that introspects my Amazon RDS schema, turns plain-English questions into SQL, runs the query through the Data API, and returns the results in a readable answer.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'analysis'], - }, - { - icon: RDSIcon, - title: 'RDS lead capture', - prompt: - 'Build a workflow triggered by a form submission that validates the payload and inserts a new lead row into my Amazon RDS database, then confirms the write back to the submitter.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'forms'], - }, - { - icon: RDSIcon, - title: 'RDS to spreadsheet export', - prompt: - 'Create a scheduled workflow that queries Amazon RDS for the latest records, writes the rows into a Sim table, and keeps a running export the operations team can review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'sync'], - }, - { - icon: RDSIcon, - title: 'RDS record updater from Slack', - prompt: - 'Build a workflow that reads update requests posted in a Slack channel, parses the target record and fields with an agent, and runs the matching UPDATE against Amazon RDS with the conditions applied.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: RDSIcon, - title: 'RDS row-change alerter', - prompt: - 'Create a scheduled workflow that queries Amazon RDS for rows matching a watch condition, compares them to the previous run stored in a table, and posts a Slack alert when a tracked record changes.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: RDSIcon, - title: 'RDS + BigQuery analytics mirror', - prompt: - 'Build a scheduled workflow that queries analytical tables from Amazon RDS, loads the rows into BigQuery for downstream BI, and writes a sync log to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - alsoIntegrations: ['google_bigquery'], - }, - ], - skills: [ - { - name: 'run-readonly-query', - description: - 'Run a parameterized SELECT against Amazon RDS via the Data API and return the rows.', - content: - '# Run Read-only Query\n\nQuery an RDS database through the Data API to answer a question.\n\n## Steps\n1. Write a SELECT statement that returns only the columns needed.\n2. Use parameters for any user-supplied values instead of string concatenation.\n3. Execute the statement and collect the result rows.\n\n## Output\nThe returned rows in a readable table plus a row count. If the result is large, summarize and note that it was limited.', - }, - { - name: 'lookup-record', - description: - 'Fetch a specific record from Amazon RDS by an identifier and return its fields.', - content: - '# Lookup Record\n\nRetrieve one row from an RDS table by a key.\n\n## Steps\n1. Identify the table and the unique identifier (id, email, order number).\n2. Run a parameterized SELECT filtered by that identifier.\n3. Return the matching row, or report that no record was found.\n\n## Output\nThe record fields if found, or a clear "not found" result. Do not invent field values.', - }, - { - name: 'insert-record', - description: - 'Insert a new row into an Amazon RDS table from provided field values via the Data API.', - content: - '# Insert Record\n\nWrite a new record into an RDS table through the Data API.\n\n## Steps\n1. Identify the target table and map the input values to its columns as key-value pairs.\n2. Run the insert operation with that data object.\n3. To load several rows, repeat the insert for each item, or use the Execute Raw SQL operation with a multi-row INSERT statement.\n\n## Output\nConfirm the table written to and how many rows were inserted. Flag any items skipped for missing required fields.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/reddit.display.ts b/apps/sim/blocks/blocks/reddit.display.ts index 0199fd75b30..cc515c297b1 100644 --- a/apps/sim/blocks/blocks/reddit.display.ts +++ b/apps/sim/blocks/blocks/reddit.display.ts @@ -1,6 +1,6 @@ import { RedditIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RedditBlockDisplay = { type: 'reddit', @@ -15,3 +15,128 @@ export const RedditBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/reddit', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const RedditBlockMeta = { + tags: ['content-management', 'web-scraping'], + url: 'https://www.reddit.com', + templates: [ + { + icon: RedditIcon, + title: 'Social mention tracker', + prompt: + 'Create a scheduled workflow that monitors Reddit and X for mentions of my brand and competitors, scores each mention by sentiment and reach, logs them to a table, and sends a daily Slack digest of notable mentions.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring', 'analysis'], + alsoIntegrations: ['x', 'slack'], + }, + { + icon: RedditIcon, + title: 'Reddit subreddit monitor', + prompt: + 'Build a scheduled workflow that uses Reddit to watch target subreddits for posts matching brand or product keywords, scores each for relevance and sentiment, and posts notable hits to Slack with the original link.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: RedditIcon, + title: 'Reddit user-question knowledge mining', + prompt: + 'Create a workflow that pulls top questions from Reddit industry subreddits weekly, classifies by theme, and writes a content-opportunity table the marketing team can prioritize.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: RedditIcon, + title: 'Reddit AMA preparer', + prompt: + 'Build a workflow that aggregates top Reddit AMA-style questions for a topic, clusters them, drafts polished answers using a knowledge base, and posts a Q&A document for review.', + modules: ['knowledge-base', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: RedditIcon, + title: 'Reddit competitor watch', + prompt: + 'Create a scheduled workflow that monitors Reddit threads mentioning competitors weekly, summarizes sentiment and pain points, and writes a competitive intelligence note to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: RedditIcon, + title: 'Reddit crisis-signal alerter', + prompt: + 'Build a scheduled workflow that polls Reddit for sudden bursts of negative posts about the brand, classifies severity, and pages the PR team via Slack and PagerDuty when a real crisis emerges.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack', 'pagerduty'], + }, + { + icon: RedditIcon, + title: 'Reddit content-idea collector', + prompt: + 'Create a scheduled workflow that polls marketing-relevant Reddit subreddits, captures upvoted long-form posts, summarizes each, and adds them to a content-ideas table with effort and impact scores.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + ], + skills: [ + { + name: 'monitor-subreddit-mentions', + description: + 'Search a subreddit for brand or keyword mentions and summarize what people say.', + content: + '# Monitor Subreddit Mentions\n\nTrack what people say about a topic on Reddit.\n\n## Steps\n1. Run search with the brand or keyword query, scoped to the relevant subreddit when appropriate.\n2. For high-signal threads, run get_comments to pull the discussion.\n3. Summarize sentiment, recurring themes, and notable complaints or praise.\n4. Route urgent or negative threads to the right channel.\n\n## Output\nReturn a digest of top mentions with links, sentiment, and key takeaways.', + }, + { + name: 'surface-trending-posts', + description: + 'Pull top and controversial posts from a subreddit for a content or research brief.', + content: + '# Surface Trending Posts\n\nFind what is rising and contentious in a community.\n\n## Steps\n1. Run get_posts for the subreddit using a hot or top sort to capture momentum.\n2. Run get_controversial to surface divisive discussions.\n3. Read get_comments on the standouts for context.\n4. Cluster the posts into themes.\n\n## Output\nReturn a ranked brief of trending and controversial posts with titles, links, and a one-line takeaway each.', + }, + { + name: 'reply-to-mention', + description: 'Draft and post a helpful, on-brand reply to a Reddit post or comment.', + content: + '# Reply To Mention\n\nRespond to a relevant Reddit thread.\n\n## Steps\n1. Read the target post or comment with get_posts or get_comments for full context.\n2. Draft a concise, non-promotional reply that adds genuine value.\n3. Run reply to post it on the chosen thread.\n4. Optionally save the thread for later follow-up.\n\n## Output\nReturn the posted reply text and a link to the comment. Respect subreddit rules and avoid spammy self-promotion.', + }, + { + name: 'submit-announcement-post', + description: 'Submit a new post to a target subreddit for an announcement or launch.', + content: + '# Submit Announcement Post\n\nShare an announcement on Reddit.\n\n## Steps\n1. Run get_subreddit_rules to confirm the target subreddit allows the post type and self-promotion.\n2. Run submit_post with a clear title and body tailored to the community.\n3. Capture the returned post id and link.\n4. Monitor early get_comments and respond to questions.\n\n## Output\nReturn the new post link and an initial engagement check.', + }, + { + name: 'research-a-redditor', + description: 'Profile a Reddit user from their public posts, comments, and karma.', + content: + '# Research A Redditor\n\nBuild a picture of a Reddit user for vetting or community research.\n\n## Steps\n1. Run get_user to pull profile, karma, and account age.\n2. Run get_user_posts and get_user_comments to sample their recent activity.\n3. Identify the subreddits, topics, and tone they engage with most.\n4. Flag anything notable (expertise, affiliations, red flags).\n\n## Output\nReturn a short profile: account summary, top communities, themes, and a sample of representative posts/comments with links.', + }, + { + name: 'discover-communities', + description: 'Find the most relevant subreddits for a topic before posting or monitoring.', + content: + '# Discover Communities\n\nLocate the right subreddits for a topic or campaign.\n\n## Steps\n1. Run search_subreddits with the topic keywords to find candidate communities.\n2. Run get_subreddit_info on the strongest matches to compare size and activity.\n3. Run get_subreddit_rules to check posting and self-promotion rules.\n4. Optionally run list_my_subreddits to see which you already follow.\n\n## Output\nReturn a ranked shortlist of subreddits with subscriber counts, activity, fit, and key rules.', + }, + { + name: 'manage-saved-research', + description: 'Curate a research reading list from saved Reddit posts and comments.', + content: + '# Manage Saved Research\n\nTurn saved Reddit items into an organized research list.\n\n## Steps\n1. Run get_saved to pull your saved posts and comments.\n2. Run get_info to re-hydrate any specific fullnames you are tracking.\n3. Summarize and cluster the items by theme.\n4. Use save / unsave to keep the list current.\n\n## Output\nReturn a themed reading list with titles, links, and one-line summaries.', + }, + { + name: 'triage-mod-queue', + description: 'Moderate a subreddit: review reported content and act on it against the rules.', + content: + '# Triage Mod Queue\n\nReview and action content in a subreddit you moderate.\n\n## Steps\n1. Run get_posts / get_comments to pull the content under review.\n2. Run get_subreddit_rules and evaluate each item against them.\n3. Take action: mod_approve to keep, mod_remove (optionally as spam) to remove, lock to stop replies, mod_distinguish or mod_sticky to highlight official posts.\n4. Log each decision and the rule it maps to.\n\n## Output\nReturn a decision list: item link, action taken, and the rule or reason. Only act on subreddits you moderate.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/reddit.ts b/apps/sim/blocks/blocks/reddit.ts index 58f4eb894a9..7b71147b2e6 100644 --- a/apps/sim/blocks/blocks/reddit.ts +++ b/apps/sim/blocks/blocks/reddit.ts @@ -1,7 +1,6 @@ -import { RedditIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { RedditBlockDisplay } from '@/blocks/blocks/reddit.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RedditResponse } from '@/tools/reddit/types' @@ -1378,128 +1377,3 @@ Return ONLY the message content - no meta-commentary.`, site_rules: { type: 'json', description: 'Reddit site-wide rules (string[])' }, }, } - -export const RedditBlockMeta = { - tags: ['content-management', 'web-scraping'], - url: 'https://www.reddit.com', - templates: [ - { - icon: RedditIcon, - title: 'Social mention tracker', - prompt: - 'Create a scheduled workflow that monitors Reddit and X for mentions of my brand and competitors, scores each mention by sentiment and reach, logs them to a table, and sends a daily Slack digest of notable mentions.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring', 'analysis'], - alsoIntegrations: ['x', 'slack'], - }, - { - icon: RedditIcon, - title: 'Reddit subreddit monitor', - prompt: - 'Build a scheduled workflow that uses Reddit to watch target subreddits for posts matching brand or product keywords, scores each for relevance and sentiment, and posts notable hits to Slack with the original link.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: RedditIcon, - title: 'Reddit user-question knowledge mining', - prompt: - 'Create a workflow that pulls top questions from Reddit industry subreddits weekly, classifies by theme, and writes a content-opportunity table the marketing team can prioritize.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: RedditIcon, - title: 'Reddit AMA preparer', - prompt: - 'Build a workflow that aggregates top Reddit AMA-style questions for a topic, clusters them, drafts polished answers using a knowledge base, and posts a Q&A document for review.', - modules: ['knowledge-base', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: RedditIcon, - title: 'Reddit competitor watch', - prompt: - 'Create a scheduled workflow that monitors Reddit threads mentioning competitors weekly, summarizes sentiment and pain points, and writes a competitive intelligence note to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: RedditIcon, - title: 'Reddit crisis-signal alerter', - prompt: - 'Build a scheduled workflow that polls Reddit for sudden bursts of negative posts about the brand, classifies severity, and pages the PR team via Slack and PagerDuty when a real crisis emerges.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack', 'pagerduty'], - }, - { - icon: RedditIcon, - title: 'Reddit content-idea collector', - prompt: - 'Create a scheduled workflow that polls marketing-relevant Reddit subreddits, captures upvoted long-form posts, summarizes each, and adds them to a content-ideas table with effort and impact scores.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - ], - skills: [ - { - name: 'monitor-subreddit-mentions', - description: - 'Search a subreddit for brand or keyword mentions and summarize what people say.', - content: - '# Monitor Subreddit Mentions\n\nTrack what people say about a topic on Reddit.\n\n## Steps\n1. Run search with the brand or keyword query, scoped to the relevant subreddit when appropriate.\n2. For high-signal threads, run get_comments to pull the discussion.\n3. Summarize sentiment, recurring themes, and notable complaints or praise.\n4. Route urgent or negative threads to the right channel.\n\n## Output\nReturn a digest of top mentions with links, sentiment, and key takeaways.', - }, - { - name: 'surface-trending-posts', - description: - 'Pull top and controversial posts from a subreddit for a content or research brief.', - content: - '# Surface Trending Posts\n\nFind what is rising and contentious in a community.\n\n## Steps\n1. Run get_posts for the subreddit using a hot or top sort to capture momentum.\n2. Run get_controversial to surface divisive discussions.\n3. Read get_comments on the standouts for context.\n4. Cluster the posts into themes.\n\n## Output\nReturn a ranked brief of trending and controversial posts with titles, links, and a one-line takeaway each.', - }, - { - name: 'reply-to-mention', - description: 'Draft and post a helpful, on-brand reply to a Reddit post or comment.', - content: - '# Reply To Mention\n\nRespond to a relevant Reddit thread.\n\n## Steps\n1. Read the target post or comment with get_posts or get_comments for full context.\n2. Draft a concise, non-promotional reply that adds genuine value.\n3. Run reply to post it on the chosen thread.\n4. Optionally save the thread for later follow-up.\n\n## Output\nReturn the posted reply text and a link to the comment. Respect subreddit rules and avoid spammy self-promotion.', - }, - { - name: 'submit-announcement-post', - description: 'Submit a new post to a target subreddit for an announcement or launch.', - content: - '# Submit Announcement Post\n\nShare an announcement on Reddit.\n\n## Steps\n1. Run get_subreddit_rules to confirm the target subreddit allows the post type and self-promotion.\n2. Run submit_post with a clear title and body tailored to the community.\n3. Capture the returned post id and link.\n4. Monitor early get_comments and respond to questions.\n\n## Output\nReturn the new post link and an initial engagement check.', - }, - { - name: 'research-a-redditor', - description: 'Profile a Reddit user from their public posts, comments, and karma.', - content: - '# Research A Redditor\n\nBuild a picture of a Reddit user for vetting or community research.\n\n## Steps\n1. Run get_user to pull profile, karma, and account age.\n2. Run get_user_posts and get_user_comments to sample their recent activity.\n3. Identify the subreddits, topics, and tone they engage with most.\n4. Flag anything notable (expertise, affiliations, red flags).\n\n## Output\nReturn a short profile: account summary, top communities, themes, and a sample of representative posts/comments with links.', - }, - { - name: 'discover-communities', - description: 'Find the most relevant subreddits for a topic before posting or monitoring.', - content: - '# Discover Communities\n\nLocate the right subreddits for a topic or campaign.\n\n## Steps\n1. Run search_subreddits with the topic keywords to find candidate communities.\n2. Run get_subreddit_info on the strongest matches to compare size and activity.\n3. Run get_subreddit_rules to check posting and self-promotion rules.\n4. Optionally run list_my_subreddits to see which you already follow.\n\n## Output\nReturn a ranked shortlist of subreddits with subscriber counts, activity, fit, and key rules.', - }, - { - name: 'manage-saved-research', - description: 'Curate a research reading list from saved Reddit posts and comments.', - content: - '# Manage Saved Research\n\nTurn saved Reddit items into an organized research list.\n\n## Steps\n1. Run get_saved to pull your saved posts and comments.\n2. Run get_info to re-hydrate any specific fullnames you are tracking.\n3. Summarize and cluster the items by theme.\n4. Use save / unsave to keep the list current.\n\n## Output\nReturn a themed reading list with titles, links, and one-line summaries.', - }, - { - name: 'triage-mod-queue', - description: 'Moderate a subreddit: review reported content and act on it against the rules.', - content: - '# Triage Mod Queue\n\nReview and action content in a subreddit you moderate.\n\n## Steps\n1. Run get_posts / get_comments to pull the content under review.\n2. Run get_subreddit_rules and evaluate each item against them.\n3. Take action: mod_approve to keep, mod_remove (optionally as spam) to remove, lock to stop replies, mod_distinguish or mod_sticky to highlight official posts.\n4. Log each decision and the rule it maps to.\n\n## Output\nReturn a decision list: item link, action taken, and the rule or reason. Only act on subreddits you moderate.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/redis.display.ts b/apps/sim/blocks/blocks/redis.display.ts index f53b6a78c62..00d2f50d744 100644 --- a/apps/sim/blocks/blocks/redis.display.ts +++ b/apps/sim/blocks/blocks/redis.display.ts @@ -1,6 +1,6 @@ import { RedisIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RedisBlockDisplay = { type: 'redis', @@ -15,3 +15,100 @@ export const RedisBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/redis', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const RedisBlockMeta = { + tags: ['cloud'], + url: 'https://redis.io', + templates: [ + { + icon: RedisIcon, + title: 'Redis response cache', + prompt: + 'Build a workflow that checks Redis for a cached result by key before running an expensive step, and writes the computed result back with a TTL when there is a miss so repeat requests stay fast.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + }, + { + icon: RedisIcon, + title: 'Redis rate limiter', + prompt: + 'Create a workflow that increments a per-user Redis counter on each request, sets an expiry on the first hit, and blocks the request when the counter passes the allowed threshold within the window.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: RedisIcon, + title: 'Redis feature-flag reader', + prompt: + 'Build a workflow that reads feature-flag values from a Redis hash, branches downstream logic on whether each flag is enabled, and falls back to a default when a flag key is missing.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: RedisIcon, + title: 'Redis job queue worker', + prompt: + 'Create a scheduled workflow that pops the next job off a Redis list, processes it with an agent, and writes the outcome to a table so a backlog of work is drained on an interval.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: RedisIcon, + title: 'Redis cache warmer', + prompt: + 'Build a scheduled workflow that reads a list of hot keys from a table and sets each one in Redis with fresh values and a TTL, so popular lookups stay warm.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: RedisIcon, + title: 'Redis daily counter digest', + prompt: + 'Create a scheduled workflow that reads the day’s Redis counters by key pattern, builds a summary of the totals with an agent, and posts the digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: RedisIcon, + title: 'Redis session lookup', + prompt: + 'Build a workflow that reads a session hash from Redis by token, returns the stored user context to the caller, and refreshes the key’s expiry so active sessions stay alive.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + ], + skills: [ + { + name: 'cache-with-expiry', + description: 'Cache a computed value in Redis with a TTL and read it back on later runs.', + content: + '# Cache With Expiry\n\nStore an expensive result in Redis so later runs reuse it.\n\n## Steps\n1. Run get on the cache key first; if a value is returned, use it and stop.\n2. On a miss, compute the value, then run set with an ex expiry in seconds.\n3. Use setnx instead of set when only the first writer should win.\n4. Return the value to the caller.\n\n## Output\nReport whether the result was a cache hit or a fresh computation, and the key TTL.', + }, + { + name: 'rate-limit-counter', + description: 'Track per-key request counts in Redis with a sliding expiry to enforce limits.', + content: + '# Rate Limit Counter\n\nEnforce a request budget using a Redis counter.\n\n## Steps\n1. Run incr on a counter key derived from the user or client id.\n2. If the returned count is 1, run expire to start the window.\n3. Compare the count to the allowed limit.\n4. Allow or reject the request based on the result.\n\n## Output\nReturn the current count, the limit, and whether the request is allowed. Include ttl for the reset time.', + }, + { + name: 'manage-session-data', + description: 'Store and refresh session context in a Redis hash keyed by token.', + content: + '# Manage Session Data\n\nKeep session state in a Redis hash and keep active sessions alive.\n\n## Steps\n1. On write, run hset to store session fields under the session key.\n2. On read, run hgetall by token to return the full session context.\n3. Run expire to refresh the TTL so active sessions do not lapse.\n4. Run delete on logout to clear the session.\n\n## Output\nReturn the session context and confirm the refreshed expiry, or confirm deletion on logout.', + }, + { + name: 'manage-work-queue', + description: 'Push jobs onto a Redis list and pop them for processing in order.', + content: + '# Manage Work Queue\n\nUse a Redis list as a simple job queue.\n\n## Steps\n1. Run rpush to enqueue a job payload onto the queue key.\n2. Run lpop to dequeue the next job for processing (FIFO).\n3. Check llen to monitor backlog depth.\n4. Use lrange to inspect pending jobs without removing them.\n\n## Output\nReturn the dequeued job, the remaining queue length, and processing status.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/redis.ts b/apps/sim/blocks/blocks/redis.ts index 251cc6ab02e..614bcd47dc7 100644 --- a/apps/sim/blocks/blocks/redis.ts +++ b/apps/sim/blocks/blocks/redis.ts @@ -1,6 +1,5 @@ -import { RedisIcon } from '@/components/icons' import { RedisBlockDisplay } from '@/blocks/blocks/redis.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RedisCommandResponse, @@ -311,100 +310,3 @@ export const RedisBlock: BlockConfig = { }, }, } - -export const RedisBlockMeta = { - tags: ['cloud'], - url: 'https://redis.io', - templates: [ - { - icon: RedisIcon, - title: 'Redis response cache', - prompt: - 'Build a workflow that checks Redis for a cached result by key before running an expensive step, and writes the computed result back with a TTL when there is a miss so repeat requests stay fast.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - }, - { - icon: RedisIcon, - title: 'Redis rate limiter', - prompt: - 'Create a workflow that increments a per-user Redis counter on each request, sets an expiry on the first hit, and blocks the request when the counter passes the allowed threshold within the window.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: RedisIcon, - title: 'Redis feature-flag reader', - prompt: - 'Build a workflow that reads feature-flag values from a Redis hash, branches downstream logic on whether each flag is enabled, and falls back to a default when a flag key is missing.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: RedisIcon, - title: 'Redis job queue worker', - prompt: - 'Create a scheduled workflow that pops the next job off a Redis list, processes it with an agent, and writes the outcome to a table so a backlog of work is drained on an interval.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: RedisIcon, - title: 'Redis cache warmer', - prompt: - 'Build a scheduled workflow that reads a list of hot keys from a table and sets each one in Redis with fresh values and a TTL, so popular lookups stay warm.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: RedisIcon, - title: 'Redis daily counter digest', - prompt: - 'Create a scheduled workflow that reads the day’s Redis counters by key pattern, builds a summary of the totals with an agent, and posts the digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: RedisIcon, - title: 'Redis session lookup', - prompt: - 'Build a workflow that reads a session hash from Redis by token, returns the stored user context to the caller, and refreshes the key’s expiry so active sessions stay alive.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - ], - skills: [ - { - name: 'cache-with-expiry', - description: 'Cache a computed value in Redis with a TTL and read it back on later runs.', - content: - '# Cache With Expiry\n\nStore an expensive result in Redis so later runs reuse it.\n\n## Steps\n1. Run get on the cache key first; if a value is returned, use it and stop.\n2. On a miss, compute the value, then run set with an ex expiry in seconds.\n3. Use setnx instead of set when only the first writer should win.\n4. Return the value to the caller.\n\n## Output\nReport whether the result was a cache hit or a fresh computation, and the key TTL.', - }, - { - name: 'rate-limit-counter', - description: 'Track per-key request counts in Redis with a sliding expiry to enforce limits.', - content: - '# Rate Limit Counter\n\nEnforce a request budget using a Redis counter.\n\n## Steps\n1. Run incr on a counter key derived from the user or client id.\n2. If the returned count is 1, run expire to start the window.\n3. Compare the count to the allowed limit.\n4. Allow or reject the request based on the result.\n\n## Output\nReturn the current count, the limit, and whether the request is allowed. Include ttl for the reset time.', - }, - { - name: 'manage-session-data', - description: 'Store and refresh session context in a Redis hash keyed by token.', - content: - '# Manage Session Data\n\nKeep session state in a Redis hash and keep active sessions alive.\n\n## Steps\n1. On write, run hset to store session fields under the session key.\n2. On read, run hgetall by token to return the full session context.\n3. Run expire to refresh the TTL so active sessions do not lapse.\n4. Run delete on logout to clear the session.\n\n## Output\nReturn the session context and confirm the refreshed expiry, or confirm deletion on logout.', - }, - { - name: 'manage-work-queue', - description: 'Push jobs onto a Redis list and pop them for processing in order.', - content: - '# Manage Work Queue\n\nUse a Redis list as a simple job queue.\n\n## Steps\n1. Run rpush to enqueue a job payload onto the queue key.\n2. Run lpop to dequeue the next job for processing (FIFO).\n3. Check llen to monitor backlog depth.\n4. Use lrange to inspect pending jobs without removing them.\n\n## Output\nReturn the dequeued job, the remaining queue length, and processing status.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/reducto.display.ts b/apps/sim/blocks/blocks/reducto.display.ts index 830c0b24a35..eac23a00f28 100644 --- a/apps/sim/blocks/blocks/reducto.display.ts +++ b/apps/sim/blocks/blocks/reducto.display.ts @@ -1,6 +1,6 @@ import { ReductoIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ReductoBlockDisplay = { type: 'reducto', @@ -22,3 +22,97 @@ export const ReductoV2BlockDisplay = { longDescription: `Integrate Reducto Parse into the workflow. Can extract text from uploaded PDF documents or file references.`, hideFromToolbar: false, } satisfies BlockDisplay + +export const ReductoBlockMeta = { + tags: ['document-processing', 'ocr'], + url: 'https://reducto.ai', + templates: [ + { + icon: ReductoIcon, + title: 'Reducto contract parser', + prompt: + 'Create a workflow that uses Reducto to parse uploaded contract PDFs into structured clauses, writes payment terms, liability caps, and termination conditions to a table, and flags non-standard clauses.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'analysis'], + }, + { + icon: ReductoIcon, + title: 'Reducto + knowledge base loader', + prompt: + 'Build a workflow that parses every PDF in a Drive folder with Reducto, normalizes the structure, and upserts chunks into a knowledge base with section-aware metadata so retrieval returns the right passage.', + modules: ['knowledge-base', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + alsoIntegrations: ['google_drive'], + }, + { + icon: ReductoIcon, + title: 'Reducto medical-record digester', + prompt: + 'Build a workflow that parses medical record PDFs with Reducto, extracts diagnoses, medications, and visit summaries to structured rows, and produces a patient-facing one-pager file.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + }, + { + icon: ReductoIcon, + title: 'Reducto + Mem0 contract memory', + prompt: + 'Create a workflow that parses contracts with Reducto and writes the key terms into Mem0 per counterparty, so future interactions reference the real contract terms.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + alsoIntegrations: ['mem0'], + }, + { + icon: ReductoIcon, + title: 'Reducto invoice line-item extractor', + prompt: + 'Build a workflow that parses incoming invoice PDFs with Reducto, extracts vendor, line items, tax, and totals into an accounts-payable table, and flags any invoice that fails to reconcile against its purchase order.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation', 'analysis'], + }, + { + icon: ReductoIcon, + title: 'Reducto financial-statement digitizer', + prompt: + 'Create a workflow that parses quarterly financial-statement PDFs with Reducto, extracts the balance sheet and income statement figures into structured rows, and writes a normalized table the finance team can chart over time.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'reporting'], + }, + { + icon: ReductoIcon, + title: 'Reducto form-intake router', + prompt: + 'Build a workflow that runs each uploaded intake form through Reducto, extracts the applicant fields into a table, and routes the parsed submission to the right reviewer in Slack based on the form type.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'forms', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'extract-document-text', + description: 'Parse an uploaded PDF into clean text for downstream summarizing or search.', + content: + '# Extract Document Text\n\nTurn a PDF into clean, structured text with Reducto.\n\n## Steps\n1. Pass the uploaded document (file or file path) to the parser.\n2. Optionally limit to specific pages by passing a comma-separated page list.\n3. Capture the extracted text and structure from the result.\n4. Pass the text downstream for summarizing, classification, or indexing.\n\n## Output\nReturn the extracted text and a brief note of the page count processed.', + }, + { + name: 'extract-form-fields', + description: 'Parse an intake form PDF and pull structured fields into a table or record.', + content: + '# Extract Form Fields\n\nLift structured fields out of a form PDF.\n\n## Steps\n1. Run the parser on the uploaded form document.\n2. From the parsed text, identify the target fields (for example name, date, amount, form type).\n3. Map the fields into a structured record and write them to a table.\n4. Route the record to the right reviewer based on form type.\n\n## Output\nReturn the extracted field record and confirm where it was stored or routed. Flag any field that could not be located.', + }, + { + name: 'extract-invoice-tables', + description: + 'Parse an invoice or financial PDF into structured line-item tables for AP automation.', + content: + '# Extract Invoice Tables\n\nPull line-item tables out of invoices, receipts, or statements with Reducto.\n\n## Steps\n1. Run the parser on the uploaded invoice or financial document.\n2. Set the table output format so tables come back in a structured, machine-readable shape.\n3. Limit to the relevant pages with a comma-separated page list when the document is long.\n4. Map header fields and line items into a record and write the rows to a table.\n\n## Output\nReturn the parsed line items and invoice totals. Flag any row or amount that could not be confidently extracted.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/reducto.ts b/apps/sim/blocks/blocks/reducto.ts index b553a7c9156..684ceea85e2 100644 --- a/apps/sim/blocks/blocks/reducto.ts +++ b/apps/sim/blocks/blocks/reducto.ts @@ -1,7 +1,6 @@ import { toError } from '@sim/utils/errors' -import { ReductoIcon } from '@/components/icons' import { ReductoBlockDisplay, ReductoV2BlockDisplay } from '@/blocks/blocks/reducto.display' -import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' +import { AuthMode, type BlockConfig, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { ReductoParserOutput } from '@/tools/reducto/types' @@ -213,97 +212,3 @@ export const ReductoV2Block: BlockConfig = { }, inputs: reductoV2Inputs, } - -export const ReductoBlockMeta = { - tags: ['document-processing', 'ocr'], - url: 'https://reducto.ai', - templates: [ - { - icon: ReductoIcon, - title: 'Reducto contract parser', - prompt: - 'Create a workflow that uses Reducto to parse uploaded contract PDFs into structured clauses, writes payment terms, liability caps, and termination conditions to a table, and flags non-standard clauses.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'analysis'], - }, - { - icon: ReductoIcon, - title: 'Reducto + knowledge base loader', - prompt: - 'Build a workflow that parses every PDF in a Drive folder with Reducto, normalizes the structure, and upserts chunks into a knowledge base with section-aware metadata so retrieval returns the right passage.', - modules: ['knowledge-base', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - alsoIntegrations: ['google_drive'], - }, - { - icon: ReductoIcon, - title: 'Reducto medical-record digester', - prompt: - 'Build a workflow that parses medical record PDFs with Reducto, extracts diagnoses, medications, and visit summaries to structured rows, and produces a patient-facing one-pager file.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - }, - { - icon: ReductoIcon, - title: 'Reducto + Mem0 contract memory', - prompt: - 'Create a workflow that parses contracts with Reducto and writes the key terms into Mem0 per counterparty, so future interactions reference the real contract terms.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - alsoIntegrations: ['mem0'], - }, - { - icon: ReductoIcon, - title: 'Reducto invoice line-item extractor', - prompt: - 'Build a workflow that parses incoming invoice PDFs with Reducto, extracts vendor, line items, tax, and totals into an accounts-payable table, and flags any invoice that fails to reconcile against its purchase order.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation', 'analysis'], - }, - { - icon: ReductoIcon, - title: 'Reducto financial-statement digitizer', - prompt: - 'Create a workflow that parses quarterly financial-statement PDFs with Reducto, extracts the balance sheet and income statement figures into structured rows, and writes a normalized table the finance team can chart over time.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis', 'reporting'], - }, - { - icon: ReductoIcon, - title: 'Reducto form-intake router', - prompt: - 'Build a workflow that runs each uploaded intake form through Reducto, extracts the applicant fields into a table, and routes the parsed submission to the right reviewer in Slack based on the form type.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'forms', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'extract-document-text', - description: 'Parse an uploaded PDF into clean text for downstream summarizing or search.', - content: - '# Extract Document Text\n\nTurn a PDF into clean, structured text with Reducto.\n\n## Steps\n1. Pass the uploaded document (file or file path) to the parser.\n2. Optionally limit to specific pages by passing a comma-separated page list.\n3. Capture the extracted text and structure from the result.\n4. Pass the text downstream for summarizing, classification, or indexing.\n\n## Output\nReturn the extracted text and a brief note of the page count processed.', - }, - { - name: 'extract-form-fields', - description: 'Parse an intake form PDF and pull structured fields into a table or record.', - content: - '# Extract Form Fields\n\nLift structured fields out of a form PDF.\n\n## Steps\n1. Run the parser on the uploaded form document.\n2. From the parsed text, identify the target fields (for example name, date, amount, form type).\n3. Map the fields into a structured record and write them to a table.\n4. Route the record to the right reviewer based on form type.\n\n## Output\nReturn the extracted field record and confirm where it was stored or routed. Flag any field that could not be located.', - }, - { - name: 'extract-invoice-tables', - description: - 'Parse an invoice or financial PDF into structured line-item tables for AP automation.', - content: - '# Extract Invoice Tables\n\nPull line-item tables out of invoices, receipts, or statements with Reducto.\n\n## Steps\n1. Run the parser on the uploaded invoice or financial document.\n2. Set the table output format so tables come back in a structured, machine-readable shape.\n3. Limit to the relevant pages with a comma-separated page list when the document is long.\n4. Map header fields and line items into a record and write the rows to a table.\n\n## Output\nReturn the parsed line items and invoice totals. Flag any row or amount that could not be confidently extracted.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/resend.display.ts b/apps/sim/blocks/blocks/resend.display.ts index 52dd96f4b6e..fe700e91db2 100644 --- a/apps/sim/blocks/blocks/resend.display.ts +++ b/apps/sim/blocks/blocks/resend.display.ts @@ -1,6 +1,6 @@ import { ResendIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ResendBlockDisplay = { type: 'resend', @@ -14,3 +14,96 @@ export const ResendBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/resend', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const ResendBlockMeta = { + tags: ['email-marketing', 'messaging'], + url: 'https://resend.com', + templates: [ + { + icon: ResendIcon, + title: 'Resend + Loops onboarding emails', + prompt: + 'Build a workflow that listens for new signups, creates a Loops contact with the right user group, and sends the welcome email through Resend with a personalized subject and body so the first impression is on-brand and fast.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['marketing', 'automation', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: ResendIcon, + title: 'Resend domain monitor', + prompt: + 'Create a scheduled workflow that lists Resend domains, checks DNS verification status for each, and posts a Slack alert the moment any domain shows a verification or DKIM problem so we never silently lose deliverability.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'devops', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: ResendIcon, + title: 'Resend transactional flow', + prompt: + 'Build a workflow that listens for product events, renders the right transactional email body, sends it through Resend, then retrieves the message status after a short delay and writes delivery, open, and click events to a per-user activity table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'communication'], + }, + { + icon: ResendIcon, + title: 'Resend + AgentMail reply handler', + prompt: + 'Create a workflow that sends outbound messages through Resend but routes replies into a per-customer AgentMail inbox, threads them with the original send, and posts unread inbox digests to the support owner.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + alsoIntegrations: ['agentmail'], + }, + { + icon: ResendIcon, + title: 'Resend marketing broadcast', + prompt: + 'Build a workflow that takes a marketing message and a Resend audience, splits the recipient list into safe-volume batches, sends each batch through Resend with rate-limit pacing, and logs per-batch send results to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: ResendIcon, + title: 'Resend audience sync', + prompt: + 'Create a workflow that reads my subscriber list from a table, creates or updates each Resend contact in the matching audience, and removes contacts that have unsubscribed by deleting them so the Resend audience stays in sync with my source of truth.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'sync'], + }, + { + icon: ResendIcon, + title: 'Resend unsubscribe handler', + prompt: + 'Build a workflow that listens for unsubscribe events, looks up the matching Resend contact, updates it to unsubscribed, logs the opt-out reason to a table, and sends a confirmation email through Resend acknowledging the change.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'communication', 'compliance'], + }, + ], + skills: [ + { + name: 'send-transactional-email', + description: 'Send a personalized transactional email and confirm delivery via Resend.', + content: + '# Send Transactional Email\n\nSend a one-off transactional email through Resend.\n\n## Steps\n1. Compose the recipient, from address, subject, and HTML or text body, filling in personalization fields.\n2. Run the send operation.\n3. Capture the returned email id.\n4. Optionally run get_email with the id to confirm the delivery status.\n\n## Output\nReturn the email id and delivery status. If sending fails, report the error reason.', + }, + { + name: 'add-contact-to-audience', + description: 'Create or update a Resend contact in an audience for marketing sends.', + content: + '# Add Contact To Audience\n\nKeep a Resend audience in sync with new contacts.\n\n## Steps\n1. Run list_contacts or get_contact to check whether the person already exists.\n2. If new, run create_contact with email and name fields and the subscribed state.\n3. If existing, run update_contact to refresh fields.\n4. Confirm the contact is in the correct audience.\n\n## Output\nReturn the contact id and whether it was created or updated.', + }, + { + name: 'handle-unsubscribe', + description: 'Mark a Resend contact as unsubscribed and send a confirmation email.', + content: + '# Handle Unsubscribe\n\nProcess an opt-out request cleanly.\n\n## Steps\n1. Run get_contact to look up the matching contact by email.\n2. Run update_contact to set unsubscribed to true.\n3. Log the opt-out reason for compliance records.\n4. Run the send operation to deliver a brief confirmation acknowledging the change.\n\n## Output\nConfirm the contact is unsubscribed and the acknowledgement email id.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/resend.ts b/apps/sim/blocks/blocks/resend.ts index 545a837193d..e52ad0cb986 100644 --- a/apps/sim/blocks/blocks/resend.ts +++ b/apps/sim/blocks/blocks/resend.ts @@ -1,6 +1,5 @@ -import { ResendIcon } from '@/components/icons' import { ResendBlockDisplay } from '@/blocks/blocks/resend.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' @@ -314,96 +313,3 @@ Return ONLY the email body - no explanations, no extra text.`, deleted: { type: 'boolean', description: 'Whether the resource was deleted' }, }, } - -export const ResendBlockMeta = { - tags: ['email-marketing', 'messaging'], - url: 'https://resend.com', - templates: [ - { - icon: ResendIcon, - title: 'Resend + Loops onboarding emails', - prompt: - 'Build a workflow that listens for new signups, creates a Loops contact with the right user group, and sends the welcome email through Resend with a personalized subject and body so the first impression is on-brand and fast.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['marketing', 'automation', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: ResendIcon, - title: 'Resend domain monitor', - prompt: - 'Create a scheduled workflow that lists Resend domains, checks DNS verification status for each, and posts a Slack alert the moment any domain shows a verification or DKIM problem so we never silently lose deliverability.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'devops', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: ResendIcon, - title: 'Resend transactional flow', - prompt: - 'Build a workflow that listens for product events, renders the right transactional email body, sends it through Resend, then retrieves the message status after a short delay and writes delivery, open, and click events to a per-user activity table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'communication'], - }, - { - icon: ResendIcon, - title: 'Resend + AgentMail reply handler', - prompt: - 'Create a workflow that sends outbound messages through Resend but routes replies into a per-customer AgentMail inbox, threads them with the original send, and posts unread inbox digests to the support owner.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - alsoIntegrations: ['agentmail'], - }, - { - icon: ResendIcon, - title: 'Resend marketing broadcast', - prompt: - 'Build a workflow that takes a marketing message and a Resend audience, splits the recipient list into safe-volume batches, sends each batch through Resend with rate-limit pacing, and logs per-batch send results to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: ResendIcon, - title: 'Resend audience sync', - prompt: - 'Create a workflow that reads my subscriber list from a table, creates or updates each Resend contact in the matching audience, and removes contacts that have unsubscribed by deleting them so the Resend audience stays in sync with my source of truth.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'sync'], - }, - { - icon: ResendIcon, - title: 'Resend unsubscribe handler', - prompt: - 'Build a workflow that listens for unsubscribe events, looks up the matching Resend contact, updates it to unsubscribed, logs the opt-out reason to a table, and sends a confirmation email through Resend acknowledging the change.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'communication', 'compliance'], - }, - ], - skills: [ - { - name: 'send-transactional-email', - description: 'Send a personalized transactional email and confirm delivery via Resend.', - content: - '# Send Transactional Email\n\nSend a one-off transactional email through Resend.\n\n## Steps\n1. Compose the recipient, from address, subject, and HTML or text body, filling in personalization fields.\n2. Run the send operation.\n3. Capture the returned email id.\n4. Optionally run get_email with the id to confirm the delivery status.\n\n## Output\nReturn the email id and delivery status. If sending fails, report the error reason.', - }, - { - name: 'add-contact-to-audience', - description: 'Create or update a Resend contact in an audience for marketing sends.', - content: - '# Add Contact To Audience\n\nKeep a Resend audience in sync with new contacts.\n\n## Steps\n1. Run list_contacts or get_contact to check whether the person already exists.\n2. If new, run create_contact with email and name fields and the subscribed state.\n3. If existing, run update_contact to refresh fields.\n4. Confirm the contact is in the correct audience.\n\n## Output\nReturn the contact id and whether it was created or updated.', - }, - { - name: 'handle-unsubscribe', - description: 'Mark a Resend contact as unsubscribed and send a confirmation email.', - content: - '# Handle Unsubscribe\n\nProcess an opt-out request cleanly.\n\n## Steps\n1. Run get_contact to look up the matching contact by email.\n2. Run update_contact to set unsubscribed to true.\n3. Log the opt-out reason for compliance records.\n4. Run the send operation to deliver a brief confirmation acknowledging the change.\n\n## Output\nConfirm the contact is unsubscribed and the acknowledgement email id.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/revenuecat.display.ts b/apps/sim/blocks/blocks/revenuecat.display.ts index 5441d3108aa..fa14fd616fb 100644 --- a/apps/sim/blocks/blocks/revenuecat.display.ts +++ b/apps/sim/blocks/blocks/revenuecat.display.ts @@ -1,6 +1,6 @@ import { RevenueCatIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RevenueCatBlockDisplay = { type: 'revenuecat', @@ -15,3 +15,105 @@ export const RevenueCatBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/revenuecat', integrationType: IntegrationType.Commerce, } satisfies BlockDisplay + +export const RevenueCatBlockMeta = { + tags: ['payments', 'subscriptions'], + url: 'https://www.revenuecat.com', + templates: [ + { + icon: RevenueCatIcon, + title: 'RevenueCat MRR dashboard', + prompt: + 'Build a scheduled daily workflow that pulls RevenueCat subscriber and offering data, calculates MRR, ARPU, and trial-to-paid conversion, logs the metrics to a tracking table with historical trends, and posts a daily Slack summary for the growth team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: RevenueCatIcon, + title: 'Entitlement granter', + prompt: + 'Create a workflow that listens for a customer-success approval — for example a Slack reaction or a row in a table — looks up the RevenueCat subscriber, grants a promotional entitlement with the right expiry, and logs the grant in an audit table for compliance.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'support', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: RevenueCatIcon, + title: 'Failed renewal recovery', + prompt: + 'Build a scheduled workflow that lists RevenueCat subscribers with failed renewals, segments them by plan and tenure, drafts a tailored win-back email, sends it via Gmail, and tracks recovery outcomes in a table with retry cadence rules.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'marketing', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: RevenueCatIcon, + title: 'Subscriber attribute sync', + prompt: + 'Create a workflow that listens for changes in your customer table — like email, display name, or company — and updates the matching RevenueCat subscriber attributes so analytics and targeted offers always reflect the latest customer state.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'sync', 'automation'], + }, + { + icon: RevenueCatIcon, + title: 'Trial expiry digest', + prompt: + 'Build a scheduled daily workflow that lists RevenueCat subscribers whose trials expire in the next three days, ranks them by engagement, drafts a personalized conversion nudge, and emails the success team a prioritized list to call.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sales', 'finance', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: RevenueCatIcon, + title: 'Google Play refund operator', + prompt: + 'Create a workflow that takes a refund approval from a support ticket, calls the RevenueCat Google Play refund operation with the right transaction identifier, revokes access, posts the outcome back on the ticket, and logs the action in a compliance table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'support', 'compliance'], + alsoIntegrations: ['zendesk'], + }, + { + icon: RevenueCatIcon, + title: 'Offering performance report', + prompt: + 'Build a scheduled weekly workflow that pulls RevenueCat offerings and recent purchases, computes conversion rate per offering and per package, writes a narrative analysis file with recommendations, and Slacks growth leadership the top findings.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'check-subscription-status', + description: 'Look up a customer in RevenueCat and report their active entitlements.', + content: + '# Check Subscription Status\n\nDetermine what a customer is entitled to right now.\n\n## Steps\n1. Run get_customer with the app user id.\n2. Inspect the returned entitlements for active grants and expiration dates.\n3. Determine whether the customer has the entitlement you are gating on.\n4. Return a clear allow or deny decision.\n\n## Output\nReturn the active entitlements, their expiration dates, and whether the gated feature should be unlocked.', + }, + { + name: 'grant-promotional-access', + description: 'Grant a promotional entitlement to a customer for support or a campaign.', + content: + '# Grant Promotional Access\n\nGive a customer temporary access via a promotional entitlement.\n\n## Steps\n1. Confirm the target app user id with get_customer.\n2. Run grant_entitlement with the entitlement identifier and duration.\n3. Verify the grant by re-checking get_customer.\n4. To reverse a grant later, run revoke_entitlement.\n\n## Output\nConfirm the granted entitlement, its duration, and the customer it was applied to.', + }, + { + name: 'process-subscription-refund', + description: 'Refund and revoke a Google Play subscription for a customer support request.', + content: + '# Process Subscription Refund\n\nHandle a refund request for a store subscription.\n\n## Steps\n1. Look up the customer with get_customer to find the relevant subscription.\n2. For Google Play, run refund_google_subscription with the store transaction id.\n3. If access should end immediately, run revoke_google_subscription.\n4. Log the action for the support record.\n\n## Output\nConfirm the refund and revocation status, and the affected customer and product.', + }, + { + name: 'sync-subscriber-attributes', + description: 'Update RevenueCat subscriber attributes to power targeting and analytics.', + content: + '# Sync Subscriber Attributes\n\nKeep RevenueCat subscriber attributes current.\n\n## Steps\n1. Gather the attributes to set (for example email, plan tier, or campaign source).\n2. Run update_subscriber_attributes for the app user id with the attribute map.\n3. Confirm the update with get_customer.\n\n## Output\nReturn the updated attributes and confirm they were applied to the subscriber.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/revenuecat.ts b/apps/sim/blocks/blocks/revenuecat.ts index 97c2c1b6388..814a4f27434 100644 --- a/apps/sim/blocks/blocks/revenuecat.ts +++ b/apps/sim/blocks/blocks/revenuecat.ts @@ -1,6 +1,5 @@ -import { RevenueCatIcon } from '@/components/icons' import { RevenueCatBlockDisplay } from '@/blocks/blocks/revenuecat.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RevenueCatResponse } from '@/tools/revenuecat/types' @@ -478,105 +477,3 @@ Return ONLY the numeric timestamp, no text.`, }, }, } - -export const RevenueCatBlockMeta = { - tags: ['payments', 'subscriptions'], - url: 'https://www.revenuecat.com', - templates: [ - { - icon: RevenueCatIcon, - title: 'RevenueCat MRR dashboard', - prompt: - 'Build a scheduled daily workflow that pulls RevenueCat subscriber and offering data, calculates MRR, ARPU, and trial-to-paid conversion, logs the metrics to a tracking table with historical trends, and posts a daily Slack summary for the growth team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: RevenueCatIcon, - title: 'Entitlement granter', - prompt: - 'Create a workflow that listens for a customer-success approval — for example a Slack reaction or a row in a table — looks up the RevenueCat subscriber, grants a promotional entitlement with the right expiry, and logs the grant in an audit table for compliance.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'support', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: RevenueCatIcon, - title: 'Failed renewal recovery', - prompt: - 'Build a scheduled workflow that lists RevenueCat subscribers with failed renewals, segments them by plan and tenure, drafts a tailored win-back email, sends it via Gmail, and tracks recovery outcomes in a table with retry cadence rules.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'marketing', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: RevenueCatIcon, - title: 'Subscriber attribute sync', - prompt: - 'Create a workflow that listens for changes in your customer table — like email, display name, or company — and updates the matching RevenueCat subscriber attributes so analytics and targeted offers always reflect the latest customer state.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'sync', 'automation'], - }, - { - icon: RevenueCatIcon, - title: 'Trial expiry digest', - prompt: - 'Build a scheduled daily workflow that lists RevenueCat subscribers whose trials expire in the next three days, ranks them by engagement, drafts a personalized conversion nudge, and emails the success team a prioritized list to call.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sales', 'finance', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: RevenueCatIcon, - title: 'Google Play refund operator', - prompt: - 'Create a workflow that takes a refund approval from a support ticket, calls the RevenueCat Google Play refund operation with the right transaction identifier, revokes access, posts the outcome back on the ticket, and logs the action in a compliance table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'support', 'compliance'], - alsoIntegrations: ['zendesk'], - }, - { - icon: RevenueCatIcon, - title: 'Offering performance report', - prompt: - 'Build a scheduled weekly workflow that pulls RevenueCat offerings and recent purchases, computes conversion rate per offering and per package, writes a narrative analysis file with recommendations, and Slacks growth leadership the top findings.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'check-subscription-status', - description: 'Look up a customer in RevenueCat and report their active entitlements.', - content: - '# Check Subscription Status\n\nDetermine what a customer is entitled to right now.\n\n## Steps\n1. Run get_customer with the app user id.\n2. Inspect the returned entitlements for active grants and expiration dates.\n3. Determine whether the customer has the entitlement you are gating on.\n4. Return a clear allow or deny decision.\n\n## Output\nReturn the active entitlements, their expiration dates, and whether the gated feature should be unlocked.', - }, - { - name: 'grant-promotional-access', - description: 'Grant a promotional entitlement to a customer for support or a campaign.', - content: - '# Grant Promotional Access\n\nGive a customer temporary access via a promotional entitlement.\n\n## Steps\n1. Confirm the target app user id with get_customer.\n2. Run grant_entitlement with the entitlement identifier and duration.\n3. Verify the grant by re-checking get_customer.\n4. To reverse a grant later, run revoke_entitlement.\n\n## Output\nConfirm the granted entitlement, its duration, and the customer it was applied to.', - }, - { - name: 'process-subscription-refund', - description: 'Refund and revoke a Google Play subscription for a customer support request.', - content: - '# Process Subscription Refund\n\nHandle a refund request for a store subscription.\n\n## Steps\n1. Look up the customer with get_customer to find the relevant subscription.\n2. For Google Play, run refund_google_subscription with the store transaction id.\n3. If access should end immediately, run revoke_google_subscription.\n4. Log the action for the support record.\n\n## Output\nConfirm the refund and revocation status, and the affected customer and product.', - }, - { - name: 'sync-subscriber-attributes', - description: 'Update RevenueCat subscriber attributes to power targeting and analytics.', - content: - '# Sync Subscriber Attributes\n\nKeep RevenueCat subscriber attributes current.\n\n## Steps\n1. Gather the attributes to set (for example email, plan tier, or campaign source).\n2. Run update_subscriber_attributes for the app user id with the attribute map.\n3. Confirm the update with get_customer.\n\n## Output\nReturn the updated attributes and confirm they were applied to the subscriber.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rippling.display.ts b/apps/sim/blocks/blocks/rippling.display.ts index bfce8e95ac7..5b5bff4c3dc 100644 --- a/apps/sim/blocks/blocks/rippling.display.ts +++ b/apps/sim/blocks/blocks/rippling.display.ts @@ -1,6 +1,6 @@ import { RipplingIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RipplingBlockDisplay = { type: 'rippling', @@ -14,3 +14,111 @@ export const RipplingBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/rippling', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const RipplingBlockMeta = { + tags: ['hiring'], + url: 'https://www.rippling.com', + templates: [ + { + icon: RipplingIcon, + title: 'Rippling new-hire provisioning', + prompt: + 'Build a scheduled workflow that polls Rippling for new workers, creates accounts in the matching downstream tools, drops each new hire into the right Slack channels, books day-one onboarding via Google Calendar, and writes provisioning status to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation', 'team'], + alsoIntegrations: ['slack', 'google_calendar'], + }, + { + icon: RipplingIcon, + title: 'Rippling departure offboarder', + prompt: + 'Create a scheduled workflow that polls Rippling for workers transitioning out, gathers their owned resources, deactivates downstream accounts, schedules data handoff meetings, posts a structured offboarding checklist to a table, and notifies the people team in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'compliance'], + alsoIntegrations: ['slack'], + }, + { + icon: RipplingIcon, + title: 'Org chart export and review', + prompt: + 'Build a scheduled weekly workflow that pulls Rippling workers, departments, teams, and titles, writes an updated org chart file, diffs against last week to find structural changes, and Slacks people operations any unexpected moves for review.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: RipplingIcon, + title: 'Custom object data sync', + prompt: + 'Create a workflow that reads rows from a Sim table representing custom Rippling objects — perks, equipment, allowances — and upserts them into Rippling so HR can manage company-specific data with the same governance as core worker records.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'sync', 'automation'], + }, + { + icon: RipplingIcon, + title: 'Team and title auditor', + prompt: + 'Build a scheduled monthly workflow that lists Rippling teams, titles, and job functions, flags duplicates, unused values, and inconsistent naming, writes a cleanup report file, and opens a Linear task for the people operations owner of each issue.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'analysis'], + alsoIntegrations: ['linear'], + }, + { + icon: RipplingIcon, + title: 'Manager change notifier', + prompt: + 'Create a scheduled workflow that polls Rippling workers for manager reassignments, notifies the worker and the new manager via email, schedules a thirty-minute intro on Google Calendar, and logs the transition in a tracking table for HR visibility.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'team', 'communication'], + alsoIntegrations: ['gmail', 'google_calendar'], + }, + { + icon: RipplingIcon, + title: 'Department headcount digest', + prompt: + 'Build a scheduled weekly workflow that pulls Rippling workers grouped by department and employment type, computes headcount, open requisitions, and growth versus the prior week, writes a narrative summary, and emails it to department heads.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'reporting', 'enterprise'], + }, + ], + skills: [ + { + name: 'lookup-employee-profile', + description: 'Find a Rippling worker and return their role, department, and team details.', + content: + '# Lookup Employee Profile\n\nRetrieve a complete profile for an employee.\n\n## Steps\n1. Run list_workers filtered by name or attributes to find the worker, or list_users if you have a user id.\n2. Run get_worker for the full record once identified.\n3. Enrich with get_department, get_team, and get_title as needed for context.\n4. Assemble the profile.\n\n## Output\nReturn the worker name, title, department, team, and employment type. Note any field that is unavailable.', + }, + { + name: 'department-headcount-report', + description: 'Group Rippling workers by department and employment type to report headcount.', + content: + '# Department Headcount Report\n\nBuild a headcount snapshot across the org.\n\n## Steps\n1. Run list_departments to enumerate departments.\n2. Run list_workers and group by department and employment type.\n3. Compute headcount per group and compare against a prior snapshot for growth.\n4. Write a narrative summary of the changes.\n\n## Output\nReturn headcount per department and employment type, plus week-over-week change where available.', + }, + { + name: 'manage-department', + description: 'Create or update a department record in Rippling for an org change.', + content: + '# Manage Department\n\nKeep the Rippling org structure current.\n\n## Steps\n1. Run list_departments to check whether the department already exists.\n2. If new, run create_department with the name and parent details.\n3. If it exists, run update_department to adjust the record.\n4. Confirm with get_department.\n\n## Output\nReturn the department id and whether it was created or updated.', + }, + { + name: 'sync-custom-object-records', + description: + 'Push external data (training, licenses, assets) onto Rippling custom object records.', + content: + '# Sync Custom Object Records\n\nWrite product data onto Rippling profiles via custom objects.\n\n## Steps\n1. Run list_custom_objects to find the target object, then list_custom_object_fields to confirm its schema.\n2. Build the records to write (for example training completion dates, license assignments, or asset ids).\n3. Use create_custom_object_record or update_custom_object_record for single writes, or bulk_create_custom_object_records and bulk_update_custom_object_records for batches.\n4. Verify with query_custom_object_records or get_custom_object_record_by_external_id.\n\n## Output\nReturn the count of records created or updated and flag any that failed validation.', + }, + { + name: 'run-rippling-report', + description: 'Trigger a Rippling report run and retrieve the completed results.', + content: + '# Run Rippling Report\n\nGenerate and collect a Rippling report for downstream analysis.\n\n## Steps\n1. Run trigger_report_run for the target report id to start a run.\n2. Capture the returned run id.\n3. Poll get_report_run until the run completes.\n4. Pass the results downstream to a table or summary.\n\n## Output\nReturn the report run id, completion status, and a summary of the returned rows.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rippling.ts b/apps/sim/blocks/blocks/rippling.ts index 5099a93ef5e..83eec46139d 100644 --- a/apps/sim/blocks/blocks/rippling.ts +++ b/apps/sim/blocks/blocks/rippling.ts @@ -1,6 +1,5 @@ -import { RipplingIcon } from '@/components/icons' import { RipplingBlockDisplay } from '@/blocks/blocks/rippling.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' /** Operations that support the filter query parameter */ @@ -1464,111 +1463,3 @@ Return ONLY the sort expression - no explanations, no extra text.`, __meta: { type: 'json', description: 'Metadata including redacted_fields' }, }, } - -export const RipplingBlockMeta = { - tags: ['hiring'], - url: 'https://www.rippling.com', - templates: [ - { - icon: RipplingIcon, - title: 'Rippling new-hire provisioning', - prompt: - 'Build a scheduled workflow that polls Rippling for new workers, creates accounts in the matching downstream tools, drops each new hire into the right Slack channels, books day-one onboarding via Google Calendar, and writes provisioning status to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation', 'team'], - alsoIntegrations: ['slack', 'google_calendar'], - }, - { - icon: RipplingIcon, - title: 'Rippling departure offboarder', - prompt: - 'Create a scheduled workflow that polls Rippling for workers transitioning out, gathers their owned resources, deactivates downstream accounts, schedules data handoff meetings, posts a structured offboarding checklist to a table, and notifies the people team in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'compliance'], - alsoIntegrations: ['slack'], - }, - { - icon: RipplingIcon, - title: 'Org chart export and review', - prompt: - 'Build a scheduled weekly workflow that pulls Rippling workers, departments, teams, and titles, writes an updated org chart file, diffs against last week to find structural changes, and Slacks people operations any unexpected moves for review.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: RipplingIcon, - title: 'Custom object data sync', - prompt: - 'Create a workflow that reads rows from a Sim table representing custom Rippling objects — perks, equipment, allowances — and upserts them into Rippling so HR can manage company-specific data with the same governance as core worker records.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'sync', 'automation'], - }, - { - icon: RipplingIcon, - title: 'Team and title auditor', - prompt: - 'Build a scheduled monthly workflow that lists Rippling teams, titles, and job functions, flags duplicates, unused values, and inconsistent naming, writes a cleanup report file, and opens a Linear task for the people operations owner of each issue.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'analysis'], - alsoIntegrations: ['linear'], - }, - { - icon: RipplingIcon, - title: 'Manager change notifier', - prompt: - 'Create a scheduled workflow that polls Rippling workers for manager reassignments, notifies the worker and the new manager via email, schedules a thirty-minute intro on Google Calendar, and logs the transition in a tracking table for HR visibility.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'team', 'communication'], - alsoIntegrations: ['gmail', 'google_calendar'], - }, - { - icon: RipplingIcon, - title: 'Department headcount digest', - prompt: - 'Build a scheduled weekly workflow that pulls Rippling workers grouped by department and employment type, computes headcount, open requisitions, and growth versus the prior week, writes a narrative summary, and emails it to department heads.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'reporting', 'enterprise'], - }, - ], - skills: [ - { - name: 'lookup-employee-profile', - description: 'Find a Rippling worker and return their role, department, and team details.', - content: - '# Lookup Employee Profile\n\nRetrieve a complete profile for an employee.\n\n## Steps\n1. Run list_workers filtered by name or attributes to find the worker, or list_users if you have a user id.\n2. Run get_worker for the full record once identified.\n3. Enrich with get_department, get_team, and get_title as needed for context.\n4. Assemble the profile.\n\n## Output\nReturn the worker name, title, department, team, and employment type. Note any field that is unavailable.', - }, - { - name: 'department-headcount-report', - description: 'Group Rippling workers by department and employment type to report headcount.', - content: - '# Department Headcount Report\n\nBuild a headcount snapshot across the org.\n\n## Steps\n1. Run list_departments to enumerate departments.\n2. Run list_workers and group by department and employment type.\n3. Compute headcount per group and compare against a prior snapshot for growth.\n4. Write a narrative summary of the changes.\n\n## Output\nReturn headcount per department and employment type, plus week-over-week change where available.', - }, - { - name: 'manage-department', - description: 'Create or update a department record in Rippling for an org change.', - content: - '# Manage Department\n\nKeep the Rippling org structure current.\n\n## Steps\n1. Run list_departments to check whether the department already exists.\n2. If new, run create_department with the name and parent details.\n3. If it exists, run update_department to adjust the record.\n4. Confirm with get_department.\n\n## Output\nReturn the department id and whether it was created or updated.', - }, - { - name: 'sync-custom-object-records', - description: - 'Push external data (training, licenses, assets) onto Rippling custom object records.', - content: - '# Sync Custom Object Records\n\nWrite product data onto Rippling profiles via custom objects.\n\n## Steps\n1. Run list_custom_objects to find the target object, then list_custom_object_fields to confirm its schema.\n2. Build the records to write (for example training completion dates, license assignments, or asset ids).\n3. Use create_custom_object_record or update_custom_object_record for single writes, or bulk_create_custom_object_records and bulk_update_custom_object_records for batches.\n4. Verify with query_custom_object_records or get_custom_object_record_by_external_id.\n\n## Output\nReturn the count of records created or updated and flag any that failed validation.', - }, - { - name: 'run-rippling-report', - description: 'Trigger a Rippling report run and retrieve the completed results.', - content: - '# Run Rippling Report\n\nGenerate and collect a Rippling report for downstream analysis.\n\n## Steps\n1. Run trigger_report_run for the target report id to start a run.\n2. Capture the returned run id.\n3. Poll get_report_run until the run completes.\n4. Pass the results downstream to a table or summary.\n\n## Output\nReturn the report run id, completion status, and a summary of the returned rows.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rootly.display.ts b/apps/sim/blocks/blocks/rootly.display.ts index 64299e8b205..c09f9da9d87 100644 --- a/apps/sim/blocks/blocks/rootly.display.ts +++ b/apps/sim/blocks/blocks/rootly.display.ts @@ -1,6 +1,6 @@ import { RootlyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RootlyBlockDisplay = { type: 'rootly', @@ -15,3 +15,113 @@ export const RootlyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/rootly', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const RootlyBlockMeta = { + tags: ['incident-management', 'monitoring'], + url: 'https://rootly.com', + templates: [ + { + icon: RootlyIcon, + title: 'Rootly incident war-room', + prompt: + 'Build a scheduled workflow that polls Rootly for newly opened incidents, creates a Slack war-room channel for each, invites responders, posts the incident summary, and keeps the channel topic in sync with severity.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: RootlyIcon, + title: 'Rootly retro generator', + prompt: + 'Create a scheduled workflow that polls Rootly for recently closed incidents, drafts the retrospective doc, pulls the Slack thread and timeline, and assigns owners for follow-up actions in Linear.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack', 'linear'], + }, + { + icon: RootlyIcon, + title: 'Rootly weekly digest', + prompt: + 'Build a scheduled weekly workflow that summarizes Rootly incident counts, MTTR, top affected services, and outstanding action items, and posts a digest to leadership Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: RootlyIcon, + title: 'Rootly customer-comms drafter', + prompt: + 'Create a workflow that drafts and queues customer-facing status updates during a Rootly incident based on severity and impacted services, holding for approval before publishing.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + }, + { + icon: RootlyIcon, + title: 'Rootly action-item tracker', + prompt: + 'Build a workflow that tracks Rootly follow-up actions across incidents, opens Linear tickets, and writes a tables-based dashboard that flags overdue items by owner.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['linear'], + }, + { + icon: RootlyIcon, + title: 'Rootly on-call digest', + prompt: + 'Create a scheduled daily workflow that summarizes the past 24 hours of Rootly pages, the on-call responder load by person, and writes a digest to the SRE Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: RootlyIcon, + title: 'Rootly + LangSmith agent-incident tracker', + prompt: + 'Build a workflow that for each Rootly incident involving an AI agent attaches the LangSmith trace, captures the failure mode, and writes the agent-quality regression analysis.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'engineering'], + alsoIntegrations: ['langsmith'], + }, + ], + skills: [ + { + name: 'declare-incident', + description: 'Open a Rootly incident with the right severity, service, and team assigned.', + content: + '# Declare Incident\n\nSpin up a structured Rootly incident from an alert or report.\n\n## Steps\n1. Run list_severities, list_services, and list_teams to resolve the correct ids.\n2. Run create_incident with a clear title, summary, severity, affected service, and owning team.\n3. Capture the returned incident id.\n4. Add an opening timeline note with add_incident_event.\n\n## Output\nReturn the incident id, severity, assigned team, and a link. Confirm the opening event was logged.', + }, + { + name: 'post-incident-update', + description: 'Append a status update event to an active Rootly incident timeline.', + content: + '# Post Incident Update\n\nKeep an incident timeline current.\n\n## Steps\n1. Run get_incident to confirm the current state.\n2. Run add_incident_event with the update text (mitigation steps, customer impact, next checkpoint).\n3. Run update_incident if the severity or status has changed.\n\n## Output\nReturn the appended event and the current incident status.', + }, + { + name: 'triage-alerts', + description: + 'List open Rootly alerts, acknowledge them, and escalate to an incident if needed.', + content: + '# Triage Alerts\n\nWork through the open alert queue.\n\n## Steps\n1. Run list_alerts to pull open alerts.\n2. For each, run get_alert for detail and run acknowledge_alert to claim it.\n3. If an alert warrants response, run create_incident and link it.\n4. Run resolve_alert once the alert is handled.\n\n## Output\nReturn how many alerts were acknowledged, resolved, and escalated to incidents.', + }, + { + name: 'check-on-call', + description: + 'Look up who is currently on call across Rootly schedules and escalation policies.', + content: + '# Check On Call\n\nFind the right person to page right now.\n\n## Steps\n1. Run list_schedules to enumerate on-call schedules.\n2. Run list_on_calls to read the current rotation members.\n3. Cross-reference list_escalation_policies for the escalation path.\n\n## Output\nReturn the current on-call person per schedule and the escalation order.', + }, + { + name: 'track-action-items', + description: 'Create and list retrospective action items tied to a Rootly incident.', + content: + '# Track Action Items\n\nCapture and follow up on postmortem action items.\n\n## Steps\n1. Run get_incident to confirm the incident context.\n2. Run create_action_item for each follow-up with a clear owner and description.\n3. Run list_action_items to review open items for the incident.\n\n## Output\nReturn the created action items and the list of outstanding follow-ups.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rootly.ts b/apps/sim/blocks/blocks/rootly.ts index 340b8e5c9b1..f9c33c2ae70 100644 --- a/apps/sim/blocks/blocks/rootly.ts +++ b/apps/sim/blocks/blocks/rootly.ts @@ -1,6 +1,5 @@ -import { RootlyIcon } from '@/components/icons' import { RootlyBlockDisplay } from '@/blocks/blocks/rootly.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { RootlyResponse } from '@/tools/rootly/types' @@ -2406,113 +2405,3 @@ export const RootlyBlock: BlockConfig = { totalCount: { type: 'number', description: 'Total count of items returned' }, }, } - -export const RootlyBlockMeta = { - tags: ['incident-management', 'monitoring'], - url: 'https://rootly.com', - templates: [ - { - icon: RootlyIcon, - title: 'Rootly incident war-room', - prompt: - 'Build a scheduled workflow that polls Rootly for newly opened incidents, creates a Slack war-room channel for each, invites responders, posts the incident summary, and keeps the channel topic in sync with severity.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: RootlyIcon, - title: 'Rootly retro generator', - prompt: - 'Create a scheduled workflow that polls Rootly for recently closed incidents, drafts the retrospective doc, pulls the Slack thread and timeline, and assigns owners for follow-up actions in Linear.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack', 'linear'], - }, - { - icon: RootlyIcon, - title: 'Rootly weekly digest', - prompt: - 'Build a scheduled weekly workflow that summarizes Rootly incident counts, MTTR, top affected services, and outstanding action items, and posts a digest to leadership Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: RootlyIcon, - title: 'Rootly customer-comms drafter', - prompt: - 'Create a workflow that drafts and queues customer-facing status updates during a Rootly incident based on severity and impacted services, holding for approval before publishing.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - }, - { - icon: RootlyIcon, - title: 'Rootly action-item tracker', - prompt: - 'Build a workflow that tracks Rootly follow-up actions across incidents, opens Linear tickets, and writes a tables-based dashboard that flags overdue items by owner.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['linear'], - }, - { - icon: RootlyIcon, - title: 'Rootly on-call digest', - prompt: - 'Create a scheduled daily workflow that summarizes the past 24 hours of Rootly pages, the on-call responder load by person, and writes a digest to the SRE Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: RootlyIcon, - title: 'Rootly + LangSmith agent-incident tracker', - prompt: - 'Build a workflow that for each Rootly incident involving an AI agent attaches the LangSmith trace, captures the failure mode, and writes the agent-quality regression analysis.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'engineering'], - alsoIntegrations: ['langsmith'], - }, - ], - skills: [ - { - name: 'declare-incident', - description: 'Open a Rootly incident with the right severity, service, and team assigned.', - content: - '# Declare Incident\n\nSpin up a structured Rootly incident from an alert or report.\n\n## Steps\n1. Run list_severities, list_services, and list_teams to resolve the correct ids.\n2. Run create_incident with a clear title, summary, severity, affected service, and owning team.\n3. Capture the returned incident id.\n4. Add an opening timeline note with add_incident_event.\n\n## Output\nReturn the incident id, severity, assigned team, and a link. Confirm the opening event was logged.', - }, - { - name: 'post-incident-update', - description: 'Append a status update event to an active Rootly incident timeline.', - content: - '# Post Incident Update\n\nKeep an incident timeline current.\n\n## Steps\n1. Run get_incident to confirm the current state.\n2. Run add_incident_event with the update text (mitigation steps, customer impact, next checkpoint).\n3. Run update_incident if the severity or status has changed.\n\n## Output\nReturn the appended event and the current incident status.', - }, - { - name: 'triage-alerts', - description: - 'List open Rootly alerts, acknowledge them, and escalate to an incident if needed.', - content: - '# Triage Alerts\n\nWork through the open alert queue.\n\n## Steps\n1. Run list_alerts to pull open alerts.\n2. For each, run get_alert for detail and run acknowledge_alert to claim it.\n3. If an alert warrants response, run create_incident and link it.\n4. Run resolve_alert once the alert is handled.\n\n## Output\nReturn how many alerts were acknowledged, resolved, and escalated to incidents.', - }, - { - name: 'check-on-call', - description: - 'Look up who is currently on call across Rootly schedules and escalation policies.', - content: - '# Check On Call\n\nFind the right person to page right now.\n\n## Steps\n1. Run list_schedules to enumerate on-call schedules.\n2. Run list_on_calls to read the current rotation members.\n3. Cross-reference list_escalation_policies for the escalation path.\n\n## Output\nReturn the current on-call person per schedule and the escalation order.', - }, - { - name: 'track-action-items', - description: 'Create and list retrospective action items tied to a Rootly incident.', - content: - '# Track Action Items\n\nCapture and follow up on postmortem action items.\n\n## Steps\n1. Run get_incident to confirm the incident context.\n2. Run create_action_item for each follow-up with a clear owner and description.\n3. Run list_action_items to review open items for the incident.\n\n## Output\nReturn the created action items and the list of outstanding follow-ups.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rss.display.ts b/apps/sim/blocks/blocks/rss.display.ts index b1c5ce0dac9..424ac7ca8b7 100644 --- a/apps/sim/blocks/blocks/rss.display.ts +++ b/apps/sim/blocks/blocks/rss.display.ts @@ -1,6 +1,7 @@ +import { BookOpen, Table } from '@/components/emcn/icons' import { RssIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const RssBlockDisplay = { type: 'rss', @@ -15,3 +16,38 @@ export const RssBlockDisplay = { integrationType: IntegrationType.Search, triggerAllowed: true, } satisfies BlockDisplay + +export const RssBlockMeta = { + tags: ['automation', 'content-management'], + templates: [ + { + icon: RssIcon, + title: 'RSS post to Slack', + prompt: + 'Build a workflow that triggers when a new item is published in an RSS feed, writes a one-line summary of the item with an agent, and posts the title, summary, and link to a Slack channel.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: Table, + title: 'RSS feed to content table', + prompt: + 'Create a workflow that triggers on each new RSS feed item, extracts the title, link, and publish date, tags the topic with an agent, and appends a row to a content tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['content', 'automation'], + }, + { + icon: BookOpen, + title: 'Competitor blog watcher', + prompt: + 'Build a workflow that triggers when a competitor publishes a new RSS item, summarizes the post and flags anything relevant to our roadmap with an agent, and emails the brief to the team.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'monitoring'], + alsoIntegrations: ['gmail'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/rss.ts b/apps/sim/blocks/blocks/rss.ts index 0343d760b78..dbaca2828e2 100644 --- a/apps/sim/blocks/blocks/rss.ts +++ b/apps/sim/blocks/blocks/rss.ts @@ -1,7 +1,5 @@ -import { BookOpen, Table } from '@/components/emcn/icons' -import { RssIcon } from '@/components/icons' import { RssBlockDisplay } from '@/blocks/blocks/rss.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { getTrigger } from '@/triggers' export const RssBlock: BlockConfig = { @@ -27,38 +25,3 @@ export const RssBlock: BlockConfig = { available: ['rss_poller'], }, } - -export const RssBlockMeta = { - tags: ['automation', 'content-management'], - templates: [ - { - icon: RssIcon, - title: 'RSS post to Slack', - prompt: - 'Build a workflow that triggers when a new item is published in an RSS feed, writes a one-line summary of the item with an agent, and posts the title, summary, and link to a Slack channel.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: Table, - title: 'RSS feed to content table', - prompt: - 'Create a workflow that triggers on each new RSS feed item, extracts the title, link, and publish date, tags the topic with an agent, and appends a row to a content tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['content', 'automation'], - }, - { - icon: BookOpen, - title: 'Competitor blog watcher', - prompt: - 'Build a workflow that triggers when a competitor publishes a new RSS item, summarizes the post and flags anything relevant to our roadmap with an agent, and emails the brief to the team.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'monitoring'], - alsoIntegrations: ['gmail'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/s3.display.ts b/apps/sim/blocks/blocks/s3.display.ts index 62db1dc769d..8d9eae46ef9 100644 --- a/apps/sim/blocks/blocks/s3.display.ts +++ b/apps/sim/blocks/blocks/s3.display.ts @@ -1,6 +1,6 @@ import { S3Icon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const S3BlockDisplay = { type: 's3', @@ -14,3 +14,101 @@ export const S3BlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/s3', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const S3BlockMeta = { + tags: ['cloud', 'automation'], + url: 'https://aws.amazon.com/s3', + templates: [ + { + icon: S3Icon, + title: 'S3 report archiver', + prompt: + 'Build a scheduled workflow that generates a daily report file, uploads it to an S3 bucket under a dated prefix, and posts the object link to Slack so the team always has the latest archived copy.', + modules: ['scheduled', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: S3Icon, + title: 'S3 document ingestion to knowledge base', + prompt: + 'Create a workflow that lists objects in an S3 bucket, downloads each new document, and indexes it into a Sim knowledge base so agents can answer questions over files stored in S3.', + modules: ['files', 'knowledge-base', 'agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'sync'], + }, + { + icon: S3Icon, + title: 'S3 incoming-file processor', + prompt: + 'Build a workflow that downloads a newly uploaded S3 object, parses its contents, writes the extracted rows to a table, and deletes the source object once processing succeeds.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise'], + }, + { + icon: S3Icon, + title: 'S3 backup retention sweeper', + prompt: + 'Create a scheduled workflow that lists objects in an S3 backup bucket, identifies files older than the retention window, deletes the expired objects, and writes a deletion manifest to a table for audit.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise', 'monitoring'], + }, + { + icon: S3Icon, + title: 'S3 export-to-customer flow', + prompt: + 'Build a workflow that generates a per-customer data export file, uploads it to a customer-scoped S3 prefix, and emails the customer a download link once the upload completes.', + modules: ['files', 'agent', 'workflows'], + category: 'support', + tags: ['automation', 'support'], + alsoIntegrations: ['gmail'], + }, + { + icon: S3Icon, + title: 'S3 bucket inventory dashboard', + prompt: + 'Create a scheduled workflow that lists objects across an S3 bucket, aggregates object count and total size by prefix, and writes a daily inventory snapshot to a table for cost and growth tracking.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'monitoring', 'automation'], + }, + { + icon: S3Icon, + title: 'S3 media-asset publisher', + prompt: + 'Build a workflow that takes a generated image or document, uploads it to a public S3 bucket, retrieves the object URL, and writes the link back to the originating row in a table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['content', 'automation'], + }, + ], + skills: [ + { + name: 'upload-and-share-asset', + description: 'Upload a generated file to an S3 bucket and return its object URL.', + content: + '# Upload And Share Asset\n\nPublish a file to S3 and hand back a usable link.\n\n## Steps\n1. Take the generated image or document as the object body.\n2. Run put_object with the bucket, key, and content type.\n3. Construct or capture the resulting object URL.\n4. Write the link back to the originating record (for example a table row).\n\n## Output\nReturn the object key and URL. Note the bucket and whether the object is publicly accessible.', + }, + { + name: 'fetch-object-contents', + description: 'Download an object from S3 and pass its contents to downstream steps.', + content: + '# Fetch Object Contents\n\nRetrieve a file from S3 for processing.\n\n## Steps\n1. Identify the bucket and object key.\n2. Run get_object to download the file.\n3. Pass the contents downstream for parsing, summarizing, or transformation.\n\n## Output\nReturn the object contents (or a file reference) and confirm the source key.', + }, + { + name: 'list-bucket-objects', + description: 'List objects in an S3 bucket under a prefix for inventory or cleanup.', + content: + '# List Bucket Objects\n\nEnumerate what lives under an S3 prefix.\n\n## Steps\n1. Run list_objects with the bucket and an optional prefix to scope the listing.\n2. Page through results if the listing is truncated.\n3. Filter the keys by name, date, or size as needed.\n\n## Output\nReturn the matching object keys with sizes and last-modified dates.', + }, + { + name: 'archive-object', + description: 'Copy an S3 object to an archive location and delete the original.', + content: + '# Archive Object\n\nMove an object to an archive prefix or bucket.\n\n## Steps\n1. Run copy_object from the source key to the archive destination key.\n2. Verify the copy succeeded.\n3. Run delete_object on the original to complete the move.\n\n## Output\nConfirm the archived destination key and that the original was removed.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/s3.ts b/apps/sim/blocks/blocks/s3.ts index 9a9e45c6151..77eefe145d5 100644 --- a/apps/sim/blocks/blocks/s3.ts +++ b/apps/sim/blocks/blocks/s3.ts @@ -1,6 +1,5 @@ -import { S3Icon } from '@/components/icons' import { S3BlockDisplay } from '@/blocks/blocks/s3.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { S3Response } from '@/tools/s3/types' @@ -405,101 +404,3 @@ export const S3Block: BlockConfig = { metadata: { type: 'json', description: 'Operation metadata' }, }, } - -export const S3BlockMeta = { - tags: ['cloud', 'automation'], - url: 'https://aws.amazon.com/s3', - templates: [ - { - icon: S3Icon, - title: 'S3 report archiver', - prompt: - 'Build a scheduled workflow that generates a daily report file, uploads it to an S3 bucket under a dated prefix, and posts the object link to Slack so the team always has the latest archived copy.', - modules: ['scheduled', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: S3Icon, - title: 'S3 document ingestion to knowledge base', - prompt: - 'Create a workflow that lists objects in an S3 bucket, downloads each new document, and indexes it into a Sim knowledge base so agents can answer questions over files stored in S3.', - modules: ['files', 'knowledge-base', 'agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'sync'], - }, - { - icon: S3Icon, - title: 'S3 incoming-file processor', - prompt: - 'Build a workflow that downloads a newly uploaded S3 object, parses its contents, writes the extracted rows to a table, and deletes the source object once processing succeeds.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise'], - }, - { - icon: S3Icon, - title: 'S3 backup retention sweeper', - prompt: - 'Create a scheduled workflow that lists objects in an S3 backup bucket, identifies files older than the retention window, deletes the expired objects, and writes a deletion manifest to a table for audit.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise', 'monitoring'], - }, - { - icon: S3Icon, - title: 'S3 export-to-customer flow', - prompt: - 'Build a workflow that generates a per-customer data export file, uploads it to a customer-scoped S3 prefix, and emails the customer a download link once the upload completes.', - modules: ['files', 'agent', 'workflows'], - category: 'support', - tags: ['automation', 'support'], - alsoIntegrations: ['gmail'], - }, - { - icon: S3Icon, - title: 'S3 bucket inventory dashboard', - prompt: - 'Create a scheduled workflow that lists objects across an S3 bucket, aggregates object count and total size by prefix, and writes a daily inventory snapshot to a table for cost and growth tracking.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'monitoring', 'automation'], - }, - { - icon: S3Icon, - title: 'S3 media-asset publisher', - prompt: - 'Build a workflow that takes a generated image or document, uploads it to a public S3 bucket, retrieves the object URL, and writes the link back to the originating row in a table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['content', 'automation'], - }, - ], - skills: [ - { - name: 'upload-and-share-asset', - description: 'Upload a generated file to an S3 bucket and return its object URL.', - content: - '# Upload And Share Asset\n\nPublish a file to S3 and hand back a usable link.\n\n## Steps\n1. Take the generated image or document as the object body.\n2. Run put_object with the bucket, key, and content type.\n3. Construct or capture the resulting object URL.\n4. Write the link back to the originating record (for example a table row).\n\n## Output\nReturn the object key and URL. Note the bucket and whether the object is publicly accessible.', - }, - { - name: 'fetch-object-contents', - description: 'Download an object from S3 and pass its contents to downstream steps.', - content: - '# Fetch Object Contents\n\nRetrieve a file from S3 for processing.\n\n## Steps\n1. Identify the bucket and object key.\n2. Run get_object to download the file.\n3. Pass the contents downstream for parsing, summarizing, or transformation.\n\n## Output\nReturn the object contents (or a file reference) and confirm the source key.', - }, - { - name: 'list-bucket-objects', - description: 'List objects in an S3 bucket under a prefix for inventory or cleanup.', - content: - '# List Bucket Objects\n\nEnumerate what lives under an S3 prefix.\n\n## Steps\n1. Run list_objects with the bucket and an optional prefix to scope the listing.\n2. Page through results if the listing is truncated.\n3. Filter the keys by name, date, or size as needed.\n\n## Output\nReturn the matching object keys with sizes and last-modified dates.', - }, - { - name: 'archive-object', - description: 'Copy an S3 object to an archive location and delete the original.', - content: - '# Archive Object\n\nMove an object to an archive prefix or bucket.\n\n## Steps\n1. Run copy_object from the source key to the archive destination key.\n2. Verify the copy succeeded.\n3. Run delete_object on the original to complete the move.\n\n## Output\nConfirm the archived destination key and that the original was removed.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/salesforce.display.ts b/apps/sim/blocks/blocks/salesforce.display.ts index b2899327d54..a9a99049a67 100644 --- a/apps/sim/blocks/blocks/salesforce.display.ts +++ b/apps/sim/blocks/blocks/salesforce.display.ts @@ -1,6 +1,6 @@ import { SalesforceIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SalesforceBlockDisplay = { type: 'salesforce', @@ -14,3 +14,112 @@ export const SalesforceBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/salesforce', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const SalesforceBlockMeta = { + tags: ['sales-engagement', 'customer-support'], + url: 'https://www.salesforce.com', + templates: [ + { + icon: SalesforceIcon, + title: 'CRM knowledge search', + prompt: + 'Create a knowledge base connected to my Salesforce account so all deals, contacts, notes, and activities are automatically synced and searchable. Then build an agent I can ask things like "what\'s the history with Acme Corp?" or "who was involved in the last enterprise deal?" and get instant answers with CRM record citations.', + modules: ['knowledge-base', 'agent'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + }, + { + icon: SalesforceIcon, + title: 'Deal pipeline tracker', + prompt: + 'Create a table with columns for deal name, stage, amount, close date, and next steps. Build a workflow that syncs open deals from Salesforce into this table daily, and sends me a Slack summary each morning of deals that need attention or are at risk of slipping.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + + { + icon: SalesforceIcon, + title: 'Push Salesforce pipeline updates to Slack', + prompt: + 'Build a workflow that monitors Salesforce opportunities and posts a Slack notification to your sales team whenever a deal advances, closes, or needs immediate attention.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['slack'], + }, + { + icon: SalesforceIcon, + title: 'Inbound lead router', + prompt: + 'Build a workflow that triggers on new inbound form submissions, creates a Salesforce lead with the captured fields, runs a SOQL query to check for an existing account match, assigns the lead to the right owner, and posts the new lead with its score to Slack.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: SalesforceIcon, + title: 'Salesforce case escalation', + prompt: + 'Create a scheduled workflow that queries open Salesforce cases past their SLA, escalates each by updating its priority and owner, creates a follow-up task on the account, and Slacks the support lead a summary of everything that breached.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'crm', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SalesforceIcon, + title: 'Salesforce report digest', + prompt: + 'Build a scheduled workflow that runs a saved Salesforce report each morning, refreshes the linked dashboard, summarizes the key metrics and biggest movers with an agent, and emails the leadership team a written narrative of what changed.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting', 'analysis'], + }, + { + icon: SalesforceIcon, + title: 'Closed-won onboarding kickoff', + prompt: + 'Create a workflow that watches Salesforce opportunities for stage changes to closed-won, pulls the related account and contacts, creates onboarding tasks for the CS owner, and writes a kickoff record into a tables-based project tracker.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sales', 'crm', 'automation'], + }, + ], + skills: [ + { + name: 'capture-inbound-lead', + description: + 'Create or update a Salesforce lead from an inbound signal and assign follow-up.', + content: + '# Capture Inbound Lead\n\nGet an inbound lead into Salesforce cleanly.\n\n## Steps\n1. Run get_leads to check for an existing lead with the same email.\n2. If new, run create_lead with name, company, email, and source; otherwise run update_lead to enrich it.\n3. Run create_task to assign a follow-up to the owner.\n\n## Output\nReturn the lead id, whether it was created or updated, and the follow-up task id.', + }, + { + name: 'log-opportunity-update', + description: 'Advance a Salesforce opportunity stage and record the change for the account.', + content: + '# Log Opportunity Update\n\nKeep a deal current in Salesforce.\n\n## Steps\n1. Run get_opportunities to locate the deal.\n2. Run update_opportunity to set the new stage, amount, or close date.\n3. Run create_task to capture the next action.\n\n## Output\nReturn the opportunity id, its new stage, and the next-step task. Note if the stage moved to closed-won or closed-lost.', + }, + { + name: 'sync-account-contacts', + description: 'Pull a Salesforce account with its contacts for a 360 view.', + content: + '# Sync Account Contacts\n\nAssemble a full picture of an account.\n\n## Steps\n1. Run get_accounts to resolve the target account.\n2. Run get_contacts filtered to the account to list its people.\n3. Optionally run get_opportunities and get_cases for active deals and support context.\n\n## Output\nReturn the account, its contacts with roles, and a summary of open opportunities and cases.', + }, + { + name: 'create-support-case', + description: 'Open a Salesforce case for a customer issue and assign the owner.', + content: + '# Create Support Case\n\nFile a support case in Salesforce.\n\n## Steps\n1. Run get_contacts or get_accounts to link the case to the right record.\n2. Run create_case with subject, description, priority, and origin.\n3. Run create_task for the assigned owner if a follow-up is required.\n\n## Output\nReturn the case id, priority, and linked account or contact.', + }, + { + name: 'run-sales-report', + description: 'Run a Salesforce report and summarize the results for a stakeholder.', + content: + '# Run Sales Report\n\nPull live numbers from a Salesforce report.\n\n## Steps\n1. Run list_reports to find the report, or use a known report id.\n2. Run run_report to execute it and capture the result set.\n3. Summarize the key metrics and notable changes.\n\n## Output\nReturn the headline metrics and a short narrative of what the report shows.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/salesforce.ts b/apps/sim/blocks/blocks/salesforce.ts index b63edcd01ff..52c2ffee136 100644 --- a/apps/sim/blocks/blocks/salesforce.ts +++ b/apps/sim/blocks/blocks/salesforce.ts @@ -1,7 +1,6 @@ -import { SalesforceIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { SalesforceBlockDisplay } from '@/blocks/blocks/salesforce.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { SalesforceResponse } from '@/tools/salesforce/types' import { getTrigger } from '@/triggers' @@ -990,112 +989,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n }, }, } - -export const SalesforceBlockMeta = { - tags: ['sales-engagement', 'customer-support'], - url: 'https://www.salesforce.com', - templates: [ - { - icon: SalesforceIcon, - title: 'CRM knowledge search', - prompt: - 'Create a knowledge base connected to my Salesforce account so all deals, contacts, notes, and activities are automatically synced and searchable. Then build an agent I can ask things like "what\'s the history with Acme Corp?" or "who was involved in the last enterprise deal?" and get instant answers with CRM record citations.', - modules: ['knowledge-base', 'agent'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - }, - { - icon: SalesforceIcon, - title: 'Deal pipeline tracker', - prompt: - 'Create a table with columns for deal name, stage, amount, close date, and next steps. Build a workflow that syncs open deals from Salesforce into this table daily, and sends me a Slack summary each morning of deals that need attention or are at risk of slipping.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - - { - icon: SalesforceIcon, - title: 'Push Salesforce pipeline updates to Slack', - prompt: - 'Build a workflow that monitors Salesforce opportunities and posts a Slack notification to your sales team whenever a deal advances, closes, or needs immediate attention.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['slack'], - }, - { - icon: SalesforceIcon, - title: 'Inbound lead router', - prompt: - 'Build a workflow that triggers on new inbound form submissions, creates a Salesforce lead with the captured fields, runs a SOQL query to check for an existing account match, assigns the lead to the right owner, and posts the new lead with its score to Slack.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: SalesforceIcon, - title: 'Salesforce case escalation', - prompt: - 'Create a scheduled workflow that queries open Salesforce cases past their SLA, escalates each by updating its priority and owner, creates a follow-up task on the account, and Slacks the support lead a summary of everything that breached.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'crm', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SalesforceIcon, - title: 'Salesforce report digest', - prompt: - 'Build a scheduled workflow that runs a saved Salesforce report each morning, refreshes the linked dashboard, summarizes the key metrics and biggest movers with an agent, and emails the leadership team a written narrative of what changed.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting', 'analysis'], - }, - { - icon: SalesforceIcon, - title: 'Closed-won onboarding kickoff', - prompt: - 'Create a workflow that watches Salesforce opportunities for stage changes to closed-won, pulls the related account and contacts, creates onboarding tasks for the CS owner, and writes a kickoff record into a tables-based project tracker.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sales', 'crm', 'automation'], - }, - ], - skills: [ - { - name: 'capture-inbound-lead', - description: - 'Create or update a Salesforce lead from an inbound signal and assign follow-up.', - content: - '# Capture Inbound Lead\n\nGet an inbound lead into Salesforce cleanly.\n\n## Steps\n1. Run get_leads to check for an existing lead with the same email.\n2. If new, run create_lead with name, company, email, and source; otherwise run update_lead to enrich it.\n3. Run create_task to assign a follow-up to the owner.\n\n## Output\nReturn the lead id, whether it was created or updated, and the follow-up task id.', - }, - { - name: 'log-opportunity-update', - description: 'Advance a Salesforce opportunity stage and record the change for the account.', - content: - '# Log Opportunity Update\n\nKeep a deal current in Salesforce.\n\n## Steps\n1. Run get_opportunities to locate the deal.\n2. Run update_opportunity to set the new stage, amount, or close date.\n3. Run create_task to capture the next action.\n\n## Output\nReturn the opportunity id, its new stage, and the next-step task. Note if the stage moved to closed-won or closed-lost.', - }, - { - name: 'sync-account-contacts', - description: 'Pull a Salesforce account with its contacts for a 360 view.', - content: - '# Sync Account Contacts\n\nAssemble a full picture of an account.\n\n## Steps\n1. Run get_accounts to resolve the target account.\n2. Run get_contacts filtered to the account to list its people.\n3. Optionally run get_opportunities and get_cases for active deals and support context.\n\n## Output\nReturn the account, its contacts with roles, and a summary of open opportunities and cases.', - }, - { - name: 'create-support-case', - description: 'Open a Salesforce case for a customer issue and assign the owner.', - content: - '# Create Support Case\n\nFile a support case in Salesforce.\n\n## Steps\n1. Run get_contacts or get_accounts to link the case to the right record.\n2. Run create_case with subject, description, priority, and origin.\n3. Run create_task for the assigned owner if a follow-up is required.\n\n## Output\nReturn the case id, priority, and linked account or contact.', - }, - { - name: 'run-sales-report', - description: 'Run a Salesforce report and summarize the results for a stakeholder.', - content: - '# Run Sales Report\n\nPull live numbers from a Salesforce report.\n\n## Steps\n1. Run list_reports to find the report, or use a known report id.\n2. Run run_report to execute it and capture the result set.\n3. Summarize the key metrics and notable changes.\n\n## Output\nReturn the headline metrics and a short narrative of what the report shows.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sap_concur.display.ts b/apps/sim/blocks/blocks/sap_concur.display.ts index 42a49c03ed6..40de7f48d0f 100644 --- a/apps/sim/blocks/blocks/sap_concur.display.ts +++ b/apps/sim/blocks/blocks/sap_concur.display.ts @@ -1,6 +1,6 @@ import { SapConcurIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SapConcurBlockDisplay = { type: 'sap_concur', @@ -14,3 +14,106 @@ export const SapConcurBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sap_concur', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const SapConcurBlockMeta = { + tags: ['automation'], + url: 'https://www.concur.com', + templates: [ + { + icon: SapConcurIcon, + title: 'SAP Concur expense classifier', + prompt: + 'Build a scheduled workflow that polls SAP Concur for newly submitted expense reports, classifies each line item, validates against policy, and routes exceptions to the approver in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur policy auditor', + prompt: + 'Create a scheduled monthly workflow that audits SAP Concur expense reports against policy, flags pattern violations by employee, and writes a compliance report.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur travel pre-approval', + prompt: + 'Build a scheduled workflow that polls SAP Concur for pending travel requests, routes each to the right approver based on amount and destination, captures the decision over Microsoft Teams, and moves the request to the approved or sent-back state.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur receipt OCR', + prompt: + 'Create a workflow that processes SAP Concur receipt images with AWS Textract, validates the extracted vendor and amount against the report line, and flags mismatches.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['textract'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur reimbursement chaser', + prompt: + 'Build a scheduled workflow that finds SAP Concur reports stuck pending more than 7 days, sends the approver a reminder, and writes the chase log to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur travel reconciler', + prompt: + 'Create a workflow that reconciles SAP Concur travel bookings with corporate card transactions, flags missing receipts, and writes a reconciliation table for finance.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise'], + }, + { + icon: SapConcurIcon, + title: 'SAP Concur budget watcher', + prompt: + 'Build a scheduled monthly workflow that aggregates SAP Concur spend per department, compares against budget, and pings managers in Teams when overspend is projected.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + alsoIntegrations: ['microsoft_teams'], + }, + ], + skills: [ + { + name: 'review-expense-reports', + description: + 'List submitted SAP Concur expense reports, inspect line items, and flag policy exceptions.', + content: + '# Review Expense Reports\n\nSurface expense reports that need attention and check them against policy.\n\n## Steps\n1. Run List Expense Reports to pull recently submitted reports, or List Reports To Approve for items awaiting the current approver.\n2. For each report of interest, run Get Expense Report and List Expenses to read the individual line items, then List Exceptions to see Concur policy flags.\n3. Summarize totals, flagged line items, and any missing receipts.\n\n## Output\nReturn a per-report summary with the report ID, owner, total amount, and a list of policy exceptions or anomalies that warrant follow-up.', + }, + { + name: 'route-report-approval', + description: 'Approve or send back a submitted SAP Concur expense report after review.', + content: + '# Route Report Approval\n\nAct on an expense report once a review decision is made.\n\n## Steps\n1. Confirm the report ID and the decision.\n2. To approve, run Approve Expense Report. To return it for correction, run Send Back Expense Report with a clear comment explaining what must change.\n3. Optionally run Create Report Comment first to leave context for the submitter.\n\n## Output\nConfirm the report ID, the action taken (approved or sent back), and the comment provided so the decision is auditable.', + }, + { + name: 'capture-quick-expense', + description: + 'Create a quick expense in SAP Concur from a receipt, attaching the receipt image.', + content: + '# Capture Quick Expense\n\nLog an out-of-pocket expense quickly, with the receipt attached.\n\n## Steps\n1. If you have a receipt image, run Upload Receipt Image and keep the returned receipt ID, or use Create Quick Expense (With Image) to do both in one step.\n2. Run Create Quick Expense with the vendor, amount, currency, and transaction date.\n3. Verify the entry with Get Expense.\n\n## Output\nReport the created quick expense ID, the captured vendor and amount, and confirm the receipt image is attached.', + }, + { + name: 'manage-travel-requests', + description: + 'List and act on SAP Concur travel requests, moving them through the approval workflow.', + content: + '# Manage Travel Requests\n\nHandle pre-trip travel requests through their approval lifecycle.\n\n## Steps\n1. Run List Travel Requests to find pending requests, then Get Travel Request for full detail on a specific one.\n2. Review the expected expenses and any linked cash advance via Get Request Cash Advance.\n3. Run Move Travel Request (Workflow Action) to advance, approve, or send back the request based on the decision.\n\n## Output\nReturn the travel request ID, destination, estimated cost, and the workflow action applied so the trip approval state is clear.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sap_concur.ts b/apps/sim/blocks/blocks/sap_concur.ts index bedbd8242f1..2e02c84d0f6 100644 --- a/apps/sim/blocks/blocks/sap_concur.ts +++ b/apps/sim/blocks/blocks/sap_concur.ts @@ -1,6 +1,5 @@ -import { SapConcurIcon } from '@/components/icons' import { SapConcurBlockDisplay } from '@/blocks/blocks/sap_concur.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SapConcurProxyResponse, UserFileLike } from '@/tools/sap_concur/types' @@ -1890,106 +1889,3 @@ export const SapConcurBlock: BlockConfig = { data: { type: 'json', description: 'Concur API response payload' }, }, } - -export const SapConcurBlockMeta = { - tags: ['automation'], - url: 'https://www.concur.com', - templates: [ - { - icon: SapConcurIcon, - title: 'SAP Concur expense classifier', - prompt: - 'Build a scheduled workflow that polls SAP Concur for newly submitted expense reports, classifies each line item, validates against policy, and routes exceptions to the approver in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur policy auditor', - prompt: - 'Create a scheduled monthly workflow that audits SAP Concur expense reports against policy, flags pattern violations by employee, and writes a compliance report.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur travel pre-approval', - prompt: - 'Build a scheduled workflow that polls SAP Concur for pending travel requests, routes each to the right approver based on amount and destination, captures the decision over Microsoft Teams, and moves the request to the approved or sent-back state.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur receipt OCR', - prompt: - 'Create a workflow that processes SAP Concur receipt images with AWS Textract, validates the extracted vendor and amount against the report line, and flags mismatches.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['textract'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur reimbursement chaser', - prompt: - 'Build a scheduled workflow that finds SAP Concur reports stuck pending more than 7 days, sends the approver a reminder, and writes the chase log to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur travel reconciler', - prompt: - 'Create a workflow that reconciles SAP Concur travel bookings with corporate card transactions, flags missing receipts, and writes a reconciliation table for finance.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise'], - }, - { - icon: SapConcurIcon, - title: 'SAP Concur budget watcher', - prompt: - 'Build a scheduled monthly workflow that aggregates SAP Concur spend per department, compares against budget, and pings managers in Teams when overspend is projected.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - alsoIntegrations: ['microsoft_teams'], - }, - ], - skills: [ - { - name: 'review-expense-reports', - description: - 'List submitted SAP Concur expense reports, inspect line items, and flag policy exceptions.', - content: - '# Review Expense Reports\n\nSurface expense reports that need attention and check them against policy.\n\n## Steps\n1. Run List Expense Reports to pull recently submitted reports, or List Reports To Approve for items awaiting the current approver.\n2. For each report of interest, run Get Expense Report and List Expenses to read the individual line items, then List Exceptions to see Concur policy flags.\n3. Summarize totals, flagged line items, and any missing receipts.\n\n## Output\nReturn a per-report summary with the report ID, owner, total amount, and a list of policy exceptions or anomalies that warrant follow-up.', - }, - { - name: 'route-report-approval', - description: 'Approve or send back a submitted SAP Concur expense report after review.', - content: - '# Route Report Approval\n\nAct on an expense report once a review decision is made.\n\n## Steps\n1. Confirm the report ID and the decision.\n2. To approve, run Approve Expense Report. To return it for correction, run Send Back Expense Report with a clear comment explaining what must change.\n3. Optionally run Create Report Comment first to leave context for the submitter.\n\n## Output\nConfirm the report ID, the action taken (approved or sent back), and the comment provided so the decision is auditable.', - }, - { - name: 'capture-quick-expense', - description: - 'Create a quick expense in SAP Concur from a receipt, attaching the receipt image.', - content: - '# Capture Quick Expense\n\nLog an out-of-pocket expense quickly, with the receipt attached.\n\n## Steps\n1. If you have a receipt image, run Upload Receipt Image and keep the returned receipt ID, or use Create Quick Expense (With Image) to do both in one step.\n2. Run Create Quick Expense with the vendor, amount, currency, and transaction date.\n3. Verify the entry with Get Expense.\n\n## Output\nReport the created quick expense ID, the captured vendor and amount, and confirm the receipt image is attached.', - }, - { - name: 'manage-travel-requests', - description: - 'List and act on SAP Concur travel requests, moving them through the approval workflow.', - content: - '# Manage Travel Requests\n\nHandle pre-trip travel requests through their approval lifecycle.\n\n## Steps\n1. Run List Travel Requests to find pending requests, then Get Travel Request for full detail on a specific one.\n2. Review the expected expenses and any linked cash advance via Get Request Cash Advance.\n3. Run Move Travel Request (Workflow Action) to advance, approve, or send back the request based on the decision.\n\n## Output\nReturn the travel request ID, destination, estimated cost, and the workflow action applied so the trip approval state is clear.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sap_s4hana.display.ts b/apps/sim/blocks/blocks/sap_s4hana.display.ts index 097db3065d6..33d024f4d39 100644 --- a/apps/sim/blocks/blocks/sap_s4hana.display.ts +++ b/apps/sim/blocks/blocks/sap_s4hana.display.ts @@ -1,6 +1,6 @@ import { SapS4HanaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SapS4HanaBlockDisplay = { type: 'sap_s4hana', @@ -14,3 +14,106 @@ export const SapS4HanaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sap_s4hana', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const SapS4HanaBlockMeta = { + tags: ['automation'], + url: 'https://www.sap.com/products/erp/s4hana.html', + templates: [ + { + icon: SapS4HanaIcon, + title: 'SAP business partner sync', + prompt: + 'Build a workflow that takes new customer rows from a CRM-backed table and creates or updates SAP S/4HANA business partners via the API_BUSINESS_PARTNER service, mapping person and organization categories correctly so finance and sales stay aligned.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'sync'], + }, + { + icon: SapS4HanaIcon, + title: 'SAP sales order monitor', + prompt: + 'Create a scheduled workflow that lists open SAP S/4HANA sales orders, flags orders past their expected delivery date, summarizes top blockers, logs them to a tracking table, and emails the operations leads a daily prioritized list.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'monitoring'], + }, + { + icon: SapS4HanaIcon, + title: 'SAP supplier invoice intake', + prompt: + 'Build a workflow that ingests inbound supplier invoice PDFs from Gmail, extracts header and line-item data with an agent, validates the vendor against SAP S/4HANA suppliers, creates the supplier invoice via OData, and writes the outcome to a finance audit table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: SapS4HanaIcon, + title: 'SAP billing reconciliation', + prompt: + 'Create a scheduled workflow that pulls SAP S/4HANA billing documents, joins them against your CRM revenue table, flags mismatches in amounts or customers, and emails finance a reconciliation report file with the specific rows to investigate.', + modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'reporting'], + }, + { + icon: SapS4HanaIcon, + title: 'SAP delivery exception alerts', + prompt: + 'Build a workflow that runs every hour, lists SAP S/4HANA outbound and inbound deliveries with delays or missing reference documents, classifies the exception, posts a Slack alert to the operations channel, and updates a remediation tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SapS4HanaIcon, + title: 'SAP stock-level digest', + prompt: + 'Create a scheduled daily workflow that queries SAP S/4HANA for product stock and material document movements, identifies SKUs trending toward stock-out, writes a prioritized digest file, and Slacks the supply chain team for action.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['operations', 'enterprise', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SapS4HanaIcon, + title: 'Purchase requisition router', + prompt: + 'Build a workflow exposed to internal users as a form that captures purchase requisition details, classifies the request, creates the requisition in SAP S/4HANA via OData, posts the requisition number back to the requester, and logs the request in a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'enterprise', 'automation'], + }, + ], + skills: [ + { + name: 'look-up-business-partner', + description: + 'Find a customer, supplier, or business partner in SAP S4HANA and return their master data.', + content: + '# Look Up Business Partner\n\nRetrieve master data for a customer, supplier, or general business partner.\n\n## Steps\n1. Run List Business Partners (or List Customers / List Suppliers for the typed view) with a filter on name, ID, or other criteria.\n2. Once the right record is identified, run Get Business Partner, Get Customer, or Get Supplier to pull full detail.\n3. Note key fields such as the partner ID, addresses, roles, and payment terms.\n\n## Output\nReturn the matched partner ID and the relevant master-data fields, and call out if no match or multiple matches were found.', + }, + { + name: 'check-sales-order-status', + description: + 'Look up a SAP S4HANA sales order and trace its related deliveries and billing documents.', + content: + '# Check Sales Order Status\n\nTrace a sales order from creation through delivery and billing.\n\n## Steps\n1. Run List Sales Orders to find the order, or Get Sales Order if you already have the order number.\n2. Run List Outbound Deliveries and List Billing Documents to find the delivery and invoice tied to that order.\n3. Get any specific delivery or billing document for line-level detail.\n\n## Output\nReturn the sales order number, its status, the linked delivery numbers, and billing document numbers so the order-to-cash state is clear.', + }, + { + name: 'create-purchase-requisition', + description: + 'Create a purchase requisition in SAP S4HANA via OData from supplied line-item details.', + content: + '# Create Purchase Requisition\n\nRaise a purchase requisition for procurement.\n\n## Steps\n1. Gather the requisition header and line items: material or product, quantity, plant, and delivery date.\n2. Optionally run List Products and Get Product to confirm material numbers before submitting.\n3. Run Create Purchase Requisition with the assembled payload.\n4. Confirm by running Get Purchase Requisition on the returned number.\n\n## Output\nReport the created purchase requisition number and a summary of its line items, and surface any OData validation error verbatim.', + }, + { + name: 'check-material-stock', + description: + 'Read current material stock and recent material documents for an item in SAP S4HANA.', + content: + '# Check Material Stock\n\nReport on-hand stock and recent inventory movements for a material.\n\n## Steps\n1. Run List Material Stock filtered by the material and plant to read current quantities.\n2. Run List Material Documents to see recent goods movements for that material, and Get Material Document for line detail on a specific posting.\n3. Compare on-hand stock against expected levels.\n\n## Output\nReturn the material number, plant, current stock quantity, and a short list of recent material movements with their document numbers.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sap_s4hana.ts b/apps/sim/blocks/blocks/sap_s4hana.ts index cfb983f6795..28f8c4fbc86 100644 --- a/apps/sim/blocks/blocks/sap_s4hana.ts +++ b/apps/sim/blocks/blocks/sap_s4hana.ts @@ -1,6 +1,5 @@ -import { SapS4HanaIcon } from '@/components/icons' import { SapS4HanaBlockDisplay } from '@/blocks/blocks/sap_s4hana.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { SapProxyResponse } from '@/tools/sap_s4hana/types' @@ -1199,106 +1198,3 @@ Return ONLY the JSON array - no explanations, no extra text.`, data: { type: 'json', description: 'Parsed OData payload (entity, collection, or null)' }, }, } - -export const SapS4HanaBlockMeta = { - tags: ['automation'], - url: 'https://www.sap.com/products/erp/s4hana.html', - templates: [ - { - icon: SapS4HanaIcon, - title: 'SAP business partner sync', - prompt: - 'Build a workflow that takes new customer rows from a CRM-backed table and creates or updates SAP S/4HANA business partners via the API_BUSINESS_PARTNER service, mapping person and organization categories correctly so finance and sales stay aligned.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'sync'], - }, - { - icon: SapS4HanaIcon, - title: 'SAP sales order monitor', - prompt: - 'Create a scheduled workflow that lists open SAP S/4HANA sales orders, flags orders past their expected delivery date, summarizes top blockers, logs them to a tracking table, and emails the operations leads a daily prioritized list.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'monitoring'], - }, - { - icon: SapS4HanaIcon, - title: 'SAP supplier invoice intake', - prompt: - 'Build a workflow that ingests inbound supplier invoice PDFs from Gmail, extracts header and line-item data with an agent, validates the vendor against SAP S/4HANA suppliers, creates the supplier invoice via OData, and writes the outcome to a finance audit table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: SapS4HanaIcon, - title: 'SAP billing reconciliation', - prompt: - 'Create a scheduled workflow that pulls SAP S/4HANA billing documents, joins them against your CRM revenue table, flags mismatches in amounts or customers, and emails finance a reconciliation report file with the specific rows to investigate.', - modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'reporting'], - }, - { - icon: SapS4HanaIcon, - title: 'SAP delivery exception alerts', - prompt: - 'Build a workflow that runs every hour, lists SAP S/4HANA outbound and inbound deliveries with delays or missing reference documents, classifies the exception, posts a Slack alert to the operations channel, and updates a remediation tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SapS4HanaIcon, - title: 'SAP stock-level digest', - prompt: - 'Create a scheduled daily workflow that queries SAP S/4HANA for product stock and material document movements, identifies SKUs trending toward stock-out, writes a prioritized digest file, and Slacks the supply chain team for action.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['operations', 'enterprise', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SapS4HanaIcon, - title: 'Purchase requisition router', - prompt: - 'Build a workflow exposed to internal users as a form that captures purchase requisition details, classifies the request, creates the requisition in SAP S/4HANA via OData, posts the requisition number back to the requester, and logs the request in a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'enterprise', 'automation'], - }, - ], - skills: [ - { - name: 'look-up-business-partner', - description: - 'Find a customer, supplier, or business partner in SAP S4HANA and return their master data.', - content: - '# Look Up Business Partner\n\nRetrieve master data for a customer, supplier, or general business partner.\n\n## Steps\n1. Run List Business Partners (or List Customers / List Suppliers for the typed view) with a filter on name, ID, or other criteria.\n2. Once the right record is identified, run Get Business Partner, Get Customer, or Get Supplier to pull full detail.\n3. Note key fields such as the partner ID, addresses, roles, and payment terms.\n\n## Output\nReturn the matched partner ID and the relevant master-data fields, and call out if no match or multiple matches were found.', - }, - { - name: 'check-sales-order-status', - description: - 'Look up a SAP S4HANA sales order and trace its related deliveries and billing documents.', - content: - '# Check Sales Order Status\n\nTrace a sales order from creation through delivery and billing.\n\n## Steps\n1. Run List Sales Orders to find the order, or Get Sales Order if you already have the order number.\n2. Run List Outbound Deliveries and List Billing Documents to find the delivery and invoice tied to that order.\n3. Get any specific delivery or billing document for line-level detail.\n\n## Output\nReturn the sales order number, its status, the linked delivery numbers, and billing document numbers so the order-to-cash state is clear.', - }, - { - name: 'create-purchase-requisition', - description: - 'Create a purchase requisition in SAP S4HANA via OData from supplied line-item details.', - content: - '# Create Purchase Requisition\n\nRaise a purchase requisition for procurement.\n\n## Steps\n1. Gather the requisition header and line items: material or product, quantity, plant, and delivery date.\n2. Optionally run List Products and Get Product to confirm material numbers before submitting.\n3. Run Create Purchase Requisition with the assembled payload.\n4. Confirm by running Get Purchase Requisition on the returned number.\n\n## Output\nReport the created purchase requisition number and a summary of its line items, and surface any OData validation error verbatim.', - }, - { - name: 'check-material-stock', - description: - 'Read current material stock and recent material documents for an item in SAP S4HANA.', - content: - '# Check Material Stock\n\nReport on-hand stock and recent inventory movements for a material.\n\n## Steps\n1. Run List Material Stock filtered by the material and plant to read current quantities.\n2. Run List Material Documents to see recent goods movements for that material, and Get Material Document for line detail on a specific posting.\n3. Compare on-hand stock against expected levels.\n\n## Output\nReturn the material number, plant, current stock quantity, and a short list of recent material movements with their document numbers.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/secrets_manager.display.ts b/apps/sim/blocks/blocks/secrets_manager.display.ts index 2f4a9ce75df..56a453c57bf 100644 --- a/apps/sim/blocks/blocks/secrets_manager.display.ts +++ b/apps/sim/blocks/blocks/secrets_manager.display.ts @@ -1,6 +1,6 @@ import { SecretsManagerIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SecretsManagerBlockDisplay = { type: 'secrets_manager', @@ -14,3 +14,109 @@ export const SecretsManagerBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/secrets_manager', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const SecretsManagerBlockMeta = { + tags: ['cloud', 'secrets-management'], + url: 'https://aws.amazon.com/secrets-manager', + templates: [ + { + icon: SecretsManagerIcon, + title: 'Secrets Manager scheduled rotation', + prompt: + 'Build a scheduled workflow that lists AWS Secrets Manager secrets, generates a new value for each secret past its rotation window, updates it with the new value, and writes the rotation status to a compliance table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager inventory auditor', + prompt: + 'Create a scheduled workflow that lists all AWS Secrets Manager secrets, flags ones missing descriptions or older than a chosen age, writes a security review, and posts the findings to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager stale-secret cleaner', + prompt: + 'Build a scheduled workflow that lists AWS Secrets Manager secrets, identifies ones created before a chosen cutoff, requests owner approval in Slack, deletes the approved secrets, and writes the cleanup audit.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager + Infisical mirror', + prompt: + 'Create a workflow that mirrors secrets between AWS Secrets Manager and Infisical for cross-cloud applications, normalizes naming, and writes a sync log.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + alsoIntegrations: ['infisical'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager break-glass retrieval', + prompt: + 'Build a workflow that gates retrieval of a sensitive AWS Secrets Manager secret behind a Slack approval, captures the requester and justification, fetches the secret only after sign-off, and writes the audit record.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager + 1Password bridge', + prompt: + 'Create a workflow that bridges select AWS Secrets Manager secrets into 1Password for human-shared credentials while keeping access logs aligned for audit.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + alsoIntegrations: ['onepassword'], + }, + { + icon: SecretsManagerIcon, + title: 'Secrets Manager change watcher', + prompt: + 'Build a scheduled workflow that polls AWS Secrets Manager secret version IDs, compares them against a baseline stored in a table, and pings the security Slack channel when a secret changes unexpectedly.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'rotate-secret-value', + description: + 'Update a stored secret in AWS Secrets Manager with a new value as part of a rotation flow. Use to push refreshed credentials without manual console edits.', + content: + '# Rotate Secret Value\n\nUpdate a secret with a new value.\n\n## Steps\n1. Confirm the target secret exists by getting it (do not log the returned value).\n2. Obtain the new secret value to store, as a string or JSON key/value payload.\n3. Update the secret with the new value, creating a new version.\n4. Verify by getting the secret and checking the updated version metadata, not the raw value.\n\n## Output\nConfirm the secret name and that a new version was created. Never print the secret value itself.', + }, + { + name: 'audit-secret-inventory', + description: + 'List secrets in AWS Secrets Manager and report metadata like last-changed and rotation status. Use for hygiene checks and finding stale secrets.', + content: + '# Audit Secret Inventory\n\nReport on the secrets that exist without exposing their values.\n\n## Steps\n1. List secrets to enumerate names, descriptions, and tags.\n2. For each secret of interest, read metadata such as last changed and last rotated dates.\n3. Flag secrets that are stale, undescribed, or appear unused.\n4. Summarize without ever fetching or printing secret values.\n\n## Output\nAn inventory summary: secret names with last-changed and rotation status, and stale or unrotated secrets called out. No secret values.', + }, + { + name: 'store-new-secret', + description: + 'Create a new secret in AWS Secrets Manager from a provided credential or generated value. Use to register app credentials, API keys, or DB passwords centrally.', + content: + '# Store New Secret\n\nRegister a new credential in Secrets Manager.\n\n## Steps\n1. Choose a clear hierarchical name for the secret, such as my-app/prod/db-password.\n2. Assemble the value to store — a plain string, or a JSON object of key/value pairs for structured credentials.\n3. Create the secret with that name, value, and a description of what it is and where it is used.\n4. Confirm creation by reading back the version metadata, not the value.\n\n## Output\nConfirm the secret name, ARN, and new version ID. Never echo the stored secret value back.', + }, + { + name: 'decommission-secret', + description: + 'Schedule deletion of a secret in AWS Secrets Manager with a recovery window so it can be restored if needed. Use to retire unused or rotated-out credentials safely.', + content: + '# Decommission Secret\n\nRetire a secret without permanently losing it immediately.\n\n## Steps\n1. Confirm the target secret and that nothing still depends on it.\n2. Schedule deletion with a recovery window (e.g. 30 days) so it can be restored during that period; reserve force delete for confirmed-orphaned secrets only.\n3. Record the scheduled deletion date.\n4. Re-list secrets to confirm it is marked for deletion.\n\n## Output\nConfirm the secret name and the scheduled deletion date, or that immediate deletion was requested. Do not print the secret value.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/secrets_manager.ts b/apps/sim/blocks/blocks/secrets_manager.ts index 2ff71c711ef..8d370ed12ac 100644 --- a/apps/sim/blocks/blocks/secrets_manager.ts +++ b/apps/sim/blocks/blocks/secrets_manager.ts @@ -1,6 +1,5 @@ -import { SecretsManagerIcon } from '@/components/icons' import { SecretsManagerBlockDisplay } from '@/blocks/blocks/secrets_manager.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { SecretsManagerBaseResponse } from '@/tools/secrets_manager/types' export const SecretsManagerBlock: BlockConfig = { @@ -270,109 +269,3 @@ export const SecretsManagerBlock: BlockConfig = { }, }, } - -export const SecretsManagerBlockMeta = { - tags: ['cloud', 'secrets-management'], - url: 'https://aws.amazon.com/secrets-manager', - templates: [ - { - icon: SecretsManagerIcon, - title: 'Secrets Manager scheduled rotation', - prompt: - 'Build a scheduled workflow that lists AWS Secrets Manager secrets, generates a new value for each secret past its rotation window, updates it with the new value, and writes the rotation status to a compliance table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager inventory auditor', - prompt: - 'Create a scheduled workflow that lists all AWS Secrets Manager secrets, flags ones missing descriptions or older than a chosen age, writes a security review, and posts the findings to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager stale-secret cleaner', - prompt: - 'Build a scheduled workflow that lists AWS Secrets Manager secrets, identifies ones created before a chosen cutoff, requests owner approval in Slack, deletes the approved secrets, and writes the cleanup audit.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager + Infisical mirror', - prompt: - 'Create a workflow that mirrors secrets between AWS Secrets Manager and Infisical for cross-cloud applications, normalizes naming, and writes a sync log.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - alsoIntegrations: ['infisical'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager break-glass retrieval', - prompt: - 'Build a workflow that gates retrieval of a sensitive AWS Secrets Manager secret behind a Slack approval, captures the requester and justification, fetches the secret only after sign-off, and writes the audit record.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager + 1Password bridge', - prompt: - 'Create a workflow that bridges select AWS Secrets Manager secrets into 1Password for human-shared credentials while keeping access logs aligned for audit.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - alsoIntegrations: ['onepassword'], - }, - { - icon: SecretsManagerIcon, - title: 'Secrets Manager change watcher', - prompt: - 'Build a scheduled workflow that polls AWS Secrets Manager secret version IDs, compares them against a baseline stored in a table, and pings the security Slack channel when a secret changes unexpectedly.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'rotate-secret-value', - description: - 'Update a stored secret in AWS Secrets Manager with a new value as part of a rotation flow. Use to push refreshed credentials without manual console edits.', - content: - '# Rotate Secret Value\n\nUpdate a secret with a new value.\n\n## Steps\n1. Confirm the target secret exists by getting it (do not log the returned value).\n2. Obtain the new secret value to store, as a string or JSON key/value payload.\n3. Update the secret with the new value, creating a new version.\n4. Verify by getting the secret and checking the updated version metadata, not the raw value.\n\n## Output\nConfirm the secret name and that a new version was created. Never print the secret value itself.', - }, - { - name: 'audit-secret-inventory', - description: - 'List secrets in AWS Secrets Manager and report metadata like last-changed and rotation status. Use for hygiene checks and finding stale secrets.', - content: - '# Audit Secret Inventory\n\nReport on the secrets that exist without exposing their values.\n\n## Steps\n1. List secrets to enumerate names, descriptions, and tags.\n2. For each secret of interest, read metadata such as last changed and last rotated dates.\n3. Flag secrets that are stale, undescribed, or appear unused.\n4. Summarize without ever fetching or printing secret values.\n\n## Output\nAn inventory summary: secret names with last-changed and rotation status, and stale or unrotated secrets called out. No secret values.', - }, - { - name: 'store-new-secret', - description: - 'Create a new secret in AWS Secrets Manager from a provided credential or generated value. Use to register app credentials, API keys, or DB passwords centrally.', - content: - '# Store New Secret\n\nRegister a new credential in Secrets Manager.\n\n## Steps\n1. Choose a clear hierarchical name for the secret, such as my-app/prod/db-password.\n2. Assemble the value to store — a plain string, or a JSON object of key/value pairs for structured credentials.\n3. Create the secret with that name, value, and a description of what it is and where it is used.\n4. Confirm creation by reading back the version metadata, not the value.\n\n## Output\nConfirm the secret name, ARN, and new version ID. Never echo the stored secret value back.', - }, - { - name: 'decommission-secret', - description: - 'Schedule deletion of a secret in AWS Secrets Manager with a recovery window so it can be restored if needed. Use to retire unused or rotated-out credentials safely.', - content: - '# Decommission Secret\n\nRetire a secret without permanently losing it immediately.\n\n## Steps\n1. Confirm the target secret and that nothing still depends on it.\n2. Schedule deletion with a recovery window (e.g. 30 days) so it can be restored during that period; reserve force delete for confirmed-orphaned secrets only.\n3. Record the scheduled deletion date.\n4. Re-list secrets to confirm it is marked for deletion.\n\n## Output\nConfirm the secret name and the scheduled deletion date, or that immediate deletion was requested. Do not print the secret value.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sendblue.display.ts b/apps/sim/blocks/blocks/sendblue.display.ts index 29c0998d50e..99d45179c06 100644 --- a/apps/sim/blocks/blocks/sendblue.display.ts +++ b/apps/sim/blocks/blocks/sendblue.display.ts @@ -1,6 +1,6 @@ import { SendblueIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SendblueBlockDisplay = { type: 'sendblue', @@ -14,3 +14,105 @@ export const SendblueBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sendblue', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const SendblueBlockMeta = { + tags: ['messaging', 'automation', 'webhooks'], + url: 'https://sendblue.com', + templates: [ + { + icon: SendblueIcon, + title: 'Sendblue lead speed-to-text', + prompt: + 'Build a workflow that fires when a new lead submits a form, drafts a friendly intro, and sends it as an iMessage via Sendblue within seconds so reps reach hot leads while they are still interested.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['messaging', 'sales', 'automation'], + alsoIntegrations: ['typeform'], + }, + { + icon: SendblueIcon, + title: 'Sendblue appointment reminders', + prompt: + "Create a scheduled workflow that reads tomorrow's appointments from a table and sends each customer a personalized Sendblue iMessage reminder with the time and a reschedule link.", + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation', 'scheduling'], + }, + { + icon: SendblueIcon, + title: 'Sendblue inbound reply autoresponder', + prompt: + 'Build a workflow triggered when a Sendblue message is received that classifies the inbound text, drafts a context-aware reply with an agent, and sends it back to the same number as an iMessage.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['messaging', 'automation', 'support'], + }, + { + icon: SendblueIcon, + title: 'Sendblue iMessage vs SMS routing', + prompt: + 'Create a workflow that evaluates whether a recipient number supports iMessage with Sendblue, then sends a rich iMessage when supported or a plain SMS fallback otherwise.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['messaging', 'automation'], + }, + { + icon: SendblueIcon, + title: 'Sendblue order-status notifier', + prompt: + 'Create a workflow triggered when an order ships that looks up the customer phone number and sends a Sendblue iMessage with the tracking number and estimated delivery date.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation'], + alsoIntegrations: ['shopify'], + }, + { + icon: SendblueIcon, + title: 'Sendblue delivery-failure alerts', + prompt: + 'Build a workflow triggered by a Sendblue message status update that, when the status is ERROR, posts the failing number and error message to a Slack channel so the team can follow up.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation', 'incident-management'], + alsoIntegrations: ['slack'], + }, + { + icon: SendblueIcon, + title: 'Sendblue group broadcast', + prompt: + 'Create a workflow that reads a list of VIP customers from a table and sends them a single Sendblue group iMessage announcing a new product launch with an image attachment.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['messaging', 'marketing', 'automation'], + }, + { + icon: SendblueIcon, + title: 'Sendblue conversational support agent', + prompt: + 'Build a workflow triggered on inbound Sendblue messages that shows a typing indicator, looks up the customer in a table, answers their question with an agent, and replies over iMessage.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['messaging', 'support', 'automation'], + }, + ], + skills: [ + { + name: 'send-imessage-notification', + description: 'Send an iMessage or SMS notification to a single recipient via Sendblue.', + content: + '# Send an iMessage or SMS Notification\n\nDeliver a message to one recipient through your Sendblue number.\n\n## Steps\n1. Choose the Send Message operation.\n2. Enter the Recipient Number and your From Number in E.164 format (for example +19998887777).\n3. Write the Message text. To send media instead of or alongside text, add a Media URL.\n4. Provide your Sendblue API Key ID and API Secret Key.\n\n## Output\nReturn the message status (QUEUED, SENT, DELIVERED, ERROR) and the message handle so the send can be tracked.', + }, + { + name: 'route-imessage-or-sms', + description: 'Check whether a number supports iMessage before sending with Sendblue.', + content: + '# Route iMessage vs SMS\n\nDecide how to reach a recipient based on their service.\n\n## Steps\n1. Use the Evaluate Service operation with the Recipient Number to learn whether the number supports iMessage or only SMS.\n2. Branch on the returned service value.\n3. Send a rich iMessage when supported, or a plain SMS fallback otherwise, using the Send Message operation.\n\n## Output\nReturn the evaluated number and its supported service so downstream steps can branch correctly.', + }, + { + name: 'reply-to-inbound-message', + description: 'Trigger on an inbound Sendblue message and reply automatically.', + content: + '# Reply to an Inbound Message\n\nRespond to customers as soon as they text in.\n\n## Steps\n1. Add the Sendblue Message Received trigger and point your Sendblue Receive Webhook at the generated URL.\n2. Read the inbound content, from_number, and service from the trigger output.\n3. Draft a reply with an agent and send it back with the Send Message operation, using the from_number as the recipient.\n\n## Output\nReturn the reply message handle and status so the conversation can be tracked.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sendblue.ts b/apps/sim/blocks/blocks/sendblue.ts index b79e85c9a28..5fad0482db9 100644 --- a/apps/sim/blocks/blocks/sendblue.ts +++ b/apps/sim/blocks/blocks/sendblue.ts @@ -1,6 +1,5 @@ -import { SendblueIcon } from '@/components/icons' import { SendblueBlockDisplay } from '@/blocks/blocks/sendblue.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' @@ -270,105 +269,3 @@ export const SendblueBlock: BlockConfig = { available: ['sendblue_message_received', 'sendblue_message_status_updated'], }, } - -export const SendblueBlockMeta = { - tags: ['messaging', 'automation', 'webhooks'], - url: 'https://sendblue.com', - templates: [ - { - icon: SendblueIcon, - title: 'Sendblue lead speed-to-text', - prompt: - 'Build a workflow that fires when a new lead submits a form, drafts a friendly intro, and sends it as an iMessage via Sendblue within seconds so reps reach hot leads while they are still interested.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['messaging', 'sales', 'automation'], - alsoIntegrations: ['typeform'], - }, - { - icon: SendblueIcon, - title: 'Sendblue appointment reminders', - prompt: - "Create a scheduled workflow that reads tomorrow's appointments from a table and sends each customer a personalized Sendblue iMessage reminder with the time and a reschedule link.", - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation', 'scheduling'], - }, - { - icon: SendblueIcon, - title: 'Sendblue inbound reply autoresponder', - prompt: - 'Build a workflow triggered when a Sendblue message is received that classifies the inbound text, drafts a context-aware reply with an agent, and sends it back to the same number as an iMessage.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['messaging', 'automation', 'support'], - }, - { - icon: SendblueIcon, - title: 'Sendblue iMessage vs SMS routing', - prompt: - 'Create a workflow that evaluates whether a recipient number supports iMessage with Sendblue, then sends a rich iMessage when supported or a plain SMS fallback otherwise.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['messaging', 'automation'], - }, - { - icon: SendblueIcon, - title: 'Sendblue order-status notifier', - prompt: - 'Create a workflow triggered when an order ships that looks up the customer phone number and sends a Sendblue iMessage with the tracking number and estimated delivery date.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation'], - alsoIntegrations: ['shopify'], - }, - { - icon: SendblueIcon, - title: 'Sendblue delivery-failure alerts', - prompt: - 'Build a workflow triggered by a Sendblue message status update that, when the status is ERROR, posts the failing number and error message to a Slack channel so the team can follow up.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation', 'incident-management'], - alsoIntegrations: ['slack'], - }, - { - icon: SendblueIcon, - title: 'Sendblue group broadcast', - prompt: - 'Create a workflow that reads a list of VIP customers from a table and sends them a single Sendblue group iMessage announcing a new product launch with an image attachment.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['messaging', 'marketing', 'automation'], - }, - { - icon: SendblueIcon, - title: 'Sendblue conversational support agent', - prompt: - 'Build a workflow triggered on inbound Sendblue messages that shows a typing indicator, looks up the customer in a table, answers their question with an agent, and replies over iMessage.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['messaging', 'support', 'automation'], - }, - ], - skills: [ - { - name: 'send-imessage-notification', - description: 'Send an iMessage or SMS notification to a single recipient via Sendblue.', - content: - '# Send an iMessage or SMS Notification\n\nDeliver a message to one recipient through your Sendblue number.\n\n## Steps\n1. Choose the Send Message operation.\n2. Enter the Recipient Number and your From Number in E.164 format (for example +19998887777).\n3. Write the Message text. To send media instead of or alongside text, add a Media URL.\n4. Provide your Sendblue API Key ID and API Secret Key.\n\n## Output\nReturn the message status (QUEUED, SENT, DELIVERED, ERROR) and the message handle so the send can be tracked.', - }, - { - name: 'route-imessage-or-sms', - description: 'Check whether a number supports iMessage before sending with Sendblue.', - content: - '# Route iMessage vs SMS\n\nDecide how to reach a recipient based on their service.\n\n## Steps\n1. Use the Evaluate Service operation with the Recipient Number to learn whether the number supports iMessage or only SMS.\n2. Branch on the returned service value.\n3. Send a rich iMessage when supported, or a plain SMS fallback otherwise, using the Send Message operation.\n\n## Output\nReturn the evaluated number and its supported service so downstream steps can branch correctly.', - }, - { - name: 'reply-to-inbound-message', - description: 'Trigger on an inbound Sendblue message and reply automatically.', - content: - '# Reply to an Inbound Message\n\nRespond to customers as soon as they text in.\n\n## Steps\n1. Add the Sendblue Message Received trigger and point your Sendblue Receive Webhook at the generated URL.\n2. Read the inbound content, from_number, and service from the trigger output.\n3. Draft a reply with an agent and send it back with the Send Message operation, using the from_number as the recipient.\n\n## Output\nReturn the reply message handle and status so the conversation can be tracked.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sendgrid.display.ts b/apps/sim/blocks/blocks/sendgrid.display.ts index aa2c5988799..c3897bce947 100644 --- a/apps/sim/blocks/blocks/sendgrid.display.ts +++ b/apps/sim/blocks/blocks/sendgrid.display.ts @@ -1,6 +1,6 @@ import { SendgridIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SendGridBlockDisplay = { type: 'sendgrid', @@ -14,3 +14,107 @@ export const SendGridBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sendgrid', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const SendGridBlockMeta = { + tags: ['email-marketing', 'messaging'], + url: 'https://www.twilio.com/en-us/sendgrid', + templates: [ + { + icon: SendgridIcon, + title: 'SendGrid transactional pipeline', + prompt: + 'Build a workflow that listens for product events from my tables — signup, password reset, receipt — picks the matching SendGrid dynamic template, populates the variables, sends the email, and writes the message ID back to the table for audit.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'communication'], + }, + { + icon: SendgridIcon, + title: 'SendGrid send-failure monitor', + prompt: + 'Create a workflow that sends emails through SendGrid, logs each send result and any error to a delivery table, and posts a Slack alert summarizing failure patterns by recipient domain and template when the failure rate crosses a threshold.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SendgridIcon, + title: 'SendGrid + Resend failover', + prompt: + 'Build a workflow that sends transactional emails through SendGrid by default and automatically falls back to Resend when the primary send fails or rate limits, logging every send and the provider used to a delivery table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'monitoring', 'enterprise'], + alsoIntegrations: ['resend'], + }, + { + icon: SendgridIcon, + title: 'SendGrid contact list cleaner', + prompt: + 'Create a scheduled workflow that searches SendGrid marketing contacts for invalid or duplicate entries, removes the bad addresses, merges duplicates, and writes a cleanup report to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'analysis'], + }, + { + icon: SendgridIcon, + title: 'SendGrid + SES enterprise sender', + prompt: + 'Build a workflow that splits transactional traffic between SendGrid and AWS SES based on message category and recipient region, balances volume to stay under per-provider limits, and writes provider, status, and latency to a delivery table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation', 'monitoring'], + alsoIntegrations: ['ses'], + }, + { + icon: SendgridIcon, + title: 'SendGrid + Mailgun send scorecard', + prompt: + 'Create a scheduled weekly workflow that sends categorized test messages through both SendGrid and Mailgun, records each provider response, latency, and error to a delivery table, and generates a scorecard file recommending which provider to use per send category.', + modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['analysis', 'reporting', 'enterprise'], + alsoIntegrations: ['mailgun'], + }, + { + icon: SendgridIcon, + title: 'SendGrid segmented list builder', + prompt: + 'Build a workflow that reads a freshly scored audience from a table, creates a new SendGrid marketing list, adds each matching contact to the list, and removes anyone who no longer qualifies so the segment is ready for the next campaign send.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'sync'], + }, + ], + skills: [ + { + name: 'send-transactional-email', + description: + 'Send a transactional email through SendGrid, optionally using a dynamic template and variables.', + content: + '# Send Transactional Email\n\nSend a single transactional email (receipt, confirmation, password reset) through SendGrid.\n\n## Steps\n1. Set the verified From address and the recipient To address.\n2. For a one-off message, set the Subject and Content (choose HTML or plain text). For a templated message, set the Template ID and provide Dynamic Template Data as a JSON object whose keys match the template variables.\n3. Add CC, BCC, or Reply-To addresses if needed, and attach files via Attachments.\n4. Run the Send Mail operation and capture the returned message ID.\n\n## Output\nReport whether the send succeeded and include the SendGrid message ID for later delivery tracking and audit.', + }, + { + name: 'sync-contacts-to-list', + description: + 'Add or update marketing contacts and place them on a specific SendGrid list for a campaign segment.', + content: + '# Sync Contacts to List\n\nUpsert marketing contacts and assign them to a SendGrid list so a segment is ready to receive a campaign.\n\n## Steps\n1. If the target list does not exist, run Create List with a descriptive name and keep the returned list ID.\n2. Build a JSON array of contacts, each with at least an email plus optional first name, last name, and custom fields.\n3. Run Add Contacts to List with the list ID and the contacts array.\n4. Optionally run Remove Contacts from List to drop addresses that no longer qualify for the segment.\n\n## Output\nReport the list ID, the count of contacts added, and the job ID returned for the async upsert.', + }, + { + name: 'clean-contact-list', + description: + 'Search SendGrid marketing contacts for invalid or unwanted addresses and remove them.', + content: + '# Clean Contact List\n\nFind and remove low-quality marketing contacts using SendGrid Query Language.\n\n## Steps\n1. Run Search Contacts with an SGQL query that targets the unwanted records (for example addresses matching a bad domain or stale by created date).\n2. Collect the contact IDs from the results.\n3. Run Delete Contacts with the comma-separated contact IDs, or Remove Contacts from List to drop them only from a specific segment.\n4. Record what was removed for a cleanup report.\n\n## Output\nReport the search criteria used, the number of contacts found, and how many were deleted or removed from the list.', + }, + { + name: 'create-dynamic-template', + description: + 'Create a SendGrid dynamic template and an active version with HTML and a subject line.', + content: + '# Create Dynamic Template\n\nStand up a reusable SendGrid dynamic template for a recurring transactional message.\n\n## Steps\n1. Run Create Template with a descriptive name and the dynamic generation.\n2. Keep the returned template ID.\n3. Run Create Template Version against that template ID, supplying a version name, the Template Subject (Handlebars variables allowed), and the HTML content. Set the version active so it is used on send.\n4. Optionally supply plain text content as a fallback.\n\n## Output\nReport the template ID and version, and confirm the active version is ready to reference from Send Mail operations.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sendgrid.ts b/apps/sim/blocks/blocks/sendgrid.ts index 24a42e9f431..fc7380d8d8b 100644 --- a/apps/sim/blocks/blocks/sendgrid.ts +++ b/apps/sim/blocks/blocks/sendgrid.ts @@ -1,6 +1,5 @@ -import { SendgridIcon } from '@/components/icons' import { SendGridBlockDisplay } from '@/blocks/blocks/sendgrid.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SendMailResult } from '@/tools/sendgrid/types' @@ -674,107 +673,3 @@ Return ONLY the HTML content.`, plainContent: { type: 'string', description: 'Plain text content' }, }, } - -export const SendGridBlockMeta = { - tags: ['email-marketing', 'messaging'], - url: 'https://www.twilio.com/en-us/sendgrid', - templates: [ - { - icon: SendgridIcon, - title: 'SendGrid transactional pipeline', - prompt: - 'Build a workflow that listens for product events from my tables — signup, password reset, receipt — picks the matching SendGrid dynamic template, populates the variables, sends the email, and writes the message ID back to the table for audit.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'communication'], - }, - { - icon: SendgridIcon, - title: 'SendGrid send-failure monitor', - prompt: - 'Create a workflow that sends emails through SendGrid, logs each send result and any error to a delivery table, and posts a Slack alert summarizing failure patterns by recipient domain and template when the failure rate crosses a threshold.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SendgridIcon, - title: 'SendGrid + Resend failover', - prompt: - 'Build a workflow that sends transactional emails through SendGrid by default and automatically falls back to Resend when the primary send fails or rate limits, logging every send and the provider used to a delivery table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'monitoring', 'enterprise'], - alsoIntegrations: ['resend'], - }, - { - icon: SendgridIcon, - title: 'SendGrid contact list cleaner', - prompt: - 'Create a scheduled workflow that searches SendGrid marketing contacts for invalid or duplicate entries, removes the bad addresses, merges duplicates, and writes a cleanup report to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'analysis'], - }, - { - icon: SendgridIcon, - title: 'SendGrid + SES enterprise sender', - prompt: - 'Build a workflow that splits transactional traffic between SendGrid and AWS SES based on message category and recipient region, balances volume to stay under per-provider limits, and writes provider, status, and latency to a delivery table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation', 'monitoring'], - alsoIntegrations: ['ses'], - }, - { - icon: SendgridIcon, - title: 'SendGrid + Mailgun send scorecard', - prompt: - 'Create a scheduled weekly workflow that sends categorized test messages through both SendGrid and Mailgun, records each provider response, latency, and error to a delivery table, and generates a scorecard file recommending which provider to use per send category.', - modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['analysis', 'reporting', 'enterprise'], - alsoIntegrations: ['mailgun'], - }, - { - icon: SendgridIcon, - title: 'SendGrid segmented list builder', - prompt: - 'Build a workflow that reads a freshly scored audience from a table, creates a new SendGrid marketing list, adds each matching contact to the list, and removes anyone who no longer qualifies so the segment is ready for the next campaign send.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'sync'], - }, - ], - skills: [ - { - name: 'send-transactional-email', - description: - 'Send a transactional email through SendGrid, optionally using a dynamic template and variables.', - content: - '# Send Transactional Email\n\nSend a single transactional email (receipt, confirmation, password reset) through SendGrid.\n\n## Steps\n1. Set the verified From address and the recipient To address.\n2. For a one-off message, set the Subject and Content (choose HTML or plain text). For a templated message, set the Template ID and provide Dynamic Template Data as a JSON object whose keys match the template variables.\n3. Add CC, BCC, or Reply-To addresses if needed, and attach files via Attachments.\n4. Run the Send Mail operation and capture the returned message ID.\n\n## Output\nReport whether the send succeeded and include the SendGrid message ID for later delivery tracking and audit.', - }, - { - name: 'sync-contacts-to-list', - description: - 'Add or update marketing contacts and place them on a specific SendGrid list for a campaign segment.', - content: - '# Sync Contacts to List\n\nUpsert marketing contacts and assign them to a SendGrid list so a segment is ready to receive a campaign.\n\n## Steps\n1. If the target list does not exist, run Create List with a descriptive name and keep the returned list ID.\n2. Build a JSON array of contacts, each with at least an email plus optional first name, last name, and custom fields.\n3. Run Add Contacts to List with the list ID and the contacts array.\n4. Optionally run Remove Contacts from List to drop addresses that no longer qualify for the segment.\n\n## Output\nReport the list ID, the count of contacts added, and the job ID returned for the async upsert.', - }, - { - name: 'clean-contact-list', - description: - 'Search SendGrid marketing contacts for invalid or unwanted addresses and remove them.', - content: - '# Clean Contact List\n\nFind and remove low-quality marketing contacts using SendGrid Query Language.\n\n## Steps\n1. Run Search Contacts with an SGQL query that targets the unwanted records (for example addresses matching a bad domain or stale by created date).\n2. Collect the contact IDs from the results.\n3. Run Delete Contacts with the comma-separated contact IDs, or Remove Contacts from List to drop them only from a specific segment.\n4. Record what was removed for a cleanup report.\n\n## Output\nReport the search criteria used, the number of contacts found, and how many were deleted or removed from the list.', - }, - { - name: 'create-dynamic-template', - description: - 'Create a SendGrid dynamic template and an active version with HTML and a subject line.', - content: - '# Create Dynamic Template\n\nStand up a reusable SendGrid dynamic template for a recurring transactional message.\n\n## Steps\n1. Run Create Template with a descriptive name and the dynamic generation.\n2. Keep the returned template ID.\n3. Run Create Template Version against that template ID, supplying a version name, the Template Subject (Handlebars variables allowed), and the HTML content. Set the version active so it is used on send.\n4. Optionally supply plain text content as a fallback.\n\n## Output\nReport the template ID and version, and confirm the active version is ready to reference from Send Mail operations.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sentry.display.ts b/apps/sim/blocks/blocks/sentry.display.ts index 1d3564b84e3..cc7424cb63d 100644 --- a/apps/sim/blocks/blocks/sentry.display.ts +++ b/apps/sim/blocks/blocks/sentry.display.ts @@ -1,6 +1,7 @@ +import { Bug } from '@/components/emcn/icons' import { SentryIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SentryBlockDisplay = { type: 'sentry', @@ -14,3 +15,110 @@ export const SentryBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sentry', integrationType: IntegrationType.Observability, } satisfies BlockDisplay + +export const SentryBlockMeta = { + tags: ['error-tracking', 'monitoring'], + url: 'https://sentry.io', + templates: [ + { + icon: Bug, + title: 'Bug triage agent', + prompt: + 'Build an agent that monitors Sentry for new errors, automatically triages them by severity and affected users, creates Linear tickets for critical issues with full stack traces, and sends a Slack notification to the on-call channel.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'automation'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: SentryIcon, + title: 'Sentry error triage', + prompt: + 'Build a scheduled workflow that polls Sentry for new unresolved issues, classifies severity, groups similar issues, creates a Linear ticket on first occurrence above the threshold, and pings the owning team in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops'], + alsoIntegrations: ['linear', 'slack'], + }, + { + icon: SentryIcon, + title: 'Sentry release health gate', + prompt: + 'Create a workflow that runs after a Vercel deploy, checks Sentry release health, and rolls back the deploy if the error rate exceeds the threshold, posting an alert to Slack.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['vercel', 'slack'], + }, + { + icon: SentryIcon, + title: 'Sentry weekly regression brief', + prompt: + 'Build a scheduled weekly workflow that compares Sentry error rates week-over-week, identifies top regressors, and writes a brief to engineering leadership in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SentryIcon, + title: 'Sentry source-map verifier', + prompt: + 'Create a scheduled workflow that scans Sentry for issues with missing or stale source maps, writes a tracking table, and opens Linear tickets for the worst offenders.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: SentryIcon, + title: 'Sentry customer-impact mapper', + prompt: + 'Build a workflow that takes a Sentry issue and matches affected users to CRM accounts, scoring customer impact, and creates a customer-facing incident note in HubSpot for the worst-affected accounts.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'sales'], + alsoIntegrations: ['hubspot'], + }, + { + icon: SentryIcon, + title: 'Sentry release tracker on deploy', + prompt: + 'Create a workflow that watches GitHub for merges to main, creates a new Sentry release with the commit range, marks the deploy in Sentry for the production environment, and posts the release notes and linked issues to Slack so the team knows what shipped.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'ci-cd', 'automation'], + alsoIntegrations: ['github', 'slack'], + }, + ], + skills: [ + { + name: 'triage-unresolved-errors', + description: + 'List unresolved Sentry issues, rank them by impact, and summarize the most urgent errors to fix.', + content: + '# Triage Unresolved Errors\n\nProduce a prioritized view of the Sentry errors that most need attention.\n\n## Steps\n1. Run List Issues with the query is:unresolved, sorting by frequency or user count and setting a stats period such as 24h or 7d.\n2. For the top issues, run Get Issue to pull the title, culprit, event count, and number of affected users.\n3. Rank by a blend of event volume, affected users, and recency.\n\n## Output\nReturn a ranked list of issues with their ID, title, event count, affected users, and a one-line recommendation for each. Link each issue so an engineer can open it directly.', + }, + { + name: 'resolve-or-assign-issue', + description: + 'Update a Sentry issue to change status, assign an owner, or bookmark it for follow-up.', + content: + '# Resolve or Assign Issue\n\nAct on a specific Sentry issue once a decision has been made.\n\n## Steps\n1. Identify the issue ID (from a triage step or a notification).\n2. Run Update Issue, setting the new status (resolved, ignored, or resolved in next release) as appropriate.\n3. To route ownership, set Assign To with a user ID or email. Bookmark or subscribe if the team wants to track it.\n\n## Output\nConfirm the issue ID, its new status, and the assignee, so the change is auditable.', + }, + { + name: 'investigate-issue-events', + description: + 'Pull the events behind a Sentry issue to inspect impacted users, environments, and context.', + content: + '# Investigate Issue Events\n\nDrill into the raw events for an issue to understand who and what is affected.\n\n## Steps\n1. Run List Events for the project, optionally filtering by an issue ID and an events search query (for example user.email or environment filters).\n2. Run Get Event on a representative event ID to retrieve the full payload: tags, breadcrumbs, request context, and stack trace.\n3. Group findings by environment, release, browser, or OS.\n\n## Output\nSummarize the affected environments and users, the common context across events, and the likely trigger, citing the specific event IDs examined.', + }, + { + name: 'track-release-and-deploy', + description: + 'Create a Sentry release for a version and mark a deploy to an environment for regression tracking.', + content: + '# Track Release and Deploy\n\nRegister a new version in Sentry so errors can be attributed to the release that introduced them.\n\n## Steps\n1. Run Create Release with the version string and the comma-separated project slugs. Add the git ref, release URL, and commits JSON if available so Sentry can associate suspect commits.\n2. Run Create Deploy with the same version and the target environment (for example production), including start and finish times.\n3. Optionally run List Releases afterward to confirm the version is registered.\n\n## Output\nReport the created release version, the deploy environment, and confirm both were recorded for regression monitoring.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sentry.ts b/apps/sim/blocks/blocks/sentry.ts index ad51ba3dcc9..14548507da3 100644 --- a/apps/sim/blocks/blocks/sentry.ts +++ b/apps/sim/blocks/blocks/sentry.ts @@ -1,7 +1,5 @@ -import { Bug } from '@/components/emcn/icons' -import { SentryIcon } from '@/components/icons' import { SentryBlockDisplay } from '@/blocks/blocks/sentry.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { SentryResponse } from '@/tools/sentry/types' @@ -703,110 +701,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, hasMore: { type: 'boolean', description: 'More results available' }, }, } - -export const SentryBlockMeta = { - tags: ['error-tracking', 'monitoring'], - url: 'https://sentry.io', - templates: [ - { - icon: Bug, - title: 'Bug triage agent', - prompt: - 'Build an agent that monitors Sentry for new errors, automatically triages them by severity and affected users, creates Linear tickets for critical issues with full stack traces, and sends a Slack notification to the on-call channel.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'automation'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: SentryIcon, - title: 'Sentry error triage', - prompt: - 'Build a scheduled workflow that polls Sentry for new unresolved issues, classifies severity, groups similar issues, creates a Linear ticket on first occurrence above the threshold, and pings the owning team in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops'], - alsoIntegrations: ['linear', 'slack'], - }, - { - icon: SentryIcon, - title: 'Sentry release health gate', - prompt: - 'Create a workflow that runs after a Vercel deploy, checks Sentry release health, and rolls back the deploy if the error rate exceeds the threshold, posting an alert to Slack.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['vercel', 'slack'], - }, - { - icon: SentryIcon, - title: 'Sentry weekly regression brief', - prompt: - 'Build a scheduled weekly workflow that compares Sentry error rates week-over-week, identifies top regressors, and writes a brief to engineering leadership in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SentryIcon, - title: 'Sentry source-map verifier', - prompt: - 'Create a scheduled workflow that scans Sentry for issues with missing or stale source maps, writes a tracking table, and opens Linear tickets for the worst offenders.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: SentryIcon, - title: 'Sentry customer-impact mapper', - prompt: - 'Build a workflow that takes a Sentry issue and matches affected users to CRM accounts, scoring customer impact, and creates a customer-facing incident note in HubSpot for the worst-affected accounts.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'sales'], - alsoIntegrations: ['hubspot'], - }, - { - icon: SentryIcon, - title: 'Sentry release tracker on deploy', - prompt: - 'Create a workflow that watches GitHub for merges to main, creates a new Sentry release with the commit range, marks the deploy in Sentry for the production environment, and posts the release notes and linked issues to Slack so the team knows what shipped.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'ci-cd', 'automation'], - alsoIntegrations: ['github', 'slack'], - }, - ], - skills: [ - { - name: 'triage-unresolved-errors', - description: - 'List unresolved Sentry issues, rank them by impact, and summarize the most urgent errors to fix.', - content: - '# Triage Unresolved Errors\n\nProduce a prioritized view of the Sentry errors that most need attention.\n\n## Steps\n1. Run List Issues with the query is:unresolved, sorting by frequency or user count and setting a stats period such as 24h or 7d.\n2. For the top issues, run Get Issue to pull the title, culprit, event count, and number of affected users.\n3. Rank by a blend of event volume, affected users, and recency.\n\n## Output\nReturn a ranked list of issues with their ID, title, event count, affected users, and a one-line recommendation for each. Link each issue so an engineer can open it directly.', - }, - { - name: 'resolve-or-assign-issue', - description: - 'Update a Sentry issue to change status, assign an owner, or bookmark it for follow-up.', - content: - '# Resolve or Assign Issue\n\nAct on a specific Sentry issue once a decision has been made.\n\n## Steps\n1. Identify the issue ID (from a triage step or a notification).\n2. Run Update Issue, setting the new status (resolved, ignored, or resolved in next release) as appropriate.\n3. To route ownership, set Assign To with a user ID or email. Bookmark or subscribe if the team wants to track it.\n\n## Output\nConfirm the issue ID, its new status, and the assignee, so the change is auditable.', - }, - { - name: 'investigate-issue-events', - description: - 'Pull the events behind a Sentry issue to inspect impacted users, environments, and context.', - content: - '# Investigate Issue Events\n\nDrill into the raw events for an issue to understand who and what is affected.\n\n## Steps\n1. Run List Events for the project, optionally filtering by an issue ID and an events search query (for example user.email or environment filters).\n2. Run Get Event on a representative event ID to retrieve the full payload: tags, breadcrumbs, request context, and stack trace.\n3. Group findings by environment, release, browser, or OS.\n\n## Output\nSummarize the affected environments and users, the common context across events, and the likely trigger, citing the specific event IDs examined.', - }, - { - name: 'track-release-and-deploy', - description: - 'Create a Sentry release for a version and mark a deploy to an environment for regression tracking.', - content: - '# Track Release and Deploy\n\nRegister a new version in Sentry so errors can be attributed to the release that introduced them.\n\n## Steps\n1. Run Create Release with the version string and the comma-separated project slugs. Add the git ref, release URL, and commits JSON if available so Sentry can associate suspect commits.\n2. Run Create Deploy with the same version and the target environment (for example production), including start and finish times.\n3. Optionally run List Releases afterward to confirm the version is registered.\n\n## Output\nReport the created release version, the deploy environment, and confirm both were recorded for regression monitoring.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/serper.display.ts b/apps/sim/blocks/blocks/serper.display.ts index f0c54436af4..b5a3c8ba2df 100644 --- a/apps/sim/blocks/blocks/serper.display.ts +++ b/apps/sim/blocks/blocks/serper.display.ts @@ -1,6 +1,6 @@ import { SerperIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SerperBlockDisplay = { type: 'serper', @@ -13,3 +13,106 @@ export const SerperBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/serper', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const SerperBlockMeta = { + tags: ['web-scraping', 'seo'], + url: 'https://serper.dev', + templates: [ + { + icon: SerperIcon, + title: 'Serper SERP digest', + prompt: + 'Build a scheduled daily workflow that runs Serper searches for tracked keywords, writes the SERP positions of my domain into a tables-based SEO log, and pings on changes.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SerperIcon, + title: 'Serper competitor SERP watcher', + prompt: + 'Create a workflow that runs Serper searches for competitor keywords weekly, captures top SERP entries, and writes a competitive SEO digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SerperIcon, + title: 'Serper news monitor', + prompt: + 'Build a scheduled workflow that uses Serper news search for brand keywords, classifies each result, and posts notable mentions to a Slack PR channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SerperIcon, + title: 'Serper local-pack tracker', + prompt: + 'Create a workflow that uses Serper to track Google local-pack rankings for tracked queries by city, writes the results to a tables-based SEO log, and surfaces wins.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: SerperIcon, + title: 'Serper research agent', + prompt: + 'Build an agent that uses Serper as a primary web-search tool, returns answers with citations, and saves long-form research to a knowledge base.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: SerperIcon, + title: 'Serper image-search collector', + prompt: + 'Create a workflow that uses Serper image search for brand or product mentions, captures unique image URLs into a table, and flags potential trademark misuse.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: SerperIcon, + title: 'Serper geo-SERP comparator', + prompt: + 'Build a scheduled workflow that runs Serper across multiple regions for the same keywords, identifies geo-relevant ranking differences, and writes the analysis to a file.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + ], + skills: [ + { + name: 'research-web-topic', + description: + 'Run a Serper web search on a topic and synthesize the top organic results into a sourced summary.', + content: + '# Research Web Topic\n\nGather current web results on a topic and turn them into a concise, sourced briefing.\n\n## Steps\n1. Run the search operation with a focused query. Set the country and language for the target audience and choose a result count (10 to 100) appropriate to the depth needed.\n2. Read the organic results, titles, snippets, and any answer box or knowledge graph data.\n3. Synthesize the findings, noting agreement and disagreement across sources.\n\n## Output\nReturn a short summary of what the web says about the topic, each key claim linked to the result URL it came from.', + }, + { + name: 'monitor-news-mentions', + description: + 'Search recent news for a brand, person, or topic via Serper and summarize the coverage.', + content: + '# Monitor News Mentions\n\nTrack what the news is saying about a brand, competitor, person, or topic.\n\n## Steps\n1. Run the news operation with the entity or topic as the query, setting country and language to scope the coverage.\n2. Collect the headlines, sources, publish dates, and snippets.\n3. Group the coverage by sentiment or theme and highlight the most recent and most prominent items.\n\n## Output\nReturn a dated list of news items with source and headline, plus a short overall read on tone and notable developments.', + }, + { + name: 'compare-regional-rankings', + description: + 'Run the same Serper query across multiple regions to compare search rankings by geography.', + content: + '# Compare Regional Rankings\n\nSee how search results differ for the same query across countries.\n\n## Steps\n1. Pick the target keyword and the set of countries to compare.\n2. Run the search operation once per country, varying only the country (and language where relevant), keeping the result count consistent.\n3. Line up the top organic results per region and note which domains rank where.\n\n## Output\nReturn a per-region ranking comparison for the keyword, calling out domains that rank strongly in some regions but not others.', + }, + { + name: 'find-local-businesses', + description: + 'Use the Serper places operation to find local businesses for a query and area, and rank them.', + content: + '# Find Local Businesses\n\nPull Google Maps style local results for a query in a target area.\n\n## Steps\n1. Run the places operation with a query that includes the business type and location (for example coffee shops in Seattle), setting the country and language to scope results.\n2. Read each place result: name, address, rating, review count, category, and phone or website where present.\n3. Rank or filter the results by rating, review volume, or proximity to the target area.\n\n## Output\nReturn a ranked list of local businesses with name, address, rating, and review count, noting the top candidates for the query.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/serper.ts b/apps/sim/blocks/blocks/serper.ts index 20dcda8b927..1b1cba69c8e 100644 --- a/apps/sim/blocks/blocks/serper.ts +++ b/apps/sim/blocks/blocks/serper.ts @@ -1,6 +1,5 @@ -import { SerperIcon } from '@/components/icons' import { SerperBlockDisplay } from '@/blocks/blocks/serper.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { SearchResponse } from '@/tools/serper/types' @@ -90,106 +89,3 @@ export const SerperBlock: BlockConfig = { searchResults: { type: 'json', description: 'Search results data' }, }, } - -export const SerperBlockMeta = { - tags: ['web-scraping', 'seo'], - url: 'https://serper.dev', - templates: [ - { - icon: SerperIcon, - title: 'Serper SERP digest', - prompt: - 'Build a scheduled daily workflow that runs Serper searches for tracked keywords, writes the SERP positions of my domain into a tables-based SEO log, and pings on changes.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SerperIcon, - title: 'Serper competitor SERP watcher', - prompt: - 'Create a workflow that runs Serper searches for competitor keywords weekly, captures top SERP entries, and writes a competitive SEO digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SerperIcon, - title: 'Serper news monitor', - prompt: - 'Build a scheduled workflow that uses Serper news search for brand keywords, classifies each result, and posts notable mentions to a Slack PR channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SerperIcon, - title: 'Serper local-pack tracker', - prompt: - 'Create a workflow that uses Serper to track Google local-pack rankings for tracked queries by city, writes the results to a tables-based SEO log, and surfaces wins.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: SerperIcon, - title: 'Serper research agent', - prompt: - 'Build an agent that uses Serper as a primary web-search tool, returns answers with citations, and saves long-form research to a knowledge base.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: SerperIcon, - title: 'Serper image-search collector', - prompt: - 'Create a workflow that uses Serper image search for brand or product mentions, captures unique image URLs into a table, and flags potential trademark misuse.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: SerperIcon, - title: 'Serper geo-SERP comparator', - prompt: - 'Build a scheduled workflow that runs Serper across multiple regions for the same keywords, identifies geo-relevant ranking differences, and writes the analysis to a file.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - ], - skills: [ - { - name: 'research-web-topic', - description: - 'Run a Serper web search on a topic and synthesize the top organic results into a sourced summary.', - content: - '# Research Web Topic\n\nGather current web results on a topic and turn them into a concise, sourced briefing.\n\n## Steps\n1. Run the search operation with a focused query. Set the country and language for the target audience and choose a result count (10 to 100) appropriate to the depth needed.\n2. Read the organic results, titles, snippets, and any answer box or knowledge graph data.\n3. Synthesize the findings, noting agreement and disagreement across sources.\n\n## Output\nReturn a short summary of what the web says about the topic, each key claim linked to the result URL it came from.', - }, - { - name: 'monitor-news-mentions', - description: - 'Search recent news for a brand, person, or topic via Serper and summarize the coverage.', - content: - '# Monitor News Mentions\n\nTrack what the news is saying about a brand, competitor, person, or topic.\n\n## Steps\n1. Run the news operation with the entity or topic as the query, setting country and language to scope the coverage.\n2. Collect the headlines, sources, publish dates, and snippets.\n3. Group the coverage by sentiment or theme and highlight the most recent and most prominent items.\n\n## Output\nReturn a dated list of news items with source and headline, plus a short overall read on tone and notable developments.', - }, - { - name: 'compare-regional-rankings', - description: - 'Run the same Serper query across multiple regions to compare search rankings by geography.', - content: - '# Compare Regional Rankings\n\nSee how search results differ for the same query across countries.\n\n## Steps\n1. Pick the target keyword and the set of countries to compare.\n2. Run the search operation once per country, varying only the country (and language where relevant), keeping the result count consistent.\n3. Line up the top organic results per region and note which domains rank where.\n\n## Output\nReturn a per-region ranking comparison for the keyword, calling out domains that rank strongly in some regions but not others.', - }, - { - name: 'find-local-businesses', - description: - 'Use the Serper places operation to find local businesses for a query and area, and rank them.', - content: - '# Find Local Businesses\n\nPull Google Maps style local results for a query in a target area.\n\n## Steps\n1. Run the places operation with a query that includes the business type and location (for example coffee shops in Seattle), setting the country and language to scope results.\n2. Read each place result: name, address, rating, review count, category, and phone or website where present.\n3. Rank or filter the results by rating, review volume, or proximity to the target area.\n\n## Output\nReturn a ranked list of local businesses with name, address, rating, and review count, noting the top candidates for the query.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/servicenow.display.ts b/apps/sim/blocks/blocks/servicenow.display.ts index 88efbaac230..eaeb8844bce 100644 --- a/apps/sim/blocks/blocks/servicenow.display.ts +++ b/apps/sim/blocks/blocks/servicenow.display.ts @@ -1,6 +1,6 @@ import { ServiceNowIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ServiceNowBlockDisplay = { type: 'servicenow', @@ -14,3 +14,100 @@ export const ServiceNowBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/servicenow', integrationType: IntegrationType.Support, } satisfies BlockDisplay + +export const ServiceNowBlockMeta = { + tags: ['customer-support', 'ticketing', 'incident-management'], + url: 'https://www.servicenow.com', + templates: [ + { + icon: ServiceNowIcon, + title: 'ServiceNow incident commander', + prompt: + 'Build a workflow triggered when a ServiceNow incident is created at P1 or P2 that opens a Slack war-room channel, posts the incident description and impacted CI, invites the assignment group, and keeps the channel topic in sync with the incident state.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'automation', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow change request analyzer', + prompt: + 'Create a workflow that reads new ServiceNow change requests, scores risk based on affected services, blackout windows, and change history, and updates the change record with a recommended approver chain and a risk justification note.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis', 'devops'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow knowledge sync', + prompt: + 'Build a scheduled workflow that pulls Confluence pages tagged for IT operations and creates or updates matching ServiceNow knowledge articles, mapping categories and authors so the knowledge base stays in sync without manual copy-paste.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync', 'team'], + alsoIntegrations: ['confluence'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow asset audit', + prompt: + 'Create a scheduled workflow that queries the ServiceNow CMDB for assets missing owner, lifecycle, or last-discovered fields, flags stale or orphaned records in a tracking table, and opens remediation tasks against the responsible group.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring', 'analysis'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow ticket auto-classifier', + prompt: + 'Build a workflow triggered by new ServiceNow incidents that classifies category and subcategory, sets impact and urgency, infers the affected service from the description, and routes the ticket to the right assignment group.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation', 'support'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow weekly ops digest', + prompt: + 'Create a scheduled weekly workflow that pulls ServiceNow incident, change, and request data, calculates MTTR, change success rate, and top failing services, and posts a digest to Slack with the standout records linked.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'reporting', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: ServiceNowIcon, + title: 'ServiceNow ticket deflection bot', + prompt: + 'Build a Slack bot that lets employees report IT issues in natural language, reads similar resolved ServiceNow records to suggest a fix first, and only creates a new ServiceNow incident record with the right category when self-service does not resolve it.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'create-incident', + description: + 'Create a new ServiceNow incident record with the right category, priority, and description.', + content: + '# Create Incident\n\nFile a new ServiceNow incident from a reported issue.\n\n## Steps\n1. Use the Create Record operation against the incident table.\n2. Populate the field values: a clear short description, the longer description, category, and priority or impact and urgency.\n3. Set caller or assignment group fields when known.\n\n## Output\nReturn the created record sys_id and incident number so the reporter can track it, and echo the category and priority that were set.', + }, + { + name: 'search-records', + description: + 'Query a ServiceNow table for records matching a condition and return the matching rows.', + content: + '# Search Records\n\nFind records in any ServiceNow table that match a condition.\n\n## Steps\n1. Use the Read Records operation against the target table (for example incident, change_request, or sc_task).\n2. Provide an encoded query to filter (for example active incidents in a category) and limit the number of rows returned.\n3. Choose the display-value setting so returned fields are human-readable rather than raw sys_ids when needed.\n\n## Output\nReturn the matched records with their key fields and sys_ids, and report how many matched the query.', + }, + { + name: 'update-record-status', + description: + 'Update fields on an existing ServiceNow record, such as state, assignment, or work notes.', + content: + '# Update Record Status\n\nModify an existing ServiceNow record once a decision or action is taken.\n\n## Steps\n1. Identify the record by its sys_id (from a search step or a notification).\n2. Use the Update Record operation against the correct table, supplying only the fields to change such as state, assigned_to, or work_notes.\n3. Confirm the change by reading the record back.\n\n## Output\nConfirm the record number, the fields that changed, and their new values so the update is auditable.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/servicenow.ts b/apps/sim/blocks/blocks/servicenow.ts index 2e9d95f664f..05914fc5fdc 100644 --- a/apps/sim/blocks/blocks/servicenow.ts +++ b/apps/sim/blocks/blocks/servicenow.ts @@ -1,6 +1,5 @@ -import { ServiceNowIcon } from '@/components/icons' import { ServiceNowBlockDisplay } from '@/blocks/blocks/servicenow.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ServiceNowResponse } from '@/tools/servicenow/types' @@ -454,100 +453,3 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st ], }, } - -export const ServiceNowBlockMeta = { - tags: ['customer-support', 'ticketing', 'incident-management'], - url: 'https://www.servicenow.com', - templates: [ - { - icon: ServiceNowIcon, - title: 'ServiceNow incident commander', - prompt: - 'Build a workflow triggered when a ServiceNow incident is created at P1 or P2 that opens a Slack war-room channel, posts the incident description and impacted CI, invites the assignment group, and keeps the channel topic in sync with the incident state.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'automation', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow change request analyzer', - prompt: - 'Create a workflow that reads new ServiceNow change requests, scores risk based on affected services, blackout windows, and change history, and updates the change record with a recommended approver chain and a risk justification note.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis', 'devops'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow knowledge sync', - prompt: - 'Build a scheduled workflow that pulls Confluence pages tagged for IT operations and creates or updates matching ServiceNow knowledge articles, mapping categories and authors so the knowledge base stays in sync without manual copy-paste.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync', 'team'], - alsoIntegrations: ['confluence'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow asset audit', - prompt: - 'Create a scheduled workflow that queries the ServiceNow CMDB for assets missing owner, lifecycle, or last-discovered fields, flags stale or orphaned records in a tracking table, and opens remediation tasks against the responsible group.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring', 'analysis'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow ticket auto-classifier', - prompt: - 'Build a workflow triggered by new ServiceNow incidents that classifies category and subcategory, sets impact and urgency, infers the affected service from the description, and routes the ticket to the right assignment group.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation', 'support'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow weekly ops digest', - prompt: - 'Create a scheduled weekly workflow that pulls ServiceNow incident, change, and request data, calculates MTTR, change success rate, and top failing services, and posts a digest to Slack with the standout records linked.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'reporting', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: ServiceNowIcon, - title: 'ServiceNow ticket deflection bot', - prompt: - 'Build a Slack bot that lets employees report IT issues in natural language, reads similar resolved ServiceNow records to suggest a fix first, and only creates a new ServiceNow incident record with the right category when self-service does not resolve it.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'create-incident', - description: - 'Create a new ServiceNow incident record with the right category, priority, and description.', - content: - '# Create Incident\n\nFile a new ServiceNow incident from a reported issue.\n\n## Steps\n1. Use the Create Record operation against the incident table.\n2. Populate the field values: a clear short description, the longer description, category, and priority or impact and urgency.\n3. Set caller or assignment group fields when known.\n\n## Output\nReturn the created record sys_id and incident number so the reporter can track it, and echo the category and priority that were set.', - }, - { - name: 'search-records', - description: - 'Query a ServiceNow table for records matching a condition and return the matching rows.', - content: - '# Search Records\n\nFind records in any ServiceNow table that match a condition.\n\n## Steps\n1. Use the Read Records operation against the target table (for example incident, change_request, or sc_task).\n2. Provide an encoded query to filter (for example active incidents in a category) and limit the number of rows returned.\n3. Choose the display-value setting so returned fields are human-readable rather than raw sys_ids when needed.\n\n## Output\nReturn the matched records with their key fields and sys_ids, and report how many matched the query.', - }, - { - name: 'update-record-status', - description: - 'Update fields on an existing ServiceNow record, such as state, assignment, or work notes.', - content: - '# Update Record Status\n\nModify an existing ServiceNow record once a decision or action is taken.\n\n## Steps\n1. Identify the record by its sys_id (from a search step or a notification).\n2. Use the Update Record operation against the correct table, supplying only the fields to change such as state, assigned_to, or work_notes.\n3. Confirm the change by reading the record back.\n\n## Output\nConfirm the record number, the fields that changed, and their new values so the update is auditable.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ses.display.ts b/apps/sim/blocks/blocks/ses.display.ts index 6065a13176e..fce1b4da499 100644 --- a/apps/sim/blocks/blocks/ses.display.ts +++ b/apps/sim/blocks/blocks/ses.display.ts @@ -1,6 +1,6 @@ import { SESIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SESBlockDisplay = { type: 'ses', @@ -14,3 +14,106 @@ export const SESBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/ses', integrationType: IntegrationType.Email, } satisfies BlockDisplay + +export const SESBlockMeta = { + tags: ['cloud', 'email-marketing', 'messaging'], + url: 'https://aws.amazon.com/ses', + templates: [ + { + icon: SESIcon, + title: 'SES bulk announcement', + prompt: + 'Create a workflow that takes a recipient list from a table and an SES email template, sends the announcement using SES bulk send with per-recipient template data, and writes the per-recipient send status back to the table.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation', 'communication'], + }, + { + icon: SESIcon, + title: 'SES verified-identity audit', + prompt: + 'Build a scheduled workflow that lists AWS SES verified identities, checks the account sending quota and reputation, and posts a Slack report when any identity is unverified or the account approaches the daily quota.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: SESIcon, + title: 'SES templated nurture', + prompt: + 'Create a workflow that walks each contact in a tables-based nurture sequence through staged SES templated sends with delays between steps, branches on open or click, and stops the sequence when the contact replies.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: SESIcon, + title: 'SES + Mailgun multi-region sender', + prompt: + 'Build a workflow that routes transactional emails through SES in primary regions and through Mailgun for regions where SES is not provisioned, normalizing template variables and writing one unified send log to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'infrastructure', 'automation'], + alsoIntegrations: ['mailgun'], + }, + { + icon: SESIcon, + title: 'SES + AgentMail customer concierge', + prompt: + 'Create a workflow that sends outbound customer messages through AWS SES but provisions a per-customer AgentMail inbox to receive replies, threads conversations across both, and tags AgentMail threads with the customer ID.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'automation'], + alsoIntegrations: ['agentmail'], + }, + { + icon: SESIcon, + title: 'SES domain reputation monitor', + prompt: + 'Build a scheduled daily workflow that pulls SES account sending statistics and per-identity reputation indicators, logs them to a tracking table for trend lines, and flags any identity whose complaint or bounce rate is trending up.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring', 'analysis'], + }, + { + icon: SESIcon, + title: 'SES template library sync', + prompt: + 'Build a workflow that reads my approved email templates from a table, creates or updates each one in AWS SES with create template, lists existing SES templates to detect drift, and deletes templates that have been removed from the table so the SES library stays in sync.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['marketing', 'automation', 'content'], + }, + ], + skills: [ + { + name: 'send-notification-email', + description: + 'Send a transactional email through AWS SES to one or more recipients. Use for alerts, confirmations, and one-off notifications from a workflow.', + content: + '# Send Notification Email\n\nSend a transactional email via SES.\n\n## Steps\n1. Determine the verified sender identity, the recipients, subject, and body.\n2. Choose a plain-text or HTML body to match the message.\n3. Send the email, including reply-to or CC recipients if needed.\n4. Confirm the send succeeded and capture the message ID.\n\n## Output\nReport the SES message ID and the recipients. If the send was rejected, surface the SES error (for example, an unverified sender or sandbox restriction).', + }, + { + name: 'send-templated-campaign', + description: + 'Send a templated SES email to many recipients with per-recipient personalization. Use for newsletters, onboarding sequences, and bulk notifications.', + content: + "# Send Templated Campaign\n\nSend personalized emails using an SES template.\n\n## Steps\n1. Confirm the template exists with get template, or create it first.\n2. Assemble the recipient list with each recipient's template data for personalization.\n3. Use send bulk email for many recipients, or send templated email for a single message.\n4. Collect per-recipient send status.\n\n## Output\nReport how many messages were accepted versus failed, with message IDs and the reason for any failures.", + }, + { + name: 'manage-email-templates', + description: + 'Create, fetch, list, and delete reusable email templates in AWS SES. Use to maintain a consistent, version-controlled template library.', + content: + '# Manage Email Templates\n\nMaintain the SES template library.\n\n## Steps\n1. To add a template, create it with a name, subject, and HTML and text parts using placeholder variables.\n2. To review, get a template by name or list templates.\n3. To retire one, delete the template by name.\n4. Keep template names descriptive so they are easy to reference when sending.\n\n## Output\nReport the template name affected and the action taken, or the template contents for a fetch.', + }, + { + name: 'check-sending-health', + description: + 'Inspect AWS SES account sending limits, quota usage, and verified identities. Use to confirm capacity and deliverability readiness before a send.', + content: + '# Check Sending Health\n\nVerify SES is ready to send.\n\n## Steps\n1. Get the account to read the sending quota, send rate, and whether the account is out of the sandbox.\n2. List identities to confirm the intended sender domain or address is verified.\n3. Compare planned volume against the remaining 24-hour quota.\n4. Flag any blockers — sandbox mode, unverified senders, or quota nearly exhausted.\n\n## Output\nReport sending enabled status, quota used versus max, and any unverified identities that would block the send.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/ses.ts b/apps/sim/blocks/blocks/ses.ts index 662c8ac7821..4c9e2250a65 100644 --- a/apps/sim/blocks/blocks/ses.ts +++ b/apps/sim/blocks/blocks/ses.ts @@ -1,6 +1,5 @@ -import { SESIcon } from '@/components/icons' import { SESBlockDisplay } from '@/blocks/blocks/ses.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' @@ -488,106 +487,3 @@ export const SESBlock: BlockConfig = { }, }, } - -export const SESBlockMeta = { - tags: ['cloud', 'email-marketing', 'messaging'], - url: 'https://aws.amazon.com/ses', - templates: [ - { - icon: SESIcon, - title: 'SES bulk announcement', - prompt: - 'Create a workflow that takes a recipient list from a table and an SES email template, sends the announcement using SES bulk send with per-recipient template data, and writes the per-recipient send status back to the table.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation', 'communication'], - }, - { - icon: SESIcon, - title: 'SES verified-identity audit', - prompt: - 'Build a scheduled workflow that lists AWS SES verified identities, checks the account sending quota and reputation, and posts a Slack report when any identity is unverified or the account approaches the daily quota.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: SESIcon, - title: 'SES templated nurture', - prompt: - 'Create a workflow that walks each contact in a tables-based nurture sequence through staged SES templated sends with delays between steps, branches on open or click, and stops the sequence when the contact replies.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: SESIcon, - title: 'SES + Mailgun multi-region sender', - prompt: - 'Build a workflow that routes transactional emails through SES in primary regions and through Mailgun for regions where SES is not provisioned, normalizing template variables and writing one unified send log to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'infrastructure', 'automation'], - alsoIntegrations: ['mailgun'], - }, - { - icon: SESIcon, - title: 'SES + AgentMail customer concierge', - prompt: - 'Create a workflow that sends outbound customer messages through AWS SES but provisions a per-customer AgentMail inbox to receive replies, threads conversations across both, and tags AgentMail threads with the customer ID.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'automation'], - alsoIntegrations: ['agentmail'], - }, - { - icon: SESIcon, - title: 'SES domain reputation monitor', - prompt: - 'Build a scheduled daily workflow that pulls SES account sending statistics and per-identity reputation indicators, logs them to a tracking table for trend lines, and flags any identity whose complaint or bounce rate is trending up.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring', 'analysis'], - }, - { - icon: SESIcon, - title: 'SES template library sync', - prompt: - 'Build a workflow that reads my approved email templates from a table, creates or updates each one in AWS SES with create template, lists existing SES templates to detect drift, and deletes templates that have been removed from the table so the SES library stays in sync.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['marketing', 'automation', 'content'], - }, - ], - skills: [ - { - name: 'send-notification-email', - description: - 'Send a transactional email through AWS SES to one or more recipients. Use for alerts, confirmations, and one-off notifications from a workflow.', - content: - '# Send Notification Email\n\nSend a transactional email via SES.\n\n## Steps\n1. Determine the verified sender identity, the recipients, subject, and body.\n2. Choose a plain-text or HTML body to match the message.\n3. Send the email, including reply-to or CC recipients if needed.\n4. Confirm the send succeeded and capture the message ID.\n\n## Output\nReport the SES message ID and the recipients. If the send was rejected, surface the SES error (for example, an unverified sender or sandbox restriction).', - }, - { - name: 'send-templated-campaign', - description: - 'Send a templated SES email to many recipients with per-recipient personalization. Use for newsletters, onboarding sequences, and bulk notifications.', - content: - "# Send Templated Campaign\n\nSend personalized emails using an SES template.\n\n## Steps\n1. Confirm the template exists with get template, or create it first.\n2. Assemble the recipient list with each recipient's template data for personalization.\n3. Use send bulk email for many recipients, or send templated email for a single message.\n4. Collect per-recipient send status.\n\n## Output\nReport how many messages were accepted versus failed, with message IDs and the reason for any failures.", - }, - { - name: 'manage-email-templates', - description: - 'Create, fetch, list, and delete reusable email templates in AWS SES. Use to maintain a consistent, version-controlled template library.', - content: - '# Manage Email Templates\n\nMaintain the SES template library.\n\n## Steps\n1. To add a template, create it with a name, subject, and HTML and text parts using placeholder variables.\n2. To review, get a template by name or list templates.\n3. To retire one, delete the template by name.\n4. Keep template names descriptive so they are easy to reference when sending.\n\n## Output\nReport the template name affected and the action taken, or the template contents for a fetch.', - }, - { - name: 'check-sending-health', - description: - 'Inspect AWS SES account sending limits, quota usage, and verified identities. Use to confirm capacity and deliverability readiness before a send.', - content: - '# Check Sending Health\n\nVerify SES is ready to send.\n\n## Steps\n1. Get the account to read the sending quota, send rate, and whether the account is out of the sandbox.\n2. List identities to confirm the intended sender domain or address is verified.\n3. Compare planned volume against the remaining 24-hour quota.\n4. Flag any blockers — sandbox mode, unverified senders, or quota nearly exhausted.\n\n## Output\nReport sending enabled status, quota used versus max, and any unverified identities that would block the send.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sharepoint.display.ts b/apps/sim/blocks/blocks/sharepoint.display.ts index 7ee699c2eab..9eafa171364 100644 --- a/apps/sim/blocks/blocks/sharepoint.display.ts +++ b/apps/sim/blocks/blocks/sharepoint.display.ts @@ -1,6 +1,6 @@ import { MicrosoftSharepointIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SharepointBlockDisplay = { type: 'sharepoint', @@ -22,3 +22,107 @@ export const SharepointV2BlockDisplay = { name: 'SharePoint', hideFromToolbar: false, } satisfies BlockDisplay + +export const SharepointBlockMeta = { + tags: ['microsoft-365', 'content-management', 'document-processing'], + url: 'https://www.microsoft.com/microsoft-365/sharepoint/collaboration', + templates: [ + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint policy publisher', + prompt: + 'Build a workflow that turns a Google Docs policy update into a published SharePoint page, posts the change diff to the policies team in Microsoft Teams, and writes the version history.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + alsoIntegrations: ['google_docs', 'microsoft_teams'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint stale-page sweeper', + prompt: + 'Create a scheduled workflow that lists SharePoint pages not updated in 180 days, opens an owner-review thread in Teams, and archives pages once the owner approves.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'team'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint knowledge agent', + prompt: + 'Build an agent that indexes SharePoint sites into a knowledge base, answers internal questions with cited links, and deploys as a Teams chat endpoint.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['enterprise', 'research'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint external-share audit', + prompt: + 'Create a scheduled workflow that audits SharePoint external sharing, flags items above the sensitivity threshold, and posts a security report to Teams compliance channel.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint onboarding hub', + prompt: + 'Build a workflow triggered by a new hire in Workday that creates a personalized SharePoint onboarding hub with role-relevant docs and shares it with the hire and their manager.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint search-relevance auditor', + prompt: + 'Create a scheduled workflow that runs benchmark queries against SharePoint search weekly, scores the top result relevance, and writes a quality report to Teams.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'analysis'], + alsoIntegrations: ['microsoft_teams'], + }, + { + icon: MicrosoftSharepointIcon, + title: 'SharePoint to Confluence migrator', + prompt: + 'Build a workflow that imports SharePoint pages into Confluence under matching spaces, preserves attachments, and writes a mapping table so links can be redirected.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'sync'], + alsoIntegrations: ['confluence'], + }, + ], + skills: [ + { + name: 'publish-site-page', + description: 'Create a new SharePoint page on a site with a title and content body.', + content: + '# Publish Site Page\n\nCreate a new page on a SharePoint site, for example an announcement or knowledge article.\n\n## Steps\n1. Run List Sites to find the target site and note its identifier.\n2. Run Create Page on that site with a clear title and the page content body.\n3. Optionally run Read Page afterward to confirm the page was created as intended.\n\n## Output\nReturn the created page title and its URL or identifier so the page can be shared.', + }, + { + name: 'append-list-items', + description: + 'Add rows to a SharePoint list, creating the list first if it does not yet exist.', + content: + '# Append List Items\n\nWrite structured rows into a SharePoint list.\n\n## Steps\n1. Run List Sites to locate the site, then Read List to confirm the target list and its column schema.\n2. If the list does not exist, run Create List with the needed columns.\n3. Run Add List Items with the field values mapped to the list columns.\n\n## Output\nReturn the list name and the number of items added, and confirm the field values matched the list schema.', + }, + { + name: 'read-list-data', + description: 'Read items from a SharePoint list and summarize the rows for downstream use.', + content: + '# Read List Data\n\nPull the contents of a SharePoint list into the workflow.\n\n## Steps\n1. Run List Sites to find the site, then Read List against the target list.\n2. Inspect the returned items and their column values.\n3. Filter or summarize the rows as needed for the task.\n\n## Output\nReturn the list items with their relevant column values and a count of rows read.', + }, + { + name: 'upload-file-to-site', + description: 'Upload a file to a SharePoint site document library from a previous block.', + content: + '# Upload File to Site\n\nStore a file in a SharePoint document library.\n\n## Steps\n1. Run List Sites to identify the destination site.\n2. Provide the file from a previous block and run Upload File to the target site library.\n3. Confirm the upload completed.\n\n## Output\nReturn the uploaded file name and its location on the SharePoint site.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sharepoint.ts b/apps/sim/blocks/blocks/sharepoint.ts index afdfd6308c8..7989b4a12c8 100644 --- a/apps/sim/blocks/blocks/sharepoint.ts +++ b/apps/sim/blocks/blocks/sharepoint.ts @@ -1,12 +1,11 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' -import { MicrosoftSharepointIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { SharepointBlockDisplay, SharepointV2BlockDisplay, } from '@/blocks/blocks/sharepoint.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SharepointResponse } from '@/tools/sharepoint/types' @@ -1041,107 +1040,3 @@ Return ONLY the JSON object - no explanations, no markdown, no extra text.`, error: { type: 'string', description: 'Error message' }, }, } - -export const SharepointBlockMeta = { - tags: ['microsoft-365', 'content-management', 'document-processing'], - url: 'https://www.microsoft.com/microsoft-365/sharepoint/collaboration', - templates: [ - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint policy publisher', - prompt: - 'Build a workflow that turns a Google Docs policy update into a published SharePoint page, posts the change diff to the policies team in Microsoft Teams, and writes the version history.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - alsoIntegrations: ['google_docs', 'microsoft_teams'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint stale-page sweeper', - prompt: - 'Create a scheduled workflow that lists SharePoint pages not updated in 180 days, opens an owner-review thread in Teams, and archives pages once the owner approves.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'team'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint knowledge agent', - prompt: - 'Build an agent that indexes SharePoint sites into a knowledge base, answers internal questions with cited links, and deploys as a Teams chat endpoint.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['enterprise', 'research'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint external-share audit', - prompt: - 'Create a scheduled workflow that audits SharePoint external sharing, flags items above the sensitivity threshold, and posts a security report to Teams compliance channel.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint onboarding hub', - prompt: - 'Build a workflow triggered by a new hire in Workday that creates a personalized SharePoint onboarding hub with role-relevant docs and shares it with the hire and their manager.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint search-relevance auditor', - prompt: - 'Create a scheduled workflow that runs benchmark queries against SharePoint search weekly, scores the top result relevance, and writes a quality report to Teams.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'analysis'], - alsoIntegrations: ['microsoft_teams'], - }, - { - icon: MicrosoftSharepointIcon, - title: 'SharePoint to Confluence migrator', - prompt: - 'Build a workflow that imports SharePoint pages into Confluence under matching spaces, preserves attachments, and writes a mapping table so links can be redirected.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'sync'], - alsoIntegrations: ['confluence'], - }, - ], - skills: [ - { - name: 'publish-site-page', - description: 'Create a new SharePoint page on a site with a title and content body.', - content: - '# Publish Site Page\n\nCreate a new page on a SharePoint site, for example an announcement or knowledge article.\n\n## Steps\n1. Run List Sites to find the target site and note its identifier.\n2. Run Create Page on that site with a clear title and the page content body.\n3. Optionally run Read Page afterward to confirm the page was created as intended.\n\n## Output\nReturn the created page title and its URL or identifier so the page can be shared.', - }, - { - name: 'append-list-items', - description: - 'Add rows to a SharePoint list, creating the list first if it does not yet exist.', - content: - '# Append List Items\n\nWrite structured rows into a SharePoint list.\n\n## Steps\n1. Run List Sites to locate the site, then Read List to confirm the target list and its column schema.\n2. If the list does not exist, run Create List with the needed columns.\n3. Run Add List Items with the field values mapped to the list columns.\n\n## Output\nReturn the list name and the number of items added, and confirm the field values matched the list schema.', - }, - { - name: 'read-list-data', - description: 'Read items from a SharePoint list and summarize the rows for downstream use.', - content: - '# Read List Data\n\nPull the contents of a SharePoint list into the workflow.\n\n## Steps\n1. Run List Sites to find the site, then Read List against the target list.\n2. Inspect the returned items and their column values.\n3. Filter or summarize the rows as needed for the task.\n\n## Output\nReturn the list items with their relevant column values and a count of rows read.', - }, - { - name: 'upload-file-to-site', - description: 'Upload a file to a SharePoint site document library from a previous block.', - content: - '# Upload File to Site\n\nStore a file in a SharePoint document library.\n\n## Steps\n1. Run List Sites to identify the destination site.\n2. Provide the file from a previous block and run Upload File to the target site library.\n3. Confirm the upload completed.\n\n## Output\nReturn the uploaded file name and its location on the SharePoint site.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/shopify.display.ts b/apps/sim/blocks/blocks/shopify.display.ts index 954ea61291d..46e0382645d 100644 --- a/apps/sim/blocks/blocks/shopify.display.ts +++ b/apps/sim/blocks/blocks/shopify.display.ts @@ -1,6 +1,6 @@ import { ShopifyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ShopifyBlockDisplay = { type: 'shopify', @@ -14,3 +14,112 @@ export const ShopifyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/shopify', integrationType: IntegrationType.Commerce, } satisfies BlockDisplay + +export const ShopifyBlockMeta = { + tags: ['payments', 'automation'], + url: 'https://www.shopify.com', + templates: [ + { + icon: ShopifyIcon, + title: 'E-commerce order monitor', + prompt: + 'Build a workflow that monitors Shopify orders, flags high-value or unusual orders for review, tracks fulfillment status in a table, and sends daily inventory and sales summaries to Slack with restock alerts when items run low.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ShopifyIcon, + title: 'Unpaid order recovery', + prompt: + 'Build a scheduled workflow that lists Shopify orders left open and unpaid in the past day, drafts a personalized recovery email referencing the items, and sends it via Gmail while logging recovery attempts to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'marketing', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: ShopifyIcon, + title: 'Low-stock restock alerter', + prompt: + 'Create a scheduled hourly workflow that lists Shopify inventory items, computes days-of-cover from recent sales velocity, flags SKUs below a configurable threshold, and posts a Slack alert to the operations channel with the variant, location, and recommended reorder quantity.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'monitoring', 'operations'], + alsoIntegrations: ['slack'], + }, + { + icon: ShopifyIcon, + title: 'Shopify VIP segmenter', + prompt: + 'Build a scheduled weekly workflow that pulls Shopify customers, calculates lifetime value and order frequency, segments them into VIP, regular, and at-risk cohorts in a tracking table, and emails the marketing team a list of new VIPs to nurture.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'marketing', 'analysis'], + }, + { + icon: ShopifyIcon, + title: 'Fulfillment status tracker', + prompt: + 'Create a scheduled workflow that lists Shopify orders and their fulfillment status, updates a status table with shipped, in-transit, and delivered states, and proactively emails customers when their order misses an SLA so support gets ahead of the inquiry.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'support', 'monitoring'], + alsoIntegrations: ['gmail'], + }, + { + icon: ShopifyIcon, + title: 'Product launch publisher', + prompt: + 'Build a workflow that takes a new product brief, creates the product in Shopify with variants and pricing, adds it to the right collection, drafts a launch announcement, and queues a Slack and email broadcast for marketing review before going live.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'marketing', 'automation'], + alsoIntegrations: ['gmail', 'slack'], + }, + { + icon: ShopifyIcon, + title: 'Order anomaly detector', + prompt: + 'Create a scheduled workflow that runs every fifteen minutes, lists recent Shopify orders, scores each for anomalies — high value, unusual destination, mismatched billing — flags suspects in a review queue table, and Slacks the operations team for hands-on inspection.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'monitoring', 'analysis'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'create-product-listing', + description: 'Create a new Shopify product with title, description, status, and variants.', + content: + '# Create Product Listing\n\nAdd a new product to the Shopify store.\n\n## Steps\n1. Run Create Product with the title, body description, vendor, and product type.\n2. Set the status (active, draft, or archived) so the product publishes only when ready.\n3. Verify with Get Product on the returned product ID.\n\n## Output\nReturn the new product ID, title, and status, and confirm the listing was created as draft or active as intended.', + }, + { + name: 'process-recent-orders', + description: + 'List recent Shopify orders and summarize them by status, value, or fulfillment need.', + content: + '# Process Recent Orders\n\nReview the latest orders to triage fulfillment and flag anything unusual.\n\n## Steps\n1. Run List Orders filtered by status (open, closed, cancelled, or any) and a recent time window.\n2. For orders needing detail, run Get Order to read line items, customer, and shipping address.\n3. Group orders by fulfillment status and total value.\n\n## Output\nReturn a summary of recent orders with their order numbers, totals, and status, highlighting any that need immediate fulfillment or review.', + }, + { + name: 'fulfill-order', + description: 'Create a fulfillment for a Shopify order and update its status.', + content: + '# Fulfill Order\n\nMark an order as fulfilled once it has shipped.\n\n## Steps\n1. Run Get Order to confirm the order and its line items, and List Locations to identify the fulfilling location.\n2. Run Create Fulfillment for the order, supplying the location and tracking details if available.\n3. Optionally run Update Order to record any notes.\n\n## Output\nConfirm the order number, the fulfillment created, and any tracking number supplied.', + }, + { + name: 'adjust-inventory', + description: 'Check and adjust Shopify inventory levels for an item at a location.', + content: + '# Adjust Inventory\n\nReconcile stock levels for an inventory item.\n\n## Steps\n1. Run List Inventory Items and List Locations to identify the item and the location.\n2. Run Get Inventory Level to read the current available quantity.\n3. Run Adjust Inventory with the delta needed to reach the correct count.\n\n## Output\nReport the inventory item, the location, the previous and new quantities, and the adjustment applied.', + }, + { + name: 'manage-customer-record', + description: 'Create, look up, or update a Shopify customer record.', + content: + '# Manage Customer Record\n\nMaintain a customer profile in Shopify.\n\n## Steps\n1. To find an existing customer, run List Customers with a filter or Get Customer by ID.\n2. To add a new one, run Create Customer with name, email, and any tags.\n3. To change details, run Update Customer with only the fields to modify.\n\n## Output\nReturn the customer ID, name, and email, and note whether the record was created, found, or updated.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/shopify.ts b/apps/sim/blocks/blocks/shopify.ts index c1d8ead2728..75fec13fa11 100644 --- a/apps/sim/blocks/blocks/shopify.ts +++ b/apps/sim/blocks/blocks/shopify.ts @@ -1,7 +1,6 @@ -import { ShopifyIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { ShopifyBlockDisplay } from '@/blocks/blocks/shopify.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, parseOptionalNumberInput } from '@/blocks/utils' @@ -1020,112 +1019,3 @@ export const ShopifyBlock: BlockConfig = { success: { type: 'boolean', description: 'Operation success status' }, }, } - -export const ShopifyBlockMeta = { - tags: ['payments', 'automation'], - url: 'https://www.shopify.com', - templates: [ - { - icon: ShopifyIcon, - title: 'E-commerce order monitor', - prompt: - 'Build a workflow that monitors Shopify orders, flags high-value or unusual orders for review, tracks fulfillment status in a table, and sends daily inventory and sales summaries to Slack with restock alerts when items run low.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ShopifyIcon, - title: 'Unpaid order recovery', - prompt: - 'Build a scheduled workflow that lists Shopify orders left open and unpaid in the past day, drafts a personalized recovery email referencing the items, and sends it via Gmail while logging recovery attempts to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'marketing', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: ShopifyIcon, - title: 'Low-stock restock alerter', - prompt: - 'Create a scheduled hourly workflow that lists Shopify inventory items, computes days-of-cover from recent sales velocity, flags SKUs below a configurable threshold, and posts a Slack alert to the operations channel with the variant, location, and recommended reorder quantity.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'monitoring', 'operations'], - alsoIntegrations: ['slack'], - }, - { - icon: ShopifyIcon, - title: 'Shopify VIP segmenter', - prompt: - 'Build a scheduled weekly workflow that pulls Shopify customers, calculates lifetime value and order frequency, segments them into VIP, regular, and at-risk cohorts in a tracking table, and emails the marketing team a list of new VIPs to nurture.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'marketing', 'analysis'], - }, - { - icon: ShopifyIcon, - title: 'Fulfillment status tracker', - prompt: - 'Create a scheduled workflow that lists Shopify orders and their fulfillment status, updates a status table with shipped, in-transit, and delivered states, and proactively emails customers when their order misses an SLA so support gets ahead of the inquiry.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'support', 'monitoring'], - alsoIntegrations: ['gmail'], - }, - { - icon: ShopifyIcon, - title: 'Product launch publisher', - prompt: - 'Build a workflow that takes a new product brief, creates the product in Shopify with variants and pricing, adds it to the right collection, drafts a launch announcement, and queues a Slack and email broadcast for marketing review before going live.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'marketing', 'automation'], - alsoIntegrations: ['gmail', 'slack'], - }, - { - icon: ShopifyIcon, - title: 'Order anomaly detector', - prompt: - 'Create a scheduled workflow that runs every fifteen minutes, lists recent Shopify orders, scores each for anomalies — high value, unusual destination, mismatched billing — flags suspects in a review queue table, and Slacks the operations team for hands-on inspection.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'monitoring', 'analysis'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'create-product-listing', - description: 'Create a new Shopify product with title, description, status, and variants.', - content: - '# Create Product Listing\n\nAdd a new product to the Shopify store.\n\n## Steps\n1. Run Create Product with the title, body description, vendor, and product type.\n2. Set the status (active, draft, or archived) so the product publishes only when ready.\n3. Verify with Get Product on the returned product ID.\n\n## Output\nReturn the new product ID, title, and status, and confirm the listing was created as draft or active as intended.', - }, - { - name: 'process-recent-orders', - description: - 'List recent Shopify orders and summarize them by status, value, or fulfillment need.', - content: - '# Process Recent Orders\n\nReview the latest orders to triage fulfillment and flag anything unusual.\n\n## Steps\n1. Run List Orders filtered by status (open, closed, cancelled, or any) and a recent time window.\n2. For orders needing detail, run Get Order to read line items, customer, and shipping address.\n3. Group orders by fulfillment status and total value.\n\n## Output\nReturn a summary of recent orders with their order numbers, totals, and status, highlighting any that need immediate fulfillment or review.', - }, - { - name: 'fulfill-order', - description: 'Create a fulfillment for a Shopify order and update its status.', - content: - '# Fulfill Order\n\nMark an order as fulfilled once it has shipped.\n\n## Steps\n1. Run Get Order to confirm the order and its line items, and List Locations to identify the fulfilling location.\n2. Run Create Fulfillment for the order, supplying the location and tracking details if available.\n3. Optionally run Update Order to record any notes.\n\n## Output\nConfirm the order number, the fulfillment created, and any tracking number supplied.', - }, - { - name: 'adjust-inventory', - description: 'Check and adjust Shopify inventory levels for an item at a location.', - content: - '# Adjust Inventory\n\nReconcile stock levels for an inventory item.\n\n## Steps\n1. Run List Inventory Items and List Locations to identify the item and the location.\n2. Run Get Inventory Level to read the current available quantity.\n3. Run Adjust Inventory with the delta needed to reach the correct count.\n\n## Output\nReport the inventory item, the location, the previous and new quantities, and the adjustment applied.', - }, - { - name: 'manage-customer-record', - description: 'Create, look up, or update a Shopify customer record.', - content: - '# Manage Customer Record\n\nMaintain a customer profile in Shopify.\n\n## Steps\n1. To find an existing customer, run List Customers with a filter or Get Customer by ID.\n2. To add a new one, run Create Customer with name, email, and any tags.\n3. To change details, run Update Customer with only the fields to modify.\n\n## Output\nReturn the customer ID, name, and email, and note whether the record was created, found, or updated.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/similarweb.display.ts b/apps/sim/blocks/blocks/similarweb.display.ts index 2fab0b2bb92..911f25d63d4 100644 --- a/apps/sim/blocks/blocks/similarweb.display.ts +++ b/apps/sim/blocks/blocks/similarweb.display.ts @@ -1,6 +1,6 @@ import { SimilarwebIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SimilarwebBlockDisplay = { type: 'similarweb', @@ -14,3 +14,99 @@ export const SimilarwebBlockDisplay = { docsLink: 'https://developers.similarweb.com/docs/similarweb-web-traffic-api', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const SimilarwebBlockMeta = { + tags: ['marketing', 'data-analytics', 'seo'], + url: 'https://www.similarweb.com', + templates: [ + { + icon: SimilarwebIcon, + title: 'Similarweb traffic intelligence', + prompt: + 'Build a scheduled workflow that pulls Similarweb traffic data for tracked competitor domains monthly, writes traffic, sources, and engagement to a tables-based scoreboard, and flags step changes in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb account intel sync', + prompt: + 'Create a workflow that watches my CRM for new accounts, pulls Similarweb data on each account domain, writes traffic estimates, rankings, and engagement signals back to the account record for sales context.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb category benchmarking', + prompt: + 'Create a scheduled workflow that pulls Similarweb category rank, visit duration, and bounce rate for my domain and a set of tracked competitors, then writes a ranked benchmarking table for the marketing review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb funnel-source analyzer', + prompt: + 'Build a scheduled workflow that pulls Similarweb traffic-source data for my domain and competitors, surfaces shifting acquisition channels, and writes the analysis to a marketing table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb traffic-source overlap finder', + prompt: + 'Create a scheduled workflow that pulls Similarweb traffic-source breakdowns for my domain and tracked competitors, identifies channels where competitors over-index, and writes an acquisition opportunity table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb engagement scorecard', + prompt: + 'Build a scheduled workflow that pulls Similarweb bounce rate, pages per visit, and average visit duration for my domain and key competitors, writes the engagement metrics to a table, and posts a Slack scorecard highlighting where my site under- or over-performs the set.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SimilarwebIcon, + title: 'Similarweb prospect prioritizer', + prompt: + "Create a workflow that reads a list of target company domains from a table, pulls each domain's Similarweb website overview and monthly visits, scores them by traffic size and growth, and writes a prioritized outbound list for the sales team.", + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'analysis'], + }, + ], + skills: [ + { + name: 'profile-website-traffic', + description: + 'Pull a Similarweb website overview and traffic metrics for a domain and summarize its scale.', + content: + '# Profile Website Traffic\n\nBuild a quick traffic profile for a single domain.\n\n## Steps\n1. Run Website Overview for the domain to get a high-level snapshot.\n2. Run Traffic Visits, Bounce Rate, Pages Per Visit, and Visit Duration for deeper engagement metrics, setting the country (or worldwide) to scope the data.\n3. Interpret the numbers together: high visits with a low bounce rate and long duration indicates strong engagement.\n\n## Output\nReturn a concise profile of the domain: estimated monthly visits, bounce rate, pages per visit, and average visit duration, with a one-line read on overall traffic health.', + }, + { + name: 'compare-competitor-domains', + description: + 'Pull Similarweb traffic metrics for several domains and rank them for a competitive view.', + content: + '# Compare Competitor Domains\n\nBenchmark a set of competing domains on traffic and engagement.\n\n## Steps\n1. For each domain, run Website Overview and Traffic Visits using the same country scope so the numbers are comparable.\n2. Optionally add Bounce Rate and Pages Per Visit for an engagement dimension.\n3. Rank the domains by visits and engagement.\n\n## Output\nReturn a ranked table of the domains with their visits, bounce rate, and engagement metrics, and a short read on which competitor leads.', + }, + { + name: 'score-prospect-domains', + description: + 'Score a list of prospect domains by Similarweb traffic size to prioritize outreach.', + content: + '# Score Prospect Domains\n\nPrioritize sales prospects by the size of their web traffic.\n\n## Steps\n1. For each prospect domain, run Website Overview and Traffic Visits in the relevant region.\n2. Assign a score based on monthly visits and any visible growth trend.\n3. Sort the prospects from highest to lowest score.\n\n## Output\nReturn the prospect domains ranked by score, each with its estimated monthly visits, so the sales team can prioritize the biggest-traffic targets.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/similarweb.ts b/apps/sim/blocks/blocks/similarweb.ts index 847ffe4b687..3ce7eef3cd4 100644 --- a/apps/sim/blocks/blocks/similarweb.ts +++ b/apps/sim/blocks/blocks/similarweb.ts @@ -1,6 +1,5 @@ -import { SimilarwebIcon } from '@/components/icons' import { SimilarwebBlockDisplay } from '@/blocks/blocks/similarweb.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const SimilarwebBlock: BlockConfig = { @@ -191,99 +190,3 @@ Return ONLY the date string in YYYY-MM format - no explanations, no quotes, no e averageVisitDuration: { type: 'json', description: 'Desktop visit duration data over time' }, }, } - -export const SimilarwebBlockMeta = { - tags: ['marketing', 'data-analytics', 'seo'], - url: 'https://www.similarweb.com', - templates: [ - { - icon: SimilarwebIcon, - title: 'Similarweb traffic intelligence', - prompt: - 'Build a scheduled workflow that pulls Similarweb traffic data for tracked competitor domains monthly, writes traffic, sources, and engagement to a tables-based scoreboard, and flags step changes in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb account intel sync', - prompt: - 'Create a workflow that watches my CRM for new accounts, pulls Similarweb data on each account domain, writes traffic estimates, rankings, and engagement signals back to the account record for sales context.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb category benchmarking', - prompt: - 'Create a scheduled workflow that pulls Similarweb category rank, visit duration, and bounce rate for my domain and a set of tracked competitors, then writes a ranked benchmarking table for the marketing review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb funnel-source analyzer', - prompt: - 'Build a scheduled workflow that pulls Similarweb traffic-source data for my domain and competitors, surfaces shifting acquisition channels, and writes the analysis to a marketing table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb traffic-source overlap finder', - prompt: - 'Create a scheduled workflow that pulls Similarweb traffic-source breakdowns for my domain and tracked competitors, identifies channels where competitors over-index, and writes an acquisition opportunity table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb engagement scorecard', - prompt: - 'Build a scheduled workflow that pulls Similarweb bounce rate, pages per visit, and average visit duration for my domain and key competitors, writes the engagement metrics to a table, and posts a Slack scorecard highlighting where my site under- or over-performs the set.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SimilarwebIcon, - title: 'Similarweb prospect prioritizer', - prompt: - "Create a workflow that reads a list of target company domains from a table, pulls each domain's Similarweb website overview and monthly visits, scores them by traffic size and growth, and writes a prioritized outbound list for the sales team.", - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'analysis'], - }, - ], - skills: [ - { - name: 'profile-website-traffic', - description: - 'Pull a Similarweb website overview and traffic metrics for a domain and summarize its scale.', - content: - '# Profile Website Traffic\n\nBuild a quick traffic profile for a single domain.\n\n## Steps\n1. Run Website Overview for the domain to get a high-level snapshot.\n2. Run Traffic Visits, Bounce Rate, Pages Per Visit, and Visit Duration for deeper engagement metrics, setting the country (or worldwide) to scope the data.\n3. Interpret the numbers together: high visits with a low bounce rate and long duration indicates strong engagement.\n\n## Output\nReturn a concise profile of the domain: estimated monthly visits, bounce rate, pages per visit, and average visit duration, with a one-line read on overall traffic health.', - }, - { - name: 'compare-competitor-domains', - description: - 'Pull Similarweb traffic metrics for several domains and rank them for a competitive view.', - content: - '# Compare Competitor Domains\n\nBenchmark a set of competing domains on traffic and engagement.\n\n## Steps\n1. For each domain, run Website Overview and Traffic Visits using the same country scope so the numbers are comparable.\n2. Optionally add Bounce Rate and Pages Per Visit for an engagement dimension.\n3. Rank the domains by visits and engagement.\n\n## Output\nReturn a ranked table of the domains with their visits, bounce rate, and engagement metrics, and a short read on which competitor leads.', - }, - { - name: 'score-prospect-domains', - description: - 'Score a list of prospect domains by Similarweb traffic size to prioritize outreach.', - content: - '# Score Prospect Domains\n\nPrioritize sales prospects by the size of their web traffic.\n\n## Steps\n1. For each prospect domain, run Website Overview and Traffic Visits in the relevant region.\n2. Assign a score based on monthly visits and any visible growth trend.\n3. Sort the prospects from highest to lowest score.\n\n## Output\nReturn the prospect domains ranked by score, each with its estimated monthly visits, so the sales team can prioritize the biggest-traffic targets.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sixtyfour.display.ts b/apps/sim/blocks/blocks/sixtyfour.display.ts index 4957e68ef8f..5ef8932f692 100644 --- a/apps/sim/blocks/blocks/sixtyfour.display.ts +++ b/apps/sim/blocks/blocks/sixtyfour.display.ts @@ -1,6 +1,6 @@ import { SixtyfourIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SixtyfourBlockDisplay = { type: 'sixtyfour', @@ -14,3 +14,101 @@ export const SixtyfourBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sixtyfour', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const SixtyfourBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://sixtyfour.ai', + templates: [ + { + icon: SixtyfourIcon, + title: 'Sixtyfour contact researcher', + prompt: + 'Build a workflow that runs Sixtyfour AI on inbound leads, enriches with deep research-grade signals, and writes a research brief into the CRM contact record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['hubspot'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour account intelligence', + prompt: + 'Create a workflow that for tracked accounts runs Sixtyfour deep research weekly, surfaces new signals, and writes the digest into a research table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour outbound briefer', + prompt: + 'Build a workflow that runs Sixtyfour on a prospect, generates a tailored outreach brief with hooks, and queues it for the rep to send via Email Bison.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour event-attendee researcher', + prompt: + 'Create a workflow that takes a Luma event attendee list, runs Sixtyfour deep research per attendee, and writes per-person briefs for the sales team.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['luma'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour competitor-intel digest', + prompt: + 'Build a scheduled weekly workflow that runs Sixtyfour deep research on competitors and writes a competitive-intel digest to a Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['slack'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour CRM enricher', + prompt: + 'Create a scheduled workflow that finds CRM accounts missing deep-research signals, runs Sixtyfour, and writes the structured findings back to the account record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: SixtyfourIcon, + title: 'Sixtyfour deal-prep packet', + prompt: + 'Build a workflow that runs Sixtyfour the morning of every meeting, generates a meeting-prep packet with company and attendee research, and emails the rep.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'enrich-lead', + description: + 'Enrich a single lead with Sixtyfour AI research to fill in role, company, and contact context.', + content: + '# Enrich Lead\n\nTurn a thin lead record into a researched profile.\n\n## Steps\n1. Run Enrich Lead with whatever you know about the person: name, company, email, or LinkedIn.\n2. Request only the fields you need to keep credit usage down.\n3. Review the returned profile: title, seniority, company, and any social or contact data.\n\n## Output\nReturn the enriched lead profile with the discovered role, company, and context, and note any fields the research could not resolve.', + }, + { + name: 'find-contact-details', + description: 'Find a verified email or phone number for a prospect using Sixtyfour AI.', + content: + '# Find Contact Details\n\nLocate a reachable email or phone number for a prospect.\n\n## Steps\n1. Provide the person identity you have: name plus company or domain.\n2. Run Find Email to discover a work email, or Find Phone for a phone number. Choose the professional or personal type as appropriate.\n3. Validate that the result matches the intended person before using it.\n\n## Output\nReturn the discovered email or phone number with its type, and clearly state if no verified contact could be found.', + }, + { + name: 'enrich-company', + description: + 'Research a company with Sixtyfour AI to build a firmographic and account-context profile.', + content: + '# Enrich Company\n\nBuild an account profile for a target company.\n\n## Steps\n1. Run Enrich Company with the company name or domain.\n2. Request the firmographic fields you need: industry, size, location, funding, and technologies in use.\n3. Use the result to qualify the account against your ideal customer profile.\n\n## Output\nReturn the company profile with industry, size, location, and notable signals, plus a short note on how well it fits the target profile.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sixtyfour.ts b/apps/sim/blocks/blocks/sixtyfour.ts index f0518e03e7e..c0f3207eca6 100644 --- a/apps/sim/blocks/blocks/sixtyfour.ts +++ b/apps/sim/blocks/blocks/sixtyfour.ts @@ -1,6 +1,5 @@ -import { SixtyfourIcon } from '@/components/icons' import { SixtyfourBlockDisplay } from '@/blocks/blocks/sixtyfour.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' export const SixtyfourBlock: BlockConfig = { ...SixtyfourBlockDisplay, @@ -287,101 +286,3 @@ export const SixtyfourBlock: BlockConfig = { }, }, } - -export const SixtyfourBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://sixtyfour.ai', - templates: [ - { - icon: SixtyfourIcon, - title: 'Sixtyfour contact researcher', - prompt: - 'Build a workflow that runs Sixtyfour AI on inbound leads, enriches with deep research-grade signals, and writes a research brief into the CRM contact record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['hubspot'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour account intelligence', - prompt: - 'Create a workflow that for tracked accounts runs Sixtyfour deep research weekly, surfaces new signals, and writes the digest into a research table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour outbound briefer', - prompt: - 'Build a workflow that runs Sixtyfour on a prospect, generates a tailored outreach brief with hooks, and queues it for the rep to send via Email Bison.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour event-attendee researcher', - prompt: - 'Create a workflow that takes a Luma event attendee list, runs Sixtyfour deep research per attendee, and writes per-person briefs for the sales team.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['luma'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour competitor-intel digest', - prompt: - 'Build a scheduled weekly workflow that runs Sixtyfour deep research on competitors and writes a competitive-intel digest to a Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['slack'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour CRM enricher', - prompt: - 'Create a scheduled workflow that finds CRM accounts missing deep-research signals, runs Sixtyfour, and writes the structured findings back to the account record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: SixtyfourIcon, - title: 'Sixtyfour deal-prep packet', - prompt: - 'Build a workflow that runs Sixtyfour the morning of every meeting, generates a meeting-prep packet with company and attendee research, and emails the rep.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'enrich-lead', - description: - 'Enrich a single lead with Sixtyfour AI research to fill in role, company, and contact context.', - content: - '# Enrich Lead\n\nTurn a thin lead record into a researched profile.\n\n## Steps\n1. Run Enrich Lead with whatever you know about the person: name, company, email, or LinkedIn.\n2. Request only the fields you need to keep credit usage down.\n3. Review the returned profile: title, seniority, company, and any social or contact data.\n\n## Output\nReturn the enriched lead profile with the discovered role, company, and context, and note any fields the research could not resolve.', - }, - { - name: 'find-contact-details', - description: 'Find a verified email or phone number for a prospect using Sixtyfour AI.', - content: - '# Find Contact Details\n\nLocate a reachable email or phone number for a prospect.\n\n## Steps\n1. Provide the person identity you have: name plus company or domain.\n2. Run Find Email to discover a work email, or Find Phone for a phone number. Choose the professional or personal type as appropriate.\n3. Validate that the result matches the intended person before using it.\n\n## Output\nReturn the discovered email or phone number with its type, and clearly state if no verified contact could be found.', - }, - { - name: 'enrich-company', - description: - 'Research a company with Sixtyfour AI to build a firmographic and account-context profile.', - content: - '# Enrich Company\n\nBuild an account profile for a target company.\n\n## Steps\n1. Run Enrich Company with the company name or domain.\n2. Request the firmographic fields you need: industry, size, location, funding, and technologies in use.\n3. Use the result to qualify the account against your ideal customer profile.\n\n## Output\nReturn the company profile with industry, size, location, and notable signals, plus a short note on how well it fits the target profile.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/slack.display.ts b/apps/sim/blocks/blocks/slack.display.ts index 7da2ceaed62..811b1f45292 100644 --- a/apps/sim/blocks/blocks/slack.display.ts +++ b/apps/sim/blocks/blocks/slack.display.ts @@ -1,6 +1,7 @@ -import { SlackIcon } from '@/components/icons' +import { BookOpen, ClipboardList, File, Table, Users } from '@/components/emcn/icons' +import { GoogleTranslateIcon, GreptileIcon, LinearIcon, SlackIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SlackBlockDisplay = { type: 'slack', @@ -16,3 +17,156 @@ export const SlackBlockDisplay = { integrationType: IntegrationType.Communication, triggerAllowed: true, } satisfies BlockDisplay + +export const SlackBlockMeta = { + tags: ['messaging', 'webhooks', 'automation'], + url: 'https://slack.com', + templates: [ + { + icon: SlackIcon, + title: 'Slack Q&A bot', + prompt: + 'Create a knowledge base connected to my Notion workspace so it stays synced with my company wiki. Then build a workflow that monitors Slack channels for questions and answers them using the knowledge base with source citations.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'communication', 'team'], + alsoIntegrations: ['notion'], + }, + { + icon: Table, + title: 'Churn risk detector', + prompt: + 'Create a workflow that monitors customer activity — support ticket frequency, response sentiment, usage patterns — scores each account for churn risk in a table, and triggers a Slack alert to the account team when a customer crosses the risk threshold.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'sales', 'monitoring', 'analysis'], + }, + { + icon: LinearIcon, + title: 'Incident postmortem writer', + prompt: + 'Create a workflow that when triggered after an incident, pulls the Slack thread from the incident channel, gathers relevant Sentry errors and deployment logs, and drafts a structured postmortem with timeline, root cause, and action items.', + modules: ['agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'devops', 'analysis'], + alsoIntegrations: ['sentry'], + }, + { + icon: GreptileIcon, + title: 'Slack code Q&A bot', + prompt: + 'Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files so the team gets quick, sourced engineering answers.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'communication', 'team'], + alsoIntegrations: ['greptile'], + }, + { + icon: SlackIcon, + title: 'Slack knowledge search', + prompt: + 'Create a knowledge base connected to my Slack workspace so all channel conversations and threads are automatically synced and searchable. Then build an agent I can ask things like "what did the team decide about the launch date?" or "what was the outcome of the design review?" and get answers with links to the original messages.', + modules: ['knowledge-base', 'agent'], + category: 'productivity', + tags: ['team', 'research', 'communication'], + }, + { + icon: File, + title: 'Automated narrative report', + prompt: + 'Build a scheduled workflow that pulls key data from my tables every week, analyzes trends and anomalies, and writes a narrative report — not just charts and numbers, but written insights explaining what changed, why it matters, and what to do next. Save it as a document and send a summary to Slack.', + modules: ['tables', 'scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['founder', 'reporting', 'analysis'], + }, + { + icon: BookOpen, + title: 'Email digest curator', + prompt: + 'Create a scheduled daily workflow that searches the web for the latest articles, papers, and news on topics I care about, picks the top 5 most relevant pieces, writes a one-paragraph summary for each, and delivers a curated reading digest to my inbox or Slack.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['individual', 'research', 'content'], + }, + { + icon: ClipboardList, + title: 'Daily standup summary', + prompt: + 'Create a scheduled workflow that reads the #standup Slack channel each morning, summarizes what everyone is working on, identifies blockers, and posts a structured recap to a Google Docs document.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting', 'communication'], + alsoIntegrations: ['google_docs'], + }, + { + icon: Users, + title: 'New hire onboarding automation', + prompt: + "Build a workflow that when triggered with a new hire's info, creates their accounts, sends a personalized welcome message in Slack, schedules 1:1s with their team on Google Calendar, shares relevant onboarding docs from the knowledge base, and tracks completion in a table.", + modules: ['knowledge-base', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation', 'team'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: Table, + title: 'Customer 360 view', + prompt: + 'Create a comprehensive customer table that aggregates data from my CRM, support tickets, billing history, and product usage into a single unified view per customer. Schedule it to sync daily and send a Slack alert when any customer shows signs of trouble across multiple signals.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['founder', 'sales', 'support', 'enterprise', 'sync'], + }, + { + icon: GoogleTranslateIcon, + title: 'Slack thread translator', + prompt: + 'Build a workflow that watches international Slack channels, detects non-English messages, translates them with Google Translate, and posts the English version in a thread so the wider team stays in the loop.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['google_translate'], + }, + + { + icon: SlackIcon, + title: 'Archive Slack conversations to Notion', + prompt: + 'Build a workflow that captures important Slack messages and threads and saves them as Notion pages or database entries, so meeting notes and decisions are always documented.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'communication'], + featured: true, + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'daily-standup-summary', + description: + 'Read a standup channel and post a structured recap of progress, plans, and blockers.', + content: + '# Daily Standup Summary\n\nRead the messages posted in the standup channel since the last working day and produce a concise team recap.\n\n## Steps\n1. Collect every standup update in the channel from the relevant window (skip bot and off-topic messages).\n2. Group the content into three sections:\n - **Done** — what was completed.\n - **Today** — what each person plans to work on.\n - **Blockers** — anything waiting on someone else, with the owner @-mentioned.\n3. Call out anyone who did not post an update.\n\n## Output\nPost a single threaded message with the three sections as bullet lists. Keep each bullet to one line. Lead with blockers if any exist so they are not missed.', + }, + { + name: 'channel-catch-up', + description: 'Summarize what happened in a busy Slack channel so you can catch up fast.', + content: + '# Channel Catch-Up\n\nSummarize recent activity in a Slack channel for someone who has been away.\n\n## Steps\n1. Pull messages from the requested time range (default: since the user was last active, or the last 24 hours).\n2. Cluster the conversation into topics or threads rather than listing messages chronologically.\n3. For each topic, capture: the gist, any decision reached, and open questions still unanswered.\n\n## Output\n- A 1-sentence TL;DR.\n- A bulleted list of topics, each with **Decision:** and **Open:** lines where relevant.\n- A final "Needs your input" list of items where the user was @-mentioned or a question is unresolved.\nLink to the source thread for each topic.', + }, + { + name: 'slack-question-responder', + description: + 'Watch a channel for questions and draft sourced, in-thread answers from your knowledge base.', + content: + '# Slack Question Responder\n\nMonitor a support or help channel and answer incoming questions.\n\n## Steps\n1. Detect when a message is a genuine question (ends in a question mark, asks "how/where/can someone", or is a help request).\n2. Search the connected knowledge base for the answer.\n3. If a confident answer exists, draft a concise reply in the thread with the answer and a citation/link to the source.\n4. If no confident answer exists, do not guess — post a short note that a human should help, and @-mention the channel owner.\n\n## Guidance\n- Always reply in-thread, never in the main channel.\n- Keep answers to 2–4 sentences plus the source link.\n- Never fabricate links or policy.', + }, + { + name: 'escalate-urgent-messages', + description: + 'Scan a channel for urgent or at-risk messages and surface them to the right owner.', + content: + '# Escalate Urgent Messages\n\nTriage a channel for messages that need fast attention.\n\n## Steps\n1. Review recent messages and classify each as **Urgent**, **Today**, or **FYI** based on signals like "blocked", "down", "ASAP", customer impact, or an unanswered direct ask.\n2. For Urgent items, identify the most likely owner from the channel topic or message context.\n3. Skip resolved threads (those with a ✅ reaction or a clear answer).\n\n## Output\nPost a short escalation summary listing only Urgent and Today items: each as a one-line description, an @-mention of the owner, and a link to the message. If nothing is urgent, say so in one line.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/slack.ts b/apps/sim/blocks/blocks/slack.ts index aee0e858832..2ca5c80ca16 100644 --- a/apps/sim/blocks/blocks/slack.ts +++ b/apps/sim/blocks/blocks/slack.ts @@ -1,8 +1,6 @@ -import { BookOpen, ClipboardList, File, Table, Users } from '@/components/emcn/icons' -import { GoogleTranslateIcon, GreptileIcon, LinearIcon, SlackIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { SlackBlockDisplay } from '@/blocks/blocks/slack.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SlackResponse } from '@/tools/slack/types' @@ -2220,156 +2218,3 @@ Do not include any explanations, markdown formatting, or other text outside the available: ['slack_webhook'], }, } - -export const SlackBlockMeta = { - tags: ['messaging', 'webhooks', 'automation'], - url: 'https://slack.com', - templates: [ - { - icon: SlackIcon, - title: 'Slack Q&A bot', - prompt: - 'Create a knowledge base connected to my Notion workspace so it stays synced with my company wiki. Then build a workflow that monitors Slack channels for questions and answers them using the knowledge base with source citations.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'communication', 'team'], - alsoIntegrations: ['notion'], - }, - { - icon: Table, - title: 'Churn risk detector', - prompt: - 'Create a workflow that monitors customer activity — support ticket frequency, response sentiment, usage patterns — scores each account for churn risk in a table, and triggers a Slack alert to the account team when a customer crosses the risk threshold.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'sales', 'monitoring', 'analysis'], - }, - { - icon: LinearIcon, - title: 'Incident postmortem writer', - prompt: - 'Create a workflow that when triggered after an incident, pulls the Slack thread from the incident channel, gathers relevant Sentry errors and deployment logs, and drafts a structured postmortem with timeline, root cause, and action items.', - modules: ['agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'devops', 'analysis'], - alsoIntegrations: ['sentry'], - }, - { - icon: GreptileIcon, - title: 'Slack code Q&A bot', - prompt: - 'Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files so the team gets quick, sourced engineering answers.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'communication', 'team'], - alsoIntegrations: ['greptile'], - }, - { - icon: SlackIcon, - title: 'Slack knowledge search', - prompt: - 'Create a knowledge base connected to my Slack workspace so all channel conversations and threads are automatically synced and searchable. Then build an agent I can ask things like "what did the team decide about the launch date?" or "what was the outcome of the design review?" and get answers with links to the original messages.', - modules: ['knowledge-base', 'agent'], - category: 'productivity', - tags: ['team', 'research', 'communication'], - }, - { - icon: File, - title: 'Automated narrative report', - prompt: - 'Build a scheduled workflow that pulls key data from my tables every week, analyzes trends and anomalies, and writes a narrative report — not just charts and numbers, but written insights explaining what changed, why it matters, and what to do next. Save it as a document and send a summary to Slack.', - modules: ['tables', 'scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['founder', 'reporting', 'analysis'], - }, - { - icon: BookOpen, - title: 'Email digest curator', - prompt: - 'Create a scheduled daily workflow that searches the web for the latest articles, papers, and news on topics I care about, picks the top 5 most relevant pieces, writes a one-paragraph summary for each, and delivers a curated reading digest to my inbox or Slack.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['individual', 'research', 'content'], - }, - { - icon: ClipboardList, - title: 'Daily standup summary', - prompt: - 'Create a scheduled workflow that reads the #standup Slack channel each morning, summarizes what everyone is working on, identifies blockers, and posts a structured recap to a Google Docs document.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting', 'communication'], - alsoIntegrations: ['google_docs'], - }, - { - icon: Users, - title: 'New hire onboarding automation', - prompt: - "Build a workflow that when triggered with a new hire's info, creates their accounts, sends a personalized welcome message in Slack, schedules 1:1s with their team on Google Calendar, shares relevant onboarding docs from the knowledge base, and tracks completion in a table.", - modules: ['knowledge-base', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation', 'team'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: Table, - title: 'Customer 360 view', - prompt: - 'Create a comprehensive customer table that aggregates data from my CRM, support tickets, billing history, and product usage into a single unified view per customer. Schedule it to sync daily and send a Slack alert when any customer shows signs of trouble across multiple signals.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['founder', 'sales', 'support', 'enterprise', 'sync'], - }, - { - icon: GoogleTranslateIcon, - title: 'Slack thread translator', - prompt: - 'Build a workflow that watches international Slack channels, detects non-English messages, translates them with Google Translate, and posts the English version in a thread so the wider team stays in the loop.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['google_translate'], - }, - - { - icon: SlackIcon, - title: 'Archive Slack conversations to Notion', - prompt: - 'Build a workflow that captures important Slack messages and threads and saves them as Notion pages or database entries, so meeting notes and decisions are always documented.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'communication'], - featured: true, - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'daily-standup-summary', - description: - 'Read a standup channel and post a structured recap of progress, plans, and blockers.', - content: - '# Daily Standup Summary\n\nRead the messages posted in the standup channel since the last working day and produce a concise team recap.\n\n## Steps\n1. Collect every standup update in the channel from the relevant window (skip bot and off-topic messages).\n2. Group the content into three sections:\n - **Done** — what was completed.\n - **Today** — what each person plans to work on.\n - **Blockers** — anything waiting on someone else, with the owner @-mentioned.\n3. Call out anyone who did not post an update.\n\n## Output\nPost a single threaded message with the three sections as bullet lists. Keep each bullet to one line. Lead with blockers if any exist so they are not missed.', - }, - { - name: 'channel-catch-up', - description: 'Summarize what happened in a busy Slack channel so you can catch up fast.', - content: - '# Channel Catch-Up\n\nSummarize recent activity in a Slack channel for someone who has been away.\n\n## Steps\n1. Pull messages from the requested time range (default: since the user was last active, or the last 24 hours).\n2. Cluster the conversation into topics or threads rather than listing messages chronologically.\n3. For each topic, capture: the gist, any decision reached, and open questions still unanswered.\n\n## Output\n- A 1-sentence TL;DR.\n- A bulleted list of topics, each with **Decision:** and **Open:** lines where relevant.\n- A final "Needs your input" list of items where the user was @-mentioned or a question is unresolved.\nLink to the source thread for each topic.', - }, - { - name: 'slack-question-responder', - description: - 'Watch a channel for questions and draft sourced, in-thread answers from your knowledge base.', - content: - '# Slack Question Responder\n\nMonitor a support or help channel and answer incoming questions.\n\n## Steps\n1. Detect when a message is a genuine question (ends in a question mark, asks "how/where/can someone", or is a help request).\n2. Search the connected knowledge base for the answer.\n3. If a confident answer exists, draft a concise reply in the thread with the answer and a citation/link to the source.\n4. If no confident answer exists, do not guess — post a short note that a human should help, and @-mention the channel owner.\n\n## Guidance\n- Always reply in-thread, never in the main channel.\n- Keep answers to 2–4 sentences plus the source link.\n- Never fabricate links or policy.', - }, - { - name: 'escalate-urgent-messages', - description: - 'Scan a channel for urgent or at-risk messages and surface them to the right owner.', - content: - '# Escalate Urgent Messages\n\nTriage a channel for messages that need fast attention.\n\n## Steps\n1. Review recent messages and classify each as **Urgent**, **Today**, or **FYI** based on signals like "blocked", "down", "ASAP", customer impact, or an unanswered direct ask.\n2. For Urgent items, identify the most likely owner from the channel topic or message context.\n3. Skip resolved threads (those with a ✅ reaction or a clear answer).\n\n## Output\nPost a short escalation summary listing only Urgent and Today items: each as a one-line description, an @-mention of the owner, and a link to the message. If nothing is urgent, say so in one line.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sportmonks.display.ts b/apps/sim/blocks/blocks/sportmonks.display.ts index 32f1842a134..20fe79f140a 100644 --- a/apps/sim/blocks/blocks/sportmonks.display.ts +++ b/apps/sim/blocks/blocks/sportmonks.display.ts @@ -1,6 +1,6 @@ import { SportmonksIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SportmonksBlockDisplay = { type: 'sportmonks', @@ -14,3 +14,139 @@ export const SportmonksBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sportmonks', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const SportmonksBlockMeta = { + tags: ['data-analytics'], + url: 'https://www.sportmonks.com', + templates: [ + { + icon: SportmonksIcon, + title: 'Daily football fixtures digest', + prompt: + "Build a scheduled daily workflow that fetches today's football fixtures from Sportmonks for the leagues I follow, summarizes the key matchups and kickoff times, and posts the digest to Slack.", + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SportmonksIcon, + title: 'Live football score alerter', + prompt: + 'Create a scheduled workflow that polls Sportmonks inplay football scores, detects goals and status changes since the last run, and pings Slack with the updated scoreline for tracked matches.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: SportmonksIcon, + title: 'Weekly league standings report', + prompt: + 'Build a scheduled weekly workflow that pulls the Sportmonks football standings and topscorers for a season, formats a league table with recent form, and emails the report to the group.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis'], + alsoIntegrations: ['gmail'], + }, + { + icon: SportmonksIcon, + title: 'Race weekend schedule digest', + prompt: + "Build a scheduled workflow that fetches this weekend's motorsport sessions from Sportmonks, summarizes the practice, qualifying, and race times, and posts the schedule to Slack.", + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['automation', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SportmonksIcon, + title: 'Motorsport championship tracker', + prompt: + 'Create a scheduled weekly workflow that pulls the Sportmonks motorsport driver and constructor standings for the current season, formats the championship tables, and emails them to the group.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis'], + alsoIntegrations: ['gmail'], + }, + { + icon: SportmonksIcon, + title: 'Pre-match odds snapshot', + prompt: + 'Build a workflow that pulls Sportmonks pre-match odds for a fixture across selected bookmakers, computes the implied probability for each outcome, and writes the snapshot to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis'], + }, + { + icon: SportmonksIcon, + title: 'Live odds movement alerter', + prompt: + 'Create a scheduled workflow that polls Sportmonks in-play odds for a fixture, detects sharp price moves since the last run, and pings Slack with the updated lines.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'finance'], + alsoIntegrations: ['slack'], + }, + { + icon: SportmonksIcon, + title: 'Head-to-head match preview', + prompt: + 'Create a workflow that takes two team names, resolves them to IDs via Sportmonks football team search, pulls their head-to-head history and current standings, and writes a match preview file.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content'], + }, + ], + skills: [ + { + name: 'daily-football-fixtures', + description: "List a day's football fixtures from Sportmonks, optionally filtered by league.", + content: + '# Daily Football Fixtures\n\nGet the football matches scheduled for a given day.\n\n## Steps\n1. Use Get Football Fixtures by Date with the target date in YYYY-MM-DD format.\n2. Optionally set Includes to `participants;scores;league` to enrich each fixture.\n3. Optionally set Filters such as `fixtureLeagues:501,271` to restrict to specific leagues.\n\n## Output\nA list of fixtures with kickoff time, the participating teams, and league.', + }, + { + name: 'live-football-scores', + description: 'Fetch in-play football matches and their current scores from Sportmonks.', + content: + '# Live Football Scores\n\nSee which matches are being played now and the live score.\n\n## Steps\n1. Use Get Inplay Football Scores to fetch matches in progress.\n2. Set Includes to `participants;scores` for team names and the scoreline.\n3. Optionally filter with `fixtureLeagues:501`.\n\n## Output\nA list of live fixtures, each with the two teams, current score, and match state.', + }, + { + name: 'football-league-table', + description: 'Build a football league standings table for a season from Sportmonks.', + content: + "# Football League Table\n\nGet the current standings for a competition.\n\n## Steps\n1. Find the season ID (use Get Football Leagues, then its current season).\n2. Use Get Football Standings by Season with that season ID.\n3. Set Includes to `participant` for team names and `form` for recent results.\n\n## Output\nAn ordered league table with each team's position, points, and recent form.", + }, + { + name: 'race-weekend-sessions', + description: 'List the motorsport sessions on a given date from Sportmonks.', + content: + '# Race Weekend Sessions\n\nGet the practice, qualifying, and race sessions for a day.\n\n## Steps\n1. Use Get Motorsport Fixtures by Date with the target date in YYYY-MM-DD format.\n2. Set Includes to `venue;participants` to attach the track and entrants.\n\n## Output\nA list of sessions for the day with type (Practice/Qualifying/Race), track, and start time.', + }, + { + name: 'motorsport-championship', + description: 'Fetch driver and constructor championship standings for a motorsport season.', + content: + "# Motorsport Championship\n\nGet the title race state for a season.\n\n## Steps\n1. Use Get Motorsport Driver Standings by Season with the season ID.\n2. Use Get Motorsport Team Standings by Season with the same season ID.\n3. Set Includes to `participant` for driver/team names.\n\n## Output\nOrdered drivers and constructors tables with each participant's position and points.", + }, + { + name: 'pre-match-odds', + description: 'Fetch pre-match odds for a fixture and compute implied probabilities.', + content: + '# Pre-match Odds\n\nGet the betting odds for an upcoming fixture.\n\n## Steps\n1. Use Get Pre-match Odds by Fixture with the fixture ID.\n2. Set Includes to `market;bookmaker` and optionally Filters like `bookmakers:2,14` to narrow results.\n\n## Output\nThe odds per outcome with decimal value and implied probability, grouped by market and bookmaker.', + }, + { + name: 'odds-line-shopping', + description: 'Find the best available price per outcome across bookmakers.', + content: + '# Odds Line Shopping\n\nFind the best odds for each outcome.\n\n## Steps\n1. Use Get Pre-match Odds by Fixture for the fixture (do not filter to one bookmaker).\n2. Group the returned odds by market and outcome label.\n3. For each outcome, pick the highest value and note its bookmaker_id.\n\n## Output\nFor each outcome, the best decimal price and which bookmaker offers it.', + }, + { + name: 'resolve-country', + description: + 'Resolve a country name to its Sportmonks ID and ISO codes via Core reference data.', + content: + '# Resolve Country\n\nNormalize a country name to Sportmonks reference data.\n\n## Steps\n1. Use Search Countries with the country name.\n2. Read the matching country id, iso2, iso3, and fifa_name.\n\n## Output\nThe country id plus its ISO2, ISO3, and FIFA codes for use in other lookups.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sportmonks.ts b/apps/sim/blocks/blocks/sportmonks.ts index 2c747718b4e..98d8473e921 100644 --- a/apps/sim/blocks/blocks/sportmonks.ts +++ b/apps/sim/blocks/blocks/sportmonks.ts @@ -1,6 +1,5 @@ -import { SportmonksIcon } from '@/components/icons' import { SportmonksBlockDisplay } from '@/blocks/blocks/sportmonks.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' const DATE_WAND_CONFIG = { enabled: true, @@ -2277,139 +2276,3 @@ export const SportmonksBlock: BlockConfig = { }, }, } - -export const SportmonksBlockMeta = { - tags: ['data-analytics'], - url: 'https://www.sportmonks.com', - templates: [ - { - icon: SportmonksIcon, - title: 'Daily football fixtures digest', - prompt: - "Build a scheduled daily workflow that fetches today's football fixtures from Sportmonks for the leagues I follow, summarizes the key matchups and kickoff times, and posts the digest to Slack.", - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SportmonksIcon, - title: 'Live football score alerter', - prompt: - 'Create a scheduled workflow that polls Sportmonks inplay football scores, detects goals and status changes since the last run, and pings Slack with the updated scoreline for tracked matches.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: SportmonksIcon, - title: 'Weekly league standings report', - prompt: - 'Build a scheduled weekly workflow that pulls the Sportmonks football standings and topscorers for a season, formats a league table with recent form, and emails the report to the group.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis'], - alsoIntegrations: ['gmail'], - }, - { - icon: SportmonksIcon, - title: 'Race weekend schedule digest', - prompt: - "Build a scheduled workflow that fetches this weekend's motorsport sessions from Sportmonks, summarizes the practice, qualifying, and race times, and posts the schedule to Slack.", - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['automation', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SportmonksIcon, - title: 'Motorsport championship tracker', - prompt: - 'Create a scheduled weekly workflow that pulls the Sportmonks motorsport driver and constructor standings for the current season, formats the championship tables, and emails them to the group.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis'], - alsoIntegrations: ['gmail'], - }, - { - icon: SportmonksIcon, - title: 'Pre-match odds snapshot', - prompt: - 'Build a workflow that pulls Sportmonks pre-match odds for a fixture across selected bookmakers, computes the implied probability for each outcome, and writes the snapshot to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis'], - }, - { - icon: SportmonksIcon, - title: 'Live odds movement alerter', - prompt: - 'Create a scheduled workflow that polls Sportmonks in-play odds for a fixture, detects sharp price moves since the last run, and pings Slack with the updated lines.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'finance'], - alsoIntegrations: ['slack'], - }, - { - icon: SportmonksIcon, - title: 'Head-to-head match preview', - prompt: - 'Create a workflow that takes two team names, resolves them to IDs via Sportmonks football team search, pulls their head-to-head history and current standings, and writes a match preview file.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content'], - }, - ], - skills: [ - { - name: 'daily-football-fixtures', - description: "List a day's football fixtures from Sportmonks, optionally filtered by league.", - content: - '# Daily Football Fixtures\n\nGet the football matches scheduled for a given day.\n\n## Steps\n1. Use Get Football Fixtures by Date with the target date in YYYY-MM-DD format.\n2. Optionally set Includes to `participants;scores;league` to enrich each fixture.\n3. Optionally set Filters such as `fixtureLeagues:501,271` to restrict to specific leagues.\n\n## Output\nA list of fixtures with kickoff time, the participating teams, and league.', - }, - { - name: 'live-football-scores', - description: 'Fetch in-play football matches and their current scores from Sportmonks.', - content: - '# Live Football Scores\n\nSee which matches are being played now and the live score.\n\n## Steps\n1. Use Get Inplay Football Scores to fetch matches in progress.\n2. Set Includes to `participants;scores` for team names and the scoreline.\n3. Optionally filter with `fixtureLeagues:501`.\n\n## Output\nA list of live fixtures, each with the two teams, current score, and match state.', - }, - { - name: 'football-league-table', - description: 'Build a football league standings table for a season from Sportmonks.', - content: - "# Football League Table\n\nGet the current standings for a competition.\n\n## Steps\n1. Find the season ID (use Get Football Leagues, then its current season).\n2. Use Get Football Standings by Season with that season ID.\n3. Set Includes to `participant` for team names and `form` for recent results.\n\n## Output\nAn ordered league table with each team's position, points, and recent form.", - }, - { - name: 'race-weekend-sessions', - description: 'List the motorsport sessions on a given date from Sportmonks.', - content: - '# Race Weekend Sessions\n\nGet the practice, qualifying, and race sessions for a day.\n\n## Steps\n1. Use Get Motorsport Fixtures by Date with the target date in YYYY-MM-DD format.\n2. Set Includes to `venue;participants` to attach the track and entrants.\n\n## Output\nA list of sessions for the day with type (Practice/Qualifying/Race), track, and start time.', - }, - { - name: 'motorsport-championship', - description: 'Fetch driver and constructor championship standings for a motorsport season.', - content: - "# Motorsport Championship\n\nGet the title race state for a season.\n\n## Steps\n1. Use Get Motorsport Driver Standings by Season with the season ID.\n2. Use Get Motorsport Team Standings by Season with the same season ID.\n3. Set Includes to `participant` for driver/team names.\n\n## Output\nOrdered drivers and constructors tables with each participant's position and points.", - }, - { - name: 'pre-match-odds', - description: 'Fetch pre-match odds for a fixture and compute implied probabilities.', - content: - '# Pre-match Odds\n\nGet the betting odds for an upcoming fixture.\n\n## Steps\n1. Use Get Pre-match Odds by Fixture with the fixture ID.\n2. Set Includes to `market;bookmaker` and optionally Filters like `bookmakers:2,14` to narrow results.\n\n## Output\nThe odds per outcome with decimal value and implied probability, grouped by market and bookmaker.', - }, - { - name: 'odds-line-shopping', - description: 'Find the best available price per outcome across bookmakers.', - content: - '# Odds Line Shopping\n\nFind the best odds for each outcome.\n\n## Steps\n1. Use Get Pre-match Odds by Fixture for the fixture (do not filter to one bookmaker).\n2. Group the returned odds by market and outcome label.\n3. For each outcome, pick the highest value and note its bookmaker_id.\n\n## Output\nFor each outcome, the best decimal price and which bookmaker offers it.', - }, - { - name: 'resolve-country', - description: - 'Resolve a country name to its Sportmonks ID and ISO codes via Core reference data.', - content: - '# Resolve Country\n\nNormalize a country name to Sportmonks reference data.\n\n## Steps\n1. Use Search Countries with the country name.\n2. Read the matching country id, iso2, iso3, and fifa_name.\n\n## Output\nThe country id plus its ISO2, ISO3, and FIFA codes for use in other lookups.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/spotify.display.ts b/apps/sim/blocks/blocks/spotify.display.ts index dfd27a4eded..9c980f65a62 100644 --- a/apps/sim/blocks/blocks/spotify.display.ts +++ b/apps/sim/blocks/blocks/spotify.display.ts @@ -1,6 +1,6 @@ import { SpotifyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SpotifyBlockDisplay = { type: 'spotify', @@ -15,3 +15,77 @@ export const SpotifyBlockDisplay = { integrationType: IntegrationType.Communication, hideFromToolbar: true, } satisfies BlockDisplay + +export const SpotifyBlockMeta = { + tags: ['content-management', 'automation'], + url: 'https://www.spotify.com', + templates: [ + { + icon: SpotifyIcon, + title: 'Spotify weekly playlist builder', + prompt: + 'Build a scheduled weekly workflow that searches Spotify for new releases in the genres a team follows, creates a fresh playlist, and adds the top tracks so there is always a curated Friday playlist ready.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['content', 'automation'], + }, + { + icon: SpotifyIcon, + title: 'Spotify request bot', + prompt: + 'Create a workflow triggered by a Slack message that takes a song request, searches Spotify for the best match, and adds the track to a shared office playlist, replying in the thread with what was added.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['content', 'communication', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: SpotifyIcon, + title: 'Spotify event soundtrack generator', + prompt: + 'Build a workflow that takes an event theme, searches Spotify for fitting tracks, creates a new playlist, sets a custom cover image, and returns the shareable playlist link for the event page.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['content', 'marketing', 'automation'], + }, + { + icon: SpotifyIcon, + title: 'Spotify podcast episode digest', + prompt: + 'Create a scheduled workflow that fetches the latest episodes for a set of Spotify shows, summarizes each episode’s description, and emails a weekly listening digest to the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['content', 'reporting', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: SpotifyIcon, + title: 'Spotify playlist growth tracker', + prompt: + 'Build a scheduled workflow that checks the follower count on each of an artist’s Spotify playlists, logs the daily totals to a table, and pings Slack when a playlist crosses a follower milestone.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SpotifyIcon, + title: 'Spotify new-music newsletter', + prompt: + 'Create a workflow that searches Spotify for this week’s releases from followed artists, builds a formatted newsletter section with track links, and drafts the email for the music team to send.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['content', 'email-marketing', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: SpotifyIcon, + title: 'Spotify follow-status checker', + prompt: + 'Build a workflow that takes a list of artist IDs, checks whether the connected Spotify account follows each one, and writes the follow status to a table so the team can audit which artists still need following.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'reporting'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/spotify.ts b/apps/sim/blocks/blocks/spotify.ts index 2605107056c..d2c4e164462 100644 --- a/apps/sim/blocks/blocks/spotify.ts +++ b/apps/sim/blocks/blocks/spotify.ts @@ -1,6 +1,5 @@ -import { SpotifyIcon } from '@/components/icons' import { SpotifyBlockDisplay } from '@/blocks/blocks/spotify.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ToolResponse } from '@/tools/types' @@ -1356,77 +1355,3 @@ export const SpotifyBlock: BlockConfig = { }, }, } - -export const SpotifyBlockMeta = { - tags: ['content-management', 'automation'], - url: 'https://www.spotify.com', - templates: [ - { - icon: SpotifyIcon, - title: 'Spotify weekly playlist builder', - prompt: - 'Build a scheduled weekly workflow that searches Spotify for new releases in the genres a team follows, creates a fresh playlist, and adds the top tracks so there is always a curated Friday playlist ready.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['content', 'automation'], - }, - { - icon: SpotifyIcon, - title: 'Spotify request bot', - prompt: - 'Create a workflow triggered by a Slack message that takes a song request, searches Spotify for the best match, and adds the track to a shared office playlist, replying in the thread with what was added.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['content', 'communication', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: SpotifyIcon, - title: 'Spotify event soundtrack generator', - prompt: - 'Build a workflow that takes an event theme, searches Spotify for fitting tracks, creates a new playlist, sets a custom cover image, and returns the shareable playlist link for the event page.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['content', 'marketing', 'automation'], - }, - { - icon: SpotifyIcon, - title: 'Spotify podcast episode digest', - prompt: - 'Create a scheduled workflow that fetches the latest episodes for a set of Spotify shows, summarizes each episode’s description, and emails a weekly listening digest to the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['content', 'reporting', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: SpotifyIcon, - title: 'Spotify playlist growth tracker', - prompt: - 'Build a scheduled workflow that checks the follower count on each of an artist’s Spotify playlists, logs the daily totals to a table, and pings Slack when a playlist crosses a follower milestone.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SpotifyIcon, - title: 'Spotify new-music newsletter', - prompt: - 'Create a workflow that searches Spotify for this week’s releases from followed artists, builds a formatted newsletter section with track links, and drafts the email for the music team to send.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['content', 'email-marketing', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: SpotifyIcon, - title: 'Spotify follow-status checker', - prompt: - 'Build a workflow that takes a list of artist IDs, checks whether the connected Spotify account follows each one, and writes the follow status to a table so the team can audit which artists still need following.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'reporting'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sqs.display.ts b/apps/sim/blocks/blocks/sqs.display.ts index 46a425e3ef9..28e3171b3b3 100644 --- a/apps/sim/blocks/blocks/sqs.display.ts +++ b/apps/sim/blocks/blocks/sqs.display.ts @@ -1,6 +1,6 @@ import { SQSIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SQSBlockDisplay = { type: 'sqs', @@ -14,3 +14,90 @@ export const SQSBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sqs', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const SQSBlockMeta = { + tags: ['cloud', 'messaging', 'automation'], + url: 'https://aws.amazon.com/sqs', + templates: [ + { + icon: SQSIcon, + title: 'SQS event dispatcher', + prompt: + 'Build a workflow that runs after a customer event is processed, formats a structured message, and pushes it onto an Amazon SQS queue so downstream worker services can pick it up. Log every dispatched event into a table for audit and replay.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + { + icon: SQSIcon, + title: 'Dead-letter queue replayer', + prompt: + 'Create a scheduled workflow that runs every morning, scans a table of failed jobs, regenerates the original payload, and republishes each failed message to its Amazon SQS queue with retry metadata so transient failures are recovered automatically.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + { + icon: SQSIcon, + title: 'Webhook to SQS bridge', + prompt: + 'Build a workflow exposed as a webhook endpoint that accepts inbound events from third-party services, validates the payload against a schema, transforms it into your internal event format, sends it to Amazon SQS for asynchronous processing, and returns an acknowledgement to the caller.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + { + icon: SQSIcon, + title: 'Alert fan-out queue', + prompt: + 'Create a workflow triggered by PagerDuty or Datadog alerts that classifies severity, decorates the payload with runbook context, and pushes the enriched alert to an Amazon SQS queue so multiple downstream notifiers and ticketing systems can consume it independently.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['pagerduty', 'datadog'], + }, + { + icon: SQSIcon, + title: 'Batch order processor', + prompt: + 'Build a workflow that takes a list of orders from a table and queues each one as a separate Amazon SQS message for parallel downstream processing. Track each enqueued message ID in the table so you can correlate downstream results back to the originating row.', + modules: ['tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'ecommerce', 'automation'], + }, + { + icon: SQSIcon, + title: 'Scheduled fan-out job', + prompt: + 'Create a scheduled workflow that runs every fifteen minutes, queries pending items from a table, batches them, and pushes one Amazon SQS message per batch to your worker queue. Update the table with batch IDs and timestamps so reprocessing is deterministic.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + { + icon: SQSIcon, + title: 'Cross-service notifier', + prompt: + 'Build a workflow that listens for completed builds in your CI tool, composes a status payload with build metadata and artifact links, and sends the payload to an Amazon SQS queue so internal services like deploy, audit, and notification workers can react asynchronously.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation', 'infrastructure'], + }, + ], + skills: [ + { + name: 'enqueue-job-message', + description: + 'Send a structured job message to an Amazon SQS queue to hand off background work.', + content: + '# Enqueue Job Message\n\nPublish a task onto an SQS queue for a worker to process asynchronously.\n\n## Steps\n1. Identify the target queue URL.\n2. Build the message body as JSON describing the job (type, payload, identifiers).\n3. For a FIFO queue, set the message group and deduplication IDs.\n4. Send the message.\n\n## Output\nConfirm the message was sent with its message ID and the queue it was placed on.', + }, + { + name: 'send-ordered-fifo-message', + description: + 'Send a message to an Amazon SQS FIFO queue with a message group ID and deduplication ID for ordered, exactly-once delivery.', + content: + '# Send Ordered FIFO Message\n\nDispatch a message to a FIFO queue when ordering within a stream and de-duplication matter.\n\n## Steps\n1. Identify the FIFO queue URL.\n2. Build the JSON message body.\n3. Set the message group ID so messages in the same group stay ordered, and set a deduplication ID to prevent duplicate sends.\n4. Send the message.\n\n## Output\nConfirm the message was sent with its message ID, group ID, and the queue it was placed on.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sqs.ts b/apps/sim/blocks/blocks/sqs.ts index 3ac5f4657e6..adfbf92c447 100644 --- a/apps/sim/blocks/blocks/sqs.ts +++ b/apps/sim/blocks/blocks/sqs.ts @@ -1,7 +1,6 @@ import { getErrorMessage } from '@sim/utils/errors' -import { SQSIcon } from '@/components/icons' import { SQSBlockDisplay } from '@/blocks/blocks/sqs.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { SqsResponse } from '@/tools/sqs/types' export const SQSBlock: BlockConfig = { @@ -147,90 +146,3 @@ export const SQSBlock: BlockConfig = { }, }, } - -export const SQSBlockMeta = { - tags: ['cloud', 'messaging', 'automation'], - url: 'https://aws.amazon.com/sqs', - templates: [ - { - icon: SQSIcon, - title: 'SQS event dispatcher', - prompt: - 'Build a workflow that runs after a customer event is processed, formats a structured message, and pushes it onto an Amazon SQS queue so downstream worker services can pick it up. Log every dispatched event into a table for audit and replay.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - { - icon: SQSIcon, - title: 'Dead-letter queue replayer', - prompt: - 'Create a scheduled workflow that runs every morning, scans a table of failed jobs, regenerates the original payload, and republishes each failed message to its Amazon SQS queue with retry metadata so transient failures are recovered automatically.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - { - icon: SQSIcon, - title: 'Webhook to SQS bridge', - prompt: - 'Build a workflow exposed as a webhook endpoint that accepts inbound events from third-party services, validates the payload against a schema, transforms it into your internal event format, sends it to Amazon SQS for asynchronous processing, and returns an acknowledgement to the caller.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - { - icon: SQSIcon, - title: 'Alert fan-out queue', - prompt: - 'Create a workflow triggered by PagerDuty or Datadog alerts that classifies severity, decorates the payload with runbook context, and pushes the enriched alert to an Amazon SQS queue so multiple downstream notifiers and ticketing systems can consume it independently.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['pagerduty', 'datadog'], - }, - { - icon: SQSIcon, - title: 'Batch order processor', - prompt: - 'Build a workflow that takes a list of orders from a table and queues each one as a separate Amazon SQS message for parallel downstream processing. Track each enqueued message ID in the table so you can correlate downstream results back to the originating row.', - modules: ['tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'ecommerce', 'automation'], - }, - { - icon: SQSIcon, - title: 'Scheduled fan-out job', - prompt: - 'Create a scheduled workflow that runs every fifteen minutes, queries pending items from a table, batches them, and pushes one Amazon SQS message per batch to your worker queue. Update the table with batch IDs and timestamps so reprocessing is deterministic.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - { - icon: SQSIcon, - title: 'Cross-service notifier', - prompt: - 'Build a workflow that listens for completed builds in your CI tool, composes a status payload with build metadata and artifact links, and sends the payload to an Amazon SQS queue so internal services like deploy, audit, and notification workers can react asynchronously.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation', 'infrastructure'], - }, - ], - skills: [ - { - name: 'enqueue-job-message', - description: - 'Send a structured job message to an Amazon SQS queue to hand off background work.', - content: - '# Enqueue Job Message\n\nPublish a task onto an SQS queue for a worker to process asynchronously.\n\n## Steps\n1. Identify the target queue URL.\n2. Build the message body as JSON describing the job (type, payload, identifiers).\n3. For a FIFO queue, set the message group and deduplication IDs.\n4. Send the message.\n\n## Output\nConfirm the message was sent with its message ID and the queue it was placed on.', - }, - { - name: 'send-ordered-fifo-message', - description: - 'Send a message to an Amazon SQS FIFO queue with a message group ID and deduplication ID for ordered, exactly-once delivery.', - content: - '# Send Ordered FIFO Message\n\nDispatch a message to a FIFO queue when ordering within a stream and de-duplication matter.\n\n## Steps\n1. Identify the FIFO queue URL.\n2. Build the JSON message body.\n3. Set the message group ID so messages in the same group stay ordered, and set a deduplication ID to prevent duplicate sends.\n4. Send the message.\n\n## Output\nConfirm the message was sent with its message ID, group ID, and the queue it was placed on.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/square.display.ts b/apps/sim/blocks/blocks/square.display.ts index 699be804b7d..edc7b5a6dbe 100644 --- a/apps/sim/blocks/blocks/square.display.ts +++ b/apps/sim/blocks/blocks/square.display.ts @@ -1,6 +1,6 @@ import { SquareIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SquareBlockDisplay = { type: 'square', @@ -14,3 +14,104 @@ export const SquareBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/square', integrationType: IntegrationType.Commerce, } satisfies BlockDisplay + +export const SquareBlockMeta = { + tags: ['payments', 'subscriptions', 'automation'], + url: 'https://squareup.com', + templates: [ + { + icon: SquareIcon, + title: 'Daily sales summary', + prompt: + 'Build a scheduled daily workflow that lists Square payments from the previous day across all locations, totals gross sales, refunds, and net revenue, writes the figures to a table for historical tracking, and posts a Slack summary with day-over-day trends.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting', 'founder'], + alsoIntegrations: ['slack'], + }, + { + icon: SquareIcon, + title: 'Refund pattern monitor', + prompt: + 'Create a scheduled weekly workflow that lists Square payments and their refunds, classifies each refund by reason and location, flags any location with an unusually high refund rate, and emails finance a narrative report with recommended actions.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'monitoring'], + alsoIntegrations: ['gmail'], + }, + { + icon: SquareIcon, + title: 'New customer welcome', + prompt: + 'Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sales', 'automation'], + alsoIntegrations: ['gmail', 'slack'], + }, + { + icon: SquareIcon, + title: 'Invoice chase automation', + prompt: + 'Create a scheduled workflow that lists Square invoices for a location, finds those that are unpaid past their due date, sends a polite reminder email per customer, and logs every chase action to a collections table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: SquareIcon, + title: 'Catalog image enrichment', + prompt: + 'Build a workflow that lists Square catalog items missing images, generates a product image for each one, uploads it as a catalog image attached to the item, and writes a report of which items were updated.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'automation'], + }, + { + icon: SquareIcon, + title: 'Low-stock reorder alerts', + prompt: + 'Create a scheduled workflow that lists the Square catalog, identifies items flagged as low or out of stock, drafts a reorder summary grouped by supplier, and posts it to a Slack purchasing channel with the items and quantities to reorder.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'operations'], + alsoIntegrations: ['slack'], + }, + { + icon: SquareIcon, + title: 'Customer purchase history lookup', + prompt: + 'Build a workflow that searches Square customers by email, pulls their orders and payments, summarizes lifetime spend and most-purchased items, and returns a concise profile the support team can use during a conversation.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + }, + ], + skills: [ + { + name: 'take-payment', + description: 'Take a Square payment from a payment source and confirm the result.', + content: + '# Take Payment\n\nCharge a customer using Square.\n\n## Steps\n1. Run Create Payment with the source ID (card nonce or card on file), the amount in the smallest denomination, and the currency.\n2. Optionally attach a customer ID, location ID, or order ID.\n3. Confirm the result with Get Payment if you need the latest status.\n\n## Output\nReturn the payment ID, status (APPROVED, COMPLETED, or FAILED), and the amount charged. If a refund is needed, run Refund Payment with the payment ID.', + }, + { + name: 'issue-and-publish-invoice', + description: 'Create a Square invoice for an order and publish it to the customer.', + content: + '# Issue And Publish Invoice\n\nBill a customer with a Square invoice.\n\n## Steps\n1. Make sure an order exists (use Create Order if needed) and you have the customer ID.\n2. Run Create Invoice with an invoice object referencing the location, order, primary recipient (customer), and payment requests. Note the returned invoice ID and version.\n3. Run Publish Invoice with that invoice ID and version to send it to the customer.\n4. Track payment with Get Invoice.\n\n## Output\nReturn the invoice ID, status, and the public URL where the customer can pay.', + }, + { + name: 'manage-catalog-item', + description: 'Create or update a Square catalog item and attach an image to it.', + content: + '# Manage Catalog Item\n\nBuild out the Square catalog.\n\n## Steps\n1. Run Upsert Catalog Object with an ITEM object (use a temporary id like "#Name" for new items). Capture the returned object ID.\n2. To add a picture, run Create Catalog Image with the image file and the object ID to attach it to the item.\n3. Verify with Get Catalog Object or Search Catalog Objects.\n\n## Output\nReturn the catalog object ID, type, and version, plus the image object ID when an image was attached.', + }, + { + name: 'find-customer-activity', + description: 'Look up a Square customer and summarize their orders and payments.', + content: + '# Find Customer Activity\n\nBuild a purchase history view for one customer.\n\n## Steps\n1. Run Search Customers (by email or phone) or Get Customer to identify the customer and their ID.\n2. Run Search Orders across the relevant locations filtered to that customer.\n3. Run List Payments and match payments to the customer for a full financial picture.\n\n## Output\nReturn the customer ID and email plus a summary of their orders and payments: total spend, number of orders, and any refunds.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/square.ts b/apps/sim/blocks/blocks/square.ts index 96ff3fb33fc..0999f847afc 100644 --- a/apps/sim/blocks/blocks/square.ts +++ b/apps/sim/blocks/blocks/square.ts @@ -1,6 +1,5 @@ -import { SquareIcon } from '@/components/icons' import { SquareBlockDisplay } from '@/blocks/blocks/square.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SquareResponse } from '@/tools/square/types' @@ -867,104 +866,3 @@ export const SquareBlock: BlockConfig = { metadata: { type: 'json', description: 'Operation summary metadata' }, }, } - -export const SquareBlockMeta = { - tags: ['payments', 'subscriptions', 'automation'], - url: 'https://squareup.com', - templates: [ - { - icon: SquareIcon, - title: 'Daily sales summary', - prompt: - 'Build a scheduled daily workflow that lists Square payments from the previous day across all locations, totals gross sales, refunds, and net revenue, writes the figures to a table for historical tracking, and posts a Slack summary with day-over-day trends.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting', 'founder'], - alsoIntegrations: ['slack'], - }, - { - icon: SquareIcon, - title: 'Refund pattern monitor', - prompt: - 'Create a scheduled weekly workflow that lists Square payments and their refunds, classifies each refund by reason and location, flags any location with an unusually high refund rate, and emails finance a narrative report with recommended actions.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis', 'monitoring'], - alsoIntegrations: ['gmail'], - }, - { - icon: SquareIcon, - title: 'New customer welcome', - prompt: - 'Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sales', 'automation'], - alsoIntegrations: ['gmail', 'slack'], - }, - { - icon: SquareIcon, - title: 'Invoice chase automation', - prompt: - 'Create a scheduled workflow that lists Square invoices for a location, finds those that are unpaid past their due date, sends a polite reminder email per customer, and logs every chase action to a collections table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: SquareIcon, - title: 'Catalog image enrichment', - prompt: - 'Build a workflow that lists Square catalog items missing images, generates a product image for each one, uploads it as a catalog image attached to the item, and writes a report of which items were updated.', - modules: ['agent', 'files', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'automation'], - }, - { - icon: SquareIcon, - title: 'Low-stock reorder alerts', - prompt: - 'Create a scheduled workflow that lists the Square catalog, identifies items flagged as low or out of stock, drafts a reorder summary grouped by supplier, and posts it to a Slack purchasing channel with the items and quantities to reorder.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'operations'], - alsoIntegrations: ['slack'], - }, - { - icon: SquareIcon, - title: 'Customer purchase history lookup', - prompt: - 'Build a workflow that searches Square customers by email, pulls their orders and payments, summarizes lifetime spend and most-purchased items, and returns a concise profile the support team can use during a conversation.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis'], - }, - ], - skills: [ - { - name: 'take-payment', - description: 'Take a Square payment from a payment source and confirm the result.', - content: - '# Take Payment\n\nCharge a customer using Square.\n\n## Steps\n1. Run Create Payment with the source ID (card nonce or card on file), the amount in the smallest denomination, and the currency.\n2. Optionally attach a customer ID, location ID, or order ID.\n3. Confirm the result with Get Payment if you need the latest status.\n\n## Output\nReturn the payment ID, status (APPROVED, COMPLETED, or FAILED), and the amount charged. If a refund is needed, run Refund Payment with the payment ID.', - }, - { - name: 'issue-and-publish-invoice', - description: 'Create a Square invoice for an order and publish it to the customer.', - content: - '# Issue And Publish Invoice\n\nBill a customer with a Square invoice.\n\n## Steps\n1. Make sure an order exists (use Create Order if needed) and you have the customer ID.\n2. Run Create Invoice with an invoice object referencing the location, order, primary recipient (customer), and payment requests. Note the returned invoice ID and version.\n3. Run Publish Invoice with that invoice ID and version to send it to the customer.\n4. Track payment with Get Invoice.\n\n## Output\nReturn the invoice ID, status, and the public URL where the customer can pay.', - }, - { - name: 'manage-catalog-item', - description: 'Create or update a Square catalog item and attach an image to it.', - content: - '# Manage Catalog Item\n\nBuild out the Square catalog.\n\n## Steps\n1. Run Upsert Catalog Object with an ITEM object (use a temporary id like "#Name" for new items). Capture the returned object ID.\n2. To add a picture, run Create Catalog Image with the image file and the object ID to attach it to the item.\n3. Verify with Get Catalog Object or Search Catalog Objects.\n\n## Output\nReturn the catalog object ID, type, and version, plus the image object ID when an image was attached.', - }, - { - name: 'find-customer-activity', - description: 'Look up a Square customer and summarize their orders and payments.', - content: - '# Find Customer Activity\n\nBuild a purchase history view for one customer.\n\n## Steps\n1. Run Search Customers (by email or phone) or Get Customer to identify the customer and their ID.\n2. Run Search Orders across the relevant locations filtered to that customer.\n3. Run List Payments and match payments to the customer for a full financial picture.\n\n## Output\nReturn the customer ID and email plus a summary of their orders and payments: total spend, number of orders, and any refunds.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/stagehand.display.ts b/apps/sim/blocks/blocks/stagehand.display.ts index aadef21d108..dc7132ec0b8 100644 --- a/apps/sim/blocks/blocks/stagehand.display.ts +++ b/apps/sim/blocks/blocks/stagehand.display.ts @@ -1,6 +1,6 @@ import { StagehandIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const StagehandBlockDisplay = { type: 'stagehand', @@ -14,3 +14,97 @@ export const StagehandBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/stagehand', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const StagehandBlockMeta = { + tags: ['web-scraping', 'automation', 'agentic'], + url: 'https://www.stagehand.dev', + templates: [ + { + icon: StagehandIcon, + title: 'Stagehand QA navigator', + prompt: + 'Build a workflow that uses Stagehand to run scripted browser flows against staging, captures screenshots and assertion outcomes per step, and writes a regression report file.', + modules: ['files', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'automation'], + }, + { + icon: StagehandIcon, + title: 'Stagehand booking automator', + prompt: + 'Create a workflow that uses Stagehand to log into supplier portals, place recurring orders from a tables-defined catalog, and write confirmation numbers back to the orders table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'ecommerce'], + }, + { + icon: StagehandIcon, + title: 'Stagehand price-monitor sweep', + prompt: + 'Build a scheduled workflow that uses Stagehand to navigate a catalog of supplier sites, capture current prices and stock for items in a tracking table, and alert Slack on threshold breaches.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: StagehandIcon, + title: 'Stagehand competitor product trial', + prompt: + 'Build a workflow that uses Stagehand to walk through competitor product trials weekly, captures screenshots of every step, and writes a UX-comparison file.', + modules: ['scheduled', 'files', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: StagehandIcon, + title: 'Stagehand onboarding-flow auditor', + prompt: + 'Create a workflow that uses Stagehand to test the production onboarding flow daily, captures friction points, and writes a UX regression table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'monitoring'], + }, + { + icon: StagehandIcon, + title: 'Stagehand structured lead extractor', + prompt: + 'Build a workflow that uses Stagehand to visit a list of company sites from a table, extracts structured fields — company name, contact email, pricing tier, and key features — into a defined schema, and writes the clean records back into a research table for the sales team.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'automation'], + }, + { + icon: StagehandIcon, + title: 'Stagehand autonomous task runner', + prompt: + 'Create a workflow that hands Stagehand a natural-language goal like "find the latest pricing on this vendor site and download the PDF", lets the Stagehand agent navigate and act on the page autonomously, and saves the captured result and screenshots to files.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'research', 'agentic'], + }, + ], + skills: [ + { + name: 'extract-structured-data', + description: + 'Use Stagehand to extract structured fields from a web page into a typed result.', + content: + '# Extract Structured Data\n\nPull clean, structured data off a single web page.\n\n## Steps\n1. Run the Extract Data operation with the target URL.\n2. Describe exactly what to extract and the shape you want (for example product name, price, and availability), so Stagehand returns typed fields rather than raw HTML.\n3. Choose the LLM provider for the extraction.\n\n## Output\nReturn the extracted fields as a structured object, and note any field the page did not contain so downstream steps can handle gaps.', + }, + { + name: 'run-browser-agent-task', + description: + 'Hand Stagehand a natural-language goal and let its agent navigate and act on a site autonomously.', + content: + '# Run Browser Agent Task\n\nDelegate a multi-step web task to the Stagehand agent.\n\n## Steps\n1. Run the Run Agent operation with a clear natural-language goal (for example find the latest pricing on a vendor site and capture it).\n2. Provide the starting URL and pick the execution mode (DOM, hybrid, or CUA) and the LLM provider appropriate to the task.\n3. Let the agent navigate, click, and read pages to complete the goal.\n\n## Output\nReturn the agent result, the key data it captured, and any screenshots, plus a short note if the goal could not be fully completed.', + }, + { + name: 'monitor-page-for-changes', + description: + 'Periodically extract a value from a web page with Stagehand and report when it changes.', + content: + '# Monitor Page for Changes\n\nWatch a specific value on a web page over time.\n\n## Steps\n1. Run the Extract Data operation against the target URL, extracting just the value to watch (price, stock status, headline).\n2. Compare the extracted value against the last known value stored from a previous run.\n3. Decide whether the value changed beyond a meaningful threshold.\n\n## Output\nReport the current extracted value, whether it changed since the last check, and the old and new values when a change is detected.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/stagehand.ts b/apps/sim/blocks/blocks/stagehand.ts index da8e97d1fd9..24de4b79dee 100644 --- a/apps/sim/blocks/blocks/stagehand.ts +++ b/apps/sim/blocks/blocks/stagehand.ts @@ -1,6 +1,5 @@ -import { StagehandIcon } from '@/components/icons' import { StagehandBlockDisplay } from '@/blocks/blocks/stagehand.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { StagehandAgentResponse, StagehandExtractResponse } from '@/tools/stagehand/types' export type StagehandResponse = StagehandExtractResponse | StagehandAgentResponse @@ -413,97 +412,3 @@ Example 3 (Data Collection): sessionId: { type: 'string', description: 'Browserbase session identifier (agent operation)' }, }, } - -export const StagehandBlockMeta = { - tags: ['web-scraping', 'automation', 'agentic'], - url: 'https://www.stagehand.dev', - templates: [ - { - icon: StagehandIcon, - title: 'Stagehand QA navigator', - prompt: - 'Build a workflow that uses Stagehand to run scripted browser flows against staging, captures screenshots and assertion outcomes per step, and writes a regression report file.', - modules: ['files', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'automation'], - }, - { - icon: StagehandIcon, - title: 'Stagehand booking automator', - prompt: - 'Create a workflow that uses Stagehand to log into supplier portals, place recurring orders from a tables-defined catalog, and write confirmation numbers back to the orders table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'ecommerce'], - }, - { - icon: StagehandIcon, - title: 'Stagehand price-monitor sweep', - prompt: - 'Build a scheduled workflow that uses Stagehand to navigate a catalog of supplier sites, capture current prices and stock for items in a tracking table, and alert Slack on threshold breaches.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: StagehandIcon, - title: 'Stagehand competitor product trial', - prompt: - 'Build a workflow that uses Stagehand to walk through competitor product trials weekly, captures screenshots of every step, and writes a UX-comparison file.', - modules: ['scheduled', 'files', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: StagehandIcon, - title: 'Stagehand onboarding-flow auditor', - prompt: - 'Create a workflow that uses Stagehand to test the production onboarding flow daily, captures friction points, and writes a UX regression table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'monitoring'], - }, - { - icon: StagehandIcon, - title: 'Stagehand structured lead extractor', - prompt: - 'Build a workflow that uses Stagehand to visit a list of company sites from a table, extracts structured fields — company name, contact email, pricing tier, and key features — into a defined schema, and writes the clean records back into a research table for the sales team.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'automation'], - }, - { - icon: StagehandIcon, - title: 'Stagehand autonomous task runner', - prompt: - 'Create a workflow that hands Stagehand a natural-language goal like "find the latest pricing on this vendor site and download the PDF", lets the Stagehand agent navigate and act on the page autonomously, and saves the captured result and screenshots to files.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'research', 'agentic'], - }, - ], - skills: [ - { - name: 'extract-structured-data', - description: - 'Use Stagehand to extract structured fields from a web page into a typed result.', - content: - '# Extract Structured Data\n\nPull clean, structured data off a single web page.\n\n## Steps\n1. Run the Extract Data operation with the target URL.\n2. Describe exactly what to extract and the shape you want (for example product name, price, and availability), so Stagehand returns typed fields rather than raw HTML.\n3. Choose the LLM provider for the extraction.\n\n## Output\nReturn the extracted fields as a structured object, and note any field the page did not contain so downstream steps can handle gaps.', - }, - { - name: 'run-browser-agent-task', - description: - 'Hand Stagehand a natural-language goal and let its agent navigate and act on a site autonomously.', - content: - '# Run Browser Agent Task\n\nDelegate a multi-step web task to the Stagehand agent.\n\n## Steps\n1. Run the Run Agent operation with a clear natural-language goal (for example find the latest pricing on a vendor site and capture it).\n2. Provide the starting URL and pick the execution mode (DOM, hybrid, or CUA) and the LLM provider appropriate to the task.\n3. Let the agent navigate, click, and read pages to complete the goal.\n\n## Output\nReturn the agent result, the key data it captured, and any screenshots, plus a short note if the goal could not be fully completed.', - }, - { - name: 'monitor-page-for-changes', - description: - 'Periodically extract a value from a web page with Stagehand and report when it changes.', - content: - '# Monitor Page for Changes\n\nWatch a specific value on a web page over time.\n\n## Steps\n1. Run the Extract Data operation against the target URL, extracting just the value to watch (price, stock status, headline).\n2. Compare the extracted value against the last known value stored from a previous run.\n3. Decide whether the value changed beyond a meaningful threshold.\n\n## Output\nReport the current extracted value, whether it changed since the last check, and the old and new values when a change is detected.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/stripe.display.ts b/apps/sim/blocks/blocks/stripe.display.ts index a7e4d1c48c6..03bfb0dce63 100644 --- a/apps/sim/blocks/blocks/stripe.display.ts +++ b/apps/sim/blocks/blocks/stripe.display.ts @@ -1,6 +1,6 @@ -import { StripeIcon } from '@/components/icons' +import { GoogleSheetsIcon, StripeIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const StripeBlockDisplay = { type: 'stripe', @@ -15,3 +15,108 @@ export const StripeBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/stripe', integrationType: IntegrationType.Commerce, } satisfies BlockDisplay + +export const StripeBlockMeta = { + tags: ['payments', 'subscriptions', 'webhooks'], + url: 'https://stripe.com', + templates: [ + { + icon: GoogleSheetsIcon, + title: 'Weekly metrics report', + prompt: + 'Build a scheduled workflow that pulls data from Stripe and my database every Monday, calculates key metrics like MRR, churn, new subscriptions, and failed payments, writes results to Google Sheets, and sends the team a Slack summary with week-over-week trends.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['founder', 'finance', 'reporting'], + alsoIntegrations: ['google_sheets', 'slack'], + }, + { + icon: StripeIcon, + title: 'Revenue operations dashboard', + prompt: + 'Create a scheduled daily workflow that pulls payment data from Stripe, calculates MRR, net revenue, failed payments, and new subscriptions, logs everything to a table with historical tracking, and sends a daily Slack summary with trends and anomalies.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'founder', 'reporting', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: StripeIcon, + title: 'Failed payment recovery', + prompt: + 'Build a workflow that listens for Stripe failed-payment events, looks up the customer, classifies the failure reason, drafts a tailored recovery email and a Slack alert to the success team, and logs the attempt in a tracking table so recovery rate can be measured.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'support', 'automation'], + alsoIntegrations: ['gmail', 'slack'], + }, + { + icon: StripeIcon, + title: 'Subscription churn flagger', + prompt: + 'Create a scheduled daily workflow that lists Stripe subscriptions canceled or scheduled for cancellation, enriches each customer with usage and support history, scores the churn risk, and logs the cohort to a table with recommended save plays for the success team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'support', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: StripeIcon, + title: 'Invoice chase automation', + prompt: + 'Build a scheduled workflow that lists Stripe invoices overdue by more than seven days, sends a polite chase email tailored to the customer history, escalates to a Slack alert at thirty days, and writes every action into a collections tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation', 'reporting'], + alsoIntegrations: ['gmail', 'slack'], + }, + { + icon: StripeIcon, + title: 'New customer welcome flow', + prompt: + 'Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'sales', 'automation'], + alsoIntegrations: ['gmail', 'calendly', 'slack'], + }, + { + icon: StripeIcon, + title: 'Refund pattern analyzer', + prompt: + 'Build a scheduled weekly workflow that lists Stripe charge and dispute events, classifies each refund or dispute by reason and product, identifies recurring patterns or fraud signals, writes a narrative report file, and Slacks finance with the top concerns and recommended actions.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'collect-payment', + description: + 'Create and confirm a Stripe payment intent to collect a charge from a customer.', + content: + '# Collect Payment\n\nCharge a customer by creating and confirming a payment intent.\n\n## Steps\n1. Run Create Payment Intent with the amount, currency, and customer.\n2. Confirm the intent with Confirm Payment Intent, or Capture Payment Intent if it was created for manual capture.\n3. If a charge needs to be aborted, run Cancel Payment Intent instead.\n\n## Output\nReturn the payment intent ID, its status (succeeded, requires action, or canceled), and the captured amount.', + }, + { + name: 'manage-subscription', + description: 'Create, update, pause, or cancel a Stripe subscription for a customer.', + content: + '# Manage Subscription\n\nHandle the lifecycle of a recurring subscription.\n\n## Steps\n1. To start a subscription, run Create Subscription with the customer and price items.\n2. To change a plan, run Update Subscription with the new items. To pause and later restart, use Cancel Subscription or Resume Subscription as appropriate.\n3. Confirm the current state with Retrieve Subscription.\n\n## Output\nReturn the subscription ID, its status, current period end, and the plan items, and note exactly what changed.', + }, + { + name: 'issue-invoice', + description: 'Create, finalize, and send a Stripe invoice to a customer, then track payment.', + content: + '# Issue Invoice\n\nBill a customer with a Stripe invoice.\n\n## Steps\n1. Run Create Invoice for the customer with the line items.\n2. Run Finalize Invoice to lock it, then Send Invoice to deliver it to the customer.\n3. Track payment with Retrieve Invoice, or run Pay Invoice to charge a saved payment method. Use Void Invoice to cancel an unpaid invoice.\n\n## Output\nReturn the invoice ID, its status (draft, open, paid, or void), the amount due, and the hosted invoice URL when available.', + }, + { + name: 'find-customer-activity', + description: + 'Look up a Stripe customer and search their charges and payments for a financial summary.', + content: + '# Find Customer Activity\n\nBuild a payment history view for a single customer.\n\n## Steps\n1. Run Search Customers or Retrieve Customer to identify the customer and their ID.\n2. Run Search Charges or List Charges filtered to that customer to pull their transactions.\n3. Optionally run Search Payment Intents and List Invoices for a complete picture.\n\n## Output\nReturn the customer ID and email plus a summary of their charges and invoices, including total amount, successful versus failed payments, and any refunds.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/stripe.ts b/apps/sim/blocks/blocks/stripe.ts index 293f9838b83..5087ee43ab7 100644 --- a/apps/sim/blocks/blocks/stripe.ts +++ b/apps/sim/blocks/blocks/stripe.ts @@ -1,6 +1,5 @@ -import { GoogleSheetsIcon, StripeIcon } from '@/components/icons' import { StripeBlockDisplay } from '@/blocks/blocks/stripe.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { StripeResponse } from '@/tools/stripe/types' import { getTrigger } from '@/triggers' @@ -833,108 +832,3 @@ export const StripeBlock: BlockConfig = { available: ['stripe_webhook'], }, } - -export const StripeBlockMeta = { - tags: ['payments', 'subscriptions', 'webhooks'], - url: 'https://stripe.com', - templates: [ - { - icon: GoogleSheetsIcon, - title: 'Weekly metrics report', - prompt: - 'Build a scheduled workflow that pulls data from Stripe and my database every Monday, calculates key metrics like MRR, churn, new subscriptions, and failed payments, writes results to Google Sheets, and sends the team a Slack summary with week-over-week trends.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['founder', 'finance', 'reporting'], - alsoIntegrations: ['google_sheets', 'slack'], - }, - { - icon: StripeIcon, - title: 'Revenue operations dashboard', - prompt: - 'Create a scheduled daily workflow that pulls payment data from Stripe, calculates MRR, net revenue, failed payments, and new subscriptions, logs everything to a table with historical tracking, and sends a daily Slack summary with trends and anomalies.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'founder', 'reporting', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: StripeIcon, - title: 'Failed payment recovery', - prompt: - 'Build a workflow that listens for Stripe failed-payment events, looks up the customer, classifies the failure reason, drafts a tailored recovery email and a Slack alert to the success team, and logs the attempt in a tracking table so recovery rate can be measured.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'support', 'automation'], - alsoIntegrations: ['gmail', 'slack'], - }, - { - icon: StripeIcon, - title: 'Subscription churn flagger', - prompt: - 'Create a scheduled daily workflow that lists Stripe subscriptions canceled or scheduled for cancellation, enriches each customer with usage and support history, scores the churn risk, and logs the cohort to a table with recommended save plays for the success team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'support', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: StripeIcon, - title: 'Invoice chase automation', - prompt: - 'Build a scheduled workflow that lists Stripe invoices overdue by more than seven days, sends a polite chase email tailored to the customer history, escalates to a Slack alert at thirty days, and writes every action into a collections tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation', 'reporting'], - alsoIntegrations: ['gmail', 'slack'], - }, - { - icon: StripeIcon, - title: 'New customer welcome flow', - prompt: - 'Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'sales', 'automation'], - alsoIntegrations: ['gmail', 'calendly', 'slack'], - }, - { - icon: StripeIcon, - title: 'Refund pattern analyzer', - prompt: - 'Build a scheduled weekly workflow that lists Stripe charge and dispute events, classifies each refund or dispute by reason and product, identifies recurring patterns or fraud signals, writes a narrative report file, and Slacks finance with the top concerns and recommended actions.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['finance', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'collect-payment', - description: - 'Create and confirm a Stripe payment intent to collect a charge from a customer.', - content: - '# Collect Payment\n\nCharge a customer by creating and confirming a payment intent.\n\n## Steps\n1. Run Create Payment Intent with the amount, currency, and customer.\n2. Confirm the intent with Confirm Payment Intent, or Capture Payment Intent if it was created for manual capture.\n3. If a charge needs to be aborted, run Cancel Payment Intent instead.\n\n## Output\nReturn the payment intent ID, its status (succeeded, requires action, or canceled), and the captured amount.', - }, - { - name: 'manage-subscription', - description: 'Create, update, pause, or cancel a Stripe subscription for a customer.', - content: - '# Manage Subscription\n\nHandle the lifecycle of a recurring subscription.\n\n## Steps\n1. To start a subscription, run Create Subscription with the customer and price items.\n2. To change a plan, run Update Subscription with the new items. To pause and later restart, use Cancel Subscription or Resume Subscription as appropriate.\n3. Confirm the current state with Retrieve Subscription.\n\n## Output\nReturn the subscription ID, its status, current period end, and the plan items, and note exactly what changed.', - }, - { - name: 'issue-invoice', - description: 'Create, finalize, and send a Stripe invoice to a customer, then track payment.', - content: - '# Issue Invoice\n\nBill a customer with a Stripe invoice.\n\n## Steps\n1. Run Create Invoice for the customer with the line items.\n2. Run Finalize Invoice to lock it, then Send Invoice to deliver it to the customer.\n3. Track payment with Retrieve Invoice, or run Pay Invoice to charge a saved payment method. Use Void Invoice to cancel an unpaid invoice.\n\n## Output\nReturn the invoice ID, its status (draft, open, paid, or void), the amount due, and the hosted invoice URL when available.', - }, - { - name: 'find-customer-activity', - description: - 'Look up a Stripe customer and search their charges and payments for a financial summary.', - content: - '# Find Customer Activity\n\nBuild a payment history view for a single customer.\n\n## Steps\n1. Run Search Customers or Retrieve Customer to identify the customer and their ID.\n2. Run Search Charges or List Charges filtered to that customer to pull their transactions.\n3. Optionally run Search Payment Intents and List Invoices for a complete picture.\n\n## Output\nReturn the customer ID and email plus a summary of their charges and invoices, including total amount, successful versus failed payments, and any refunds.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sts.display.ts b/apps/sim/blocks/blocks/sts.display.ts index df1e17eea63..3630b5ea9ba 100644 --- a/apps/sim/blocks/blocks/sts.display.ts +++ b/apps/sim/blocks/blocks/sts.display.ts @@ -1,6 +1,6 @@ import { STSIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const STSBlockDisplay = { type: 'sts', @@ -14,3 +14,107 @@ export const STSBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/sts', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const STSBlockMeta = { + tags: ['cloud', 'identity'], + url: 'https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html', + templates: [ + { + icon: STSIcon, + title: 'AWS STS access key identifier', + prompt: + 'Build a workflow that takes an AWS access key ID, uses AWS STS to look up the owning account and entity, flags keys that belong to unexpected accounts, and pings the security Slack channel.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: STSIcon, + title: 'STS short-lived credential provisioner', + prompt: + 'Create a workflow that on a request grants short-lived AWS STS credentials with the minimum required scope, captures the audit record, and revokes on completion.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + }, + { + icon: STSIcon, + title: 'STS caller identity verifier', + prompt: + 'Build a scheduled workflow that calls AWS STS get caller identity for each configured set of credentials, confirms the resolved account and ARN match the expected principal, and writes a verification report.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + { + icon: STSIcon, + title: 'STS session token rotator', + prompt: + 'Create a scheduled daily workflow that mints fresh AWS STS session tokens for service accounts that need them, records each token expiration in a security log, and flags any token issuance that fails.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + }, + { + icon: STSIcon, + title: 'STS just-in-time access grant', + prompt: + 'Build a workflow that handles JIT-access requests, captures Slack-based approval, mints short-lived AWS STS credentials, and writes the access record.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: STSIcon, + title: 'STS cross-account access grant', + prompt: + 'Create a workflow that handles cross-account access requests, assumes the target AWS STS role with the supplied external ID, requires owner attestation in Slack, and writes the grant record to a compliance table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: STSIcon, + title: 'STS Identity-Center role broker', + prompt: + 'Build a workflow that takes an Identity Center user request, assumes the matching AWS STS role to mint scoped short-lived credentials, writes the issuance to a session log, and alerts Slack when a request targets a privileged role.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['identity_center', 'slack'], + }, + ], + skills: [ + { + name: 'assume-cross-account-role', + description: + 'Call AWS STS to assume a role and obtain temporary credentials for a target account. Use for cross-account access in a workflow.', + content: + '# Assume Cross-Account Role\n\nObtain temporary credentials by assuming an IAM role.\n\n## Steps\n1. Identify the role ARN to assume and a descriptive session name.\n2. Set the session duration and any external ID required by the trust policy.\n3. Call assume role to receive temporary access key, secret key, and session token.\n4. Pass the temporary credentials to the downstream step that needs cross-account access.\n\n## Output\nConfirm the assumed role ARN and credential expiration. Never print the secret access key or session token in plain logs.', + }, + { + name: 'verify-caller-identity', + description: + 'Use AWS STS get caller identity to confirm which account, user, or role the current credentials resolve to. Use to validate setup and debug auth issues.', + content: + '# Verify Caller Identity\n\nConfirm which AWS identity the workflow is operating as.\n\n## Steps\n1. Call get caller identity with the active credentials.\n2. Read the returned account ID, user ID, and principal ARN.\n3. Compare against the expected account and role for the task.\n4. If it does not match, flag a likely credential or assume-role misconfiguration.\n\n## Output\nReport the account ID and ARN of the active identity, and whether it matches the expected principal.', + }, + { + name: 'mint-mfa-session-token', + description: + 'Use AWS STS to mint short-lived session credentials, optionally backed by an MFA token, for IAM-user workflows that require MFA. Use for time-boxed elevated sessions.', + content: + '# Mint MFA Session Token\n\nIssue temporary credentials, optionally enforcing MFA.\n\n## Steps\n1. Decide the session duration the downstream task needs.\n2. If MFA is required, supply the MFA device serial number and the current token code.\n3. Call get session token to receive a temporary access key, secret key, and session token.\n4. Hand the temporary credentials to the step that needs them and let them expire naturally.\n\n## Output\nConfirm that a session token was issued and its expiration time. Never print the secret access key or session token value.', + }, + { + name: 'identify-access-key-owner', + description: + 'Use AWS STS get access key info to resolve which account an access key ID belongs to. Use for incident triage of leaked or unexpected keys.', + content: + '# Identify Access Key Owner\n\nFind out which account owns an access key ID.\n\n## Steps\n1. Take the access key ID under investigation (for example, one found in a leak or an unexpected log).\n2. Call get access key info to resolve the owning AWS account ID.\n3. Compare the account against your known and expected accounts.\n4. If it belongs to an unexpected account, escalate for investigation.\n\n## Output\nReport the access key ID (never the secret) and its owning account ID, plus whether that account is expected.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/sts.ts b/apps/sim/blocks/blocks/sts.ts index 8f64edf0b98..30152c1f267 100644 --- a/apps/sim/blocks/blocks/sts.ts +++ b/apps/sim/blocks/blocks/sts.ts @@ -1,6 +1,5 @@ -import { STSIcon } from '@/components/icons' import { STSBlockDisplay } from '@/blocks/blocks/sts.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { STSBaseResponse } from '@/tools/sts/types' @@ -239,107 +238,3 @@ export const STSBlock: BlockConfig = { }, }, } - -export const STSBlockMeta = { - tags: ['cloud', 'identity'], - url: 'https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html', - templates: [ - { - icon: STSIcon, - title: 'AWS STS access key identifier', - prompt: - 'Build a workflow that takes an AWS access key ID, uses AWS STS to look up the owning account and entity, flags keys that belong to unexpected accounts, and pings the security Slack channel.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: STSIcon, - title: 'STS short-lived credential provisioner', - prompt: - 'Create a workflow that on a request grants short-lived AWS STS credentials with the minimum required scope, captures the audit record, and revokes on completion.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - }, - { - icon: STSIcon, - title: 'STS caller identity verifier', - prompt: - 'Build a scheduled workflow that calls AWS STS get caller identity for each configured set of credentials, confirms the resolved account and ARN match the expected principal, and writes a verification report.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - { - icon: STSIcon, - title: 'STS session token rotator', - prompt: - 'Create a scheduled daily workflow that mints fresh AWS STS session tokens for service accounts that need them, records each token expiration in a security log, and flags any token issuance that fails.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - }, - { - icon: STSIcon, - title: 'STS just-in-time access grant', - prompt: - 'Build a workflow that handles JIT-access requests, captures Slack-based approval, mints short-lived AWS STS credentials, and writes the access record.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: STSIcon, - title: 'STS cross-account access grant', - prompt: - 'Create a workflow that handles cross-account access requests, assumes the target AWS STS role with the supplied external ID, requires owner attestation in Slack, and writes the grant record to a compliance table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: STSIcon, - title: 'STS Identity-Center role broker', - prompt: - 'Build a workflow that takes an Identity Center user request, assumes the matching AWS STS role to mint scoped short-lived credentials, writes the issuance to a session log, and alerts Slack when a request targets a privileged role.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['identity_center', 'slack'], - }, - ], - skills: [ - { - name: 'assume-cross-account-role', - description: - 'Call AWS STS to assume a role and obtain temporary credentials for a target account. Use for cross-account access in a workflow.', - content: - '# Assume Cross-Account Role\n\nObtain temporary credentials by assuming an IAM role.\n\n## Steps\n1. Identify the role ARN to assume and a descriptive session name.\n2. Set the session duration and any external ID required by the trust policy.\n3. Call assume role to receive temporary access key, secret key, and session token.\n4. Pass the temporary credentials to the downstream step that needs cross-account access.\n\n## Output\nConfirm the assumed role ARN and credential expiration. Never print the secret access key or session token in plain logs.', - }, - { - name: 'verify-caller-identity', - description: - 'Use AWS STS get caller identity to confirm which account, user, or role the current credentials resolve to. Use to validate setup and debug auth issues.', - content: - '# Verify Caller Identity\n\nConfirm which AWS identity the workflow is operating as.\n\n## Steps\n1. Call get caller identity with the active credentials.\n2. Read the returned account ID, user ID, and principal ARN.\n3. Compare against the expected account and role for the task.\n4. If it does not match, flag a likely credential or assume-role misconfiguration.\n\n## Output\nReport the account ID and ARN of the active identity, and whether it matches the expected principal.', - }, - { - name: 'mint-mfa-session-token', - description: - 'Use AWS STS to mint short-lived session credentials, optionally backed by an MFA token, for IAM-user workflows that require MFA. Use for time-boxed elevated sessions.', - content: - '# Mint MFA Session Token\n\nIssue temporary credentials, optionally enforcing MFA.\n\n## Steps\n1. Decide the session duration the downstream task needs.\n2. If MFA is required, supply the MFA device serial number and the current token code.\n3. Call get session token to receive a temporary access key, secret key, and session token.\n4. Hand the temporary credentials to the step that needs them and let them expire naturally.\n\n## Output\nConfirm that a session token was issued and its expiration time. Never print the secret access key or session token value.', - }, - { - name: 'identify-access-key-owner', - description: - 'Use AWS STS get access key info to resolve which account an access key ID belongs to. Use for incident triage of leaked or unexpected keys.', - content: - '# Identify Access Key Owner\n\nFind out which account owns an access key ID.\n\n## Steps\n1. Take the access key ID under investigation (for example, one found in a leak or an unexpected log).\n2. Call get access key info to resolve the owning AWS account ID.\n3. Compare the account against your known and expected accounts.\n4. If it belongs to an unexpected account, escalate for investigation.\n\n## Output\nReport the access key ID (never the secret) and its owning account ID, plus whether that account is expected.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/supabase.display.ts b/apps/sim/blocks/blocks/supabase.display.ts index 736a9ff1467..3b11707124f 100644 --- a/apps/sim/blocks/blocks/supabase.display.ts +++ b/apps/sim/blocks/blocks/supabase.display.ts @@ -1,6 +1,6 @@ import { SupabaseIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const SupabaseBlockDisplay = { type: 'supabase', @@ -14,3 +14,114 @@ export const SupabaseBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/supabase', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const SupabaseBlockMeta = { + tags: ['cloud', 'data-warehouse', 'vector-search'], + url: 'https://supabase.com', + templates: [ + { + icon: SupabaseIcon, + title: 'Supabase user provisioning', + prompt: + 'Build a workflow that listens for Stripe new-customer events, provisions a Supabase user with the correct role and metadata, and emails the welcome login link.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'automation'], + alsoIntegrations: ['stripe', 'gmail'], + }, + { + icon: SupabaseIcon, + title: 'Supabase nightly export to S3', + prompt: + 'Create a scheduled workflow that runs each night, exports key Supabase tables to compressed JSON in S3 with date partitions, and writes the manifest to an audit table.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: SupabaseIcon, + title: 'Supabase row-level audit log', + prompt: + 'Build a scheduled workflow that polls Supabase sensitive tables for recently changed rows, captures the diff against the last snapshot into an audit log table, and pings Slack on unusual write patterns.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['enterprise', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: SupabaseIcon, + title: 'Supabase high-priority row alerter', + prompt: + 'Create a scheduled workflow that polls Supabase frequently for high-priority rows — new orders, fraud flags — and posts a Slack alert with context for each new row it finds.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'communication'], + alsoIntegrations: ['slack'], + }, + { + icon: SupabaseIcon, + title: 'Supabase storage cleanup', + prompt: + 'Build a scheduled workflow that finds Supabase storage objects older than the retention policy or unreferenced in the database, deletes them, and writes a cleanup report.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'automation'], + }, + { + icon: SupabaseIcon, + title: 'Supabase analytics digest', + prompt: + 'Create a scheduled daily workflow that queries Supabase for new signups, active users, and key feature usage, and posts a digest to Slack with week-over-week trend.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: SupabaseIcon, + title: 'Supabase + Algolia search sync', + prompt: + 'Build a scheduled workflow that mirrors Supabase tables into an Algolia index, propagates new and changed rows on each run, and writes sync lag to a tables-based monitor.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['engineering', 'sync'], + alsoIntegrations: ['algolia'], + }, + ], + skills: [ + { + name: 'query-table-rows', + description: + 'Read rows from a Supabase table with PostgREST filters, ordering, and pagination.', + content: + '# Query Supabase Table Rows\n\nFetch records from a Supabase table using PostgREST filters so downstream steps work with exactly the rows they need.\n\n## Steps\n1. Use the Get Many Rows operation with the project ID, service role secret, and target table.\n2. Set Select Columns to the fields you need (for example id,name,email) instead of returning every column.\n3. Add a PostgREST Filter such as status=eq.active or created_at=gte.2024-01-01 to narrow the result set.\n4. Set Order By (for example created_at DESC) plus Limit and Offset for predictable pagination.\n5. For a single record use Get a Row with a filter like id=eq.123.\n\n## Output\nReturn the matched rows as structured JSON. Note how many rows came back and surface the key fields each consumer needs.', + }, + { + name: 'upsert-record', + description: + 'Insert a new Supabase row or update it if it already exists in one idempotent call.', + content: + '# Upsert a Supabase Record\n\nWrite a record without first checking whether it exists, so repeated runs stay idempotent.\n\n## Steps\n1. Choose the Upsert a Row operation with the project ID, service role secret, and table.\n2. Provide the Data as a JSON object whose keys match the table columns, including the conflict key (such as id or email).\n3. Supabase inserts the row when the conflict key is new and updates the existing row otherwise.\n4. For a guaranteed new row use Create a Row instead; for a known existing row use Update a Row with a filter like id=eq.123.\n\n## Output\nConfirm whether the row was inserted or updated and report the resulting record fields back to the caller.', + }, + { + name: 'semantic-vector-search', + description: + 'Run pgvector similarity search against a Supabase table to retrieve the closest embeddings.', + content: + '# Semantic Vector Search in Supabase\n\nFind the most relevant rows by embedding similarity, the retrieval step for a RAG agent.\n\n## Steps\n1. Generate an embedding for the query text with your model and capture it as a numeric array.\n2. Use the Vector Search operation, pointing Function Name at your pgvector match function (for example match_documents).\n3. Pass the embedding into Query Embedding as a JSON array like [0.1, 0.2, 0.3].\n4. Tune Match Threshold (for example 0.78) and Match Count (for example 10) to balance precision and recall.\n\n## Output\nReturn the matched rows with their similarity scores, ordered by closeness, ready to feed an answer-generation step.', + }, + { + name: 'upload-file-to-storage', + description: 'Upload a file to a Supabase Storage bucket and return a public or signed URL.', + content: + '# Upload a File to Supabase Storage\n\nStore a generated or received file in a bucket and hand back a shareable link.\n\n## Steps\n1. Use Storage: Upload File with the bucket name, file name, and the file reference from a previous block.\n2. Set an optional Folder Path and Content Type, and enable Upsert if you want to overwrite an existing object.\n3. For a permanent link on a public bucket use Storage: Get Public URL with the file path.\n4. For private buckets use Storage: Create Signed URL with an Expires In value such as 3600 seconds.\n\n## Output\nReturn the stored object path plus the public or signed URL so later steps can reference or share the file.', + }, + { + name: 'invoke-edge-function', + description: 'Call a deployed Supabase Edge Function over HTTP and use its JSON response.', + content: + '# Invoke a Supabase Edge Function\n\nRun server-side logic deployed as a Supabase Edge Function and feed its result into the workflow.\n\n## Steps\n1. Use the Invoke Edge Function operation with the project ID, service role secret, and the function name (for example hello-world).\n2. Choose the HTTP Method (defaults to POST) and provide a JSON Request Body the function expects.\n3. Add optional custom Headers as a JSON object when the function reads specific headers.\n4. This is different from Call RPC Function, which runs a PostgreSQL function inside the database rather than deployed function code.\n\n## Output\nReturn the function response body as JSON so downstream steps can branch on or transform the result.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/supabase.ts b/apps/sim/blocks/blocks/supabase.ts index 18fc76be7ff..858f1118e40 100644 --- a/apps/sim/blocks/blocks/supabase.ts +++ b/apps/sim/blocks/blocks/supabase.ts @@ -1,8 +1,7 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' -import { SupabaseIcon } from '@/components/icons' import { SupabaseBlockDisplay } from '@/blocks/blocks/supabase.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { SupabaseResponse } from '@/tools/supabase/types' @@ -1285,114 +1284,3 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e }, }, } - -export const SupabaseBlockMeta = { - tags: ['cloud', 'data-warehouse', 'vector-search'], - url: 'https://supabase.com', - templates: [ - { - icon: SupabaseIcon, - title: 'Supabase user provisioning', - prompt: - 'Build a workflow that listens for Stripe new-customer events, provisions a Supabase user with the correct role and metadata, and emails the welcome login link.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'automation'], - alsoIntegrations: ['stripe', 'gmail'], - }, - { - icon: SupabaseIcon, - title: 'Supabase nightly export to S3', - prompt: - 'Create a scheduled workflow that runs each night, exports key Supabase tables to compressed JSON in S3 with date partitions, and writes the manifest to an audit table.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: SupabaseIcon, - title: 'Supabase row-level audit log', - prompt: - 'Build a scheduled workflow that polls Supabase sensitive tables for recently changed rows, captures the diff against the last snapshot into an audit log table, and pings Slack on unusual write patterns.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['enterprise', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: SupabaseIcon, - title: 'Supabase high-priority row alerter', - prompt: - 'Create a scheduled workflow that polls Supabase frequently for high-priority rows — new orders, fraud flags — and posts a Slack alert with context for each new row it finds.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'communication'], - alsoIntegrations: ['slack'], - }, - { - icon: SupabaseIcon, - title: 'Supabase storage cleanup', - prompt: - 'Build a scheduled workflow that finds Supabase storage objects older than the retention policy or unreferenced in the database, deletes them, and writes a cleanup report.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'automation'], - }, - { - icon: SupabaseIcon, - title: 'Supabase analytics digest', - prompt: - 'Create a scheduled daily workflow that queries Supabase for new signups, active users, and key feature usage, and posts a digest to Slack with week-over-week trend.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: SupabaseIcon, - title: 'Supabase + Algolia search sync', - prompt: - 'Build a scheduled workflow that mirrors Supabase tables into an Algolia index, propagates new and changed rows on each run, and writes sync lag to a tables-based monitor.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['engineering', 'sync'], - alsoIntegrations: ['algolia'], - }, - ], - skills: [ - { - name: 'query-table-rows', - description: - 'Read rows from a Supabase table with PostgREST filters, ordering, and pagination.', - content: - '# Query Supabase Table Rows\n\nFetch records from a Supabase table using PostgREST filters so downstream steps work with exactly the rows they need.\n\n## Steps\n1. Use the Get Many Rows operation with the project ID, service role secret, and target table.\n2. Set Select Columns to the fields you need (for example id,name,email) instead of returning every column.\n3. Add a PostgREST Filter such as status=eq.active or created_at=gte.2024-01-01 to narrow the result set.\n4. Set Order By (for example created_at DESC) plus Limit and Offset for predictable pagination.\n5. For a single record use Get a Row with a filter like id=eq.123.\n\n## Output\nReturn the matched rows as structured JSON. Note how many rows came back and surface the key fields each consumer needs.', - }, - { - name: 'upsert-record', - description: - 'Insert a new Supabase row or update it if it already exists in one idempotent call.', - content: - '# Upsert a Supabase Record\n\nWrite a record without first checking whether it exists, so repeated runs stay idempotent.\n\n## Steps\n1. Choose the Upsert a Row operation with the project ID, service role secret, and table.\n2. Provide the Data as a JSON object whose keys match the table columns, including the conflict key (such as id or email).\n3. Supabase inserts the row when the conflict key is new and updates the existing row otherwise.\n4. For a guaranteed new row use Create a Row instead; for a known existing row use Update a Row with a filter like id=eq.123.\n\n## Output\nConfirm whether the row was inserted or updated and report the resulting record fields back to the caller.', - }, - { - name: 'semantic-vector-search', - description: - 'Run pgvector similarity search against a Supabase table to retrieve the closest embeddings.', - content: - '# Semantic Vector Search in Supabase\n\nFind the most relevant rows by embedding similarity, the retrieval step for a RAG agent.\n\n## Steps\n1. Generate an embedding for the query text with your model and capture it as a numeric array.\n2. Use the Vector Search operation, pointing Function Name at your pgvector match function (for example match_documents).\n3. Pass the embedding into Query Embedding as a JSON array like [0.1, 0.2, 0.3].\n4. Tune Match Threshold (for example 0.78) and Match Count (for example 10) to balance precision and recall.\n\n## Output\nReturn the matched rows with their similarity scores, ordered by closeness, ready to feed an answer-generation step.', - }, - { - name: 'upload-file-to-storage', - description: 'Upload a file to a Supabase Storage bucket and return a public or signed URL.', - content: - '# Upload a File to Supabase Storage\n\nStore a generated or received file in a bucket and hand back a shareable link.\n\n## Steps\n1. Use Storage: Upload File with the bucket name, file name, and the file reference from a previous block.\n2. Set an optional Folder Path and Content Type, and enable Upsert if you want to overwrite an existing object.\n3. For a permanent link on a public bucket use Storage: Get Public URL with the file path.\n4. For private buckets use Storage: Create Signed URL with an Expires In value such as 3600 seconds.\n\n## Output\nReturn the stored object path plus the public or signed URL so later steps can reference or share the file.', - }, - { - name: 'invoke-edge-function', - description: 'Call a deployed Supabase Edge Function over HTTP and use its JSON response.', - content: - '# Invoke a Supabase Edge Function\n\nRun server-side logic deployed as a Supabase Edge Function and feed its result into the workflow.\n\n## Steps\n1. Use the Invoke Edge Function operation with the project ID, service role secret, and the function name (for example hello-world).\n2. Choose the HTTP Method (defaults to POST) and provide a JSON Request Body the function expects.\n3. Add optional custom Headers as a JSON object when the function reads specific headers.\n4. This is different from Call RPC Function, which runs a PostgreSQL function inside the database rather than deployed function code.\n\n## Output\nReturn the function response body as JSON so downstream steps can branch on or transform the result.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tailscale.display.ts b/apps/sim/blocks/blocks/tailscale.display.ts index 87a4246559a..37661dcfac9 100644 --- a/apps/sim/blocks/blocks/tailscale.display.ts +++ b/apps/sim/blocks/blocks/tailscale.display.ts @@ -1,6 +1,6 @@ import { TailscaleIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TailscaleBlockDisplay = { type: 'tailscale', @@ -14,3 +14,100 @@ export const TailscaleBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/tailscale', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const TailscaleBlockMeta = { + tags: ['monitoring'], + url: 'https://tailscale.com', + templates: [ + { + icon: TailscaleIcon, + title: 'Tailscale device inventory', + prompt: + 'Build a scheduled workflow that pulls Tailscale device inventory daily, identifies stale or non-compliant nodes, and writes a security review table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale ACL drift detector', + prompt: + 'Create a scheduled workflow that diffs Tailscale ACLs against the source of truth, alerts on drift, and writes the drift report to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale new-hire provisioner', + prompt: + 'Build a workflow that on a Workday new-hire event creates a scoped Tailscale auth key for the engineer, sets the right device tags, and writes the access record.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + alsoIntegrations: ['workday'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale offboarder', + prompt: + "Create a workflow that on a Workday termination deletes the departing engineer's Tailscale devices, revokes their auth keys, and writes the security audit log.", + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise'], + alsoIntegrations: ['workday'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale unauthorized-tag watcher', + prompt: + 'Build a scheduled workflow that polls Tailscale device tags and the ACL for unauthorized changes, posts a Slack alert to the security channel, and writes the audit.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale key-expiry sweeper', + prompt: + 'Create a scheduled workflow that lists Tailscale auth keys expiring in 14 days, notifies owners, and rotates keys past their grace period.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + alsoIntegrations: ['slack'], + }, + { + icon: TailscaleIcon, + title: 'Tailscale access audit', + prompt: + 'Build a scheduled monthly workflow that produces a Tailscale access-review report — devices, tags, ACL effective access — for the security team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['legal', 'enterprise'], + }, + ], + skills: [ + { + name: 'audit-tailnet-devices', + description: + 'List every device in the tailnet and flag stale, unauthorized, or update-pending nodes.', + content: + '# Audit Tailnet Devices\n\nProduce a clean inventory of the devices on your tailnet and surface the ones that need attention.\n\n## Steps\n1. Use the List Devices operation with your API key and tailnet (use "-" for the default tailnet).\n2. For each device review lastSeen, authorized, updateAvailable, and the assigned tags.\n3. Flag nodes not seen in 30+ days, devices still pending authorization, and any with an update available.\n4. Use Get Device with a deviceId to pull full detail on anything suspicious.\n\n## Output\nReturn a table of devices with hostname, user, OS, last seen, and authorization status, plus a short list of nodes that need review.', + }, + { + name: 'provision-auth-key', + description: + 'Create a scoped Tailscale auth key with the right tags, reusability, and expiry for onboarding.', + content: + '# Provision a Tailscale Auth Key\n\nGenerate an auth key so a new device or user can join the tailnet with the correct access.\n\n## Steps\n1. Use the Create Auth Key operation with your API key and tailnet.\n2. Set Tags (for example tag:server,tag:production) so devices joining with the key get the intended ACL access.\n3. Choose Reusable, Ephemeral, and Preauthorized values to match the use case (ephemeral for short-lived CI nodes).\n4. Set an Expiry in seconds (for example 7776000 for 90 days) and a clear Description.\n\n## Output\nReturn the generated key value once (it is only shown at creation), the key ID, its tags, and the expiry timestamp.', + }, + { + name: 'offboard-device', + description: 'Deauthorize or remove a departing user device and revoke its auth keys.', + content: + '# Offboard a Tailscale Device\n\nRemove a device from the tailnet during offboarding so access is cut cleanly.\n\n## Steps\n1. Use List Devices to find the deviceId tied to the departing user.\n2. To immediately cut access use Authorize Device set to Deauthorize, or Delete Device to remove it entirely.\n3. Use List Auth Keys to find any keys the user created, then Delete Auth Key for each.\n4. Capture the device detail with Get Device before deletion if you need an audit record.\n\n## Output\nConfirm the device was deauthorized or deleted and list the revoked auth keys for the offboarding audit log.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tailscale.ts b/apps/sim/blocks/blocks/tailscale.ts index e4219617a01..266d3a2c801 100644 --- a/apps/sim/blocks/blocks/tailscale.ts +++ b/apps/sim/blocks/blocks/tailscale.ts @@ -1,6 +1,5 @@ -import { TailscaleIcon } from '@/components/icons' import { TailscaleBlockDisplay } from '@/blocks/blocks/tailscale.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const TailscaleBlock: BlockConfig = { @@ -330,100 +329,3 @@ export const TailscaleBlock: BlockConfig = { etag: { type: 'string', description: 'ACL ETag for conditional updates' }, }, } - -export const TailscaleBlockMeta = { - tags: ['monitoring'], - url: 'https://tailscale.com', - templates: [ - { - icon: TailscaleIcon, - title: 'Tailscale device inventory', - prompt: - 'Build a scheduled workflow that pulls Tailscale device inventory daily, identifies stale or non-compliant nodes, and writes a security review table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale ACL drift detector', - prompt: - 'Create a scheduled workflow that diffs Tailscale ACLs against the source of truth, alerts on drift, and writes the drift report to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale new-hire provisioner', - prompt: - 'Build a workflow that on a Workday new-hire event creates a scoped Tailscale auth key for the engineer, sets the right device tags, and writes the access record.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - alsoIntegrations: ['workday'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale offboarder', - prompt: - "Create a workflow that on a Workday termination deletes the departing engineer's Tailscale devices, revokes their auth keys, and writes the security audit log.", - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise'], - alsoIntegrations: ['workday'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale unauthorized-tag watcher', - prompt: - 'Build a scheduled workflow that polls Tailscale device tags and the ACL for unauthorized changes, posts a Slack alert to the security channel, and writes the audit.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale key-expiry sweeper', - prompt: - 'Create a scheduled workflow that lists Tailscale auth keys expiring in 14 days, notifies owners, and rotates keys past their grace period.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - alsoIntegrations: ['slack'], - }, - { - icon: TailscaleIcon, - title: 'Tailscale access audit', - prompt: - 'Build a scheduled monthly workflow that produces a Tailscale access-review report — devices, tags, ACL effective access — for the security team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['legal', 'enterprise'], - }, - ], - skills: [ - { - name: 'audit-tailnet-devices', - description: - 'List every device in the tailnet and flag stale, unauthorized, or update-pending nodes.', - content: - '# Audit Tailnet Devices\n\nProduce a clean inventory of the devices on your tailnet and surface the ones that need attention.\n\n## Steps\n1. Use the List Devices operation with your API key and tailnet (use "-" for the default tailnet).\n2. For each device review lastSeen, authorized, updateAvailable, and the assigned tags.\n3. Flag nodes not seen in 30+ days, devices still pending authorization, and any with an update available.\n4. Use Get Device with a deviceId to pull full detail on anything suspicious.\n\n## Output\nReturn a table of devices with hostname, user, OS, last seen, and authorization status, plus a short list of nodes that need review.', - }, - { - name: 'provision-auth-key', - description: - 'Create a scoped Tailscale auth key with the right tags, reusability, and expiry for onboarding.', - content: - '# Provision a Tailscale Auth Key\n\nGenerate an auth key so a new device or user can join the tailnet with the correct access.\n\n## Steps\n1. Use the Create Auth Key operation with your API key and tailnet.\n2. Set Tags (for example tag:server,tag:production) so devices joining with the key get the intended ACL access.\n3. Choose Reusable, Ephemeral, and Preauthorized values to match the use case (ephemeral for short-lived CI nodes).\n4. Set an Expiry in seconds (for example 7776000 for 90 days) and a clear Description.\n\n## Output\nReturn the generated key value once (it is only shown at creation), the key ID, its tags, and the expiry timestamp.', - }, - { - name: 'offboard-device', - description: 'Deauthorize or remove a departing user device and revoke its auth keys.', - content: - '# Offboard a Tailscale Device\n\nRemove a device from the tailnet during offboarding so access is cut cleanly.\n\n## Steps\n1. Use List Devices to find the deviceId tied to the departing user.\n2. To immediately cut access use Authorize Device set to Deauthorize, or Delete Device to remove it entirely.\n3. Use List Auth Keys to find any keys the user created, then Delete Auth Key for each.\n4. Capture the device detail with Get Device before deletion if you need an audit record.\n\n## Output\nConfirm the device was deauthorized or deleted and list the revoked auth keys for the offboarding audit log.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tavily.display.ts b/apps/sim/blocks/blocks/tavily.display.ts index f52e700a63c..c5a987cb0d5 100644 --- a/apps/sim/blocks/blocks/tavily.display.ts +++ b/apps/sim/blocks/blocks/tavily.display.ts @@ -1,6 +1,6 @@ import { TavilyIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TavilyBlockDisplay = { type: 'tavily', @@ -14,3 +14,105 @@ export const TavilyBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/tavily', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const TavilyBlockMeta = { + tags: ['web-scraping', 'enrichment'], + url: 'https://tavily.com', + templates: [ + { + icon: TavilyIcon, + title: 'Tavily research-augmented agent', + prompt: + 'Create an agent that grounds every answer in fresh Tavily web search results, returns answers with inline citations, and saves long-form research to a knowledge base for re-use.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: TavilyIcon, + title: 'Tavily competitive monitor', + prompt: + 'Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, logs the top hits to a tables-based competitive log, and posts highlights to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TavilyIcon, + title: 'Tavily research-augmented chat', + prompt: + 'Build a chat agent that grounds each answer in fresh Tavily web search results, returns inline citations, and saves long-form answers to a knowledge base for re-use.', + modules: ['agent', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: TavilyIcon, + title: 'Tavily news watcher', + prompt: + 'Create a scheduled daily workflow that runs Tavily searches for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: TavilyIcon, + title: 'Tavily account refresher', + prompt: + 'Build a workflow that walks accounts in the CRM, runs Tavily research on each for new funding, hiring, or product launches, and writes the digest back to the account record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: TavilyIcon, + title: 'Tavily competitor mention log', + prompt: + 'Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: TavilyIcon, + title: 'Tavily URL content extractor', + prompt: + 'Build a workflow that reads a table of article URLs, uses Tavily extract to pull the clean main content from each page, summarizes the key points with an agent, and writes the summary back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'web-scraping', 'automation'], + }, + ], + skills: [ + { + name: 'answer-with-web-citations', + description: + 'Search the web with Tavily and return a grounded answer with linked source citations.', + content: + '# Answer a Question with Web Citations\n\nGround an answer in fresh web results so it is current and verifiable.\n\n## Steps\n1. Use the Search operation with the question as the Search Query.\n2. Set Include Answer to Advanced, Search Depth to advanced, and Max Results to about 5 for good coverage.\n3. Pick the Topic (news or finance) when the question is time-sensitive, and set Time Range (day, week, month) to keep results recent.\n4. Use Include Domains or Exclude Domains to keep results on trusted sources.\n\n## Output\nReturn the synthesized answer followed by a numbered list of the source titles and URLs used to support it.', + }, + { + name: 'extract-article-content', + description: + 'Pull clean main content from one or more URLs with Tavily Extract for summarization.', + content: + '# Extract Clean Article Content\n\nTurn a messy web page into clean text or markdown that an agent can summarize.\n\n## Steps\n1. Use the Extract Content operation and pass the page URL into the URL field.\n2. Set Extract Depth to advanced for content-heavy pages and choose Markdown or Text as the Format.\n3. Enable Include Images only if downstream steps need the media.\n4. Feed the extracted content to an agent to summarize the key points.\n\n## Output\nReturn the page title, source URL, and the cleaned content, plus any failed URLs so they can be retried.', + }, + { + name: 'crawl-site-section', + description: + 'Crawl a website section with Tavily and gather page content matching path rules.', + content: + '# Crawl a Website Section\n\nWalk a site beginning at a root URL and collect content from matching pages.\n\n## Steps\n1. Use the Crawl Website operation with the root Website URL.\n2. Give natural-language Instructions describing what to collect (for example "gather all product documentation pages").\n3. Bound the crawl with Max Depth, Max Breadth, and Limit so it stays focused.\n4. Use Select Paths and Exclude Paths regex patterns (for example /docs/.* to include, /admin/.* to exclude) to target the right section.\n\n## Output\nReturn the crawled pages with their URLs and extracted content, ready to index into a knowledge base or summarize.', + }, + { + name: 'map-site-structure', + description: 'Map a website URL structure with Tavily without extracting full page content.', + content: + '# Map a Website Structure\n\nDiscover the URL layout of a site quickly without pulling full page bodies.\n\n## Steps\n1. Use the Map Website operation with the root Website URL.\n2. Set Max Depth and Max Breadth to control how far the mapper explores.\n3. Apply Select Paths or Exclude Paths regex patterns to focus on the sections you care about.\n4. Toggle Allow External Links only if you want links that leave the root domain.\n\n## Output\nReturn the discovered list of URLs so you can pick targets for a later crawl or extract pass.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tavily.ts b/apps/sim/blocks/blocks/tavily.ts index 9f1fdd1643f..05a1db27400 100644 --- a/apps/sim/blocks/blocks/tavily.ts +++ b/apps/sim/blocks/blocks/tavily.ts @@ -1,6 +1,5 @@ -import { TavilyIcon } from '@/components/icons' import { TavilyBlockDisplay } from '@/blocks/blocks/tavily.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { TavilyResponse } from '@/tools/tavily/types' @@ -388,105 +387,3 @@ export const TavilyBlock: BlockConfig = { request_id: { type: 'string', description: 'Request identifier for support' }, }, } - -export const TavilyBlockMeta = { - tags: ['web-scraping', 'enrichment'], - url: 'https://tavily.com', - templates: [ - { - icon: TavilyIcon, - title: 'Tavily research-augmented agent', - prompt: - 'Create an agent that grounds every answer in fresh Tavily web search results, returns answers with inline citations, and saves long-form research to a knowledge base for re-use.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: TavilyIcon, - title: 'Tavily competitive monitor', - prompt: - 'Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, logs the top hits to a tables-based competitive log, and posts highlights to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TavilyIcon, - title: 'Tavily research-augmented chat', - prompt: - 'Build a chat agent that grounds each answer in fresh Tavily web search results, returns inline citations, and saves long-form answers to a knowledge base for re-use.', - modules: ['agent', 'knowledge-base', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: TavilyIcon, - title: 'Tavily news watcher', - prompt: - 'Create a scheduled daily workflow that runs Tavily searches for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: TavilyIcon, - title: 'Tavily account refresher', - prompt: - 'Build a workflow that walks accounts in the CRM, runs Tavily research on each for new funding, hiring, or product launches, and writes the digest back to the account record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: TavilyIcon, - title: 'Tavily competitor mention log', - prompt: - 'Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: TavilyIcon, - title: 'Tavily URL content extractor', - prompt: - 'Build a workflow that reads a table of article URLs, uses Tavily extract to pull the clean main content from each page, summarizes the key points with an agent, and writes the summary back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'web-scraping', 'automation'], - }, - ], - skills: [ - { - name: 'answer-with-web-citations', - description: - 'Search the web with Tavily and return a grounded answer with linked source citations.', - content: - '# Answer a Question with Web Citations\n\nGround an answer in fresh web results so it is current and verifiable.\n\n## Steps\n1. Use the Search operation with the question as the Search Query.\n2. Set Include Answer to Advanced, Search Depth to advanced, and Max Results to about 5 for good coverage.\n3. Pick the Topic (news or finance) when the question is time-sensitive, and set Time Range (day, week, month) to keep results recent.\n4. Use Include Domains or Exclude Domains to keep results on trusted sources.\n\n## Output\nReturn the synthesized answer followed by a numbered list of the source titles and URLs used to support it.', - }, - { - name: 'extract-article-content', - description: - 'Pull clean main content from one or more URLs with Tavily Extract for summarization.', - content: - '# Extract Clean Article Content\n\nTurn a messy web page into clean text or markdown that an agent can summarize.\n\n## Steps\n1. Use the Extract Content operation and pass the page URL into the URL field.\n2. Set Extract Depth to advanced for content-heavy pages and choose Markdown or Text as the Format.\n3. Enable Include Images only if downstream steps need the media.\n4. Feed the extracted content to an agent to summarize the key points.\n\n## Output\nReturn the page title, source URL, and the cleaned content, plus any failed URLs so they can be retried.', - }, - { - name: 'crawl-site-section', - description: - 'Crawl a website section with Tavily and gather page content matching path rules.', - content: - '# Crawl a Website Section\n\nWalk a site beginning at a root URL and collect content from matching pages.\n\n## Steps\n1. Use the Crawl Website operation with the root Website URL.\n2. Give natural-language Instructions describing what to collect (for example "gather all product documentation pages").\n3. Bound the crawl with Max Depth, Max Breadth, and Limit so it stays focused.\n4. Use Select Paths and Exclude Paths regex patterns (for example /docs/.* to include, /admin/.* to exclude) to target the right section.\n\n## Output\nReturn the crawled pages with their URLs and extracted content, ready to index into a knowledge base or summarize.', - }, - { - name: 'map-site-structure', - description: 'Map a website URL structure with Tavily without extracting full page content.', - content: - '# Map a Website Structure\n\nDiscover the URL layout of a site quickly without pulling full page bodies.\n\n## Steps\n1. Use the Map Website operation with the root Website URL.\n2. Set Max Depth and Max Breadth to control how far the mapper explores.\n3. Apply Select Paths or Exclude Paths regex patterns to focus on the sections you care about.\n4. Toggle Allow External Links only if you want links that leave the root domain.\n\n## Output\nReturn the discovered list of URLs so you can pick targets for a later crawl or extract pass.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/telegram.display.ts b/apps/sim/blocks/blocks/telegram.display.ts index 1e39a59fcfc..22fea09598a 100644 --- a/apps/sim/blocks/blocks/telegram.display.ts +++ b/apps/sim/blocks/blocks/telegram.display.ts @@ -1,6 +1,6 @@ import { TelegramIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TelegramBlockDisplay = { type: 'telegram', @@ -15,3 +15,98 @@ export const TelegramBlockDisplay = { integrationType: IntegrationType.Communication, triggerAllowed: true, } satisfies BlockDisplay + +export const TelegramBlockMeta = { + tags: ['messaging', 'webhooks', 'automation'], + url: 'https://telegram.org', + templates: [ + { + icon: TelegramIcon, + title: 'Telegram alert relay', + prompt: + 'Build a workflow that listens for critical alerts from Sentry or PagerDuty and forwards a concise summary with severity, link, and the on-call person to a Telegram group.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['sentry', 'pagerduty'], + }, + { + icon: TelegramIcon, + title: 'Telegram price-action notifier', + prompt: + 'Create a scheduled workflow that watches tracked assets in a table for price thresholds and pushes a Telegram message with the trigger, price, and a link to the chart.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'monitoring'], + }, + { + icon: TelegramIcon, + title: 'Telegram support bot', + prompt: + 'Build a Telegram bot that answers product questions using a knowledge base with citations, escalates to a human via Intercom when it cannot answer, and logs every conversation to a table.', + modules: ['knowledge-base', 'tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['intercom'], + }, + { + icon: TelegramIcon, + title: 'Telegram daily standup poller', + prompt: + 'Create a scheduled workflow that posts a daily standup prompt to a Telegram group, collects the replies, and writes a structured standup digest to a Google Doc.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['google_docs'], + }, + { + icon: TelegramIcon, + title: 'Telegram broadcast scheduler', + prompt: + 'Build a workflow that reads a tables-based content calendar and posts scheduled Telegram channel messages with formatted text, images, and links at the right time.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: TelegramIcon, + title: 'Telegram form-reply collector', + prompt: + 'Create a workflow that asks structured questions in Telegram one at a time, parses replies into fields, and saves the completed response as a row in a Sim table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'communication'], + }, + { + icon: TelegramIcon, + title: 'Telegram + WhatsApp dual-channel notifier', + prompt: + 'Build a workflow that sends critical operational alerts via both Telegram and WhatsApp based on user preference per recipient, and writes delivery status to a table.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['communication', 'monitoring'], + alsoIntegrations: ['whatsapp'], + }, + ], + skills: [ + { + name: 'send-alert-message', + description: 'Post a formatted alert or notification to a Telegram chat or channel.', + content: + '# Send a Telegram Alert\n\nDeliver a timely notification to a Telegram chat, group, or channel.\n\n## Steps\n1. Use the Send Message operation with your Bot Token and the target Chat ID.\n2. Compose the Message with the essentials up front: what happened, severity, and a link for follow-up.\n3. To find a Chat ID, add the bot to the chat, send a message, then read the chat field from the getUpdates response.\n4. For recurring alerts, build the message from upstream block outputs so each notification carries live context.\n\n## Output\nReturn the sent message ID and chat ID so the run can be traced or the message later deleted.', + }, + { + name: 'send-media-message', + description: + 'Send a photo, video, document, or audio file to a Telegram chat with a caption.', + content: + '# Send Media to Telegram\n\nDeliver a file such as a chart, report, or image to a Telegram chat.\n\n## Steps\n1. Pick the matching operation: Send Photo, Send Video, Send Audio, Send Animation, or Send Document.\n2. Provide the Bot Token and Chat ID.\n3. Upload the file directly, or reference a file produced by a previous block (for example a generated PDF or chart image).\n4. Add an optional Caption describing the attachment.\n\n## Output\nConfirm delivery and return the message ID so the media post can be referenced later.', + }, + { + name: 'route-incoming-message', + description: 'Trigger a workflow when a Telegram message arrives and act on its content.', + content: + '# Route an Incoming Telegram Message\n\nUse Telegram as a trigger so the workflow runs whenever a user messages the bot.\n\n## Steps\n1. Enable the Telegram webhook trigger so incoming messages start the workflow.\n2. Read the trigger outputs: text, from_username, chat_id, and chat_type.\n3. Branch on the message content (for example detect a command or a support question) to decide the next action.\n4. Reply with the Send Message operation using the chat_id from the trigger.\n\n## Output\nReturn the parsed incoming message fields and confirm the reply that was sent back to the user.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/telegram.ts b/apps/sim/blocks/blocks/telegram.ts index 64853f38b45..9d36d915f66 100644 --- a/apps/sim/blocks/blocks/telegram.ts +++ b/apps/sim/blocks/blocks/telegram.ts @@ -1,6 +1,5 @@ -import { TelegramIcon } from '@/components/icons' import { TelegramBlockDisplay } from '@/blocks/blocks/telegram.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { TelegramResponse } from '@/tools/telegram/types' @@ -417,98 +416,3 @@ export const TelegramBlock: BlockConfig = { available: ['telegram_webhook'], }, } - -export const TelegramBlockMeta = { - tags: ['messaging', 'webhooks', 'automation'], - url: 'https://telegram.org', - templates: [ - { - icon: TelegramIcon, - title: 'Telegram alert relay', - prompt: - 'Build a workflow that listens for critical alerts from Sentry or PagerDuty and forwards a concise summary with severity, link, and the on-call person to a Telegram group.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['sentry', 'pagerduty'], - }, - { - icon: TelegramIcon, - title: 'Telegram price-action notifier', - prompt: - 'Create a scheduled workflow that watches tracked assets in a table for price thresholds and pushes a Telegram message with the trigger, price, and a link to the chart.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'monitoring'], - }, - { - icon: TelegramIcon, - title: 'Telegram support bot', - prompt: - 'Build a Telegram bot that answers product questions using a knowledge base with citations, escalates to a human via Intercom when it cannot answer, and logs every conversation to a table.', - modules: ['knowledge-base', 'tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['intercom'], - }, - { - icon: TelegramIcon, - title: 'Telegram daily standup poller', - prompt: - 'Create a scheduled workflow that posts a daily standup prompt to a Telegram group, collects the replies, and writes a structured standup digest to a Google Doc.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['google_docs'], - }, - { - icon: TelegramIcon, - title: 'Telegram broadcast scheduler', - prompt: - 'Build a workflow that reads a tables-based content calendar and posts scheduled Telegram channel messages with formatted text, images, and links at the right time.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: TelegramIcon, - title: 'Telegram form-reply collector', - prompt: - 'Create a workflow that asks structured questions in Telegram one at a time, parses replies into fields, and saves the completed response as a row in a Sim table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'communication'], - }, - { - icon: TelegramIcon, - title: 'Telegram + WhatsApp dual-channel notifier', - prompt: - 'Build a workflow that sends critical operational alerts via both Telegram and WhatsApp based on user preference per recipient, and writes delivery status to a table.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['communication', 'monitoring'], - alsoIntegrations: ['whatsapp'], - }, - ], - skills: [ - { - name: 'send-alert-message', - description: 'Post a formatted alert or notification to a Telegram chat or channel.', - content: - '# Send a Telegram Alert\n\nDeliver a timely notification to a Telegram chat, group, or channel.\n\n## Steps\n1. Use the Send Message operation with your Bot Token and the target Chat ID.\n2. Compose the Message with the essentials up front: what happened, severity, and a link for follow-up.\n3. To find a Chat ID, add the bot to the chat, send a message, then read the chat field from the getUpdates response.\n4. For recurring alerts, build the message from upstream block outputs so each notification carries live context.\n\n## Output\nReturn the sent message ID and chat ID so the run can be traced or the message later deleted.', - }, - { - name: 'send-media-message', - description: - 'Send a photo, video, document, or audio file to a Telegram chat with a caption.', - content: - '# Send Media to Telegram\n\nDeliver a file such as a chart, report, or image to a Telegram chat.\n\n## Steps\n1. Pick the matching operation: Send Photo, Send Video, Send Audio, Send Animation, or Send Document.\n2. Provide the Bot Token and Chat ID.\n3. Upload the file directly, or reference a file produced by a previous block (for example a generated PDF or chart image).\n4. Add an optional Caption describing the attachment.\n\n## Output\nConfirm delivery and return the message ID so the media post can be referenced later.', - }, - { - name: 'route-incoming-message', - description: 'Trigger a workflow when a Telegram message arrives and act on its content.', - content: - '# Route an Incoming Telegram Message\n\nUse Telegram as a trigger so the workflow runs whenever a user messages the bot.\n\n## Steps\n1. Enable the Telegram webhook trigger so incoming messages start the workflow.\n2. Read the trigger outputs: text, from_username, chat_id, and chat_type.\n3. Branch on the message content (for example detect a command or a support question) to decide the next action.\n4. Reply with the Send Message operation using the chat_id from the trigger.\n\n## Output\nReturn the parsed incoming message fields and confirm the reply that was sent back to the user.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/temporal.display.ts b/apps/sim/blocks/blocks/temporal.display.ts index 8450942c28f..fb454fd0681 100644 --- a/apps/sim/blocks/blocks/temporal.display.ts +++ b/apps/sim/blocks/blocks/temporal.display.ts @@ -1,6 +1,6 @@ import { TemporalIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TemporalBlockDisplay = { type: 'temporal', @@ -14,3 +14,105 @@ export const TemporalBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/temporal', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const TemporalBlockMeta = { + tags: ['automation'], + url: 'https://temporal.io', + templates: [ + { + icon: TemporalIcon, + title: 'Temporal order approval gate', + prompt: + 'Create a workflow that receives an approval decision from a form, signals the matching Temporal order workflow with the decision, and posts a confirmation to Slack with the workflow ID and current status.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'approvals'], + alsoIntegrations: ['slack'], + }, + { + icon: TemporalIcon, + title: 'Temporal failed workflow digest', + prompt: + 'Build a scheduled daily workflow that lists Temporal executions that failed or timed out in the last 24 hours, pulls the close event from each history to extract the failure, and posts a digest to Slack grouped by workflow type.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: TemporalIcon, + title: 'Temporal stuck workflow watcher', + prompt: + 'Create a scheduled workflow that lists running Temporal executions, describes each one to inspect pending activities, flags workflows whose activities are retrying with high attempt counts, and opens a Linear ticket with the failure details.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: TemporalIcon, + title: 'Temporal kickoff from intake form', + prompt: + 'Build a workflow that starts a Temporal workflow execution with input assembled from an intake form submission, polls describe until the execution closes, and writes the final status and timing to a tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation'], + }, + { + icon: TemporalIcon, + title: 'Temporal status lookup agent', + prompt: + 'Create an agent that answers "where is my order" questions by querying the matching Temporal workflow for its current state and summarizing the progress, falling back to the latest history events when no query handler responds.', + modules: ['agent'], + category: 'support', + tags: ['customer-support'], + }, + { + icon: TemporalIcon, + title: 'Temporal runaway workflow janitor', + prompt: + 'Build a scheduled weekly workflow that lists Temporal executions running longer than seven days, describes each to confirm it is stalled, requests cancellation with a recorded reason, and terminates any execution that ignores the cancellation after a grace period.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: TemporalIcon, + title: 'Temporal incident escalation bridge', + prompt: + 'Create a workflow that signals a Temporal incident-response workflow with escalation details when a monitoring alert fires, using signal-with-start so a new incident workflow is created if one is not already running.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['incident-management', 'automation'], + alsoIntegrations: ['pagerduty'], + }, + ], + skills: [ + { + name: 'start-workflow-execution', + description: + 'Start a Temporal workflow execution with the right input and report the workflow and run IDs.', + content: + '# Start a Temporal Workflow\n\nKick off a workflow execution on the cluster.\n\n## Steps\n1. Confirm the workflow type, task queue, and a unique workflow ID.\n2. Assemble the JSON input arguments for the workflow.\n3. Start the workflow and capture the run ID.\n4. Describe the execution to confirm it is running.\n\n## Output\nA confirmation with the workflow ID, run ID, and initial status.', + }, + { + name: 'investigate-failed-workflow', + description: + 'Describe a failed Temporal workflow and pull its close event to explain why it failed.', + content: + '# Investigate a Failed Temporal Workflow\n\nDiagnose a workflow failure.\n\n## Steps\n1. Describe the workflow to confirm its status and timing.\n2. Fetch the history filtered to the close event to get the failure details.\n3. If needed, fetch earlier history pages to trace the failing activity.\n4. Summarize the root cause.\n\n## Output\nA failure summary with the failing event, error message, and a recommendation.', + }, + { + name: 'signal-running-workflow', + description: 'Send a signal to a running Temporal workflow and confirm it was delivered.', + content: + '# Signal a Temporal Workflow\n\nDeliver data or a decision to a running execution.\n\n## Steps\n1. Find the target execution by workflow ID (or list executions to locate it).\n2. Send the signal with the JSON payload.\n3. Query or describe the workflow to confirm the signal took effect.\n\n## Output\nA confirmation with the workflow ID, signal name, and resulting state.', + }, + { + name: 'audit-running-workflows', + description: 'List running Temporal executions and surface long-running or stuck workflows.', + content: + '# Audit Running Temporal Workflows\n\nFind executions that need attention.\n\n## Steps\n1. List executions filtered to ExecutionStatus = "Running".\n2. Sort by start time and flag the longest-running executions.\n3. Describe flagged executions to inspect pending activities and retry counts.\n4. Recommend cancellation or escalation for stuck workflows.\n\n## Output\nA per-workflow report with age, pending activities, and a recommended action.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/temporal.ts b/apps/sim/blocks/blocks/temporal.ts index 36d6cca14f8..d3b675aadde 100644 --- a/apps/sim/blocks/blocks/temporal.ts +++ b/apps/sim/blocks/blocks/temporal.ts @@ -1,6 +1,5 @@ -import { TemporalIcon } from '@/components/icons' import { TemporalBlockDisplay } from '@/blocks/blocks/temporal.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { TemporalResponse } from '@/tools/temporal/types' /** Coerces a subBlock value to a finite number, returning undefined for empty or non-numeric input. */ @@ -804,105 +803,3 @@ Return ONLY a valid JSON object - no explanations, no extra text.`, }, }, } - -export const TemporalBlockMeta = { - tags: ['automation'], - url: 'https://temporal.io', - templates: [ - { - icon: TemporalIcon, - title: 'Temporal order approval gate', - prompt: - 'Create a workflow that receives an approval decision from a form, signals the matching Temporal order workflow with the decision, and posts a confirmation to Slack with the workflow ID and current status.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'approvals'], - alsoIntegrations: ['slack'], - }, - { - icon: TemporalIcon, - title: 'Temporal failed workflow digest', - prompt: - 'Build a scheduled daily workflow that lists Temporal executions that failed or timed out in the last 24 hours, pulls the close event from each history to extract the failure, and posts a digest to Slack grouped by workflow type.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: TemporalIcon, - title: 'Temporal stuck workflow watcher', - prompt: - 'Create a scheduled workflow that lists running Temporal executions, describes each one to inspect pending activities, flags workflows whose activities are retrying with high attempt counts, and opens a Linear ticket with the failure details.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: TemporalIcon, - title: 'Temporal kickoff from intake form', - prompt: - 'Build a workflow that starts a Temporal workflow execution with input assembled from an intake form submission, polls describe until the execution closes, and writes the final status and timing to a tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation'], - }, - { - icon: TemporalIcon, - title: 'Temporal status lookup agent', - prompt: - 'Create an agent that answers "where is my order" questions by querying the matching Temporal workflow for its current state and summarizing the progress, falling back to the latest history events when no query handler responds.', - modules: ['agent'], - category: 'support', - tags: ['customer-support'], - }, - { - icon: TemporalIcon, - title: 'Temporal runaway workflow janitor', - prompt: - 'Build a scheduled weekly workflow that lists Temporal executions running longer than seven days, describes each to confirm it is stalled, requests cancellation with a recorded reason, and terminates any execution that ignores the cancellation after a grace period.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: TemporalIcon, - title: 'Temporal incident escalation bridge', - prompt: - 'Create a workflow that signals a Temporal incident-response workflow with escalation details when a monitoring alert fires, using signal-with-start so a new incident workflow is created if one is not already running.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['incident-management', 'automation'], - alsoIntegrations: ['pagerduty'], - }, - ], - skills: [ - { - name: 'start-workflow-execution', - description: - 'Start a Temporal workflow execution with the right input and report the workflow and run IDs.', - content: - '# Start a Temporal Workflow\n\nKick off a workflow execution on the cluster.\n\n## Steps\n1. Confirm the workflow type, task queue, and a unique workflow ID.\n2. Assemble the JSON input arguments for the workflow.\n3. Start the workflow and capture the run ID.\n4. Describe the execution to confirm it is running.\n\n## Output\nA confirmation with the workflow ID, run ID, and initial status.', - }, - { - name: 'investigate-failed-workflow', - description: - 'Describe a failed Temporal workflow and pull its close event to explain why it failed.', - content: - '# Investigate a Failed Temporal Workflow\n\nDiagnose a workflow failure.\n\n## Steps\n1. Describe the workflow to confirm its status and timing.\n2. Fetch the history filtered to the close event to get the failure details.\n3. If needed, fetch earlier history pages to trace the failing activity.\n4. Summarize the root cause.\n\n## Output\nA failure summary with the failing event, error message, and a recommendation.', - }, - { - name: 'signal-running-workflow', - description: 'Send a signal to a running Temporal workflow and confirm it was delivered.', - content: - '# Signal a Temporal Workflow\n\nDeliver data or a decision to a running execution.\n\n## Steps\n1. Find the target execution by workflow ID (or list executions to locate it).\n2. Send the signal with the JSON payload.\n3. Query or describe the workflow to confirm the signal took effect.\n\n## Output\nA confirmation with the workflow ID, signal name, and resulting state.', - }, - { - name: 'audit-running-workflows', - description: 'List running Temporal executions and surface long-running or stuck workflows.', - content: - '# Audit Running Temporal Workflows\n\nFind executions that need attention.\n\n## Steps\n1. List executions filtered to ExecutionStatus = "Running".\n2. Sort by start time and flag the longest-running executions.\n3. Describe flagged executions to inspect pending activities and retry counts.\n4. Recommend cancellation or escalation for stuck workflows.\n\n## Output\nA per-workflow report with age, pending activities, and a recommended action.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/textract.display.ts b/apps/sim/blocks/blocks/textract.display.ts index 8af130386e7..ac826bb3af8 100644 --- a/apps/sim/blocks/blocks/textract.display.ts +++ b/apps/sim/blocks/blocks/textract.display.ts @@ -1,6 +1,6 @@ import { TextractIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TextractBlockDisplay = { type: 'textract', @@ -22,3 +22,102 @@ export const TextractV2BlockDisplay = { name: 'AWS Textract', hideFromToolbar: false, } satisfies BlockDisplay + +export const TextractBlockMeta = { + tags: ['document-processing', 'ocr', 'cloud'], + url: 'https://aws.amazon.com/textract', + templates: [ + { + icon: TextractIcon, + title: 'Textract invoice extractor', + prompt: + 'Create a scheduled workflow that polls an S3 folder for new PDFs, runs AWS Textract to extract line items and totals, writes the structured fields to a table, and flags invoices that fail validation.', + modules: ['scheduled', 'tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['s3'], + }, + { + icon: TextractIcon, + title: 'Receipt OCR for expense reports', + prompt: + 'Build a workflow that processes Gmail attachments with AWS Textract, extracts vendor, date, total, and category, logs each receipt to an expense table, and tags reimbursable items.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: TextractIcon, + title: 'Textract ID verification', + prompt: + 'Build a workflow that runs uploaded ID documents through AWS Textract analyze-id, extracts name, DOB, and ID number, validates against a customer record, and flags mismatches for review.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['legal', 'automation'], + }, + { + icon: TextractIcon, + title: 'Textract form-to-table', + prompt: + 'Build a workflow that pushes scanned forms from Google Drive through AWS Textract analyze-document, extracts key-value pairs and tables, and writes structured rows to a Sim table for downstream automations.', + modules: ['tables', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'enterprise'], + alsoIntegrations: ['google_drive'], + }, + { + icon: TextractIcon, + title: 'Textract + Reducto cross-format extractor', + prompt: + 'Create a workflow that ingests mixed PDF and image files, routes images through AWS Textract and dense PDFs through Reducto, normalizes fields, and writes rows to a table.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'analysis'], + alsoIntegrations: ['reducto'], + }, + { + icon: TextractIcon, + title: 'Textract + Extend pipeline composer', + prompt: + 'Build a workflow that uses AWS Textract for layout-aware OCR and Extend for structured field extraction, fusing outputs into clean records for downstream automations.', + modules: ['files', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation'], + alsoIntegrations: ['extend'], + }, + { + icon: TextractIcon, + title: 'Textract handwritten-note digitizer', + prompt: + 'Build a workflow that runs scanned handwritten intake notes through AWS Textract, converts the recognized text into clean Markdown, indexes it into a knowledge base, and posts a confidence summary to Slack so low-confidence pages get a human review.', + modules: ['files', 'knowledge-base', 'agent', 'workflows'], + category: 'operations', + tags: ['ocr', 'automation', 'enterprise'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'extract-invoice-fields', + description: + 'Run an invoice or receipt through AWS Textract and return clean structured fields (vendor, date, totals, line items). Use when you need to digitize finance documents.', + content: + '# Extract Invoice Fields\n\nUse AWS Textract to pull structured data from an invoice or receipt image/PDF.\n\n## Steps\n1. Choose the processing mode: Single Page for JPEG, PNG, or one-page PDF; Multi-Page for multi-page PDF/TIFF staged in S3.\n2. Provide the document (upload, file reference, or S3 URI) and enable Extract Forms and Extract Tables so key-value pairs and line items are captured.\n3. Run the extraction and read the returned blocks (KEY_VALUE_SET, TABLE, CELL, LINE).\n4. Map key-value pairs to fields: vendor, invoice number, invoice date, due date, subtotal, tax, and total.\n5. Reconstruct line items from the TABLE/CELL blocks into rows with description, quantity, unit price, and amount.\n\n## Output\nReturn a clean JSON record with the header fields and a line-items array. Flag any field where Textract confidence is low or the totals do not reconcile so a human can review.', + }, + { + name: 'extract-form-key-values', + description: + 'Turn a scanned form into structured key-value pairs and tables using AWS Textract. Use for intake forms, applications, and contracts.', + content: + '# Extract Form Key-Values\n\nDigitize a scanned form into structured data.\n\n## Steps\n1. Select Single Page mode for an image or one-page PDF, or Multi-Page mode with an S3 URI for longer documents.\n2. Enable Extract Forms (key-value pairs) and, if the form has tables, Extract Tables. Enable Analyze Document Layout for complex multi-column forms.\n3. Run the extraction and parse the KEY_VALUE_SET blocks into field-name to field-value pairs.\n4. Normalize field names (trim labels, lowercase keys) and coerce values like dates and numbers.\n\n## Output\nReturn a flat object of normalized field names to values, plus any extracted tables as arrays of rows. Note pages or fields with low confidence for review.', + }, + { + name: 'ocr-document-to-text', + description: + 'Convert a scanned document or image into plain readable text with AWS Textract OCR. Use to digitize handwritten notes, faxes, or image-only PDFs for indexing or search.', + content: + '# OCR Document To Text\n\nExtract readable text from a scanned or image-only document.\n\n## Steps\n1. Pick the processing mode that matches the file: Single Page for an image or one-page PDF, Multi-Page (S3) for multi-page documents.\n2. Provide the document and run the extraction. Plain OCR does not require the Forms or Tables features.\n3. Read the LINE and WORD blocks and join LINE blocks in reading order to reconstruct the text.\n4. Preserve paragraph and page breaks using the PAGE blocks.\n\n## Output\nReturn the full extracted text as clean Markdown, grouped by page. Include the page count from document metadata and surface any low-confidence lines so they can be reviewed before indexing.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/textract.ts b/apps/sim/blocks/blocks/textract.ts index a43ae73f7a3..b7051ef27f8 100644 --- a/apps/sim/blocks/blocks/textract.ts +++ b/apps/sim/blocks/blocks/textract.ts @@ -1,6 +1,5 @@ -import { TextractIcon } from '@/components/icons' import { TextractBlockDisplay, TextractV2BlockDisplay } from '@/blocks/blocks/textract.display' -import { AuthMode, type BlockConfig, type BlockMeta, type SubBlockType } from '@/blocks/types' +import { AuthMode, type BlockConfig, type SubBlockType } from '@/blocks/types' import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils' import type { TextractParserOutput } from '@/tools/textract/types' @@ -272,102 +271,3 @@ export const TextractV2Block: BlockConfig = { }, inputs: textractV2Inputs, } - -export const TextractBlockMeta = { - tags: ['document-processing', 'ocr', 'cloud'], - url: 'https://aws.amazon.com/textract', - templates: [ - { - icon: TextractIcon, - title: 'Textract invoice extractor', - prompt: - 'Create a scheduled workflow that polls an S3 folder for new PDFs, runs AWS Textract to extract line items and totals, writes the structured fields to a table, and flags invoices that fail validation.', - modules: ['scheduled', 'tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['s3'], - }, - { - icon: TextractIcon, - title: 'Receipt OCR for expense reports', - prompt: - 'Build a workflow that processes Gmail attachments with AWS Textract, extracts vendor, date, total, and category, logs each receipt to an expense table, and tags reimbursable items.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: TextractIcon, - title: 'Textract ID verification', - prompt: - 'Build a workflow that runs uploaded ID documents through AWS Textract analyze-id, extracts name, DOB, and ID number, validates against a customer record, and flags mismatches for review.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['legal', 'automation'], - }, - { - icon: TextractIcon, - title: 'Textract form-to-table', - prompt: - 'Build a workflow that pushes scanned forms from Google Drive through AWS Textract analyze-document, extracts key-value pairs and tables, and writes structured rows to a Sim table for downstream automations.', - modules: ['tables', 'files', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'enterprise'], - alsoIntegrations: ['google_drive'], - }, - { - icon: TextractIcon, - title: 'Textract + Reducto cross-format extractor', - prompt: - 'Create a workflow that ingests mixed PDF and image files, routes images through AWS Textract and dense PDFs through Reducto, normalizes fields, and writes rows to a table.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'analysis'], - alsoIntegrations: ['reducto'], - }, - { - icon: TextractIcon, - title: 'Textract + Extend pipeline composer', - prompt: - 'Build a workflow that uses AWS Textract for layout-aware OCR and Extend for structured field extraction, fusing outputs into clean records for downstream automations.', - modules: ['files', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'automation'], - alsoIntegrations: ['extend'], - }, - { - icon: TextractIcon, - title: 'Textract handwritten-note digitizer', - prompt: - 'Build a workflow that runs scanned handwritten intake notes through AWS Textract, converts the recognized text into clean Markdown, indexes it into a knowledge base, and posts a confidence summary to Slack so low-confidence pages get a human review.', - modules: ['files', 'knowledge-base', 'agent', 'workflows'], - category: 'operations', - tags: ['ocr', 'automation', 'enterprise'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'extract-invoice-fields', - description: - 'Run an invoice or receipt through AWS Textract and return clean structured fields (vendor, date, totals, line items). Use when you need to digitize finance documents.', - content: - '# Extract Invoice Fields\n\nUse AWS Textract to pull structured data from an invoice or receipt image/PDF.\n\n## Steps\n1. Choose the processing mode: Single Page for JPEG, PNG, or one-page PDF; Multi-Page for multi-page PDF/TIFF staged in S3.\n2. Provide the document (upload, file reference, or S3 URI) and enable Extract Forms and Extract Tables so key-value pairs and line items are captured.\n3. Run the extraction and read the returned blocks (KEY_VALUE_SET, TABLE, CELL, LINE).\n4. Map key-value pairs to fields: vendor, invoice number, invoice date, due date, subtotal, tax, and total.\n5. Reconstruct line items from the TABLE/CELL blocks into rows with description, quantity, unit price, and amount.\n\n## Output\nReturn a clean JSON record with the header fields and a line-items array. Flag any field where Textract confidence is low or the totals do not reconcile so a human can review.', - }, - { - name: 'extract-form-key-values', - description: - 'Turn a scanned form into structured key-value pairs and tables using AWS Textract. Use for intake forms, applications, and contracts.', - content: - '# Extract Form Key-Values\n\nDigitize a scanned form into structured data.\n\n## Steps\n1. Select Single Page mode for an image or one-page PDF, or Multi-Page mode with an S3 URI for longer documents.\n2. Enable Extract Forms (key-value pairs) and, if the form has tables, Extract Tables. Enable Analyze Document Layout for complex multi-column forms.\n3. Run the extraction and parse the KEY_VALUE_SET blocks into field-name to field-value pairs.\n4. Normalize field names (trim labels, lowercase keys) and coerce values like dates and numbers.\n\n## Output\nReturn a flat object of normalized field names to values, plus any extracted tables as arrays of rows. Note pages or fields with low confidence for review.', - }, - { - name: 'ocr-document-to-text', - description: - 'Convert a scanned document or image into plain readable text with AWS Textract OCR. Use to digitize handwritten notes, faxes, or image-only PDFs for indexing or search.', - content: - '# OCR Document To Text\n\nExtract readable text from a scanned or image-only document.\n\n## Steps\n1. Pick the processing mode that matches the file: Single Page for an image or one-page PDF, Multi-Page (S3) for multi-page documents.\n2. Provide the document and run the extraction. Plain OCR does not require the Forms or Tables features.\n3. Read the LINE and WORD blocks and join LINE blocks in reading order to reconstruct the text.\n4. Preserve paragraph and page breaks using the PAGE blocks.\n\n## Output\nReturn the full extracted text as clean Markdown, grouped by page. Include the page count from document metadata and surface any low-confidence lines so they can be reviewed before indexing.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/thrive.display.ts b/apps/sim/blocks/blocks/thrive.display.ts index 1412919a27f..78311de9880 100644 --- a/apps/sim/blocks/blocks/thrive.display.ts +++ b/apps/sim/blocks/blocks/thrive.display.ts @@ -1,6 +1,6 @@ import { ThriveIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ThriveBlockDisplay = { type: 'thrive', @@ -14,3 +14,87 @@ export const ThriveBlockDisplay = { docsLink: 'https://docs.sim.ai/tools/thrive', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const ThriveBlockMeta = { + tags: ['content-management', 'knowledge-base', 'automation'], + url: 'https://thrivelearning.com', + templates: [ + { + icon: ThriveIcon, + title: 'Onboard new hires into Thrive', + prompt: + 'Build a workflow that, when a new employee row is added to a Google Sheet, creates the user in Thrive with their ref, name, email, job title, and manager, then adds them to the relevant onboarding audience.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'onboarding', 'automation'], + alsoIntegrations: ['google_sheets'], + }, + { + icon: ThriveIcon, + title: 'Compliance completion digest', + prompt: + 'Create a scheduled weekly workflow that lists Thrive enrolments for a compliance assignment, filters those still open or overdue, and posts a Slack summary to the people-ops channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['compliance', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ThriveIcon, + title: 'Sync leavers from HRIS', + prompt: + 'Build a workflow that reads terminated employees from an HRIS export and suspends each matching user in Thrive with their end date, then logs the result to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'lifecycle', 'automation'], + }, + { + icon: ThriveIcon, + title: 'Import historical completions', + prompt: + 'Create a workflow that reads a CSV of prior learning records and creates a completion in Thrive for each user and content item with the completion date.', + modules: ['files', 'agent', 'workflows'], + category: 'operations', + tags: ['migration', 'learning'], + }, + { + icon: ThriveIcon, + title: 'Assign mandatory training to an audience', + prompt: + 'Build a workflow that creates a Thrive content assignment for a chosen audience and primary content, sets a 30-day completion period, and reports how many learners were enrolled.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['compliance', 'learning'], + }, + { + icon: ThriveIcon, + title: 'CPD shortfall report', + prompt: + 'Create a scheduled monthly workflow that queries Thrive CPD user summaries for a date range, compares logged minutes against each audience CPD requirement, and emails managers a list of learners below target.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['cpd', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: ThriveIcon, + title: 'Tag learners by skill', + prompt: + 'Build a workflow that searches Thrive users by status, then adds skill tags and updates skill levels for each learner based on a mapping in a spreadsheet.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['skills', 'automation'], + alsoIntegrations: ['google_sheets'], + }, + { + icon: ThriveIcon, + title: 'Trending content to Slack', + prompt: + 'Create a scheduled workflow that queries recently updated Thrive content and activity records, summarises the most engaged-with learning, and posts a weekly highlight to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['content', 'engagement'], + alsoIntegrations: ['slack'], + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/thrive.ts b/apps/sim/blocks/blocks/thrive.ts index 5591e499be6..7ad3cd2e1f6 100644 --- a/apps/sim/blocks/blocks/thrive.ts +++ b/apps/sim/blocks/blocks/thrive.ts @@ -1,6 +1,5 @@ -import { ThriveIcon } from '@/components/icons' import { ThriveBlockDisplay } from '@/blocks/blocks/thrive.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' const PAGINATED_OPS = [ 'search_users', @@ -933,87 +932,3 @@ export const ThriveBlock: BlockConfig = { message: { type: 'string', description: 'A human-readable result message' }, }, } - -export const ThriveBlockMeta = { - tags: ['content-management', 'knowledge-base', 'automation'], - url: 'https://thrivelearning.com', - templates: [ - { - icon: ThriveIcon, - title: 'Onboard new hires into Thrive', - prompt: - 'Build a workflow that, when a new employee row is added to a Google Sheet, creates the user in Thrive with their ref, name, email, job title, and manager, then adds them to the relevant onboarding audience.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'onboarding', 'automation'], - alsoIntegrations: ['google_sheets'], - }, - { - icon: ThriveIcon, - title: 'Compliance completion digest', - prompt: - 'Create a scheduled weekly workflow that lists Thrive enrolments for a compliance assignment, filters those still open or overdue, and posts a Slack summary to the people-ops channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['compliance', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ThriveIcon, - title: 'Sync leavers from HRIS', - prompt: - 'Build a workflow that reads terminated employees from an HRIS export and suspends each matching user in Thrive with their end date, then logs the result to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'lifecycle', 'automation'], - }, - { - icon: ThriveIcon, - title: 'Import historical completions', - prompt: - 'Create a workflow that reads a CSV of prior learning records and creates a completion in Thrive for each user and content item with the completion date.', - modules: ['files', 'agent', 'workflows'], - category: 'operations', - tags: ['migration', 'learning'], - }, - { - icon: ThriveIcon, - title: 'Assign mandatory training to an audience', - prompt: - 'Build a workflow that creates a Thrive content assignment for a chosen audience and primary content, sets a 30-day completion period, and reports how many learners were enrolled.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['compliance', 'learning'], - }, - { - icon: ThriveIcon, - title: 'CPD shortfall report', - prompt: - 'Create a scheduled monthly workflow that queries Thrive CPD user summaries for a date range, compares logged minutes against each audience CPD requirement, and emails managers a list of learners below target.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['cpd', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: ThriveIcon, - title: 'Tag learners by skill', - prompt: - 'Build a workflow that searches Thrive users by status, then adds skill tags and updates skill levels for each learner based on a mapping in a spreadsheet.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['skills', 'automation'], - alsoIntegrations: ['google_sheets'], - }, - { - icon: ThriveIcon, - title: 'Trending content to Slack', - prompt: - 'Create a scheduled workflow that queries recently updated Thrive content and activity records, summarises the most engaged-with learning, and posts a weekly highlight to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['content', 'engagement'], - alsoIntegrations: ['slack'], - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tinybird.display.ts b/apps/sim/blocks/blocks/tinybird.display.ts index 7da09a6c371..b15553763c0 100644 --- a/apps/sim/blocks/blocks/tinybird.display.ts +++ b/apps/sim/blocks/blocks/tinybird.display.ts @@ -1,6 +1,6 @@ import { TinybirdIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TinybirdBlockDisplay = { type: 'tinybird', @@ -14,3 +14,108 @@ export const TinybirdBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/tinybird', integrationType: IntegrationType.Analytics, } satisfies BlockDisplay + +export const TinybirdBlockMeta = { + tags: ['data-warehouse', 'data-analytics'], + url: 'https://www.tinybird.co', + templates: [ + { + icon: TinybirdIcon, + title: 'Tinybird pipe-as-API endpoint', + prompt: + 'Create a workflow that calls a Tinybird published pipe with parameters on a schedule, normalizes the results, and writes them into a Sim table for downstream consumers.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['analysis', 'sync'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird realtime metric watcher', + prompt: + 'Build a workflow that polls a Tinybird pipe every minute for a realtime KPI, compares against a rolling baseline, and pages PagerDuty when the metric crosses a SLO threshold.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird user-segment exporter', + prompt: + 'Create a workflow that calls a Tinybird published endpoint with segment parameters, writes the user list to a table, and feeds it to a Loops campaign for targeted activation messaging.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'sync'], + alsoIntegrations: ['loops'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird usage-meter dashboard', + prompt: + 'Build a workflow that exposes a Tinybird endpoint reporting per-customer usage for billing, refreshes a Sim table hourly, and surfaces top consumers to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird funnel analytics digest', + prompt: + 'Create a scheduled workflow that queries a Tinybird pipe for daily signup, activation, and conversion counts, calculates step-over-step drop-off, and posts a funnel digest with week-over-week deltas to the growth Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['analysis', 'reporting', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird anomaly investigator', + prompt: + 'Build a workflow triggered by an alert that calls a Tinybird pipe to pull the surrounding event data for the affected metric, has an agent summarize the likely cause, and opens a Linear issue with the supporting query results attached.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'analysis', 'monitoring'], + alsoIntegrations: ['linear'], + }, + { + icon: TinybirdIcon, + title: 'Tinybird executive KPI report', + prompt: + 'Create a scheduled weekly workflow that queries several Tinybird pipes for the company’s headline KPIs, assembles them into a Markdown report file with trend commentary, and emails it to the leadership team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['reporting', 'analysis', 'enterprise'], + alsoIntegrations: ['gmail'], + }, + ], + skills: [ + { + name: 'ingest-events', + description: 'Stream JSON or NDJSON events into a Tinybird Data Source via the Events API.', + content: + '# Ingest Events into Tinybird\n\nStream realtime events into a Data Source so they are queryable within seconds.\n\n## Steps\n1. Use the Send Events operation with your Base URL and API Token.\n2. Set the Data Source name that matches your target table.\n3. Provide the events in the Data field, using NDJSON (one JSON object per line) for batches or JSON for a single object.\n4. Enable Wait for Acknowledgment when you need confirmation the rows landed before continuing.\n\n## Output\nReturn the count of successful_rows and quarantined_rows so you can confirm ingestion and catch rows that failed validation.', + }, + { + name: 'query-pipe-endpoint', + description: + 'Call a published Tinybird Pipe API Endpoint with dynamic parameters and return the result.', + content: + '# Query a Tinybird Pipe Endpoint\n\nCall a published Pipe by name to get analytics results shaped by dynamic parameters.\n\n## Steps\n1. Use the Query Pipe Endpoint operation with the Base URL, API Token, and the Pipe Name (for example top_pages).\n2. Pass dynamic Parameters as a JSON object whose keys match the parameters the Pipe expects (for example start_date and limit).\n3. Optionally add SQL on top of the Pipe result using the advanced SQL field, selecting from _ to post-process.\n\n## Output\nReturn the result rows as JSON along with the column metadata and row count, ready to write to a table or summarize.', + }, + { + name: 'run-sql-query', + description: + 'Run an ad-hoc SQL query against Tinybird with the Query API and return results.', + content: + '# Run a Tinybird SQL Query\n\nExecute SQL directly against your Tinybird data for ad-hoc analysis.\n\n## Steps\n1. Use the Query operation with the Base URL and API Token.\n2. Write the SQL Query and append FORMAT JSON to get structured rows back (other formats return raw text).\n3. Reference Data Sources or Pipes by name in the FROM clause.\n\n## Output\nReturn the result data as an array of objects plus the column metadata, row count, and execution statistics.', + }, + { + name: 'manage-datasource-rows', + description: + 'Append from a URL, truncate, or delete rows by condition in a Tinybird Data Source.', + content: + "# Manage Tinybird Data Source Rows\n\nMaintain a Data Source by loading, clearing, or pruning its rows.\n\n## Steps\n1. To load data, use Append Data Source (from URL) with the Data Source name, a Source File URL, and the source format (CSV, NDJSON, or Parquet).\n2. To clear everything, use Truncate Data Source with the Data Source name.\n3. To remove specific rows, use Delete Data Source Rows with a SQL Delete Condition such as event_date < '2024-01-01'.\n4. Enable Dry Run on a delete first to preview how many rows would be removed.\n\n## Output\nReturn the job ID and status for append and delete operations so you can poll for completion, or confirm the truncate succeeded.", + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/tinybird.ts b/apps/sim/blocks/blocks/tinybird.ts index 58308c9f174..f4899971c33 100644 --- a/apps/sim/blocks/blocks/tinybird.ts +++ b/apps/sim/blocks/blocks/tinybird.ts @@ -1,6 +1,5 @@ -import { TinybirdIcon } from '@/components/icons' import { TinybirdBlockDisplay } from '@/blocks/blocks/tinybird.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { TinybirdResponse } from '@/tools/tinybird/types' @@ -375,108 +374,3 @@ export const TinybirdBlock: BlockConfig = { result: { type: 'json', description: 'Raw truncate response body, if any' }, }, } - -export const TinybirdBlockMeta = { - tags: ['data-warehouse', 'data-analytics'], - url: 'https://www.tinybird.co', - templates: [ - { - icon: TinybirdIcon, - title: 'Tinybird pipe-as-API endpoint', - prompt: - 'Create a workflow that calls a Tinybird published pipe with parameters on a schedule, normalizes the results, and writes them into a Sim table for downstream consumers.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['analysis', 'sync'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird realtime metric watcher', - prompt: - 'Build a workflow that polls a Tinybird pipe every minute for a realtime KPI, compares against a rolling baseline, and pages PagerDuty when the metric crosses a SLO threshold.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird user-segment exporter', - prompt: - 'Create a workflow that calls a Tinybird published endpoint with segment parameters, writes the user list to a table, and feeds it to a Loops campaign for targeted activation messaging.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'sync'], - alsoIntegrations: ['loops'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird usage-meter dashboard', - prompt: - 'Build a workflow that exposes a Tinybird endpoint reporting per-customer usage for billing, refreshes a Sim table hourly, and surfaces top consumers to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird funnel analytics digest', - prompt: - 'Create a scheduled workflow that queries a Tinybird pipe for daily signup, activation, and conversion counts, calculates step-over-step drop-off, and posts a funnel digest with week-over-week deltas to the growth Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['analysis', 'reporting', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird anomaly investigator', - prompt: - 'Build a workflow triggered by an alert that calls a Tinybird pipe to pull the surrounding event data for the affected metric, has an agent summarize the likely cause, and opens a Linear issue with the supporting query results attached.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'analysis', 'monitoring'], - alsoIntegrations: ['linear'], - }, - { - icon: TinybirdIcon, - title: 'Tinybird executive KPI report', - prompt: - 'Create a scheduled weekly workflow that queries several Tinybird pipes for the company’s headline KPIs, assembles them into a Markdown report file with trend commentary, and emails it to the leadership team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['reporting', 'analysis', 'enterprise'], - alsoIntegrations: ['gmail'], - }, - ], - skills: [ - { - name: 'ingest-events', - description: 'Stream JSON or NDJSON events into a Tinybird Data Source via the Events API.', - content: - '# Ingest Events into Tinybird\n\nStream realtime events into a Data Source so they are queryable within seconds.\n\n## Steps\n1. Use the Send Events operation with your Base URL and API Token.\n2. Set the Data Source name that matches your target table.\n3. Provide the events in the Data field, using NDJSON (one JSON object per line) for batches or JSON for a single object.\n4. Enable Wait for Acknowledgment when you need confirmation the rows landed before continuing.\n\n## Output\nReturn the count of successful_rows and quarantined_rows so you can confirm ingestion and catch rows that failed validation.', - }, - { - name: 'query-pipe-endpoint', - description: - 'Call a published Tinybird Pipe API Endpoint with dynamic parameters and return the result.', - content: - '# Query a Tinybird Pipe Endpoint\n\nCall a published Pipe by name to get analytics results shaped by dynamic parameters.\n\n## Steps\n1. Use the Query Pipe Endpoint operation with the Base URL, API Token, and the Pipe Name (for example top_pages).\n2. Pass dynamic Parameters as a JSON object whose keys match the parameters the Pipe expects (for example start_date and limit).\n3. Optionally add SQL on top of the Pipe result using the advanced SQL field, selecting from _ to post-process.\n\n## Output\nReturn the result rows as JSON along with the column metadata and row count, ready to write to a table or summarize.', - }, - { - name: 'run-sql-query', - description: - 'Run an ad-hoc SQL query against Tinybird with the Query API and return results.', - content: - '# Run a Tinybird SQL Query\n\nExecute SQL directly against your Tinybird data for ad-hoc analysis.\n\n## Steps\n1. Use the Query operation with the Base URL and API Token.\n2. Write the SQL Query and append FORMAT JSON to get structured rows back (other formats return raw text).\n3. Reference Data Sources or Pipes by name in the FROM clause.\n\n## Output\nReturn the result data as an array of objects plus the column metadata, row count, and execution statistics.', - }, - { - name: 'manage-datasource-rows', - description: - 'Append from a URL, truncate, or delete rows by condition in a Tinybird Data Source.', - content: - "# Manage Tinybird Data Source Rows\n\nMaintain a Data Source by loading, clearing, or pruning its rows.\n\n## Steps\n1. To load data, use Append Data Source (from URL) with the Data Source name, a Source File URL, and the source format (CSV, NDJSON, or Parquet).\n2. To clear everything, use Truncate Data Source with the Data Source name.\n3. To remove specific rows, use Delete Data Source Rows with a SQL Delete Condition such as event_date < '2024-01-01'.\n4. Enable Dry Run on a delete first to preview how many rows would be removed.\n\n## Output\nReturn the job ID and status for append and delete operations so you can poll for completion, or confirm the truncate succeeded.", - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/trello.display.ts b/apps/sim/blocks/blocks/trello.display.ts index a0d8bb9c589..6f72be21868 100644 --- a/apps/sim/blocks/blocks/trello.display.ts +++ b/apps/sim/blocks/blocks/trello.display.ts @@ -1,6 +1,6 @@ import { TrelloIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TrelloBlockDisplay = { type: 'trello', @@ -14,3 +14,105 @@ export const TrelloBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/trello', integrationType: IntegrationType.Productivity, } satisfies BlockDisplay + +export const TrelloBlockMeta = { + tags: ['project-management', 'ticketing'], + url: 'https://trello.com', + templates: [ + { + icon: TrelloIcon, + title: 'Trello card auto-router', + prompt: + 'Build a scheduled workflow that polls a Trello inbox list, classifies each new card by topic, and moves it to the right list based on the classification.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'automation'], + }, + { + icon: TrelloIcon, + title: 'Trello + Linear bridge', + prompt: + 'Create a workflow that mirrors Trello cards in a chosen list into Linear issues, keeps status and comments in sync, and writes the link back to the Trello card.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['engineering', 'sync'], + alsoIntegrations: ['linear'], + }, + { + icon: TrelloIcon, + title: 'Trello SLA monitor', + prompt: + 'Build a workflow that watches Trello cards for due-date breaches, sends reminders, and escalates to managers via Slack when items slip more than 2 days.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TrelloIcon, + title: 'Trello content pipeline', + prompt: + 'Create a workflow that reads a Trello editorial board, publishes the cards in the "ready" list to WordPress on schedule, and moves the card to "live" with the URL attached.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['wordpress'], + }, + { + icon: TrelloIcon, + title: 'Trello weekly digest', + prompt: + 'Build a scheduled weekly workflow that summarizes Trello board movements — cards completed, blocked, in-progress — and emails the digest to the project owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: TrelloIcon, + title: 'Trello stale-card sweeper', + prompt: + 'Create a scheduled workflow that scans a Trello board for cards with no activity in 30 days, comments a nudge on each, and posts a stale-card list to Slack for the project owner.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['team', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: TrelloIcon, + title: 'Trello onboarding seeder', + prompt: + 'Build a workflow that creates the standard onboarding cards in a Trello list for each new hire, sets due dates by step, and tailors the card set to their role.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation'], + }, + ], + skills: [ + { + name: 'create-card', + description: 'Create a Trello card in a list with a description, due date, and labels.', + content: + '# Create a Trello Card\n\nAdd a new card to a list so work is captured on the right board.\n\n## Steps\n1. Use the Create Card operation and select your Trello account.\n2. Provide the List ID where the card should land and the Card Name.\n3. Add an optional Description, a Due Date (natural language like "next Friday" works), and Label IDs.\n4. Set Position to top or bottom to control where the card appears in the list.\n\n## Output\nReturn the created card including its id, url, and list, so it can be linked or updated later.', + }, + { + name: 'triage-and-move-cards', + description: + 'List cards on a board or list, classify them, and move each to the correct list.', + content: + '# Triage and Route Trello Cards\n\nRead incoming cards, decide where each belongs, and route them automatically.\n\n## Steps\n1. Use Get Lists with the Board ID to learn the available lists and their IDs.\n2. Use List Cards with the board or list ID to pull the cards needing triage.\n3. Classify each card by its name and description (topic, priority, owner).\n4. Use Update Card with the Move to List ID to route each card to its destination list.\n\n## Output\nReturn a summary of how many cards were moved and the destination list for each.', + }, + { + name: 'comment-on-card', + description: 'Add a comment to a Trello card to leave a note, nudge, or status update.', + content: + '# Comment on a Trello Card\n\nLeave a comment on a card to record context or nudge an owner.\n\n## Steps\n1. Use the Add Comment operation and select your Trello account.\n2. Provide the Card ID of the target card.\n3. Write the Comment text, including any links or mentions the team needs.\n\n## Output\nReturn the created comment action with its id and date so the note can be referenced.', + }, + { + name: 'review-card-activity', + description: 'Pull the recent action history for a Trello board or card and summarize it.', + content: + '# Review Trello Card Activity\n\nInspect what has happened recently on a board or card to build a digest or audit.\n\n## Steps\n1. Use the Get Actions operation with either a Board ID or a Card ID (one or the other, not both).\n2. Set an Action Filter such as commentCard,updateCard,createCard to focus on the events you care about.\n3. Use Board Action Limit and Action Page to page through longer histories.\n\n## Output\nReturn the actions with their type, date, author, and text, summarized into a short activity recap.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/trello.ts b/apps/sim/blocks/blocks/trello.ts index 317e2ca24ee..d1ebd59ec97 100644 --- a/apps/sim/blocks/blocks/trello.ts +++ b/apps/sim/blocks/blocks/trello.ts @@ -1,7 +1,6 @@ -import { TrelloIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { TrelloBlockDisplay } from '@/blocks/blocks/trello.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { parseOptionalBooleanInput, parseOptionalNumberInput } from '@/blocks/utils' import type { TrelloResponse } from '@/tools/trello' @@ -517,105 +516,3 @@ Return ONLY the date/timestamp string - no explanations, no extra text.`, }, }, } - -export const TrelloBlockMeta = { - tags: ['project-management', 'ticketing'], - url: 'https://trello.com', - templates: [ - { - icon: TrelloIcon, - title: 'Trello card auto-router', - prompt: - 'Build a scheduled workflow that polls a Trello inbox list, classifies each new card by topic, and moves it to the right list based on the classification.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'automation'], - }, - { - icon: TrelloIcon, - title: 'Trello + Linear bridge', - prompt: - 'Create a workflow that mirrors Trello cards in a chosen list into Linear issues, keeps status and comments in sync, and writes the link back to the Trello card.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['engineering', 'sync'], - alsoIntegrations: ['linear'], - }, - { - icon: TrelloIcon, - title: 'Trello SLA monitor', - prompt: - 'Build a workflow that watches Trello cards for due-date breaches, sends reminders, and escalates to managers via Slack when items slip more than 2 days.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TrelloIcon, - title: 'Trello content pipeline', - prompt: - 'Create a workflow that reads a Trello editorial board, publishes the cards in the "ready" list to WordPress on schedule, and moves the card to "live" with the URL attached.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['wordpress'], - }, - { - icon: TrelloIcon, - title: 'Trello weekly digest', - prompt: - 'Build a scheduled weekly workflow that summarizes Trello board movements — cards completed, blocked, in-progress — and emails the digest to the project owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: TrelloIcon, - title: 'Trello stale-card sweeper', - prompt: - 'Create a scheduled workflow that scans a Trello board for cards with no activity in 30 days, comments a nudge on each, and posts a stale-card list to Slack for the project owner.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['team', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: TrelloIcon, - title: 'Trello onboarding seeder', - prompt: - 'Build a workflow that creates the standard onboarding cards in a Trello list for each new hire, sets due dates by step, and tailors the card set to their role.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation'], - }, - ], - skills: [ - { - name: 'create-card', - description: 'Create a Trello card in a list with a description, due date, and labels.', - content: - '# Create a Trello Card\n\nAdd a new card to a list so work is captured on the right board.\n\n## Steps\n1. Use the Create Card operation and select your Trello account.\n2. Provide the List ID where the card should land and the Card Name.\n3. Add an optional Description, a Due Date (natural language like "next Friday" works), and Label IDs.\n4. Set Position to top or bottom to control where the card appears in the list.\n\n## Output\nReturn the created card including its id, url, and list, so it can be linked or updated later.', - }, - { - name: 'triage-and-move-cards', - description: - 'List cards on a board or list, classify them, and move each to the correct list.', - content: - '# Triage and Route Trello Cards\n\nRead incoming cards, decide where each belongs, and route them automatically.\n\n## Steps\n1. Use Get Lists with the Board ID to learn the available lists and their IDs.\n2. Use List Cards with the board or list ID to pull the cards needing triage.\n3. Classify each card by its name and description (topic, priority, owner).\n4. Use Update Card with the Move to List ID to route each card to its destination list.\n\n## Output\nReturn a summary of how many cards were moved and the destination list for each.', - }, - { - name: 'comment-on-card', - description: 'Add a comment to a Trello card to leave a note, nudge, or status update.', - content: - '# Comment on a Trello Card\n\nLeave a comment on a card to record context or nudge an owner.\n\n## Steps\n1. Use the Add Comment operation and select your Trello account.\n2. Provide the Card ID of the target card.\n3. Write the Comment text, including any links or mentions the team needs.\n\n## Output\nReturn the created comment action with its id and date so the note can be referenced.', - }, - { - name: 'review-card-activity', - description: 'Pull the recent action history for a Trello board or card and summarize it.', - content: - '# Review Trello Card Activity\n\nInspect what has happened recently on a board or card to build a digest or audit.\n\n## Steps\n1. Use the Get Actions operation with either a Board ID or a Card ID (one or the other, not both).\n2. Set an Action Filter such as commentCard,updateCard,createCard to focus on the events you care about.\n3. Use Board Action Limit and Action Page to page through longer histories.\n\n## Output\nReturn the actions with their type, date, author, and text, summarized into a short activity recap.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/trigger_dev.display.ts b/apps/sim/blocks/blocks/trigger_dev.display.ts index 59e2e505382..7eed2f6f44c 100644 --- a/apps/sim/blocks/blocks/trigger_dev.display.ts +++ b/apps/sim/blocks/blocks/trigger_dev.display.ts @@ -1,6 +1,6 @@ import { TriggerDevIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TriggerDevBlockDisplay = { type: 'trigger_dev', @@ -14,3 +14,133 @@ export const TriggerDevBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/trigger_dev', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const TriggerDevBlockMeta = { + tags: ['automation', 'ci-cd', 'monitoring'], + url: 'https://trigger.dev', + templates: [ + { + icon: TriggerDevIcon, + title: 'Trigger.dev job kickoff', + prompt: + 'Build a workflow that receives an event from another system, triggers the matching Trigger.dev background task with a JSON payload, and returns the run ID for tracking.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['automation'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev failed-run monitor', + prompt: + 'Build a scheduled workflow that lists Trigger.dev runs with status FAILED or CRASHED from the last hour, summarizes the failures per task, and posts a digest to the engineering Slack channel.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['monitoring', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev auto-retry agent', + prompt: + 'Create an agent that lists failed Trigger.dev runs, inspects each run error to decide whether the failure looks transient, and replays the runs that are safe to retry.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['automation', 'devops'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev run-output collector', + prompt: + 'Build a workflow that triggers a Trigger.dev task, polls Get Run until the run completes, and writes the run output and timing details into a results table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['automation', 'sync'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev schedule manager', + prompt: + 'Create an agent that manages Trigger.dev cron schedules per customer — creating a schedule with the customer ID as external ID on signup, and deactivating or deleting it on churn.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'scheduling'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev stuck-run janitor', + prompt: + 'Build a scheduled workflow that lists Trigger.dev runs still executing past their expected duration, cancels the stuck runs, and posts the canceled run IDs to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['monitoring', 'devops'], + alsoIntegrations: ['slack'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev compute cost reporter', + prompt: + 'Create a weekly scheduled workflow that uses Trigger.dev Execute Query to aggregate compute cost and duration per task for the past week, and emails a cost report to the team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['reporting', 'devops'], + alsoIntegrations: ['gmail'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev human approval gate', + prompt: + 'Build a workflow where a Trigger.dev task waits on a waitpoint token, an approver reviews the request in Slack, and the workflow completes the waitpoint token with the approval decision so the task resumes.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['automation', 'approvals'], + alsoIntegrations: ['slack'], + }, + { + icon: TriggerDevIcon, + title: 'Trigger.dev deploy watchdog', + prompt: + 'Create a workflow that checks the latest Trigger.dev deployment after each release, and if the deployment failed or new runs start crashing, promotes the previous deployment version and alerts the on-call channel.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'trigger-task-and-wait', + description: + 'Trigger a Trigger.dev background task with a payload and poll until the run completes, returning its output.', + content: + '# Trigger Task and Wait\n\nKick off a Trigger.dev background task and collect its result.\n\n## Steps\n1. Use the Trigger Task operation with the task identifier and a JSON payload. Set an idempotency key when the same event might arrive twice.\n2. Poll the Get Run operation with the returned run ID until the status is COMPLETED, FAILED, CANCELED, CRASHED, or another terminal state.\n3. On COMPLETED, read the run output. On failure states, read the attempts to surface the error message.\n\n## Output\nReturn the run ID, final status, duration, and the run output — or the error details if the run did not complete.', + }, + { + name: 'monitor-failed-runs', + description: + 'List recent failed Trigger.dev runs, group them by task, and produce a failure digest. Use for run health monitoring.', + content: + '# Monitor Failed Runs\n\nReview recent Trigger.dev failures and summarize what needs attention.\n\n## Steps\n1. Use the List Runs operation with a status filter of FAILED, CRASHED, SYSTEM_FAILURE and a created-within period (e.g., 1h or 1d).\n2. Group the runs by task identifier and count failures per task.\n3. For the most affected tasks, fetch a representative run with Get Run and pull the attempt error message.\n\n## Output\nReport failures per task with counts, representative error messages, and run IDs. If nothing failed, say so briefly.', + }, + { + name: 'replay-transient-failures', + description: + 'Inspect failed Trigger.dev runs and replay the ones whose errors look transient (timeouts, rate limits, network).', + content: + '# Replay Transient Failures\n\nRetry failed Trigger.dev runs that are safe to run again.\n\n## Steps\n1. List runs with status FAILED for the relevant period and task filter.\n2. For each run, use Get Run and inspect the attempt errors. Treat timeouts, rate limits, and network errors as transient; treat validation and logic errors as permanent.\n3. Use the Replay Run operation on transient failures only, and record the new run IDs.\n\n## Output\nList the replayed runs (old run ID to new run ID) and the runs skipped as permanent failures, with the reason for each decision.', + }, + { + name: 'human-approval-waitpoint', + description: + 'Create a Trigger.dev waitpoint token for a task to wait on, then complete it with approval data once a human decides.', + content: + '# Human Approval Waitpoint\n\nGate a Trigger.dev task on an external decision using waitpoint tokens.\n\n## Steps\n1. Use Create Waitpoint Token with a timeout (e.g., 1d) and an idempotency key tied to the request, and pass the token ID to the task that should wait.\n2. When the decision arrives, use Complete Waitpoint Token with the token ID and a JSON payload like {"status": "approved"} so the waiting run resumes with that data.\n3. Use Get Waitpoint Token or List Waitpoint Tokens to check for tokens that are still WAITING or have TIMED_OUT.\n\n## Output\nReport the token ID, its status, and the completion data passed to the run. Flag tokens that timed out without a decision.', + }, + { + name: 'manage-cron-schedules', + description: + 'Create, update, activate, deactivate, or delete Trigger.dev cron schedules for a task, scoped by external ID.', + content: + '# Manage Cron Schedules\n\nKeep Trigger.dev schedules in sync with the desired cadence.\n\n## Steps\n1. Use List Schedules to find existing schedules for the task, matching on external ID when schedules are per customer or per resource.\n2. Create a schedule with the task identifier, cron expression, timezone, and a deduplication key so reruns do not create duplicates.\n3. Update the cron or timezone on an existing schedule by ID, and use Activate or Deactivate to pause and resume without deleting.\n4. Delete schedules that are no longer needed.\n\n## Output\nReport the schedule ID, task, cron expression, timezone, active state, and next run time after the change.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/trigger_dev.ts b/apps/sim/blocks/blocks/trigger_dev.ts index d4c06ccd437..4cdfe3b2cea 100644 --- a/apps/sim/blocks/blocks/trigger_dev.ts +++ b/apps/sim/blocks/blocks/trigger_dev.ts @@ -1,6 +1,5 @@ -import { TriggerDevIcon } from '@/components/icons' import { TriggerDevBlockDisplay } from '@/blocks/blocks/trigger_dev.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { TriggerDevResponse } from '@/tools/trigger_dev/types' @@ -1120,133 +1119,3 @@ Return ONLY the valid JSON object - no explanations, no markdown.`, timezones: { type: 'json', description: 'Supported IANA timezones (List Timezones)' }, }, } - -export const TriggerDevBlockMeta = { - tags: ['automation', 'ci-cd', 'monitoring'], - url: 'https://trigger.dev', - templates: [ - { - icon: TriggerDevIcon, - title: 'Trigger.dev job kickoff', - prompt: - 'Build a workflow that receives an event from another system, triggers the matching Trigger.dev background task with a JSON payload, and returns the run ID for tracking.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['automation'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev failed-run monitor', - prompt: - 'Build a scheduled workflow that lists Trigger.dev runs with status FAILED or CRASHED from the last hour, summarizes the failures per task, and posts a digest to the engineering Slack channel.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['monitoring', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev auto-retry agent', - prompt: - 'Create an agent that lists failed Trigger.dev runs, inspects each run error to decide whether the failure looks transient, and replays the runs that are safe to retry.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['automation', 'devops'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev run-output collector', - prompt: - 'Build a workflow that triggers a Trigger.dev task, polls Get Run until the run completes, and writes the run output and timing details into a results table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['automation', 'sync'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev schedule manager', - prompt: - 'Create an agent that manages Trigger.dev cron schedules per customer — creating a schedule with the customer ID as external ID on signup, and deactivating or deleting it on churn.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'scheduling'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev stuck-run janitor', - prompt: - 'Build a scheduled workflow that lists Trigger.dev runs still executing past their expected duration, cancels the stuck runs, and posts the canceled run IDs to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['monitoring', 'devops'], - alsoIntegrations: ['slack'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev compute cost reporter', - prompt: - 'Create a weekly scheduled workflow that uses Trigger.dev Execute Query to aggregate compute cost and duration per task for the past week, and emails a cost report to the team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['reporting', 'devops'], - alsoIntegrations: ['gmail'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev human approval gate', - prompt: - 'Build a workflow where a Trigger.dev task waits on a waitpoint token, an approver reviews the request in Slack, and the workflow completes the waitpoint token with the approval decision so the task resumes.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['automation', 'approvals'], - alsoIntegrations: ['slack'], - }, - { - icon: TriggerDevIcon, - title: 'Trigger.dev deploy watchdog', - prompt: - 'Create a workflow that checks the latest Trigger.dev deployment after each release, and if the deployment failed or new runs start crashing, promotes the previous deployment version and alerts the on-call channel.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'trigger-task-and-wait', - description: - 'Trigger a Trigger.dev background task with a payload and poll until the run completes, returning its output.', - content: - '# Trigger Task and Wait\n\nKick off a Trigger.dev background task and collect its result.\n\n## Steps\n1. Use the Trigger Task operation with the task identifier and a JSON payload. Set an idempotency key when the same event might arrive twice.\n2. Poll the Get Run operation with the returned run ID until the status is COMPLETED, FAILED, CANCELED, CRASHED, or another terminal state.\n3. On COMPLETED, read the run output. On failure states, read the attempts to surface the error message.\n\n## Output\nReturn the run ID, final status, duration, and the run output — or the error details if the run did not complete.', - }, - { - name: 'monitor-failed-runs', - description: - 'List recent failed Trigger.dev runs, group them by task, and produce a failure digest. Use for run health monitoring.', - content: - '# Monitor Failed Runs\n\nReview recent Trigger.dev failures and summarize what needs attention.\n\n## Steps\n1. Use the List Runs operation with a status filter of FAILED, CRASHED, SYSTEM_FAILURE and a created-within period (e.g., 1h or 1d).\n2. Group the runs by task identifier and count failures per task.\n3. For the most affected tasks, fetch a representative run with Get Run and pull the attempt error message.\n\n## Output\nReport failures per task with counts, representative error messages, and run IDs. If nothing failed, say so briefly.', - }, - { - name: 'replay-transient-failures', - description: - 'Inspect failed Trigger.dev runs and replay the ones whose errors look transient (timeouts, rate limits, network).', - content: - '# Replay Transient Failures\n\nRetry failed Trigger.dev runs that are safe to run again.\n\n## Steps\n1. List runs with status FAILED for the relevant period and task filter.\n2. For each run, use Get Run and inspect the attempt errors. Treat timeouts, rate limits, and network errors as transient; treat validation and logic errors as permanent.\n3. Use the Replay Run operation on transient failures only, and record the new run IDs.\n\n## Output\nList the replayed runs (old run ID to new run ID) and the runs skipped as permanent failures, with the reason for each decision.', - }, - { - name: 'human-approval-waitpoint', - description: - 'Create a Trigger.dev waitpoint token for a task to wait on, then complete it with approval data once a human decides.', - content: - '# Human Approval Waitpoint\n\nGate a Trigger.dev task on an external decision using waitpoint tokens.\n\n## Steps\n1. Use Create Waitpoint Token with a timeout (e.g., 1d) and an idempotency key tied to the request, and pass the token ID to the task that should wait.\n2. When the decision arrives, use Complete Waitpoint Token with the token ID and a JSON payload like {"status": "approved"} so the waiting run resumes with that data.\n3. Use Get Waitpoint Token or List Waitpoint Tokens to check for tokens that are still WAITING or have TIMED_OUT.\n\n## Output\nReport the token ID, its status, and the completion data passed to the run. Flag tokens that timed out without a decision.', - }, - { - name: 'manage-cron-schedules', - description: - 'Create, update, activate, deactivate, or delete Trigger.dev cron schedules for a task, scoped by external ID.', - content: - '# Manage Cron Schedules\n\nKeep Trigger.dev schedules in sync with the desired cadence.\n\n## Steps\n1. Use List Schedules to find existing schedules for the task, matching on external ID when schedules are per customer or per resource.\n2. Create a schedule with the task identifier, cron expression, timezone, and a deduplication key so reruns do not create duplicates.\n3. Update the cron or timezone on an existing schedule by ID, and use Activate or Deactivate to pause and resume without deleting.\n4. Delete schedules that are no longer needed.\n\n## Output\nReport the schedule ID, task, cron expression, timezone, active state, and next run time after the change.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/twilio.display.ts b/apps/sim/blocks/blocks/twilio.display.ts index e992e5facc7..30f376543cb 100644 --- a/apps/sim/blocks/blocks/twilio.display.ts +++ b/apps/sim/blocks/blocks/twilio.display.ts @@ -1,6 +1,6 @@ import { TwilioIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TwilioSMSBlockDisplay = { type: 'twilio_sms', @@ -14,3 +14,98 @@ export const TwilioSMSBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/twilio_sms', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const TwilioSMSBlockMeta = { + tags: ['messaging', 'automation'], + url: 'https://www.twilio.com', + templates: [ + { + icon: TwilioIcon, + title: 'Twilio appointment reminders', + prompt: + 'Build a scheduled workflow that reads tomorrow’s appointments from a table and sends each customer a personalized Twilio SMS reminder with the time and a reschedule link.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation', 'support'], + }, + { + icon: TwilioIcon, + title: 'Twilio order-status notifier', + prompt: + 'Create a workflow triggered when an order ships that looks up the customer’s phone number and sends a Twilio SMS with the tracking number and estimated delivery date.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'automation'], + alsoIntegrations: ['shopify'], + }, + { + icon: TwilioIcon, + title: 'Twilio incident escalation alerts', + prompt: + 'Build a workflow triggered by a PagerDuty incident that sends a Twilio SMS to the on-call engineer with the service name and severity so critical alerts reach them even when they are away from Slack.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['messaging', 'incident-management', 'automation'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: TwilioIcon, + title: 'Twilio lead speed-to-text', + prompt: + 'Create a workflow that fires when a new lead submits a form, drafts a friendly intro message, and sends it via Twilio SMS within seconds so reps engage hot leads while they are still interested.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['messaging', 'sales', 'automation'], + alsoIntegrations: ['typeform'], + }, + { + icon: TwilioIcon, + title: 'Twilio two-factor code sender', + prompt: + 'Build a workflow that receives a verification request from an application, generates a one-time code, sends it to the user via Twilio SMS, and logs the send for audit.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['messaging', 'identity', 'automation'], + }, + { + icon: TwilioIcon, + title: 'Twilio payment-failure outreach', + prompt: + 'Create a workflow triggered by a Stripe failed-payment event that sends the customer a Twilio SMS with a secure update-payment link and logs the recovery attempt to a table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['messaging', 'finance', 'automation'], + alsoIntegrations: ['stripe'], + }, + { + icon: TwilioIcon, + title: 'Twilio daily standup nudge', + prompt: + 'Build a scheduled workflow that sends each team member a Twilio SMS prompting their async standup update every weekday morning, with a link to where to post it.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['messaging', 'automation', 'team'], + }, + ], + skills: [ + { + name: 'send-sms-notification', + description: 'Send an SMS notification to one or more phone numbers via Twilio.', + content: + '# Send an SMS Notification\n\nDeliver a text message to one or more recipients through your Twilio number.\n\n## Steps\n1. Enter the Recipient Phone Numbers in E.164 format with country code (for example +14155551234), one per line for multiple recipients.\n2. Write the Message text, keeping it concise since long messages split into multiple segments.\n3. Provide your Twilio Account SID, Auth Token, and the verified From Twilio Phone Number.\n\n## Output\nReturn the success status, the Twilio message SID, and the delivery status (queued, sent, delivered) so the send can be confirmed.', + }, + { + name: 'send-personalized-reminder', + description: + 'Send a personalized SMS reminder built from upstream data such as appointment or order details.', + content: + '# Send a Personalized SMS Reminder\n\nText each recipient a reminder tailored with their own details.\n\n## Steps\n1. Pull the recipient details from an upstream block (a table row, CRM record, or order event).\n2. Build the Message using those fields, for example the appointment time or tracking number, plus any link.\n3. Set the Recipient Phone Numbers to the customer number from the source record.\n4. Provide the Account SID, Auth Token, and From Twilio Phone Number.\n\n## Output\nReturn the message SID and status for each send so delivery can be logged back to the source record.', + }, + { + name: 'send-verification-code', + description: 'Send a one-time verification code over SMS for two-factor authentication.', + content: + '# Send a Verification Code over SMS\n\nDeliver a one-time code to a user for two-factor authentication or confirmation.\n\n## Steps\n1. Generate or receive the one-time code from an upstream step.\n2. Compose the Message with the code and a short note (for example "Your code is 482913. It expires in 10 minutes.").\n3. Set the Recipient Phone Numbers to the user number and provide the Account SID, Auth Token, and From number.\n4. Log the send outcome for audit.\n\n## Output\nReturn the message SID and delivery status so the verification send can be tracked and audited.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/twilio.ts b/apps/sim/blocks/blocks/twilio.ts index aa978c77f21..6cb450c6c74 100644 --- a/apps/sim/blocks/blocks/twilio.ts +++ b/apps/sim/blocks/blocks/twilio.ts @@ -1,6 +1,5 @@ -import { TwilioIcon } from '@/components/icons' import { TwilioSMSBlockDisplay } from '@/blocks/blocks/twilio.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { TwilioSMSBlockOutput } from '@/tools/twilio/types' @@ -65,98 +64,3 @@ export const TwilioSMSBlock: BlockConfig = { error: { type: 'string', description: 'Error information if sending fails' }, }, } - -export const TwilioSMSBlockMeta = { - tags: ['messaging', 'automation'], - url: 'https://www.twilio.com', - templates: [ - { - icon: TwilioIcon, - title: 'Twilio appointment reminders', - prompt: - 'Build a scheduled workflow that reads tomorrow’s appointments from a table and sends each customer a personalized Twilio SMS reminder with the time and a reschedule link.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation', 'support'], - }, - { - icon: TwilioIcon, - title: 'Twilio order-status notifier', - prompt: - 'Create a workflow triggered when an order ships that looks up the customer’s phone number and sends a Twilio SMS with the tracking number and estimated delivery date.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'automation'], - alsoIntegrations: ['shopify'], - }, - { - icon: TwilioIcon, - title: 'Twilio incident escalation alerts', - prompt: - 'Build a workflow triggered by a PagerDuty incident that sends a Twilio SMS to the on-call engineer with the service name and severity so critical alerts reach them even when they are away from Slack.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['messaging', 'incident-management', 'automation'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: TwilioIcon, - title: 'Twilio lead speed-to-text', - prompt: - 'Create a workflow that fires when a new lead submits a form, drafts a friendly intro message, and sends it via Twilio SMS within seconds so reps engage hot leads while they are still interested.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['messaging', 'sales', 'automation'], - alsoIntegrations: ['typeform'], - }, - { - icon: TwilioIcon, - title: 'Twilio two-factor code sender', - prompt: - 'Build a workflow that receives a verification request from an application, generates a one-time code, sends it to the user via Twilio SMS, and logs the send for audit.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['messaging', 'identity', 'automation'], - }, - { - icon: TwilioIcon, - title: 'Twilio payment-failure outreach', - prompt: - 'Create a workflow triggered by a Stripe failed-payment event that sends the customer a Twilio SMS with a secure update-payment link and logs the recovery attempt to a table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['messaging', 'finance', 'automation'], - alsoIntegrations: ['stripe'], - }, - { - icon: TwilioIcon, - title: 'Twilio daily standup nudge', - prompt: - 'Build a scheduled workflow that sends each team member a Twilio SMS prompting their async standup update every weekday morning, with a link to where to post it.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['messaging', 'automation', 'team'], - }, - ], - skills: [ - { - name: 'send-sms-notification', - description: 'Send an SMS notification to one or more phone numbers via Twilio.', - content: - '# Send an SMS Notification\n\nDeliver a text message to one or more recipients through your Twilio number.\n\n## Steps\n1. Enter the Recipient Phone Numbers in E.164 format with country code (for example +14155551234), one per line for multiple recipients.\n2. Write the Message text, keeping it concise since long messages split into multiple segments.\n3. Provide your Twilio Account SID, Auth Token, and the verified From Twilio Phone Number.\n\n## Output\nReturn the success status, the Twilio message SID, and the delivery status (queued, sent, delivered) so the send can be confirmed.', - }, - { - name: 'send-personalized-reminder', - description: - 'Send a personalized SMS reminder built from upstream data such as appointment or order details.', - content: - '# Send a Personalized SMS Reminder\n\nText each recipient a reminder tailored with their own details.\n\n## Steps\n1. Pull the recipient details from an upstream block (a table row, CRM record, or order event).\n2. Build the Message using those fields, for example the appointment time or tracking number, plus any link.\n3. Set the Recipient Phone Numbers to the customer number from the source record.\n4. Provide the Account SID, Auth Token, and From Twilio Phone Number.\n\n## Output\nReturn the message SID and status for each send so delivery can be logged back to the source record.', - }, - { - name: 'send-verification-code', - description: 'Send a one-time verification code over SMS for two-factor authentication.', - content: - '# Send a Verification Code over SMS\n\nDeliver a one-time code to a user for two-factor authentication or confirmation.\n\n## Steps\n1. Generate or receive the one-time code from an upstream step.\n2. Compose the Message with the code and a short note (for example "Your code is 482913. It expires in 10 minutes.").\n3. Set the Recipient Phone Numbers to the user number and provide the Account SID, Auth Token, and From number.\n4. Log the send outcome for audit.\n\n## Output\nReturn the message SID and delivery status so the verification send can be tracked and audited.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/twilio_voice.display.ts b/apps/sim/blocks/blocks/twilio_voice.display.ts index 4341e3625fc..60c356202eb 100644 --- a/apps/sim/blocks/blocks/twilio_voice.display.ts +++ b/apps/sim/blocks/blocks/twilio_voice.display.ts @@ -1,6 +1,6 @@ import { TwilioIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TwilioVoiceBlockDisplay = { type: 'twilio_voice', @@ -16,3 +16,104 @@ export const TwilioVoiceBlockDisplay = { integrationType: IntegrationType.Communication, triggerAllowed: true, } satisfies BlockDisplay + +export const TwilioVoiceBlockMeta = { + tags: ['messaging', 'text-to-speech'], + url: 'https://www.twilio.com', + templates: [ + { + icon: TwilioIcon, + title: 'Twilio Voice IVR router', + prompt: + 'Create a workflow that handles inbound Twilio Voice calls with an IVR menu, captures caller intent, routes to the right queue, and writes the call summary to a support table.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice outbound dialer', + prompt: + 'Build a workflow that reads a callbacks table, places Twilio Voice calls in batches, plays a recorded message or connects to an agent, and logs the call outcome back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice incident dialer', + prompt: + 'Create a workflow that on a PagerDuty severity-1 incident places a Twilio Voice call to the on-call engineer with an automated message, escalates to backup if no answer, and logs the cascade.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice transcript-to-CRM', + prompt: + 'Build a workflow that runs after a Twilio Voice call ends, transcribes the recording, summarizes the conversation, and writes the summary plus action items to the linked Salesforce account.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice survey collector', + prompt: + 'Create a workflow that places Twilio Voice survey calls to recent customers, captures their NPS rating via key press, and writes results to a feedback table for analysis.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice spam-call filter', + prompt: + 'Build a workflow that screens inbound Twilio Voice calls, classifies likely spam using number reputation plus a spoken challenge captured via Gather DTMF — press a digit to continue — and routes only verified callers to the support queue.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: TwilioIcon, + title: 'Twilio Voice call QA reviewer', + prompt: + "Create a scheduled workflow that lists yesterday's Twilio Voice calls, pulls each recording, transcribes and scores it for tone, compliance phrases, and resolution, and writes a QA scorecard to a table while flagging low-scoring calls to the team lead in Slack.", + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis', 'monitoring'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'place-outbound-call', + description: + 'Place an outbound Twilio Voice call that speaks a message or plays audio via TwiML.', + content: + '# Place an Outbound Voice Call\n\nDial a number and play a spoken message or audio using TwiML.\n\n## Steps\n1. Use the Make Call operation with your Account SID and Auth Token.\n2. Set the To Phone Number and the From Twilio Number, both in E.164 format.\n3. Provide TwiML Instructions describing what the call should say or do (use square brackets like [Say]Hello[/Say]), or point a TwiML URL at hosted instructions.\n4. Enable Record Call and set a Timeout if you need the recording or a ring limit, and add Machine Detection to handle voicemail.\n\n## Output\nReturn the call SID and status so the call can be tracked or its recording retrieved later.', + }, + { + name: 'collect-keypad-response', + description: + 'Place a call that asks a question and captures the caller keypad or speech response.', + content: + '# Collect a Keypad or Speech Response\n\nCall a recipient, ask a question, and capture their response for branching logic.\n\n## Steps\n1. Use the Make Call operation with the To and From numbers and your credentials.\n2. In the TwiML Instructions, use [Gather] to collect input, for example [Gather input="dtmf" numDigits="1"][Say]Press 1 to confirm, 2 to cancel[/Say][/Gather].\n3. For surveys, gather a rating digit; for confirmations, gather a single yes or no digit.\n4. Enable Record Call when you also want the audio.\n\n## Output\nReturn the captured digits or speech result from the webhook so a later step can branch on the caller response.', + }, + { + name: 'retrieve-call-recording', + description: 'Fetch a Twilio Voice call recording and its transcription by recording SID.', + content: + '# Retrieve a Call Recording\n\nPull the recording and transcript of a completed call for QA or CRM logging.\n\n## Steps\n1. Use the Get Recording operation with your Account SID and Auth Token.\n2. Provide the Recording SID (it begins with RE) from the call you want.\n3. If the original call TwiML used [Record transcribe="true"], the transcription text is returned alongside the audio.\n\n## Output\nReturn the media URL to download the recording, its duration, and the transcription text and status so the call can be summarized or archived.', + }, + { + name: 'review-recent-calls', + description: 'List recent Twilio Voice calls filtered by number, status, and date range.', + content: + '# Review Recent Voice Calls\n\nPull a filtered list of calls to build a report or feed a follow-up workflow.\n\n## Steps\n1. Use the List Calls operation with your Account SID and Auth Token.\n2. Filter by To Number, From Number, or Status (for example completed or no-answer).\n3. Narrow the window with After and Before dates (natural language like "last week" works), and set a Page Size.\n\n## Output\nReturn the array of matching calls with their SIDs, status, direction, and duration, plus the total count for reporting.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/twilio_voice.ts b/apps/sim/blocks/blocks/twilio_voice.ts index cf00963719c..93287e55b03 100644 --- a/apps/sim/blocks/blocks/twilio_voice.ts +++ b/apps/sim/blocks/blocks/twilio_voice.ts @@ -1,6 +1,5 @@ -import { TwilioIcon } from '@/components/icons' import { TwilioVoiceBlockDisplay } from '@/blocks/blocks/twilio_voice.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ToolResponse } from '@/tools/types' import { getTrigger } from '@/triggers' @@ -403,104 +402,3 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n available: ['twilio_voice_webhook'], }, } - -export const TwilioVoiceBlockMeta = { - tags: ['messaging', 'text-to-speech'], - url: 'https://www.twilio.com', - templates: [ - { - icon: TwilioIcon, - title: 'Twilio Voice IVR router', - prompt: - 'Create a workflow that handles inbound Twilio Voice calls with an IVR menu, captures caller intent, routes to the right queue, and writes the call summary to a support table.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice outbound dialer', - prompt: - 'Build a workflow that reads a callbacks table, places Twilio Voice calls in batches, plays a recorded message or connects to an agent, and logs the call outcome back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice incident dialer', - prompt: - 'Create a workflow that on a PagerDuty severity-1 incident places a Twilio Voice call to the on-call engineer with an automated message, escalates to backup if no answer, and logs the cascade.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice transcript-to-CRM', - prompt: - 'Build a workflow that runs after a Twilio Voice call ends, transcribes the recording, summarizes the conversation, and writes the summary plus action items to the linked Salesforce account.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice survey collector', - prompt: - 'Create a workflow that places Twilio Voice survey calls to recent customers, captures their NPS rating via key press, and writes results to a feedback table for analysis.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice spam-call filter', - prompt: - 'Build a workflow that screens inbound Twilio Voice calls, classifies likely spam using number reputation plus a spoken challenge captured via Gather DTMF — press a digit to continue — and routes only verified callers to the support queue.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: TwilioIcon, - title: 'Twilio Voice call QA reviewer', - prompt: - "Create a scheduled workflow that lists yesterday's Twilio Voice calls, pulls each recording, transcribes and scores it for tone, compliance phrases, and resolution, and writes a QA scorecard to a table while flagging low-scoring calls to the team lead in Slack.", - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis', 'monitoring'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'place-outbound-call', - description: - 'Place an outbound Twilio Voice call that speaks a message or plays audio via TwiML.', - content: - '# Place an Outbound Voice Call\n\nDial a number and play a spoken message or audio using TwiML.\n\n## Steps\n1. Use the Make Call operation with your Account SID and Auth Token.\n2. Set the To Phone Number and the From Twilio Number, both in E.164 format.\n3. Provide TwiML Instructions describing what the call should say or do (use square brackets like [Say]Hello[/Say]), or point a TwiML URL at hosted instructions.\n4. Enable Record Call and set a Timeout if you need the recording or a ring limit, and add Machine Detection to handle voicemail.\n\n## Output\nReturn the call SID and status so the call can be tracked or its recording retrieved later.', - }, - { - name: 'collect-keypad-response', - description: - 'Place a call that asks a question and captures the caller keypad or speech response.', - content: - '# Collect a Keypad or Speech Response\n\nCall a recipient, ask a question, and capture their response for branching logic.\n\n## Steps\n1. Use the Make Call operation with the To and From numbers and your credentials.\n2. In the TwiML Instructions, use [Gather] to collect input, for example [Gather input="dtmf" numDigits="1"][Say]Press 1 to confirm, 2 to cancel[/Say][/Gather].\n3. For surveys, gather a rating digit; for confirmations, gather a single yes or no digit.\n4. Enable Record Call when you also want the audio.\n\n## Output\nReturn the captured digits or speech result from the webhook so a later step can branch on the caller response.', - }, - { - name: 'retrieve-call-recording', - description: 'Fetch a Twilio Voice call recording and its transcription by recording SID.', - content: - '# Retrieve a Call Recording\n\nPull the recording and transcript of a completed call for QA or CRM logging.\n\n## Steps\n1. Use the Get Recording operation with your Account SID and Auth Token.\n2. Provide the Recording SID (it begins with RE) from the call you want.\n3. If the original call TwiML used [Record transcribe="true"], the transcription text is returned alongside the audio.\n\n## Output\nReturn the media URL to download the recording, its duration, and the transcription text and status so the call can be summarized or archived.', - }, - { - name: 'review-recent-calls', - description: 'List recent Twilio Voice calls filtered by number, status, and date range.', - content: - '# Review Recent Voice Calls\n\nPull a filtered list of calls to build a report or feed a follow-up workflow.\n\n## Steps\n1. Use the List Calls operation with your Account SID and Auth Token.\n2. Filter by To Number, From Number, or Status (for example completed or no-answer).\n3. Narrow the window with After and Before dates (natural language like "last week" works), and set a Page Size.\n\n## Output\nReturn the array of matching calls with their SIDs, status, direction, and duration, plus the total count for reporting.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/typeform.display.ts b/apps/sim/blocks/blocks/typeform.display.ts index c323fd18e4b..6299c561b53 100644 --- a/apps/sim/blocks/blocks/typeform.display.ts +++ b/apps/sim/blocks/blocks/typeform.display.ts @@ -1,6 +1,6 @@ import { TypeformIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const TypeformBlockDisplay = { type: 'typeform', @@ -14,3 +14,105 @@ export const TypeformBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/typeform', integrationType: IntegrationType.Documents, } satisfies BlockDisplay + +export const TypeformBlockMeta = { + tags: ['forms', 'data-analytics'], + url: 'https://www.typeform.com', + templates: [ + { + icon: TypeformIcon, + title: 'Survey response analyzer', + prompt: + 'Create a workflow that pulls new Typeform responses daily, categorizes feedback by theme and sentiment, logs structured results to a table, and sends a Slack digest when a new batch of responses comes in with the key takeaways.', + modules: ['tables', 'scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['product', 'analysis', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: TypeformIcon, + title: 'Typeform NPS pipeline', + prompt: + 'Build a workflow that collects Typeform NPS responses, classifies each as promoter/passive/detractor, writes the rolled-up score to a tracking table, and pings Slack on detractor spikes.', + modules: ['tables', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: TypeformIcon, + title: 'Typeform lead enricher', + prompt: + 'Create a workflow that watches Typeform lead-gen submissions, enriches each lead with company size and tech stack via Apollo, and pushes the enriched lead into Salesforce.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['apollo', 'salesforce'], + }, + { + icon: TypeformIcon, + title: 'Typeform candidate screener', + prompt: + 'Build a workflow that captures Typeform applicant responses, scores them against the role rubric with an agent, and creates a Greenhouse candidate with the score attached.', + modules: ['agent', 'workflows'], + category: 'operations', + tags: ['hr', 'analysis'], + alsoIntegrations: ['greenhouse'], + }, + { + icon: TypeformIcon, + title: 'Typeform event survey analyzer', + prompt: + 'Create a workflow that processes Typeform event survey responses, summarizes feedback themes, writes structured insights to a feedback table, and emails the organizer the digest.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'analysis'], + alsoIntegrations: ['gmail'], + }, + { + icon: TypeformIcon, + title: 'Typeform onboarding follow-up', + prompt: + 'Build a workflow that collects Typeform onboarding-flow responses, segments responders by job-to-be-done, and triggers tailored Loops email sequences for each segment.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['loops'], + }, + { + icon: TypeformIcon, + title: 'Typeform research analyzer', + prompt: + 'Create a workflow that pulls Typeform research responses, clusters answers by theme, and writes a tables-based research insight log for the product team.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['product', 'research'], + }, + ], + skills: [ + { + name: 'retrieve-form-responses', + description: 'Fetch Typeform responses for a form with date and completion filters.', + content: + '# Retrieve Typeform Responses\n\nPull submitted responses from a form so an agent can analyze or route them.\n\n## Steps\n1. Use the Retrieve Responses operation with the Form ID and your personal access token.\n2. Filter with Since and Until dates (natural language like "last week" works) to get only recent submissions.\n3. Set Completed to Only Completed to skip partial responses, and set Page Size for batch size.\n4. Use the Before and After cursor tokens to page through large result sets.\n\n## Output\nReturn the response items with their answers and metadata, plus the total count, ready for analysis or logging.', + }, + { + name: 'analyze-survey-responses', + description: 'Pull form responses and categorize them by theme and sentiment for a digest.', + content: + '# Analyze Survey Responses\n\nTurn raw form submissions into structured insights.\n\n## Steps\n1. Use Retrieve Responses with the Form ID, narrowing by Since to the new batch.\n2. For each response, classify the free-text answers by theme and sentiment with an agent.\n3. Aggregate counts per theme and capture notable quotes.\n4. Optionally use Form Insights to pull completion and drop-off metrics for context.\n\n## Output\nReturn a structured summary of themes, sentiment breakdown, and standout responses suitable for a table row or a Slack digest.', + }, + { + name: 'create-form', + description: 'Create a new Typeform form or quiz with fields and settings.', + content: + '# Create a Typeform Form\n\nSpin up a new form or quiz programmatically.\n\n## Steps\n1. Use the Create Form operation with your personal access token.\n2. Set the Form Title and choose the Form Type (form or quiz).\n3. Provide Fields as a JSON array of field objects (type, title, ref, validations) and optional Settings as JSON.\n4. Set a Workspace ID and Theme ID to place and style the form.\n\n## Output\nReturn the new form id and its links so you can share it or store the reference.', + }, + { + name: 'download-uploaded-file', + description: 'Download a file a respondent uploaded through a Typeform file-upload field.', + content: + '# Download an Uploaded Typeform File\n\nRetrieve a file that a respondent attached in their submission.\n\n## Steps\n1. Use the Download File operation with the Form ID and your personal access token.\n2. Provide the Response ID (the response token), the file-upload Field ID, and the exact Filename.\n3. Use these IDs from a Retrieve Responses result that contains file-upload answers.\n\n## Output\nReturn the downloaded file and its content type so it can be stored, forwarded, or processed by a later step.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/typeform.ts b/apps/sim/blocks/blocks/typeform.ts index 08ef0acaf44..c395d56cbac 100644 --- a/apps/sim/blocks/blocks/typeform.ts +++ b/apps/sim/blocks/blocks/typeform.ts @@ -1,6 +1,5 @@ -import { TypeformIcon } from '@/components/icons' import { TypeformBlockDisplay } from '@/blocks/blocks/typeform.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { TypeformResponse } from '@/tools/typeform/types' import { getTrigger } from '@/triggers' @@ -447,105 +446,3 @@ Do not include any explanations, markdown formatting, or other text outside the available: ['typeform_webhook'], }, } - -export const TypeformBlockMeta = { - tags: ['forms', 'data-analytics'], - url: 'https://www.typeform.com', - templates: [ - { - icon: TypeformIcon, - title: 'Survey response analyzer', - prompt: - 'Create a workflow that pulls new Typeform responses daily, categorizes feedback by theme and sentiment, logs structured results to a table, and sends a Slack digest when a new batch of responses comes in with the key takeaways.', - modules: ['tables', 'scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['product', 'analysis', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: TypeformIcon, - title: 'Typeform NPS pipeline', - prompt: - 'Build a workflow that collects Typeform NPS responses, classifies each as promoter/passive/detractor, writes the rolled-up score to a tracking table, and pings Slack on detractor spikes.', - modules: ['tables', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: TypeformIcon, - title: 'Typeform lead enricher', - prompt: - 'Create a workflow that watches Typeform lead-gen submissions, enriches each lead with company size and tech stack via Apollo, and pushes the enriched lead into Salesforce.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['apollo', 'salesforce'], - }, - { - icon: TypeformIcon, - title: 'Typeform candidate screener', - prompt: - 'Build a workflow that captures Typeform applicant responses, scores them against the role rubric with an agent, and creates a Greenhouse candidate with the score attached.', - modules: ['agent', 'workflows'], - category: 'operations', - tags: ['hr', 'analysis'], - alsoIntegrations: ['greenhouse'], - }, - { - icon: TypeformIcon, - title: 'Typeform event survey analyzer', - prompt: - 'Create a workflow that processes Typeform event survey responses, summarizes feedback themes, writes structured insights to a feedback table, and emails the organizer the digest.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'analysis'], - alsoIntegrations: ['gmail'], - }, - { - icon: TypeformIcon, - title: 'Typeform onboarding follow-up', - prompt: - 'Build a workflow that collects Typeform onboarding-flow responses, segments responders by job-to-be-done, and triggers tailored Loops email sequences for each segment.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['loops'], - }, - { - icon: TypeformIcon, - title: 'Typeform research analyzer', - prompt: - 'Create a workflow that pulls Typeform research responses, clusters answers by theme, and writes a tables-based research insight log for the product team.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['product', 'research'], - }, - ], - skills: [ - { - name: 'retrieve-form-responses', - description: 'Fetch Typeform responses for a form with date and completion filters.', - content: - '# Retrieve Typeform Responses\n\nPull submitted responses from a form so an agent can analyze or route them.\n\n## Steps\n1. Use the Retrieve Responses operation with the Form ID and your personal access token.\n2. Filter with Since and Until dates (natural language like "last week" works) to get only recent submissions.\n3. Set Completed to Only Completed to skip partial responses, and set Page Size for batch size.\n4. Use the Before and After cursor tokens to page through large result sets.\n\n## Output\nReturn the response items with their answers and metadata, plus the total count, ready for analysis or logging.', - }, - { - name: 'analyze-survey-responses', - description: 'Pull form responses and categorize them by theme and sentiment for a digest.', - content: - '# Analyze Survey Responses\n\nTurn raw form submissions into structured insights.\n\n## Steps\n1. Use Retrieve Responses with the Form ID, narrowing by Since to the new batch.\n2. For each response, classify the free-text answers by theme and sentiment with an agent.\n3. Aggregate counts per theme and capture notable quotes.\n4. Optionally use Form Insights to pull completion and drop-off metrics for context.\n\n## Output\nReturn a structured summary of themes, sentiment breakdown, and standout responses suitable for a table row or a Slack digest.', - }, - { - name: 'create-form', - description: 'Create a new Typeform form or quiz with fields and settings.', - content: - '# Create a Typeform Form\n\nSpin up a new form or quiz programmatically.\n\n## Steps\n1. Use the Create Form operation with your personal access token.\n2. Set the Form Title and choose the Form Type (form or quiz).\n3. Provide Fields as a JSON array of field objects (type, title, ref, validations) and optional Settings as JSON.\n4. Set a Workspace ID and Theme ID to place and style the form.\n\n## Output\nReturn the new form id and its links so you can share it or store the reference.', - }, - { - name: 'download-uploaded-file', - description: 'Download a file a respondent uploaded through a Typeform file-upload field.', - content: - '# Download an Uploaded Typeform File\n\nRetrieve a file that a respondent attached in their submission.\n\n## Steps\n1. Use the Download File operation with the Form ID and your personal access token.\n2. Provide the Response ID (the response token), the file-upload Field ID, and the exact Filename.\n3. Use these IDs from a Retrieve Responses result that contains file-upload answers.\n\n## Output\nReturn the downloaded file and its content type so it can be stored, forwarded, or processed by a later step.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/upstash.display.ts b/apps/sim/blocks/blocks/upstash.display.ts index 97a7dbe37c6..08732affd95 100644 --- a/apps/sim/blocks/blocks/upstash.display.ts +++ b/apps/sim/blocks/blocks/upstash.display.ts @@ -1,6 +1,6 @@ import { UpstashIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const UpstashBlockDisplay = { type: 'upstash', @@ -14,3 +14,106 @@ export const UpstashBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/upstash', integrationType: IntegrationType.Databases, } satisfies BlockDisplay + +export const UpstashBlockMeta = { + tags: ['cloud'], + url: 'https://upstash.com', + templates: [ + { + icon: UpstashIcon, + title: 'Upstash key TTL hygiene', + prompt: + 'Build a scheduled workflow that pulls Upstash Redis keys without TTLs, flags those that should expire, and either sets a TTL or routes to engineering for review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + }, + { + icon: UpstashIcon, + title: 'Upstash counter digest', + prompt: + 'Create a scheduled daily workflow that reads Upstash Redis counter keys for the day, summarizes the totals, and posts a usage digest to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: UpstashIcon, + title: 'Upstash queue drain', + prompt: + 'Build a scheduled workflow that pops queued jobs from an Upstash Redis list with LRANGE, transforms each into structured rows, and writes them into a downstream Sim table for further automation.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'sync'], + }, + { + icon: UpstashIcon, + title: 'Upstash + Vercel cache invalidator', + prompt: + 'Create a workflow triggered by a Vercel production deploy that flushes targeted Upstash cache keys for changed routes, so users never see stale responses post-deploy.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['vercel'], + }, + { + icon: UpstashIcon, + title: 'Upstash key integrity check', + prompt: + 'Build a scheduled workflow that reads a set of critical Upstash Redis keys, compares each value against the expected baseline in a table, and writes a mismatch report to an SRE audit table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise'], + }, + { + icon: UpstashIcon, + title: 'Upstash cache warmer', + prompt: + 'Create a scheduled workflow that precomputes expensive query results and writes them into Upstash Redis with a TTL using SET, so hot paths stay warm and pages PagerDuty if a warm-up run fails.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['pagerduty'], + }, + { + icon: UpstashIcon, + title: 'Upstash + DynamoDB hybrid store', + prompt: + 'Create a workflow that uses Upstash for hot keys and DynamoDB for cold storage, transparently promotes/demotes records based on access frequency.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'automation'], + alsoIntegrations: ['dynamodb'], + }, + ], + skills: [ + { + name: 'cache-value-with-ttl', + description: + 'Store a value in Upstash Redis under a key with an expiration so it auto-evicts.', + content: + '# Cache a Value with TTL\n\nWrite a computed or fetched value into Redis so hot paths read it fast and it expires automatically.\n\n## Steps\n1. Use the Set operation with your REST URL and REST Token.\n2. Provide the Key (for example user:123:profile) and the Value to store.\n3. Set the Expiration (seconds) so the entry self-evicts after the TTL.\n4. To avoid overwriting an existing entry, use SETNX instead, which only sets when the key is absent.\n\n## Output\nReturn the set result so the cache write can be confirmed before downstream reads.', + }, + { + name: 'read-cached-value', + description: 'Read a value from Upstash Redis by key, returning a cache hit or miss.', + content: + '# Read a Cached Value\n\nLook up a key in Redis and branch on whether it is present.\n\n## Steps\n1. Use the Get operation with the REST URL, REST Token, and the Key.\n2. To check presence first without fetching, use EXISTS, or use TTL to see how long the entry has left.\n3. On a cache miss (no value), fall through to recompute and write it back with Set.\n\n## Output\nReturn the retrieved value, or an empty result on a miss, so the workflow can serve cached data or recompute.', + }, + { + name: 'increment-counter', + description: + 'Atomically increment an Upstash Redis counter for rate limits or usage metering.', + content: + '# Increment a Redis Counter\n\nMaintain an atomic counter for usage tracking, rate limiting, or tallies.\n\n## Steps\n1. Use the INCR operation with the REST URL, REST Token, and the counter Key to add one.\n2. Use INCRBY with an Increment amount to add (or subtract with a negative value) a specific number.\n3. Pair with the EXPIRE operation on the key to create a time-windowed counter (for example per-minute rate limits).\n\n## Output\nReturn the new counter value after the increment so the workflow can check it against a threshold.', + }, + { + name: 'push-and-read-list', + description: + 'Push items onto an Upstash Redis list and read a range back for a simple queue.', + content: + '# Push and Read a Redis List\n\nUse a Redis list as a lightweight queue or activity log.\n\n## Steps\n1. Use the LPUSH operation with the REST URL, REST Token, Key, and Value to add an item to the list head.\n2. Use the LRANGE operation with a Start Index (0) and Stop Index (-1 for all) to read items back.\n3. For raw or unsupported operations, use the Command operation with a JSON array like ["RPOP", "myqueue"].\n\n## Output\nReturn the list length after a push and the list elements from a range read so the workflow can process queued items.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/upstash.ts b/apps/sim/blocks/blocks/upstash.ts index a9b3c58ad1d..a2cca123f58 100644 --- a/apps/sim/blocks/blocks/upstash.ts +++ b/apps/sim/blocks/blocks/upstash.ts @@ -1,6 +1,5 @@ -import { UpstashIcon } from '@/components/icons' import { UpstashBlockDisplay } from '@/blocks/blocks/upstash.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { UpstashRedisCommandResponse, @@ -339,106 +338,3 @@ export const UpstashBlock: BlockConfig = { }, }, } - -export const UpstashBlockMeta = { - tags: ['cloud'], - url: 'https://upstash.com', - templates: [ - { - icon: UpstashIcon, - title: 'Upstash key TTL hygiene', - prompt: - 'Build a scheduled workflow that pulls Upstash Redis keys without TTLs, flags those that should expire, and either sets a TTL or routes to engineering for review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - }, - { - icon: UpstashIcon, - title: 'Upstash counter digest', - prompt: - 'Create a scheduled daily workflow that reads Upstash Redis counter keys for the day, summarizes the totals, and posts a usage digest to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: UpstashIcon, - title: 'Upstash queue drain', - prompt: - 'Build a scheduled workflow that pops queued jobs from an Upstash Redis list with LRANGE, transforms each into structured rows, and writes them into a downstream Sim table for further automation.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'sync'], - }, - { - icon: UpstashIcon, - title: 'Upstash + Vercel cache invalidator', - prompt: - 'Create a workflow triggered by a Vercel production deploy that flushes targeted Upstash cache keys for changed routes, so users never see stale responses post-deploy.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['vercel'], - }, - { - icon: UpstashIcon, - title: 'Upstash key integrity check', - prompt: - 'Build a scheduled workflow that reads a set of critical Upstash Redis keys, compares each value against the expected baseline in a table, and writes a mismatch report to an SRE audit table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise'], - }, - { - icon: UpstashIcon, - title: 'Upstash cache warmer', - prompt: - 'Create a scheduled workflow that precomputes expensive query results and writes them into Upstash Redis with a TTL using SET, so hot paths stay warm and pages PagerDuty if a warm-up run fails.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['pagerduty'], - }, - { - icon: UpstashIcon, - title: 'Upstash + DynamoDB hybrid store', - prompt: - 'Create a workflow that uses Upstash for hot keys and DynamoDB for cold storage, transparently promotes/demotes records based on access frequency.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'automation'], - alsoIntegrations: ['dynamodb'], - }, - ], - skills: [ - { - name: 'cache-value-with-ttl', - description: - 'Store a value in Upstash Redis under a key with an expiration so it auto-evicts.', - content: - '# Cache a Value with TTL\n\nWrite a computed or fetched value into Redis so hot paths read it fast and it expires automatically.\n\n## Steps\n1. Use the Set operation with your REST URL and REST Token.\n2. Provide the Key (for example user:123:profile) and the Value to store.\n3. Set the Expiration (seconds) so the entry self-evicts after the TTL.\n4. To avoid overwriting an existing entry, use SETNX instead, which only sets when the key is absent.\n\n## Output\nReturn the set result so the cache write can be confirmed before downstream reads.', - }, - { - name: 'read-cached-value', - description: 'Read a value from Upstash Redis by key, returning a cache hit or miss.', - content: - '# Read a Cached Value\n\nLook up a key in Redis and branch on whether it is present.\n\n## Steps\n1. Use the Get operation with the REST URL, REST Token, and the Key.\n2. To check presence first without fetching, use EXISTS, or use TTL to see how long the entry has left.\n3. On a cache miss (no value), fall through to recompute and write it back with Set.\n\n## Output\nReturn the retrieved value, or an empty result on a miss, so the workflow can serve cached data or recompute.', - }, - { - name: 'increment-counter', - description: - 'Atomically increment an Upstash Redis counter for rate limits or usage metering.', - content: - '# Increment a Redis Counter\n\nMaintain an atomic counter for usage tracking, rate limiting, or tallies.\n\n## Steps\n1. Use the INCR operation with the REST URL, REST Token, and the counter Key to add one.\n2. Use INCRBY with an Increment amount to add (or subtract with a negative value) a specific number.\n3. Pair with the EXPIRE operation on the key to create a time-windowed counter (for example per-minute rate limits).\n\n## Output\nReturn the new counter value after the increment so the workflow can check it against a threshold.', - }, - { - name: 'push-and-read-list', - description: - 'Push items onto an Upstash Redis list and read a range back for a simple queue.', - content: - '# Push and Read a Redis List\n\nUse a Redis list as a lightweight queue or activity log.\n\n## Steps\n1. Use the LPUSH operation with the REST URL, REST Token, Key, and Value to add an item to the list head.\n2. Use the LRANGE operation with a Start Index (0) and Stop Index (-1 for all) to read items back.\n3. For raw or unsupported operations, use the Command operation with a JSON array like ["RPOP", "myqueue"].\n\n## Output\nReturn the list length after a push and the list elements from a range read so the workflow can process queued items.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/vanta.display.ts b/apps/sim/blocks/blocks/vanta.display.ts index 01bb8a45dbd..296ac4e2f79 100644 --- a/apps/sim/blocks/blocks/vanta.display.ts +++ b/apps/sim/blocks/blocks/vanta.display.ts @@ -1,6 +1,6 @@ import { VantaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const VantaBlockDisplay = { type: 'vanta', @@ -14,3 +14,112 @@ export const VantaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/vanta', integrationType: IntegrationType.Security, } satisfies BlockDisplay + +export const VantaBlockMeta = { + tags: ['monitoring', 'automation', 'document-processing'], + url: 'https://www.vanta.com', + templates: [ + { + icon: VantaIcon, + title: 'Vanta failing test alerts', + prompt: + 'Create a scheduled workflow that lists Vanta tests with status NEEDS_ATTENTION each morning, fetches the failing entities for each test, and posts a remediation digest to a Slack channel.', + modules: ['scheduled', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: VantaIcon, + title: 'Vanta evidence uploader', + prompt: + 'Build a workflow that takes a generated report file, uploads it as evidence to the matching Vanta document with a description and effective date, and then submits the document collection for review.', + modules: ['files', 'workflows'], + category: 'operations', + tags: ['automation', 'document-processing'], + }, + { + icon: VantaIcon, + title: 'Vanta vulnerability SLA watcher', + prompt: + 'Create a scheduled workflow that lists Vanta vulnerabilities with SLA deadlines in the next 7 days, groups them by severity and vulnerable asset, and emails the security team a prioritized remediation list.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: VantaIcon, + title: 'Vanta compliance status report', + prompt: + 'Build a scheduled workflow that lists Vanta frameworks with their control and test completion counts, has an agent summarize progress and gaps per framework, and writes a weekly compliance report to a table.', + modules: ['scheduled', 'agent', 'tables', 'workflows'], + category: 'operations', + tags: ['reporting', 'monitoring'], + }, + { + icon: VantaIcon, + title: 'Vanta onboarding task chaser', + prompt: + 'Create a scheduled workflow that lists current Vanta people with overdue security tasks, and sends each person a direct Slack message listing what they still need to complete.', + modules: ['scheduled', 'workflows'], + category: 'operations', + tags: ['automation', 'people'], + alsoIntegrations: ['slack'], + }, + { + icon: VantaIcon, + title: 'Vanta vendor review pipeline', + prompt: + 'Build a scheduled workflow that lists Vanta vendors whose next security review is due within 30 days, looks up each vendor’s risk levels and contract dates, and creates a review task in the team’s project tracker.', + modules: ['scheduled', 'workflows'], + category: 'operations', + tags: ['automation', 'vendor-management'], + alsoIntegrations: ['linear'], + }, + { + icon: VantaIcon, + title: 'Vanta compliance Q&A agent', + prompt: + 'Create an agent that answers compliance questions by querying Vanta: it can look up framework progress, control status, failing tests and their entities, policy approval status, and risk scenarios, and grounds every answer in the returned data.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['agentic', 'research'], + }, + ], + skills: [ + { + name: 'triage-failing-vanta-tests', + description: + 'Find failing Vanta tests, pull their failing entities, and produce a prioritized remediation list.', + content: + '# Triage Failing Vanta Tests\n\nTurn the current Vanta test status into an actionable remediation list.\n\n## Steps\n1. Use List Tests with Test Status set to Needs Attention to find failing tests. Narrow with Framework ID or Integration ID if asked.\n2. For each failing test, use List Test Entities with Entity Status set to Failing to get the exact resources that fail.\n3. Read each test’s failure description and remediation description from the output to explain what is wrong and how to fix it.\n4. Group results by test category and order by the number of failing entities.\n\n## Output\nReturn a prioritized list: test name, why it fails, the failing resources, and the documented remediation steps.', + }, + { + name: 'upload-vanta-evidence', + description: + 'Attach an evidence file to a Vanta document and submit the collection for review.', + content: + '# Upload Evidence to Vanta\n\nAttach a file to the right evidence document and make it visible to auditors.\n\n## Steps\n1. Use List Documents (filter by framework or status "Needs document" / "Needs update") to find the target document and note its ID.\n2. Use Upload Document File with the document ID, the file, a clear Description (e.g., "Q3 access review evidence"), and optionally an Effective Date.\n3. Use Submit Document with the same document ID so the evidence moves out of draft and becomes visible to auditors.\n4. Confirm with Get Document that the upload status is now OK.\n\n## Output\nReturn the uploaded file metadata and the document’s final status.', + }, + { + name: 'vanta-compliance-snapshot', + description: 'Summarize framework, control, and test completion across a Vanta account.', + content: + '# Vanta Compliance Snapshot\n\nProduce a concise status report across all frameworks.\n\n## Steps\n1. Use List Frameworks to get every framework with its control, document, and test completion counts.\n2. For frameworks that are behind, use List Framework Controls and Get Control to find controls with failing or missing evidence.\n3. Use List Tests with Test Status set to Needs Attention to count open issues per framework.\n4. Compute completion percentages from the numeric outputs (numControlsCompleted / numControlsTotal, etc.).\n\n## Output\nReturn a per-framework table: completion percentages, failing test count, and the controls that need attention.', + }, + { + name: 'vanta-vulnerability-sla-report', + description: + 'List Vanta vulnerabilities approaching their SLA deadlines with affected assets.', + content: + '# Vulnerabilities Approaching SLA\n\nFind what must be remediated soon and where.\n\n## Steps\n1. Use List Vulnerabilities with SLA Deadline Before set to the cutoff date (e.g., 7 days from now) and SLA Deadline After set to today.\n2. Narrow with Severity (CRITICAL or HIGH first) and Fix Available set to Yes for quick wins.\n3. For each vulnerability, use Get Vulnerable Asset with its asset ID to identify the affected server, repository, or workstation.\n4. Use List Vulnerability Remediations with Remediated On Time set to No to report recent SLA misses.\n\n## Output\nReturn vulnerabilities grouped by severity with remediate-by dates, fixed versions when available, and the affected assets.', + }, + { + name: 'vanta-people-task-audit', + description: 'Find people with overdue security tasks in Vanta and what each still owes.', + content: + '# Audit Outstanding Security Tasks\n\nIdentify who is blocking compliance and why.\n\n## Steps\n1. Use List People with Task Summary Statuses set to OVERDUE,DUE_SOON and Employment Status set to Current.\n2. Read each person’s tasksSummary output for the due date, and use Task Types to narrow to a specific obligation (e.g., COMPLETE_TRAININGS or ACCEPT_POLICIES) when asked.\n3. Use Get Person for any individual to confirm employment, group membership, and leave status before escalating.\n\n## Output\nReturn each person’s name, email, overdue items, and due dates, ordered by how overdue they are.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/vanta.ts b/apps/sim/blocks/blocks/vanta.ts index 65dd81fa53b..068677e8dd4 100644 --- a/apps/sim/blocks/blocks/vanta.ts +++ b/apps/sim/blocks/blocks/vanta.ts @@ -1,6 +1,5 @@ -import { VantaIcon } from '@/components/icons' import { VantaBlockDisplay } from '@/blocks/blocks/vanta.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { ToolResponse } from '@/tools/types' @@ -1120,112 +1119,3 @@ export const VantaBlock: BlockConfig = { }, }, } - -export const VantaBlockMeta = { - tags: ['monitoring', 'automation', 'document-processing'], - url: 'https://www.vanta.com', - templates: [ - { - icon: VantaIcon, - title: 'Vanta failing test alerts', - prompt: - 'Create a scheduled workflow that lists Vanta tests with status NEEDS_ATTENTION each morning, fetches the failing entities for each test, and posts a remediation digest to a Slack channel.', - modules: ['scheduled', 'workflows'], - category: 'operations', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: VantaIcon, - title: 'Vanta evidence uploader', - prompt: - 'Build a workflow that takes a generated report file, uploads it as evidence to the matching Vanta document with a description and effective date, and then submits the document collection for review.', - modules: ['files', 'workflows'], - category: 'operations', - tags: ['automation', 'document-processing'], - }, - { - icon: VantaIcon, - title: 'Vanta vulnerability SLA watcher', - prompt: - 'Create a scheduled workflow that lists Vanta vulnerabilities with SLA deadlines in the next 7 days, groups them by severity and vulnerable asset, and emails the security team a prioritized remediation list.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['monitoring', 'automation'], - alsoIntegrations: ['gmail'], - }, - { - icon: VantaIcon, - title: 'Vanta compliance status report', - prompt: - 'Build a scheduled workflow that lists Vanta frameworks with their control and test completion counts, has an agent summarize progress and gaps per framework, and writes a weekly compliance report to a table.', - modules: ['scheduled', 'agent', 'tables', 'workflows'], - category: 'operations', - tags: ['reporting', 'monitoring'], - }, - { - icon: VantaIcon, - title: 'Vanta onboarding task chaser', - prompt: - 'Create a scheduled workflow that lists current Vanta people with overdue security tasks, and sends each person a direct Slack message listing what they still need to complete.', - modules: ['scheduled', 'workflows'], - category: 'operations', - tags: ['automation', 'people'], - alsoIntegrations: ['slack'], - }, - { - icon: VantaIcon, - title: 'Vanta vendor review pipeline', - prompt: - 'Build a scheduled workflow that lists Vanta vendors whose next security review is due within 30 days, looks up each vendor’s risk levels and contract dates, and creates a review task in the team’s project tracker.', - modules: ['scheduled', 'workflows'], - category: 'operations', - tags: ['automation', 'vendor-management'], - alsoIntegrations: ['linear'], - }, - { - icon: VantaIcon, - title: 'Vanta compliance Q&A agent', - prompt: - 'Create an agent that answers compliance questions by querying Vanta: it can look up framework progress, control status, failing tests and their entities, policy approval status, and risk scenarios, and grounds every answer in the returned data.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['agentic', 'research'], - }, - ], - skills: [ - { - name: 'triage-failing-vanta-tests', - description: - 'Find failing Vanta tests, pull their failing entities, and produce a prioritized remediation list.', - content: - '# Triage Failing Vanta Tests\n\nTurn the current Vanta test status into an actionable remediation list.\n\n## Steps\n1. Use List Tests with Test Status set to Needs Attention to find failing tests. Narrow with Framework ID or Integration ID if asked.\n2. For each failing test, use List Test Entities with Entity Status set to Failing to get the exact resources that fail.\n3. Read each test’s failure description and remediation description from the output to explain what is wrong and how to fix it.\n4. Group results by test category and order by the number of failing entities.\n\n## Output\nReturn a prioritized list: test name, why it fails, the failing resources, and the documented remediation steps.', - }, - { - name: 'upload-vanta-evidence', - description: - 'Attach an evidence file to a Vanta document and submit the collection for review.', - content: - '# Upload Evidence to Vanta\n\nAttach a file to the right evidence document and make it visible to auditors.\n\n## Steps\n1. Use List Documents (filter by framework or status "Needs document" / "Needs update") to find the target document and note its ID.\n2. Use Upload Document File with the document ID, the file, a clear Description (e.g., "Q3 access review evidence"), and optionally an Effective Date.\n3. Use Submit Document with the same document ID so the evidence moves out of draft and becomes visible to auditors.\n4. Confirm with Get Document that the upload status is now OK.\n\n## Output\nReturn the uploaded file metadata and the document’s final status.', - }, - { - name: 'vanta-compliance-snapshot', - description: 'Summarize framework, control, and test completion across a Vanta account.', - content: - '# Vanta Compliance Snapshot\n\nProduce a concise status report across all frameworks.\n\n## Steps\n1. Use List Frameworks to get every framework with its control, document, and test completion counts.\n2. For frameworks that are behind, use List Framework Controls and Get Control to find controls with failing or missing evidence.\n3. Use List Tests with Test Status set to Needs Attention to count open issues per framework.\n4. Compute completion percentages from the numeric outputs (numControlsCompleted / numControlsTotal, etc.).\n\n## Output\nReturn a per-framework table: completion percentages, failing test count, and the controls that need attention.', - }, - { - name: 'vanta-vulnerability-sla-report', - description: - 'List Vanta vulnerabilities approaching their SLA deadlines with affected assets.', - content: - '# Vulnerabilities Approaching SLA\n\nFind what must be remediated soon and where.\n\n## Steps\n1. Use List Vulnerabilities with SLA Deadline Before set to the cutoff date (e.g., 7 days from now) and SLA Deadline After set to today.\n2. Narrow with Severity (CRITICAL or HIGH first) and Fix Available set to Yes for quick wins.\n3. For each vulnerability, use Get Vulnerable Asset with its asset ID to identify the affected server, repository, or workstation.\n4. Use List Vulnerability Remediations with Remediated On Time set to No to report recent SLA misses.\n\n## Output\nReturn vulnerabilities grouped by severity with remediate-by dates, fixed versions when available, and the affected assets.', - }, - { - name: 'vanta-people-task-audit', - description: 'Find people with overdue security tasks in Vanta and what each still owes.', - content: - '# Audit Outstanding Security Tasks\n\nIdentify who is blocking compliance and why.\n\n## Steps\n1. Use List People with Task Summary Statuses set to OVERDUE,DUE_SOON and Employment Status set to Current.\n2. Read each person’s tasksSummary output for the due date, and use Task Types to narrow to a specific obligation (e.g., COMPLETE_TRAININGS or ACCEPT_POLICIES) when asked.\n3. Use Get Person for any individual to confirm employment, group membership, and leave status before escalating.\n\n## Output\nReturn each person’s name, email, overdue items, and due dates, ordered by how overdue they are.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/vercel.display.ts b/apps/sim/blocks/blocks/vercel.display.ts index b90bfa81735..dc86ea8a75d 100644 --- a/apps/sim/blocks/blocks/vercel.display.ts +++ b/apps/sim/blocks/blocks/vercel.display.ts @@ -1,6 +1,6 @@ import { VercelIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const VercelBlockDisplay = { type: 'vercel', @@ -14,3 +14,106 @@ export const VercelBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/vercel', integrationType: IntegrationType.DevOps, } satisfies BlockDisplay + +export const VercelBlockMeta = { + tags: ['cloud', 'ci-cd'], + url: 'https://vercel.com', + templates: [ + { + icon: VercelIcon, + title: 'Vercel deployment monitor', + prompt: + 'Build a scheduled workflow that polls Vercel for the latest deployments across my projects every five minutes, detects failed or stuck builds, fetches the build logs, summarizes the failure cause, and posts an actionable alert to Slack with a deep link to the deployment.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['slack'], + }, + { + icon: VercelIcon, + title: 'Preview deployment reviewer', + prompt: + 'Build a workflow that watches GitHub pull requests, finds the matching Vercel preview deployment, captures the preview URL, runs a smoke check against critical pages, and posts a status comment on the pull request with the preview link and any issues found.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'engineering', 'automation'], + alsoIntegrations: ['github'], + }, + { + icon: VercelIcon, + title: 'Environment variable auditor', + prompt: + 'Create a scheduled weekly workflow that pulls environment variables from every Vercel project, compares them to a reference list in a table, flags drift, missing keys, and stale values, and emails a remediation report to the platform team.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'monitoring'], + }, + { + icon: VercelIcon, + title: 'Domain and DNS inventory', + prompt: + 'Build a scheduled workflow that lists every domain and DNS record across my Vercel account weekly, logs them into a tracking table, and sends a Slack diff of any added, removed, or modified records so DNS changes never go unnoticed.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'infrastructure'], + alsoIntegrations: ['slack'], + }, + { + icon: VercelIcon, + title: 'Project pause guard', + prompt: + 'Build a scheduled workflow that scans Vercel projects daily for low-traffic or stale candidates flagged in a table, pauses projects that meet the criteria, and Slacks a digest of paused and unpaused projects to the platform team for review.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: VercelIcon, + title: 'Deploy log triage', + prompt: + 'Create a workflow that fires after each Vercel deployment, fetches the build and runtime logs, classifies warnings and errors with an agent, groups recurring issues, and opens a Linear ticket per cluster so platform regressions get addressed early.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'engineering'], + alsoIntegrations: ['linear'], + }, + { + icon: VercelIcon, + title: 'Failed deployment recovery', + prompt: + 'Build a workflow that watches Vercel for failed production deployments, identifies the last known good production deployment, promotes it back to production for an instant rollback, and posts a Slack incident summary with the failure cause and rollback confirmation.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['devops', 'monitoring', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'monitor-deployments', + description: 'List recent Vercel deployments, surface failed builds, and pull their logs.', + content: + '# Monitor Vercel Deployments\n\nKeep an eye on builds so failures are caught fast.\n\n## Steps\n1. Use the List Deployments operation with your access token, optionally filtering by Project ID, Target (production), and State (ERROR).\n2. For any failed or stuck deployment, use Get Deployment Logs with the Deployment ID to pull the build events.\n3. Summarize the failure cause from the log events.\n4. Use Get Deployment for full detail including the deployment URL and state.\n\n## Output\nReturn the list of deployments with their state, plus a short summary of any failed build and a link to investigate.', + }, + { + name: 'rollback-deployment', + description: + 'Promote the last known good Vercel deployment to instantly roll back a bad release.', + content: + '# Roll Back a Vercel Deployment\n\nRecover production by instantly promoting a previous good deployment back to production.\n\n## Steps\n1. Use List Deployments filtered to the project, Target production, and State READY to find the last good deployment.\n2. Use the Promote Deployment operation with the Project ID and that good deployment ID to restore it to production instantly, with no rebuild.\n3. Optionally use Cancel Deployment on the broken build that is still running.\n\n## Output\nReturn the promoted deployment ID and confirmation so the rollback can be announced.', + }, + { + name: 'manage-env-vars', + description: 'Read, create, or update environment variables on a Vercel project.', + content: + '# Manage Vercel Environment Variables\n\nKeep a project configuration correct across environments.\n\n## Steps\n1. Use Get Environment Variables with the Project ID to read the current variables.\n2. To add one, use Create Environment Variable with the Key, Value, Target Environments (for example production,preview), and Variable Type.\n3. To change one, use Update Environment Variable with the Env Variable ID and the new value.\n4. Use Delete Environment Variable with the Env Variable ID to remove a stale key.\n\n## Output\nReturn the resulting variable list or confirmation of the create, update, or delete so configuration changes are auditable.', + }, + { + name: 'audit-domains-and-dns', + description: 'Inventory Vercel domains and DNS records and manage records for a domain.', + content: + '# Audit Vercel Domains and DNS\n\nTrack domains and DNS so changes never go unnoticed.\n\n## Steps\n1. Use List Domains for the account inventory, and List DNS Records with a Domain to see its records.\n2. To add a record, use Create DNS Record with the Domain, Record Name, Record Type (A, CNAME, TXT, etc.), and Value.\n3. To remove one, use Delete DNS Record with the Domain and Record ID.\n4. Use Get Domain Config to verify a domain is correctly configured.\n\n## Output\nReturn the domain and DNS record inventory, or confirmation of any record change, for the tracking log.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/vercel.ts b/apps/sim/blocks/blocks/vercel.ts index 0db5554132a..b06f0dd2f06 100644 --- a/apps/sim/blocks/blocks/vercel.ts +++ b/apps/sim/blocks/blocks/vercel.ts @@ -1,6 +1,5 @@ -import { VercelIcon } from '@/components/icons' import { VercelBlockDisplay } from '@/blocks/blocks/vercel.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' @@ -1183,106 +1182,3 @@ export const VercelBlock: BlockConfig = { }, }, } - -export const VercelBlockMeta = { - tags: ['cloud', 'ci-cd'], - url: 'https://vercel.com', - templates: [ - { - icon: VercelIcon, - title: 'Vercel deployment monitor', - prompt: - 'Build a scheduled workflow that polls Vercel for the latest deployments across my projects every five minutes, detects failed or stuck builds, fetches the build logs, summarizes the failure cause, and posts an actionable alert to Slack with a deep link to the deployment.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['slack'], - }, - { - icon: VercelIcon, - title: 'Preview deployment reviewer', - prompt: - 'Build a workflow that watches GitHub pull requests, finds the matching Vercel preview deployment, captures the preview URL, runs a smoke check against critical pages, and posts a status comment on the pull request with the preview link and any issues found.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'engineering', 'automation'], - alsoIntegrations: ['github'], - }, - { - icon: VercelIcon, - title: 'Environment variable auditor', - prompt: - 'Create a scheduled weekly workflow that pulls environment variables from every Vercel project, compares them to a reference list in a table, flags drift, missing keys, and stale values, and emails a remediation report to the platform team.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'monitoring'], - }, - { - icon: VercelIcon, - title: 'Domain and DNS inventory', - prompt: - 'Build a scheduled workflow that lists every domain and DNS record across my Vercel account weekly, logs them into a tracking table, and sends a Slack diff of any added, removed, or modified records so DNS changes never go unnoticed.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'infrastructure'], - alsoIntegrations: ['slack'], - }, - { - icon: VercelIcon, - title: 'Project pause guard', - prompt: - 'Build a scheduled workflow that scans Vercel projects daily for low-traffic or stale candidates flagged in a table, pauses projects that meet the criteria, and Slacks a digest of paused and unpaused projects to the platform team for review.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: VercelIcon, - title: 'Deploy log triage', - prompt: - 'Create a workflow that fires after each Vercel deployment, fetches the build and runtime logs, classifies warnings and errors with an agent, groups recurring issues, and opens a Linear ticket per cluster so platform regressions get addressed early.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'engineering'], - alsoIntegrations: ['linear'], - }, - { - icon: VercelIcon, - title: 'Failed deployment recovery', - prompt: - 'Build a workflow that watches Vercel for failed production deployments, identifies the last known good production deployment, promotes it back to production for an instant rollback, and posts a Slack incident summary with the failure cause and rollback confirmation.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['devops', 'monitoring', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'monitor-deployments', - description: 'List recent Vercel deployments, surface failed builds, and pull their logs.', - content: - '# Monitor Vercel Deployments\n\nKeep an eye on builds so failures are caught fast.\n\n## Steps\n1. Use the List Deployments operation with your access token, optionally filtering by Project ID, Target (production), and State (ERROR).\n2. For any failed or stuck deployment, use Get Deployment Logs with the Deployment ID to pull the build events.\n3. Summarize the failure cause from the log events.\n4. Use Get Deployment for full detail including the deployment URL and state.\n\n## Output\nReturn the list of deployments with their state, plus a short summary of any failed build and a link to investigate.', - }, - { - name: 'rollback-deployment', - description: - 'Promote the last known good Vercel deployment to instantly roll back a bad release.', - content: - '# Roll Back a Vercel Deployment\n\nRecover production by instantly promoting a previous good deployment back to production.\n\n## Steps\n1. Use List Deployments filtered to the project, Target production, and State READY to find the last good deployment.\n2. Use the Promote Deployment operation with the Project ID and that good deployment ID to restore it to production instantly, with no rebuild.\n3. Optionally use Cancel Deployment on the broken build that is still running.\n\n## Output\nReturn the promoted deployment ID and confirmation so the rollback can be announced.', - }, - { - name: 'manage-env-vars', - description: 'Read, create, or update environment variables on a Vercel project.', - content: - '# Manage Vercel Environment Variables\n\nKeep a project configuration correct across environments.\n\n## Steps\n1. Use Get Environment Variables with the Project ID to read the current variables.\n2. To add one, use Create Environment Variable with the Key, Value, Target Environments (for example production,preview), and Variable Type.\n3. To change one, use Update Environment Variable with the Env Variable ID and the new value.\n4. Use Delete Environment Variable with the Env Variable ID to remove a stale key.\n\n## Output\nReturn the resulting variable list or confirmation of the create, update, or delete so configuration changes are auditable.', - }, - { - name: 'audit-domains-and-dns', - description: 'Inventory Vercel domains and DNS records and manage records for a domain.', - content: - '# Audit Vercel Domains and DNS\n\nTrack domains and DNS so changes never go unnoticed.\n\n## Steps\n1. Use List Domains for the account inventory, and List DNS Records with a Domain to see its records.\n2. To add a record, use Create DNS Record with the Domain, Record Name, Record Type (A, CNAME, TXT, etc.), and Value.\n3. To remove one, use Delete DNS Record with the Domain and Record ID.\n4. Use Get Domain Config to verify a domain is correctly configured.\n\n## Output\nReturn the domain and DNS record inventory, or confirmation of any record change, for the tracking log.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wealthbox.display.ts b/apps/sim/blocks/blocks/wealthbox.display.ts index 89e7161c949..d516aff3aed 100644 --- a/apps/sim/blocks/blocks/wealthbox.display.ts +++ b/apps/sim/blocks/blocks/wealthbox.display.ts @@ -1,6 +1,6 @@ import { WealthboxIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WealthboxBlockDisplay = { type: 'wealthbox', @@ -14,3 +14,106 @@ export const WealthboxBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/wealthbox', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const WealthboxBlockMeta = { + tags: ['sales-engagement'], + url: 'https://www.wealthbox.com', + templates: [ + { + icon: WealthboxIcon, + title: 'Wealthbox CRM mirror', + prompt: + 'Build a scheduled workflow that reads the Wealthbox contacts and tasks listed by ID in a Sim table, refreshes each row with the latest details, and keeps the table in sync for unified reporting.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'sync'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox client review prep', + prompt: + 'Create a workflow that runs the morning of each Wealthbox client meeting, gathers recent emails, notes, and tasks for that client, and emails the advisor a prep brief.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + alsoIntegrations: ['gmail'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox task auto-creator', + prompt: + 'Build a workflow that listens for Gmail messages tagged "client action", classifies the action, and creates a matching task on the Wealthbox client record.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['gmail'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox compliance audit', + prompt: + 'Create a scheduled workflow that reads each Wealthbox contact listed in a tracking table monthly, checks for missing KYC fields or stale notes, and writes a compliance backlog to a table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'legal'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox birthday reminder', + prompt: + 'Build a scheduled workflow that runs daily, reads the Wealthbox contacts tracked in a table to find birthdays in the next 7 days, and emails advisors a reminder with a personalized message draft.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['gmail'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox book-of-business digest', + prompt: + 'Create a scheduled weekly workflow that reads the contacts and open tasks for each advisor from a tracking table, summarizes the book-of-business activity, and posts the digest to leadership in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: WealthboxIcon, + title: 'Wealthbox referral tracker', + prompt: + 'Build a scheduled workflow that polls Wealthbox notes for new referrals, captures the source and prospect, writes the referral chain into a CRM table, and pings the advisor in Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'log-client-note', + description: 'Write a note to a Wealthbox contact record to capture meeting or call details.', + content: + '# Log a Wealthbox Client Note\n\nRecord a note on a client record so the interaction history stays complete.\n\n## Steps\n1. Use the Write Note operation and select your Wealthbox account.\n2. Select the Contact the note belongs to (or enter the Contact ID in advanced mode).\n3. Write the note Content, summarizing the meeting, call, or decision.\n\n## Output\nReturn the created note with its ID and linked contact so the entry can be referenced later.', + }, + { + name: 'create-followup-task', + description: 'Create a follow-up task on a Wealthbox contact with a title and due date.', + content: + '# Create a Wealthbox Follow-up Task\n\nAdd a task to a client record so an advisor follow-up is not missed.\n\n## Steps\n1. Use the Write Task operation and select your Wealthbox account.\n2. Select the Contact the task is for.\n3. Set the Title, the Content describing the work, and a Due Date (natural language like "tomorrow at 2pm" works).\n\n## Output\nReturn the created task with its ID and due date so it can be tracked to completion.', + }, + { + name: 'upsert-contact', + description: + 'Create or read a Wealthbox contact with name, email, and background information.', + content: + '# Manage a Wealthbox Contact\n\nAdd a new client or pull an existing client record.\n\n## Steps\n1. To add a client, use the Write Contact operation with First Name, Last Name, and optionally Email Address and Background Information.\n2. To read a client, use the Read Contact operation and select the Contact or enter its Contact ID.\n3. Select your Wealthbox account for either operation.\n\n## Output\nReturn the contact record including name, email, and background info so downstream steps can use it.', + }, + { + name: 'prepare-client-brief', + description: + 'Read a Wealthbox contact plus their recent notes and tasks to build a meeting brief.', + content: + '# Prepare a Wealthbox Client Brief\n\nGather everything about a client ahead of a meeting.\n\n## Steps\n1. Use Read Contact with the Contact ID to pull the client profile and background.\n2. Use Read Note to retrieve recent notes for the contact.\n3. Use Read Task to pull open and recent tasks tied to the client.\n4. Have an agent synthesize the records into a concise prep brief.\n\n## Output\nReturn a brief covering the client profile, recent notes, and outstanding tasks, ready to email to the advisor.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wealthbox.ts b/apps/sim/blocks/blocks/wealthbox.ts index 6fb814e593c..67c06e60303 100644 --- a/apps/sim/blocks/blocks/wealthbox.ts +++ b/apps/sim/blocks/blocks/wealthbox.ts @@ -1,7 +1,6 @@ -import { WealthboxIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { WealthboxBlockDisplay } from '@/blocks/blocks/wealthbox.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { WealthboxResponse } from '@/tools/wealthbox/types' @@ -266,106 +265,3 @@ Return ONLY the date/time string - no explanations, no quotes, no extra text.`, }, }, } - -export const WealthboxBlockMeta = { - tags: ['sales-engagement'], - url: 'https://www.wealthbox.com', - templates: [ - { - icon: WealthboxIcon, - title: 'Wealthbox CRM mirror', - prompt: - 'Build a scheduled workflow that reads the Wealthbox contacts and tasks listed by ID in a Sim table, refreshes each row with the latest details, and keeps the table in sync for unified reporting.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'sync'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox client review prep', - prompt: - 'Create a workflow that runs the morning of each Wealthbox client meeting, gathers recent emails, notes, and tasks for that client, and emails the advisor a prep brief.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - alsoIntegrations: ['gmail'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox task auto-creator', - prompt: - 'Build a workflow that listens for Gmail messages tagged "client action", classifies the action, and creates a matching task on the Wealthbox client record.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['gmail'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox compliance audit', - prompt: - 'Create a scheduled workflow that reads each Wealthbox contact listed in a tracking table monthly, checks for missing KYC fields or stale notes, and writes a compliance backlog to a table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['finance', 'legal'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox birthday reminder', - prompt: - 'Build a scheduled workflow that runs daily, reads the Wealthbox contacts tracked in a table to find birthdays in the next 7 days, and emails advisors a reminder with a personalized message draft.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['gmail'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox book-of-business digest', - prompt: - 'Create a scheduled weekly workflow that reads the contacts and open tasks for each advisor from a tracking table, summarizes the book-of-business activity, and posts the digest to leadership in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: WealthboxIcon, - title: 'Wealthbox referral tracker', - prompt: - 'Build a scheduled workflow that polls Wealthbox notes for new referrals, captures the source and prospect, writes the referral chain into a CRM table, and pings the advisor in Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'log-client-note', - description: 'Write a note to a Wealthbox contact record to capture meeting or call details.', - content: - '# Log a Wealthbox Client Note\n\nRecord a note on a client record so the interaction history stays complete.\n\n## Steps\n1. Use the Write Note operation and select your Wealthbox account.\n2. Select the Contact the note belongs to (or enter the Contact ID in advanced mode).\n3. Write the note Content, summarizing the meeting, call, or decision.\n\n## Output\nReturn the created note with its ID and linked contact so the entry can be referenced later.', - }, - { - name: 'create-followup-task', - description: 'Create a follow-up task on a Wealthbox contact with a title and due date.', - content: - '# Create a Wealthbox Follow-up Task\n\nAdd a task to a client record so an advisor follow-up is not missed.\n\n## Steps\n1. Use the Write Task operation and select your Wealthbox account.\n2. Select the Contact the task is for.\n3. Set the Title, the Content describing the work, and a Due Date (natural language like "tomorrow at 2pm" works).\n\n## Output\nReturn the created task with its ID and due date so it can be tracked to completion.', - }, - { - name: 'upsert-contact', - description: - 'Create or read a Wealthbox contact with name, email, and background information.', - content: - '# Manage a Wealthbox Contact\n\nAdd a new client or pull an existing client record.\n\n## Steps\n1. To add a client, use the Write Contact operation with First Name, Last Name, and optionally Email Address and Background Information.\n2. To read a client, use the Read Contact operation and select the Contact or enter its Contact ID.\n3. Select your Wealthbox account for either operation.\n\n## Output\nReturn the contact record including name, email, and background info so downstream steps can use it.', - }, - { - name: 'prepare-client-brief', - description: - 'Read a Wealthbox contact plus their recent notes and tasks to build a meeting brief.', - content: - '# Prepare a Wealthbox Client Brief\n\nGather everything about a client ahead of a meeting.\n\n## Steps\n1. Use Read Contact with the Contact ID to pull the client profile and background.\n2. Use Read Note to retrieve recent notes for the contact.\n3. Use Read Task to pull open and recent tasks tied to the client.\n4. Have an agent synthesize the records into a concise prep brief.\n\n## Output\nReturn a brief covering the client profile, recent notes, and outstanding tasks, ready to email to the advisor.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/webflow.display.ts b/apps/sim/blocks/blocks/webflow.display.ts index 817cbd950b5..ef0891edbad 100644 --- a/apps/sim/blocks/blocks/webflow.display.ts +++ b/apps/sim/blocks/blocks/webflow.display.ts @@ -1,6 +1,6 @@ import { WebflowIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WebflowBlockDisplay = { type: 'webflow', @@ -15,3 +15,101 @@ export const WebflowBlockDisplay = { integrationType: IntegrationType.Marketing, triggerAllowed: true, } satisfies BlockDisplay + +export const WebflowBlockMeta = { + tags: ['content-management', 'seo'], + url: 'https://webflow.com', + templates: [ + { + icon: WebflowIcon, + title: 'Webflow lead capture pipeline', + prompt: + 'Create a workflow that monitors new Webflow form submissions, enriches each lead with company and contact data using Apollo and web search, adds them to a tracking table with a lead score, and sends a Slack notification to the sales team for high-potential leads.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'automation'], + alsoIntegrations: ['apollo', 'slack'], + }, + { + icon: WebflowIcon, + title: 'Webflow CMS publisher', + prompt: + 'Create a workflow that reads a draft articles table, generates an SEO-optimized post, publishes it as a Webflow CMS item, and writes the live URL back to the row.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: WebflowIcon, + title: 'Webflow form-to-CRM', + prompt: + 'Build a workflow that watches Webflow form submissions, enriches each with Apollo company data, and pushes qualifying leads into HubSpot with the right owner and source.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['apollo', 'hubspot'], + }, + { + icon: WebflowIcon, + title: 'Webflow content auditor', + prompt: + 'Create a scheduled monthly workflow that audits Webflow CMS items for missing meta descriptions, broken links, or stale dates, and writes a remediation backlog.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: WebflowIcon, + title: 'Webflow CMS backup', + prompt: + 'Build a scheduled workflow that exports every item from a Webflow CMS collection to S3 nightly with versioning, and writes the backup manifest to a tracking table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['devops', 'sync'], + alsoIntegrations: ['s3'], + }, + { + icon: WebflowIcon, + title: 'Webflow product catalog sync', + prompt: + 'Create a scheduled workflow that mirrors Shopify products and pricing into a Webflow CMS product collection, keeps both in sync, and posts conflict alerts to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'sync'], + alsoIntegrations: ['shopify', 'slack'], + }, + { + icon: WebflowIcon, + title: 'Webflow + Hubspot lead-magnet', + prompt: + 'Build a workflow that triggers on a Webflow form submission for a lead magnet, sends the asset via Loops, and writes the engagement to the matching HubSpot contact.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['loops', 'hubspot'], + }, + ], + skills: [ + { + name: 'publish-cms-item', + description: + 'Create a new item in a Webflow CMS collection from supplied or generated field data.', + content: + '# Publish a Webflow CMS Item\n\nTurn structured content into a live Webflow CMS collection item.\n\n## Steps\n1. Identify the target site and collection. If unknown, list collections to confirm the collection ID and its field schema.\n2. Map the incoming content to the collection fields, including required fields like name and slug. Generate a URL-safe slug if one is not provided.\n3. Call the create-item operation with the assembled fieldData JSON.\n4. Confirm the new item ID and slug returned by the API.\n\n## Output\nReport the created item ID, slug, and the live or staged URL. If a required field was missing, name it explicitly rather than guessing a value.', + }, + { + name: 'update-cms-item', + description: + 'Find a Webflow CMS item and update specific fields without disturbing the rest.', + content: + '# Update a Webflow CMS Item\n\nApply targeted edits to an existing collection item.\n\n## Steps\n1. Resolve the item by ID, or list items in the collection and match on slug or name.\n2. Get the current item so existing field values are known.\n3. Build fieldData containing only the fields that change, merged onto the current values so untouched fields are preserved.\n4. Call the update-item operation and confirm the change took effect.\n\n## Output\nList exactly which fields changed and their new values. Note the item ID and whether the change is live or staged.', + }, + { + name: 'audit-collection-content', + description: + 'List items in a Webflow collection and flag missing or stale fields for cleanup.', + content: + '# Audit a Webflow Collection\n\nReview a CMS collection for content-quality gaps.\n\n## Steps\n1. List all items in the target collection, paging through with offset and limit until complete.\n2. For each item, check for empty required fields such as meta description, image, or publish date.\n3. Flag items that are missing key SEO or display fields, or whose dates look stale.\n4. Summarize the findings as a remediation backlog.\n\n## Output\nReturn a table of flagged items with item ID, slug, and the specific gap found. End with a short prioritized list of what to fix first.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/webflow.ts b/apps/sim/blocks/blocks/webflow.ts index 872b5623ed1..270abaaf6a1 100644 --- a/apps/sim/blocks/blocks/webflow.ts +++ b/apps/sim/blocks/blocks/webflow.ts @@ -1,7 +1,6 @@ -import { WebflowIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { WebflowBlockDisplay } from '@/blocks/blocks/webflow.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { WebflowResponse } from '@/tools/webflow/types' import { getTrigger } from '@/triggers' @@ -247,101 +246,3 @@ export const WebflowBlock: BlockConfig = { ], }, } - -export const WebflowBlockMeta = { - tags: ['content-management', 'seo'], - url: 'https://webflow.com', - templates: [ - { - icon: WebflowIcon, - title: 'Webflow lead capture pipeline', - prompt: - 'Create a workflow that monitors new Webflow form submissions, enriches each lead with company and contact data using Apollo and web search, adds them to a tracking table with a lead score, and sends a Slack notification to the sales team for high-potential leads.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'automation'], - alsoIntegrations: ['apollo', 'slack'], - }, - { - icon: WebflowIcon, - title: 'Webflow CMS publisher', - prompt: - 'Create a workflow that reads a draft articles table, generates an SEO-optimized post, publishes it as a Webflow CMS item, and writes the live URL back to the row.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: WebflowIcon, - title: 'Webflow form-to-CRM', - prompt: - 'Build a workflow that watches Webflow form submissions, enriches each with Apollo company data, and pushes qualifying leads into HubSpot with the right owner and source.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['apollo', 'hubspot'], - }, - { - icon: WebflowIcon, - title: 'Webflow content auditor', - prompt: - 'Create a scheduled monthly workflow that audits Webflow CMS items for missing meta descriptions, broken links, or stale dates, and writes a remediation backlog.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: WebflowIcon, - title: 'Webflow CMS backup', - prompt: - 'Build a scheduled workflow that exports every item from a Webflow CMS collection to S3 nightly with versioning, and writes the backup manifest to a tracking table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['devops', 'sync'], - alsoIntegrations: ['s3'], - }, - { - icon: WebflowIcon, - title: 'Webflow product catalog sync', - prompt: - 'Create a scheduled workflow that mirrors Shopify products and pricing into a Webflow CMS product collection, keeps both in sync, and posts conflict alerts to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['ecommerce', 'sync'], - alsoIntegrations: ['shopify', 'slack'], - }, - { - icon: WebflowIcon, - title: 'Webflow + Hubspot lead-magnet', - prompt: - 'Build a workflow that triggers on a Webflow form submission for a lead magnet, sends the asset via Loops, and writes the engagement to the matching HubSpot contact.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['loops', 'hubspot'], - }, - ], - skills: [ - { - name: 'publish-cms-item', - description: - 'Create a new item in a Webflow CMS collection from supplied or generated field data.', - content: - '# Publish a Webflow CMS Item\n\nTurn structured content into a live Webflow CMS collection item.\n\n## Steps\n1. Identify the target site and collection. If unknown, list collections to confirm the collection ID and its field schema.\n2. Map the incoming content to the collection fields, including required fields like name and slug. Generate a URL-safe slug if one is not provided.\n3. Call the create-item operation with the assembled fieldData JSON.\n4. Confirm the new item ID and slug returned by the API.\n\n## Output\nReport the created item ID, slug, and the live or staged URL. If a required field was missing, name it explicitly rather than guessing a value.', - }, - { - name: 'update-cms-item', - description: - 'Find a Webflow CMS item and update specific fields without disturbing the rest.', - content: - '# Update a Webflow CMS Item\n\nApply targeted edits to an existing collection item.\n\n## Steps\n1. Resolve the item by ID, or list items in the collection and match on slug or name.\n2. Get the current item so existing field values are known.\n3. Build fieldData containing only the fields that change, merged onto the current values so untouched fields are preserved.\n4. Call the update-item operation and confirm the change took effect.\n\n## Output\nList exactly which fields changed and their new values. Note the item ID and whether the change is live or staged.', - }, - { - name: 'audit-collection-content', - description: - 'List items in a Webflow collection and flag missing or stale fields for cleanup.', - content: - '# Audit a Webflow Collection\n\nReview a CMS collection for content-quality gaps.\n\n## Steps\n1. List all items in the target collection, paging through with offset and limit until complete.\n2. For each item, check for empty required fields such as meta description, image, or publish date.\n3. Flag items that are missing key SEO or display fields, or whose dates look stale.\n4. Summarize the findings as a remediation backlog.\n\n## Output\nReturn a table of flagged items with item ID, slug, and the specific gap found. End with a short prioritized list of what to fix first.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/whatsapp.display.ts b/apps/sim/blocks/blocks/whatsapp.display.ts index 3697e69cff9..10832be16c8 100644 --- a/apps/sim/blocks/blocks/whatsapp.display.ts +++ b/apps/sim/blocks/blocks/whatsapp.display.ts @@ -1,6 +1,6 @@ import { WhatsAppIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WhatsAppBlockDisplay = { type: 'whatsapp', @@ -15,3 +15,101 @@ export const WhatsAppBlockDisplay = { integrationType: IntegrationType.Communication, triggerAllowed: true, } satisfies BlockDisplay + +export const WhatsAppBlockMeta = { + tags: ['messaging', 'automation'], + url: 'https://www.whatsapp.com', + templates: [ + { + icon: WhatsAppIcon, + title: 'WhatsApp appointment confirmations', + prompt: + 'Build a workflow that reads upcoming Google Calendar appointments each morning and sends a WhatsApp confirmation with date, time, and a one-tap reschedule link.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['communication', 'automation'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp order tracking', + prompt: + 'Create a workflow that watches Shopify shipment events and sends customers a WhatsApp message with the tracking number, ETA, and a follow-up review request after delivery.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['ecommerce', 'communication'], + alsoIntegrations: ['shopify'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp customer support agent', + prompt: + 'Build a WhatsApp business agent that answers customer questions using a knowledge base, hands off to a human in Zendesk on complex tickets, and writes the conversation back to the contact record.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['zendesk'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp lead qualifier', + prompt: + 'Create a workflow that engages new leads via WhatsApp with a guided qualification script, scores them based on responses, and pushes qualified leads into Salesforce with the conversation log attached.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['salesforce'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp campaign sender', + prompt: + 'Build a workflow that reads a segmented audience from a table and sends a personalized WhatsApp template message to each, throttling to stay under provider limits.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp event RSVP collector', + prompt: + 'Create a workflow that messages contacts about an upcoming event on WhatsApp, parses yes/no/maybe replies, and updates the RSVP table with the attendee count and dietary notes.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + }, + { + icon: WhatsAppIcon, + title: 'WhatsApp + Zoom meeting confirmer', + prompt: + 'Build a workflow that sends a WhatsApp confirmation when a Zoom meeting is booked, with the join link and a one-tap reschedule option for the attendee.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['communication', 'automation'], + alsoIntegrations: ['zoom'], + }, + ], + skills: [ + { + name: 'send-appointment-reminder', + description: + 'Send a WhatsApp message reminding a contact of an upcoming appointment or booking.', + content: + '# Send a WhatsApp Appointment Reminder\n\nNotify a contact about an upcoming appointment over WhatsApp.\n\n## Steps\n1. Gather the recipient phone number in full international format (country code, no plus sign or spaces as the API expects).\n2. Compose a short, clear message with the date, time, location or link, and any action the contact should take.\n3. Send the message with the WhatsApp send operation.\n4. Capture the returned message ID and delivery state.\n\n## Output\nConfirm the recipient, the message sent, and the message ID. If the send was rejected, report the reason rather than retrying blindly.', + }, + { + name: 'send-order-update', + description: + 'Notify a customer over WhatsApp about an order status change such as shipment or delivery.', + content: + '# Send a WhatsApp Order Update\n\nKeep a customer informed about their order via WhatsApp.\n\n## Steps\n1. Collect the customer phone number in full international format and the order details (number, status, tracking, ETA).\n2. Write a concise update that states what changed and includes the tracking link if available.\n3. Send the message and record the message ID and delivery state.\n\n## Output\nReport which customer was notified, the order referenced, and the message ID. Flag any number that could not be reached.', + }, + { + name: 'broadcast-to-segment', + description: + 'Send a personalized WhatsApp message to each contact in an audience list, one at a time.', + content: + '# Broadcast a WhatsApp Message to a Segment\n\nDeliver a personalized message to every contact in a list.\n\n## Steps\n1. Read the audience list, each row holding a phone number and any personalization fields.\n2. For each contact, build the message by filling in their name and relevant details.\n3. Send messages one per contact, pacing them to stay within WhatsApp rate and template limits.\n4. Track which sends succeeded and which failed.\n\n## Output\nReturn counts of messages sent and failed, plus a short list of failed recipients with the failure reason.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/whatsapp.ts b/apps/sim/blocks/blocks/whatsapp.ts index dbbece26f50..4e5f3ecd6d6 100644 --- a/apps/sim/blocks/blocks/whatsapp.ts +++ b/apps/sim/blocks/blocks/whatsapp.ts @@ -1,6 +1,5 @@ -import { WhatsAppIcon } from '@/components/icons' import { WhatsAppBlockDisplay } from '@/blocks/blocks/whatsapp.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { WhatsAppResponse } from '@/tools/whatsapp/types' import { getTrigger } from '@/triggers' @@ -167,101 +166,3 @@ export const WhatsAppBlock: BlockConfig = { available: ['whatsapp_webhook'], }, } - -export const WhatsAppBlockMeta = { - tags: ['messaging', 'automation'], - url: 'https://www.whatsapp.com', - templates: [ - { - icon: WhatsAppIcon, - title: 'WhatsApp appointment confirmations', - prompt: - 'Build a workflow that reads upcoming Google Calendar appointments each morning and sends a WhatsApp confirmation with date, time, and a one-tap reschedule link.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['communication', 'automation'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp order tracking', - prompt: - 'Create a workflow that watches Shopify shipment events and sends customers a WhatsApp message with the tracking number, ETA, and a follow-up review request after delivery.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['ecommerce', 'communication'], - alsoIntegrations: ['shopify'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp customer support agent', - prompt: - 'Build a WhatsApp business agent that answers customer questions using a knowledge base, hands off to a human in Zendesk on complex tickets, and writes the conversation back to the contact record.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['zendesk'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp lead qualifier', - prompt: - 'Create a workflow that engages new leads via WhatsApp with a guided qualification script, scores them based on responses, and pushes qualified leads into Salesforce with the conversation log attached.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['salesforce'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp campaign sender', - prompt: - 'Build a workflow that reads a segmented audience from a table and sends a personalized WhatsApp template message to each, throttling to stay under provider limits.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp event RSVP collector', - prompt: - 'Create a workflow that messages contacts about an upcoming event on WhatsApp, parses yes/no/maybe replies, and updates the RSVP table with the attendee count and dietary notes.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - }, - { - icon: WhatsAppIcon, - title: 'WhatsApp + Zoom meeting confirmer', - prompt: - 'Build a workflow that sends a WhatsApp confirmation when a Zoom meeting is booked, with the join link and a one-tap reschedule option for the attendee.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['communication', 'automation'], - alsoIntegrations: ['zoom'], - }, - ], - skills: [ - { - name: 'send-appointment-reminder', - description: - 'Send a WhatsApp message reminding a contact of an upcoming appointment or booking.', - content: - '# Send a WhatsApp Appointment Reminder\n\nNotify a contact about an upcoming appointment over WhatsApp.\n\n## Steps\n1. Gather the recipient phone number in full international format (country code, no plus sign or spaces as the API expects).\n2. Compose a short, clear message with the date, time, location or link, and any action the contact should take.\n3. Send the message with the WhatsApp send operation.\n4. Capture the returned message ID and delivery state.\n\n## Output\nConfirm the recipient, the message sent, and the message ID. If the send was rejected, report the reason rather than retrying blindly.', - }, - { - name: 'send-order-update', - description: - 'Notify a customer over WhatsApp about an order status change such as shipment or delivery.', - content: - '# Send a WhatsApp Order Update\n\nKeep a customer informed about their order via WhatsApp.\n\n## Steps\n1. Collect the customer phone number in full international format and the order details (number, status, tracking, ETA).\n2. Write a concise update that states what changed and includes the tracking link if available.\n3. Send the message and record the message ID and delivery state.\n\n## Output\nReport which customer was notified, the order referenced, and the message ID. Flag any number that could not be reached.', - }, - { - name: 'broadcast-to-segment', - description: - 'Send a personalized WhatsApp message to each contact in an audience list, one at a time.', - content: - '# Broadcast a WhatsApp Message to a Segment\n\nDeliver a personalized message to every contact in a list.\n\n## Steps\n1. Read the audience list, each row holding a phone number and any personalization fields.\n2. For each contact, build the message by filling in their name and relevant details.\n3. Send messages one per contact, pacing them to stay within WhatsApp rate and template limits.\n4. Track which sends succeeded and which failed.\n\n## Output\nReturn counts of messages sent and failed, plus a short list of failed recipients with the failure reason.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wikipedia.display.ts b/apps/sim/blocks/blocks/wikipedia.display.ts index 6e1c2e49083..d27e7ad2fa2 100644 --- a/apps/sim/blocks/blocks/wikipedia.display.ts +++ b/apps/sim/blocks/blocks/wikipedia.display.ts @@ -1,6 +1,6 @@ import { WikipediaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WikipediaBlockDisplay = { type: 'wikipedia', @@ -14,3 +14,97 @@ export const WikipediaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/wikipedia', integrationType: IntegrationType.Search, } satisfies BlockDisplay + +export const WikipediaBlockMeta = { + tags: ['knowledge-base'], + url: 'https://www.wikipedia.org', + templates: [ + { + icon: WikipediaIcon, + title: 'Wikipedia background-research helper', + prompt: + 'Build a workflow that for a chosen topic queries Wikipedia, extracts the lead and infobox, and writes a structured background brief file for the user.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia entity disambiguator', + prompt: + 'Create a workflow that for an ambiguous person or company name queries Wikipedia, identifies the most likely entity given context, and writes the canonical reference back.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'analysis'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia knowledge-base seeder', + prompt: + 'Build a workflow that for tracked topics fetches Wikipedia articles, chunks and embeds them, and seeds a knowledge base with canonical context.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia citation validator', + prompt: + 'Create a workflow that checks if claims drafted by an agent are supported by Wikipedia content, flags claims without strong sources, and writes a quality score.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'analysis'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia infobox extractor', + prompt: + 'Build a workflow that takes a list of entity names, extracts the Wikipedia infobox fields for each, and writes structured rows for downstream analytics.', + modules: ['tables', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sync'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia related-topic graph', + prompt: + 'Create a workflow that for a topic explores related Wikipedia pages, builds a topic graph in Neo4j, and surfaces adjacent themes.', + modules: ['agent', 'workflows'], + category: 'engineering', + tags: ['research', 'analysis'], + alsoIntegrations: ['neo4j'], + }, + { + icon: WikipediaIcon, + title: 'Wikipedia summary alerter', + prompt: + 'Build a scheduled workflow that monitors Wikipedia pages for tracked entities, detects significant edits, and posts a summary diff to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'research'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'research-topic-brief', + description: 'Search Wikipedia for a topic and assemble a concise, sourced background brief.', + content: + '# Build a Wikipedia Topic Brief\n\nProduce a quick, reliable background brief on a subject.\n\n## Steps\n1. Search pages for the topic to find the best-matching article title.\n2. Get the page summary for a fast overview, then get full page content if more depth is needed.\n3. Extract the key facts, dates, and definitions, ignoring tangential detail.\n4. Assemble a short brief in your own words.\n\n## Output\nReturn a brief with a one-line definition, three to five key points, and the Wikipedia page title used as the source.', + }, + { + name: 'disambiguate-entity', + description: + 'Resolve an ambiguous name to the correct Wikipedia entity using surrounding context.', + content: + '# Disambiguate an Entity via Wikipedia\n\nPick the right Wikipedia entity for an ambiguous name.\n\n## Steps\n1. Search pages for the name to retrieve candidate matches.\n2. For the top candidates, get the page summary.\n3. Compare each summary against the context provided (industry, location, role) and choose the best fit.\n4. If nothing matches confidently, say so rather than forcing a choice.\n\n## Output\nReturn the chosen canonical page title with a one-line justification, plus a confidence note and any close alternatives.', + }, + { + name: 'verify-claim', + description: + 'Check whether a stated claim is supported by Wikipedia content and flag unsupported claims.', + content: + '# Verify a Claim Against Wikipedia\n\nFact-check a claim using Wikipedia as a reference source.\n\n## Steps\n1. Identify the entity or topic the claim is about and search for its page.\n2. Get the page summary or content covering the relevant section.\n3. Compare the claim against the article text and decide if it is supported, contradicted, or not addressed.\n\n## Output\nReturn a verdict of supported, contradicted, or unverified, with the supporting sentence quoted and the page title cited. Do not treat absence of mention as proof either way.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wikipedia.ts b/apps/sim/blocks/blocks/wikipedia.ts index ce6ec461e70..5e9404bd972 100644 --- a/apps/sim/blocks/blocks/wikipedia.ts +++ b/apps/sim/blocks/blocks/wikipedia.ts @@ -1,6 +1,5 @@ -import { WikipediaIcon } from '@/components/icons' import { WikipediaBlockDisplay } from '@/blocks/blocks/wikipedia.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import type { WikipediaResponse } from '@/tools/wikipedia/types' export const WikipediaBlock: BlockConfig = { @@ -97,97 +96,3 @@ export const WikipediaBlock: BlockConfig = { randomPage: { type: 'json', description: 'Random page data' }, }, } - -export const WikipediaBlockMeta = { - tags: ['knowledge-base'], - url: 'https://www.wikipedia.org', - templates: [ - { - icon: WikipediaIcon, - title: 'Wikipedia background-research helper', - prompt: - 'Build a workflow that for a chosen topic queries Wikipedia, extracts the lead and infobox, and writes a structured background brief file for the user.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia entity disambiguator', - prompt: - 'Create a workflow that for an ambiguous person or company name queries Wikipedia, identifies the most likely entity given context, and writes the canonical reference back.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'analysis'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia knowledge-base seeder', - prompt: - 'Build a workflow that for tracked topics fetches Wikipedia articles, chunks and embeds them, and seeds a knowledge base with canonical context.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia citation validator', - prompt: - 'Create a workflow that checks if claims drafted by an agent are supported by Wikipedia content, flags claims without strong sources, and writes a quality score.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['research', 'analysis'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia infobox extractor', - prompt: - 'Build a workflow that takes a list of entity names, extracts the Wikipedia infobox fields for each, and writes structured rows for downstream analytics.', - modules: ['tables', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sync'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia related-topic graph', - prompt: - 'Create a workflow that for a topic explores related Wikipedia pages, builds a topic graph in Neo4j, and surfaces adjacent themes.', - modules: ['agent', 'workflows'], - category: 'engineering', - tags: ['research', 'analysis'], - alsoIntegrations: ['neo4j'], - }, - { - icon: WikipediaIcon, - title: 'Wikipedia summary alerter', - prompt: - 'Build a scheduled workflow that monitors Wikipedia pages for tracked entities, detects significant edits, and posts a summary diff to Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['monitoring', 'research'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'research-topic-brief', - description: 'Search Wikipedia for a topic and assemble a concise, sourced background brief.', - content: - '# Build a Wikipedia Topic Brief\n\nProduce a quick, reliable background brief on a subject.\n\n## Steps\n1. Search pages for the topic to find the best-matching article title.\n2. Get the page summary for a fast overview, then get full page content if more depth is needed.\n3. Extract the key facts, dates, and definitions, ignoring tangential detail.\n4. Assemble a short brief in your own words.\n\n## Output\nReturn a brief with a one-line definition, three to five key points, and the Wikipedia page title used as the source.', - }, - { - name: 'disambiguate-entity', - description: - 'Resolve an ambiguous name to the correct Wikipedia entity using surrounding context.', - content: - '# Disambiguate an Entity via Wikipedia\n\nPick the right Wikipedia entity for an ambiguous name.\n\n## Steps\n1. Search pages for the name to retrieve candidate matches.\n2. For the top candidates, get the page summary.\n3. Compare each summary against the context provided (industry, location, role) and choose the best fit.\n4. If nothing matches confidently, say so rather than forcing a choice.\n\n## Output\nReturn the chosen canonical page title with a one-line justification, plus a confidence note and any close alternatives.', - }, - { - name: 'verify-claim', - description: - 'Check whether a stated claim is supported by Wikipedia content and flag unsupported claims.', - content: - '# Verify a Claim Against Wikipedia\n\nFact-check a claim using Wikipedia as a reference source.\n\n## Steps\n1. Identify the entity or topic the claim is about and search for its page.\n2. Get the page summary or content covering the relevant section.\n3. Compare the claim against the article text and decide if it is supported, contradicted, or not addressed.\n\n## Output\nReturn a verdict of supported, contradicted, or unverified, with the supporting sentence quoted and the page title cited. Do not treat absence of mention as proof either way.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wiza.display.ts b/apps/sim/blocks/blocks/wiza.display.ts index 0b76e686993..c10d035ceeb 100644 --- a/apps/sim/blocks/blocks/wiza.display.ts +++ b/apps/sim/blocks/blocks/wiza.display.ts @@ -1,6 +1,6 @@ import { WizaIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WizaBlockDisplay = { type: 'wiza', @@ -15,3 +15,99 @@ export const WizaBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/wiza', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const WizaBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://wiza.co', + templates: [ + { + icon: WizaIcon, + title: 'Wiza prospect builder', + prompt: + 'Build a workflow that runs a Wiza prospect search against my ICP filters, reveals verified emails and phone numbers for each match, and writes the prospect list into a sender table.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: WizaIcon, + title: 'Wiza contact reveal', + prompt: + 'Create a workflow that watches a leads table for new rows, runs a Wiza individual reveal to surface verified email and phone, and writes the contact details back to each row.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'automation'], + }, + { + icon: WizaIcon, + title: 'Wiza company enricher', + prompt: + 'Build a workflow that takes a list of company domains, runs Wiza company enrichment, and writes firmographics and headcount into a tables-based research base.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: WizaIcon, + title: 'Wiza + Email Bison outbound', + prompt: + 'Create a workflow that uses Wiza to find and reveal verified prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'communication'], + alsoIntegrations: ['emailbison'], + }, + { + icon: WizaIcon, + title: 'Wiza CRM gap-filler', + prompt: + 'Build a scheduled workflow that finds Salesforce contacts missing verified phone numbers, runs a Wiza reveal to fill the gaps, and updates each contact record.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: WizaIcon, + title: 'Wiza credit monitor', + prompt: + 'Create a scheduled workflow that checks the remaining Wiza credit balance each morning, logs the daily usage to a table, and posts a Slack alert when credits fall below the threshold so reveals never silently stall mid-campaign.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: WizaIcon, + title: 'Wiza to HubSpot pipeline', + prompt: + 'Build a workflow that runs a Wiza prospect search for my target segment, reveals verified emails and phones for each match, and creates or updates the matching HubSpot contacts with the enriched fields and a lead-source tag.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'enrichment'], + alsoIntegrations: ['hubspot'], + }, + ], + skills: [ + { + name: 'find-prospects', + description: + 'Run a Wiza prospect search with filters to build a list of verified B2B contacts.', + content: + '# Find B2B Prospects with Wiza\n\nBuild a targeted list of verified prospects from an ideal-customer profile.\n\n## Steps\n1. Translate the ideal-customer profile into Wiza filters: job title, seniority, company size, industry, and location.\n2. Run the prospect-search operation with those filters and a sensible result limit.\n3. Choose how much contact data to reveal (email only, phone, or full) based on the outreach plan and credit budget.\n4. Collect the returned prospects with their verified contact fields.\n\n## Output\nReturn the matched prospects with name, title, company, and verified email or phone. Note the total matches and how many credits the reveal consumed.', + }, + { + name: 'enrich-company', + description: 'Enrich a company by domain or name to retrieve firmographic data from Wiza.', + content: + '# Enrich a Company with Wiza\n\nFill in firmographic detail for a target account.\n\n## Steps\n1. Gather the company identifier you have, typically a domain or company name.\n2. Call the company-enrichment operation.\n3. Extract the returned firmographics: industry, size, location, revenue band, and website.\n\n## Output\nReturn the enriched company record as structured fields. If the company could not be matched, say so and report the input used.', + }, + { + name: 'reveal-contact-details', + description: + 'Reveal verified email and phone for a known individual using Wiza individual reveal.', + content: + '# Reveal a Contact with Wiza\n\nGet verified contact details for a specific person.\n\n## Steps\n1. Provide the person identifiers you have, such as name and company or a LinkedIn profile.\n2. Decide the reveal level needed: email only, phone, or full contact.\n3. Call the individual-reveal operation.\n4. Capture the verified email, phone, and current role returned.\n\n## Output\nReturn the verified contact fields with a note on validation status. If credits are low, check the get-credits operation first and warn before spending.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wiza.ts b/apps/sim/blocks/blocks/wiza.ts index d835cea2eab..c8385668e92 100644 --- a/apps/sim/blocks/blocks/wiza.ts +++ b/apps/sim/blocks/blocks/wiza.ts @@ -1,6 +1,5 @@ -import { WizaIcon } from '@/components/icons' import { WizaBlockDisplay } from '@/blocks/blocks/wiza.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { WizaResponse } from '@/tools/wiza/types' @@ -616,99 +615,3 @@ Return ONLY the JSON object - no explanations, no extra text.`, api_credits: { type: 'number', description: 'Remaining API credits (get_credits)' }, }, } - -export const WizaBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://wiza.co', - templates: [ - { - icon: WizaIcon, - title: 'Wiza prospect builder', - prompt: - 'Build a workflow that runs a Wiza prospect search against my ICP filters, reveals verified emails and phone numbers for each match, and writes the prospect list into a sender table.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: WizaIcon, - title: 'Wiza contact reveal', - prompt: - 'Create a workflow that watches a leads table for new rows, runs a Wiza individual reveal to surface verified email and phone, and writes the contact details back to each row.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'automation'], - }, - { - icon: WizaIcon, - title: 'Wiza company enricher', - prompt: - 'Build a workflow that takes a list of company domains, runs Wiza company enrichment, and writes firmographics and headcount into a tables-based research base.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: WizaIcon, - title: 'Wiza + Email Bison outbound', - prompt: - 'Create a workflow that uses Wiza to find and reveal verified prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'communication'], - alsoIntegrations: ['emailbison'], - }, - { - icon: WizaIcon, - title: 'Wiza CRM gap-filler', - prompt: - 'Build a scheduled workflow that finds Salesforce contacts missing verified phone numbers, runs a Wiza reveal to fill the gaps, and updates each contact record.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: WizaIcon, - title: 'Wiza credit monitor', - prompt: - 'Create a scheduled workflow that checks the remaining Wiza credit balance each morning, logs the daily usage to a table, and posts a Slack alert when credits fall below the threshold so reveals never silently stall mid-campaign.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'operations', - tags: ['sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: WizaIcon, - title: 'Wiza to HubSpot pipeline', - prompt: - 'Build a workflow that runs a Wiza prospect search for my target segment, reveals verified emails and phones for each match, and creates or updates the matching HubSpot contacts with the enriched fields and a lead-source tag.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'enrichment'], - alsoIntegrations: ['hubspot'], - }, - ], - skills: [ - { - name: 'find-prospects', - description: - 'Run a Wiza prospect search with filters to build a list of verified B2B contacts.', - content: - '# Find B2B Prospects with Wiza\n\nBuild a targeted list of verified prospects from an ideal-customer profile.\n\n## Steps\n1. Translate the ideal-customer profile into Wiza filters: job title, seniority, company size, industry, and location.\n2. Run the prospect-search operation with those filters and a sensible result limit.\n3. Choose how much contact data to reveal (email only, phone, or full) based on the outreach plan and credit budget.\n4. Collect the returned prospects with their verified contact fields.\n\n## Output\nReturn the matched prospects with name, title, company, and verified email or phone. Note the total matches and how many credits the reveal consumed.', - }, - { - name: 'enrich-company', - description: 'Enrich a company by domain or name to retrieve firmographic data from Wiza.', - content: - '# Enrich a Company with Wiza\n\nFill in firmographic detail for a target account.\n\n## Steps\n1. Gather the company identifier you have, typically a domain or company name.\n2. Call the company-enrichment operation.\n3. Extract the returned firmographics: industry, size, location, revenue band, and website.\n\n## Output\nReturn the enriched company record as structured fields. If the company could not be matched, say so and report the input used.', - }, - { - name: 'reveal-contact-details', - description: - 'Reveal verified email and phone for a known individual using Wiza individual reveal.', - content: - '# Reveal a Contact with Wiza\n\nGet verified contact details for a specific person.\n\n## Steps\n1. Provide the person identifiers you have, such as name and company or a LinkedIn profile.\n2. Decide the reveal level needed: email only, phone, or full contact.\n3. Call the individual-reveal operation.\n4. Capture the verified email, phone, and current role returned.\n\n## Output\nReturn the verified contact fields with a note on validation status. If credits are low, check the get-credits operation first and warn before spending.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wordpress.display.ts b/apps/sim/blocks/blocks/wordpress.display.ts index 1634283be35..14a5bf44f22 100644 --- a/apps/sim/blocks/blocks/wordpress.display.ts +++ b/apps/sim/blocks/blocks/wordpress.display.ts @@ -1,6 +1,6 @@ import { WordpressIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WordPressBlockDisplay = { type: 'wordpress', @@ -15,3 +15,105 @@ export const WordPressBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/wordpress', integrationType: IntegrationType.Marketing, } satisfies BlockDisplay + +export const WordPressBlockMeta = { + tags: ['content-management', 'seo'], + url: 'https://wordpress.org', + templates: [ + { + icon: WordpressIcon, + title: 'Blog auto-publisher', + prompt: + 'Build a workflow that takes a draft document, optimizes it for SEO by researching target keywords, formats it for WordPress with proper headings and meta description, and publishes it as a draft post for final review.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: WordpressIcon, + title: 'WordPress release-notes publisher', + prompt: + 'Create a scheduled workflow that runs every Friday, pulls merged GitHub PRs for the week, drafts a user-facing changelog, and publishes it as a WordPress post.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'engineering'], + alsoIntegrations: ['github'], + }, + { + icon: WordpressIcon, + title: 'WordPress comment moderator', + prompt: + 'Build a scheduled workflow that polls new WordPress comments, classifies each as spam, question, or constructive, auto-moderates spam, and replies to questions using a knowledge base.', + modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: WordpressIcon, + title: 'WordPress SEO refresher', + prompt: + 'Create a scheduled monthly workflow that finds underperforming WordPress posts, runs Ahrefs keyword analysis, drafts refreshed sections, and stages the update as a draft revision.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['ahrefs'], + }, + { + icon: WordpressIcon, + title: 'WordPress newsletter republisher', + prompt: + 'Build a workflow that publishes a new WordPress post and then drafts an adapted Mailchimp newsletter version, links back to the post, and queues it for the editor’s review.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'communication'], + alsoIntegrations: ['mailchimp'], + }, + { + icon: WordpressIcon, + title: 'WordPress broken-link sweeper', + prompt: + 'Create a scheduled workflow that scans WordPress posts for broken outbound links, proposes replacement URLs via web search, and stages each as a draft revision for approval.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + }, + { + icon: WordpressIcon, + title: 'WordPress media-rich post builder', + prompt: + 'Build a workflow that takes a draft article and its image files, uploads each image to the WordPress media library, generates a hero image with an image generator, assigns the right categories and tags, and publishes the fully illustrated post as a draft for review.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + ], + skills: [ + { + name: 'publish-blog-post', + description: + 'Create a WordPress post from a draft, assign categories and tags, and set its publish state.', + content: + '# Publish a WordPress Post\n\nTurn a finished draft into a WordPress post.\n\n## Steps\n1. Prepare the title, body HTML, and excerpt for the post.\n2. Resolve or create the categories and tags by listing existing ones and matching by name.\n3. Decide the status: draft for review or publish to go live.\n4. Call the create-post operation with the content, taxonomy, and status.\n\n## Output\nReport the new post ID, status, and the post URL. List the categories and tags applied. If publishing directly, confirm the live link.', + }, + { + name: 'update-existing-post', + description: + 'Find a WordPress post and update its content, status, or taxonomy without overwriting the rest.', + content: + '# Update a WordPress Post\n\nApply targeted edits to a published or draft post.\n\n## Steps\n1. Locate the post by ID, or list or search posts and match on title.\n2. Get the current post to know its existing content and metadata.\n3. Build an update containing only the fields that change, such as body, status, or tags.\n4. Call the update-post operation and confirm the change.\n\n## Output\nState which fields changed and the post ID. Confirm the resulting status and URL.', + }, + { + name: 'upload-and-attach-media', + description: 'Upload an image or file to the WordPress media library for use in a post.', + content: + '# Upload Media to WordPress\n\nAdd an image or file to the media library.\n\n## Steps\n1. Provide the file to upload along with a descriptive title and alt text.\n2. Call the upload-media operation.\n3. Capture the returned media ID and source URL.\n4. If the media is for a specific post, reference the media ID or URL when creating or updating that post.\n\n## Output\nReturn the media ID, the file URL, and the alt text set. Note whether it was attached to a post.', + }, + { + name: 'moderate-comments', + description: + 'List recent WordPress comments and approve, hold, spam, or trash them by policy.', + content: + '# Moderate WordPress Comments\n\nKeep the comment queue clean and on-policy.\n\n## Steps\n1. List comments, optionally filtering by status such as hold.\n2. For each comment, judge it against the moderation policy: legitimate, spam, or abusive.\n3. Update each comment to the right status: approved, hold, spam, or trash.\n\n## Output\nReturn a summary of how many comments were approved, held, marked spam, or trashed, with the comment IDs grouped by action taken.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/wordpress.ts b/apps/sim/blocks/blocks/wordpress.ts index 25d6974f8bd..e31b875ba44 100644 --- a/apps/sim/blocks/blocks/wordpress.ts +++ b/apps/sim/blocks/blocks/wordpress.ts @@ -1,7 +1,6 @@ -import { WordpressIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { WordPressBlockDisplay } from '@/blocks/blocks/wordpress.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { normalizeFileInput } from '@/blocks/utils' import type { WordPressResponse } from '@/tools/wordpress/types' @@ -1005,105 +1004,3 @@ export const WordPressBlock: BlockConfig = { totalPages: { type: 'number', description: 'Total pages' }, }, } - -export const WordPressBlockMeta = { - tags: ['content-management', 'seo'], - url: 'https://wordpress.org', - templates: [ - { - icon: WordpressIcon, - title: 'Blog auto-publisher', - prompt: - 'Build a workflow that takes a draft document, optimizes it for SEO by researching target keywords, formats it for WordPress with proper headings and meta description, and publishes it as a draft post for final review.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: WordpressIcon, - title: 'WordPress release-notes publisher', - prompt: - 'Create a scheduled workflow that runs every Friday, pulls merged GitHub PRs for the week, drafts a user-facing changelog, and publishes it as a WordPress post.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'engineering'], - alsoIntegrations: ['github'], - }, - { - icon: WordpressIcon, - title: 'WordPress comment moderator', - prompt: - 'Build a scheduled workflow that polls new WordPress comments, classifies each as spam, question, or constructive, auto-moderates spam, and replies to questions using a knowledge base.', - modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: WordpressIcon, - title: 'WordPress SEO refresher', - prompt: - 'Create a scheduled monthly workflow that finds underperforming WordPress posts, runs Ahrefs keyword analysis, drafts refreshed sections, and stages the update as a draft revision.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['ahrefs'], - }, - { - icon: WordpressIcon, - title: 'WordPress newsletter republisher', - prompt: - 'Build a workflow that publishes a new WordPress post and then drafts an adapted Mailchimp newsletter version, links back to the post, and queues it for the editor’s review.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'communication'], - alsoIntegrations: ['mailchimp'], - }, - { - icon: WordpressIcon, - title: 'WordPress broken-link sweeper', - prompt: - 'Create a scheduled workflow that scans WordPress posts for broken outbound links, proposes replacement URLs via web search, and stages each as a draft revision for approval.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - }, - { - icon: WordpressIcon, - title: 'WordPress media-rich post builder', - prompt: - 'Build a workflow that takes a draft article and its image files, uploads each image to the WordPress media library, generates a hero image with an image generator, assigns the right categories and tags, and publishes the fully illustrated post as a draft for review.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - ], - skills: [ - { - name: 'publish-blog-post', - description: - 'Create a WordPress post from a draft, assign categories and tags, and set its publish state.', - content: - '# Publish a WordPress Post\n\nTurn a finished draft into a WordPress post.\n\n## Steps\n1. Prepare the title, body HTML, and excerpt for the post.\n2. Resolve or create the categories and tags by listing existing ones and matching by name.\n3. Decide the status: draft for review or publish to go live.\n4. Call the create-post operation with the content, taxonomy, and status.\n\n## Output\nReport the new post ID, status, and the post URL. List the categories and tags applied. If publishing directly, confirm the live link.', - }, - { - name: 'update-existing-post', - description: - 'Find a WordPress post and update its content, status, or taxonomy without overwriting the rest.', - content: - '# Update a WordPress Post\n\nApply targeted edits to a published or draft post.\n\n## Steps\n1. Locate the post by ID, or list or search posts and match on title.\n2. Get the current post to know its existing content and metadata.\n3. Build an update containing only the fields that change, such as body, status, or tags.\n4. Call the update-post operation and confirm the change.\n\n## Output\nState which fields changed and the post ID. Confirm the resulting status and URL.', - }, - { - name: 'upload-and-attach-media', - description: 'Upload an image or file to the WordPress media library for use in a post.', - content: - '# Upload Media to WordPress\n\nAdd an image or file to the media library.\n\n## Steps\n1. Provide the file to upload along with a descriptive title and alt text.\n2. Call the upload-media operation.\n3. Capture the returned media ID and source URL.\n4. If the media is for a specific post, reference the media ID or URL when creating or updating that post.\n\n## Output\nReturn the media ID, the file URL, and the alt text set. Note whether it was attached to a post.', - }, - { - name: 'moderate-comments', - description: - 'List recent WordPress comments and approve, hold, spam, or trash them by policy.', - content: - '# Moderate WordPress Comments\n\nKeep the comment queue clean and on-policy.\n\n## Steps\n1. List comments, optionally filtering by status such as hold.\n2. For each comment, judge it against the moderation policy: legitimate, spam, or abusive.\n3. Update each comment to the right status: approved, hold, spam, or trash.\n\n## Output\nReturn a summary of how many comments were approved, held, marked spam, or trashed, with the comment IDs grouped by action taken.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/workday.display.ts b/apps/sim/blocks/blocks/workday.display.ts index fa11b19f0c3..116bc72524d 100644 --- a/apps/sim/blocks/blocks/workday.display.ts +++ b/apps/sim/blocks/blocks/workday.display.ts @@ -1,6 +1,6 @@ import { WorkdayIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const WorkdayBlockDisplay = { type: 'workday', @@ -14,3 +14,106 @@ export const WorkdayBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/workday', integrationType: IntegrationType.HR, } satisfies BlockDisplay + +export const WorkdayBlockMeta = { + tags: ['hiring'], + url: 'https://www.workday.com', + templates: [ + { + icon: WorkdayIcon, + title: 'Workday new-hire kickoff', + prompt: + 'Build a scheduled workflow that polls Workday for newly hired employees, gathers each one’s position and start date, kicks off provisioning in downstream tools, assigns an onboarding plan, schedules introductions on Google Calendar, and notifies the team in Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation', 'enterprise'], + alsoIntegrations: ['slack', 'google_calendar'], + }, + { + icon: WorkdayIcon, + title: 'Pre-hire creation pipeline', + prompt: + 'Create a workflow exposed as a form that captures candidate details from recruiters, validates required fields, creates a pre-hire record in Workday, returns the pre-hire identifier, and logs the submission in a recruiting tracking table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'recruiting', 'automation'], + }, + { + icon: WorkdayIcon, + title: 'Job change orchestrator', + prompt: + 'Build a workflow that watches a Sim table of approved promotions, transfers, and demotions, performs the Workday change-job action for each row, updates downstream tools and Slack channel membership, and writes the outcome back to the table for audit.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'automation'], + alsoIntegrations: ['slack'], + }, + { + icon: WorkdayIcon, + title: 'Compensation review prep', + prompt: + 'Create a scheduled workflow that pulls Workday workers and their current compensation, joins with a performance ratings table, drafts manager-by-manager compensation review packets as files, and emails each manager their packet ahead of the cycle.', + modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: WorkdayIcon, + title: 'Termination workflow', + prompt: + 'Build a workflow triggered by an approved offboarding request that initiates the Workday Terminate Employee business process, deactivates downstream accounts, schedules an exit interview on Google Calendar, and writes a compliance record to an audit table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'compliance'], + alsoIntegrations: ['google_calendar'], + }, + { + icon: WorkdayIcon, + title: 'Org structure snapshot', + prompt: + 'Create a scheduled weekly workflow that pulls Workday workers and organizations, builds an org chart file with departments and cost centers, diffs against last week to highlight structural changes, and emails the result to people leadership.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['hr', 'enterprise', 'reporting'], + }, + { + icon: WorkdayIcon, + title: 'Personal info update self-service', + prompt: + 'Build a workflow exposed as a chat or form endpoint that takes employee-submitted personal info changes, validates the request, calls the Workday Update Personal Information action, confirms back to the employee, and logs the change in a people-operations audit table.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['hr', 'automation', 'team'], + }, + ], + skills: [ + { + name: 'look-up-worker', + description: 'Find a worker in Workday and return their core profile and employment details.', + content: + '# Look Up a Worker in Workday\n\nRetrieve a worker record for HR review or downstream use.\n\n## Steps\n1. Resolve the worker by ID, or list workers and match on name or email.\n2. Call the get-worker operation for the matched worker.\n3. Extract the relevant fields: name, position, organization, manager, and status.\n\n## Output\nReturn the worker profile as structured fields. If multiple workers matched the search, list the candidates and ask which one before fetching full detail.', + }, + { + name: 'onboard-new-hire', + description: + 'Create a pre-hire, hire the employee, and assign an onboarding plan in Workday.', + content: + '# Onboard a New Hire in Workday\n\nMove a candidate from pre-hire to onboarded employee.\n\n## Steps\n1. Create the pre-hire record with the candidate personal and contact details.\n2. Hire the employee using the pre-hire, setting position, organization, start date, and worker type.\n3. Assign the onboarding plan for the new worker.\n4. Confirm each step succeeded before moving to the next.\n\n## Output\nReport the new worker ID, position, start date, and the onboarding plan assigned. Stop and surface the error if any step fails rather than continuing.', + }, + { + name: 'process-job-change', + description: + 'Apply a job change such as a transfer or promotion to an existing Workday worker.', + content: + '# Process a Job Change in Workday\n\nUpdate a worker position with a transfer, promotion, or reassignment.\n\n## Steps\n1. Look up the worker and confirm their current position and organization.\n2. Determine the new position, organization, or compensation involved in the change.\n3. Call the change-job operation with the change details and effective date.\n4. Optionally fetch compensation to confirm the new package.\n\n## Output\nReport the worker ID, the old and new position, the effective date, and confirmation the change was recorded.', + }, + { + name: 'update-worker-info', + description: + 'Update a Workday worker personal information record with validated field changes.', + content: + '# Update Worker Personal Information\n\nApply validated personal-information changes for a worker.\n\n## Steps\n1. Look up the worker to confirm the record and current values.\n2. Validate the requested changes against expected formats before applying.\n3. Build the fields JSON with only the values that change.\n4. Call the update-worker operation and confirm acceptance.\n\n## Output\nReport which fields changed for the worker ID and confirm the update succeeded. Reject and explain any field that failed validation.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/workday.ts b/apps/sim/blocks/blocks/workday.ts index d50bab9c76f..27ccf822727 100644 --- a/apps/sim/blocks/blocks/workday.ts +++ b/apps/sim/blocks/blocks/workday.ts @@ -1,6 +1,5 @@ -import { WorkdayIcon } from '@/components/icons' import { WorkdayBlockDisplay } from '@/blocks/blocks/workday.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' export const WorkdayBlock: BlockConfig = { ...WorkdayBlockDisplay, @@ -451,106 +450,3 @@ Output: {"Marital_Status_Reference":{"ID":{"attributes":{"wd:type":"Marital_Stat terminationDate: { type: 'string', description: 'Termination date' }, }, } - -export const WorkdayBlockMeta = { - tags: ['hiring'], - url: 'https://www.workday.com', - templates: [ - { - icon: WorkdayIcon, - title: 'Workday new-hire kickoff', - prompt: - 'Build a scheduled workflow that polls Workday for newly hired employees, gathers each one’s position and start date, kicks off provisioning in downstream tools, assigns an onboarding plan, schedules introductions on Google Calendar, and notifies the team in Slack.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation', 'enterprise'], - alsoIntegrations: ['slack', 'google_calendar'], - }, - { - icon: WorkdayIcon, - title: 'Pre-hire creation pipeline', - prompt: - 'Create a workflow exposed as a form that captures candidate details from recruiters, validates required fields, creates a pre-hire record in Workday, returns the pre-hire identifier, and logs the submission in a recruiting tracking table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'recruiting', 'automation'], - }, - { - icon: WorkdayIcon, - title: 'Job change orchestrator', - prompt: - 'Build a workflow that watches a Sim table of approved promotions, transfers, and demotions, performs the Workday change-job action for each row, updates downstream tools and Slack channel membership, and writes the outcome back to the table for audit.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'automation'], - alsoIntegrations: ['slack'], - }, - { - icon: WorkdayIcon, - title: 'Compensation review prep', - prompt: - 'Create a scheduled workflow that pulls Workday workers and their current compensation, joins with a performance ratings table, drafts manager-by-manager compensation review packets as files, and emails each manager their packet ahead of the cycle.', - modules: ['scheduled', 'tables', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: WorkdayIcon, - title: 'Termination workflow', - prompt: - 'Build a workflow triggered by an approved offboarding request that initiates the Workday Terminate Employee business process, deactivates downstream accounts, schedules an exit interview on Google Calendar, and writes a compliance record to an audit table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'compliance'], - alsoIntegrations: ['google_calendar'], - }, - { - icon: WorkdayIcon, - title: 'Org structure snapshot', - prompt: - 'Create a scheduled weekly workflow that pulls Workday workers and organizations, builds an org chart file with departments and cost centers, diffs against last week to highlight structural changes, and emails the result to people leadership.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'operations', - tags: ['hr', 'enterprise', 'reporting'], - }, - { - icon: WorkdayIcon, - title: 'Personal info update self-service', - prompt: - 'Build a workflow exposed as a chat or form endpoint that takes employee-submitted personal info changes, validates the request, calls the Workday Update Personal Information action, confirms back to the employee, and logs the change in a people-operations audit table.', - modules: ['tables', 'agent', 'workflows'], - category: 'operations', - tags: ['hr', 'automation', 'team'], - }, - ], - skills: [ - { - name: 'look-up-worker', - description: 'Find a worker in Workday and return their core profile and employment details.', - content: - '# Look Up a Worker in Workday\n\nRetrieve a worker record for HR review or downstream use.\n\n## Steps\n1. Resolve the worker by ID, or list workers and match on name or email.\n2. Call the get-worker operation for the matched worker.\n3. Extract the relevant fields: name, position, organization, manager, and status.\n\n## Output\nReturn the worker profile as structured fields. If multiple workers matched the search, list the candidates and ask which one before fetching full detail.', - }, - { - name: 'onboard-new-hire', - description: - 'Create a pre-hire, hire the employee, and assign an onboarding plan in Workday.', - content: - '# Onboard a New Hire in Workday\n\nMove a candidate from pre-hire to onboarded employee.\n\n## Steps\n1. Create the pre-hire record with the candidate personal and contact details.\n2. Hire the employee using the pre-hire, setting position, organization, start date, and worker type.\n3. Assign the onboarding plan for the new worker.\n4. Confirm each step succeeded before moving to the next.\n\n## Output\nReport the new worker ID, position, start date, and the onboarding plan assigned. Stop and surface the error if any step fails rather than continuing.', - }, - { - name: 'process-job-change', - description: - 'Apply a job change such as a transfer or promotion to an existing Workday worker.', - content: - '# Process a Job Change in Workday\n\nUpdate a worker position with a transfer, promotion, or reassignment.\n\n## Steps\n1. Look up the worker and confirm their current position and organization.\n2. Determine the new position, organization, or compensation involved in the change.\n3. Call the change-job operation with the change details and effective date.\n4. Optionally fetch compensation to confirm the new package.\n\n## Output\nReport the worker ID, the old and new position, the effective date, and confirmation the change was recorded.', - }, - { - name: 'update-worker-info', - description: - 'Update a Workday worker personal information record with validated field changes.', - content: - '# Update Worker Personal Information\n\nApply validated personal-information changes for a worker.\n\n## Steps\n1. Look up the worker to confirm the record and current values.\n2. Validate the requested changes against expected formats before applying.\n3. Build the fields JSON with only the values that change.\n4. Call the update-worker operation and confirm acceptance.\n\n## Output\nReport which fields changed for the worker ID and confirm the update succeeded. Reject and explain any field that failed validation.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/x.display.ts b/apps/sim/blocks/blocks/x.display.ts index fa13be628ba..2580c84869b 100644 --- a/apps/sim/blocks/blocks/x.display.ts +++ b/apps/sim/blocks/blocks/x.display.ts @@ -1,6 +1,6 @@ import { xIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const XBlockDisplay = { type: 'x', @@ -14,3 +14,106 @@ export const XBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/x', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const XBlockMeta = { + tags: ['marketing', 'messaging'], + url: 'https://x.com', + templates: [ + { + icon: xIcon, + title: 'X (Twitter) brand mention triage', + prompt: + 'Build a scheduled workflow that polls X mentions of the brand, classifies each as praise, support request, or complaint, and routes complaints to the support team with one-tap context.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'support'], + alsoIntegrations: ['slack'], + }, + { + icon: xIcon, + title: 'X engagement digest', + prompt: + 'Create a scheduled daily workflow that summarizes top X engagement on the brand account, identifies high-influence engagers, and writes them to a sales-prospect table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'sales'], + alsoIntegrations: ['salesforce'], + }, + { + icon: xIcon, + title: 'X content scheduler', + prompt: + 'Build a workflow that reads a tables-based X content calendar and posts scheduled tweets with media at the right time, retrying transient failures.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'automation'], + }, + { + icon: xIcon, + title: 'X thread expander', + prompt: + 'Create a workflow that takes a long-form article or blog and drafts a multi-tweet X thread with hooks, key points, and a call-to-action, then queues it for review before posting.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: xIcon, + title: 'X competitor watcher', + prompt: + 'Build a scheduled workflow that tracks tweets from competitor handles and key industry voices, captures notable posts in a table, and surfaces high-engagement items to Slack.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: xIcon, + title: 'X support ticket creator', + prompt: + 'Create a scheduled workflow that polls X for tweets directed at the brand support handle, classifies each as a support request, and opens a Zendesk ticket with the tweet context and customer profile.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['zendesk'], + }, + { + icon: xIcon, + title: 'X bookmark research digest', + prompt: + 'Create a scheduled weekly workflow that pulls my saved X bookmarks, fetches the full text of each bookmarked tweet, groups them by theme, writes a curated reading digest, and emails it to me before clearing the processed bookmarks.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'productivity', + tags: ['research', 'content', 'individual'], + }, + ], + skills: [ + { + name: 'post-tweet', + description: + 'Compose and publish a tweet on X, optionally as a reply or with reply restrictions.', + content: + '# Post a Tweet on X\n\nPublish a single tweet or a reply.\n\n## Steps\n1. Draft the tweet text, keeping it within the character limit and on-brand.\n2. If it is a reply, identify the tweet ID being replied to. Set reply restrictions if the post should be limited to following or mentioned users.\n3. Call the create-tweet operation.\n4. Capture the returned tweet ID.\n\n## Output\nReturn the posted tweet text and its tweet ID with a link. Confirm whether it was a standalone post or a reply.', + }, + { + name: 'monitor-mentions', + description: 'Fetch recent mentions of a user on X and summarize what needs a response.', + content: + '# Monitor X Mentions\n\nTrack who is talking to a profile and surface what matters.\n\n## Steps\n1. Resolve the target user, using get-my-profile or search-users to confirm the user ID.\n2. Call get-user-mentions to fetch recent mentions.\n3. Classify each mention: question, complaint, praise, or noise.\n4. Highlight mentions that need a reply.\n\n## Output\nReturn a grouped summary of mentions by type, with the tweet IDs and authors for any that need a human response, ranked by urgency.', + }, + { + name: 'search-and-analyze-tweets', + description: + 'Search X for tweets matching a query and summarize themes, sentiment, and notable posts.', + content: + '# Search and Analyze Tweets on X\n\nUnderstand the conversation around a topic or keyword.\n\n## Steps\n1. Build a focused search query and choose recency or relevancy sorting.\n2. Call search-tweets with a sensible result limit.\n3. Read the results and identify recurring themes, overall sentiment, and high-engagement posts.\n\n## Output\nReturn a short report: dominant themes, sentiment split, and a few notable tweets with their IDs. Note the query and time window covered.', + }, + { + name: 'curate-bookmarks-digest', + description: + 'Pull saved X bookmarks, group them by theme, and produce a curated reading digest.', + content: + '# Curate an X Bookmarks Digest\n\nTurn saved bookmarks into an organized reading list.\n\n## Steps\n1. Call get-bookmarks to retrieve saved tweets.\n2. Fetch the full text of each bookmarked tweet where needed using get-tweets-by-IDs.\n3. Group the bookmarks by theme and write a short note on why each cluster matters.\n4. Optionally delete-bookmark for items once they are processed.\n\n## Output\nReturn a themed digest with each tweet linked by ID and a one-line takeaway per item. State how many bookmarks were processed.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/x.ts b/apps/sim/blocks/blocks/x.ts index e1d17db7d49..51cb87e9d2d 100644 --- a/apps/sim/blocks/blocks/x.ts +++ b/apps/sim/blocks/blocks/x.ts @@ -1,7 +1,6 @@ -import { xIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { XBlockDisplay } from '@/blocks/blocks/x.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' export const XBlock: BlockConfig = { @@ -747,106 +746,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, }, }, } - -export const XBlockMeta = { - tags: ['marketing', 'messaging'], - url: 'https://x.com', - templates: [ - { - icon: xIcon, - title: 'X (Twitter) brand mention triage', - prompt: - 'Build a scheduled workflow that polls X mentions of the brand, classifies each as praise, support request, or complaint, and routes complaints to the support team with one-tap context.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'support'], - alsoIntegrations: ['slack'], - }, - { - icon: xIcon, - title: 'X engagement digest', - prompt: - 'Create a scheduled daily workflow that summarizes top X engagement on the brand account, identifies high-influence engagers, and writes them to a sales-prospect table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'sales'], - alsoIntegrations: ['salesforce'], - }, - { - icon: xIcon, - title: 'X content scheduler', - prompt: - 'Build a workflow that reads a tables-based X content calendar and posts scheduled tweets with media at the right time, retrying transient failures.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'automation'], - }, - { - icon: xIcon, - title: 'X thread expander', - prompt: - 'Create a workflow that takes a long-form article or blog and drafts a multi-tweet X thread with hooks, key points, and a call-to-action, then queues it for review before posting.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: xIcon, - title: 'X competitor watcher', - prompt: - 'Build a scheduled workflow that tracks tweets from competitor handles and key industry voices, captures notable posts in a table, and surfaces high-engagement items to Slack.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: xIcon, - title: 'X support ticket creator', - prompt: - 'Create a scheduled workflow that polls X for tweets directed at the brand support handle, classifies each as a support request, and opens a Zendesk ticket with the tweet context and customer profile.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['zendesk'], - }, - { - icon: xIcon, - title: 'X bookmark research digest', - prompt: - 'Create a scheduled weekly workflow that pulls my saved X bookmarks, fetches the full text of each bookmarked tweet, groups them by theme, writes a curated reading digest, and emails it to me before clearing the processed bookmarks.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'productivity', - tags: ['research', 'content', 'individual'], - }, - ], - skills: [ - { - name: 'post-tweet', - description: - 'Compose and publish a tweet on X, optionally as a reply or with reply restrictions.', - content: - '# Post a Tweet on X\n\nPublish a single tweet or a reply.\n\n## Steps\n1. Draft the tweet text, keeping it within the character limit and on-brand.\n2. If it is a reply, identify the tweet ID being replied to. Set reply restrictions if the post should be limited to following or mentioned users.\n3. Call the create-tweet operation.\n4. Capture the returned tweet ID.\n\n## Output\nReturn the posted tweet text and its tweet ID with a link. Confirm whether it was a standalone post or a reply.', - }, - { - name: 'monitor-mentions', - description: 'Fetch recent mentions of a user on X and summarize what needs a response.', - content: - '# Monitor X Mentions\n\nTrack who is talking to a profile and surface what matters.\n\n## Steps\n1. Resolve the target user, using get-my-profile or search-users to confirm the user ID.\n2. Call get-user-mentions to fetch recent mentions.\n3. Classify each mention: question, complaint, praise, or noise.\n4. Highlight mentions that need a reply.\n\n## Output\nReturn a grouped summary of mentions by type, with the tweet IDs and authors for any that need a human response, ranked by urgency.', - }, - { - name: 'search-and-analyze-tweets', - description: - 'Search X for tweets matching a query and summarize themes, sentiment, and notable posts.', - content: - '# Search and Analyze Tweets on X\n\nUnderstand the conversation around a topic or keyword.\n\n## Steps\n1. Build a focused search query and choose recency or relevancy sorting.\n2. Call search-tweets with a sensible result limit.\n3. Read the results and identify recurring themes, overall sentiment, and high-engagement posts.\n\n## Output\nReturn a short report: dominant themes, sentiment split, and a few notable tweets with their IDs. Note the query and time window covered.', - }, - { - name: 'curate-bookmarks-digest', - description: - 'Pull saved X bookmarks, group them by theme, and produce a curated reading digest.', - content: - '# Curate an X Bookmarks Digest\n\nTurn saved bookmarks into an organized reading list.\n\n## Steps\n1. Call get-bookmarks to retrieve saved tweets.\n2. Fetch the full text of each bookmarked tweet where needed using get-tweets-by-IDs.\n3. Group the bookmarks by theme and write a short note on why each cluster matters.\n4. Optionally delete-bookmark for items once they are processed.\n\n## Output\nReturn a themed digest with each tweet linked by ID and a one-line takeaway per item. State how many bookmarks were processed.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/youtube.display.ts b/apps/sim/blocks/blocks/youtube.display.ts index 3d4e7fc7619..5ae1aab9a13 100644 --- a/apps/sim/blocks/blocks/youtube.display.ts +++ b/apps/sim/blocks/blocks/youtube.display.ts @@ -1,6 +1,6 @@ -import { YouTubeIcon } from '@/components/icons' +import { ElevenLabsIcon, YouTubeIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const YouTubeBlockDisplay = { type: 'youtube', @@ -14,3 +14,110 @@ export const YouTubeBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/youtube', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const YouTubeBlockMeta = { + tags: ['marketing', 'content-management'], + url: 'https://www.youtube.com', + templates: [ + { + icon: YouTubeIcon, + title: 'Content repurposer', + prompt: + 'Build a workflow that takes a YouTube video URL, pulls the video details and description, researches the topic on the web for additional context, and generates a Twitter thread, LinkedIn post, and blog summary optimized for each platform.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content', 'automation'], + }, + { + icon: ElevenLabsIcon, + title: 'YouTube video audio brief', + prompt: + 'Build a workflow that takes a YouTube URL, pulls the video details and top comments, summarizes them with an agent, narrates the summary with ElevenLabs, and saves the audio file for distribution.', + modules: ['agent', 'files', 'workflows'], + category: 'marketing', + tags: ['content', 'automation'], + alsoIntegrations: ['elevenlabs'], + }, + { + icon: YouTubeIcon, + title: 'YouTube channel performance digest', + prompt: + 'Create a scheduled weekly workflow that pulls a YouTube channel’s public stats and recent videos, ranks the top performers by views, writes a digest file, and emails it to the content team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'marketing', + tags: ['marketing', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: YouTubeIcon, + title: 'YouTube comment triage', + prompt: + 'Build a scheduled workflow that pulls recent YouTube comments on a video, classifies each as helpful, question, or spam, drafts suggested answers to questions using a knowledge base, and routes them to the community team in Slack for review.', + modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'community'], + alsoIntegrations: ['slack'], + }, + { + icon: YouTubeIcon, + title: 'YouTube upload-to-blog', + prompt: + 'Create a scheduled workflow that polls a YouTube channel for new uploads, pulls each video’s details and description, generates a long-form blog post with proper SEO structure, and stages it as a WordPress draft.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['wordpress'], + }, + { + icon: YouTubeIcon, + title: 'YouTube competitor watcher', + prompt: + 'Build a scheduled workflow that monitors competitor YouTube channels, flags videos that exceed average performance, and writes outline of their format to a content-research table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'research'], + }, + { + icon: YouTubeIcon, + title: 'YouTube video curation finder', + prompt: + 'Create a workflow that reads a tables-based topic list, finds matching YouTube videos via search, scores each for relevance, writes the candidates back to the table, and pings the editorial team for the final cut.', + modules: ['tables', 'agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + }, + { + icon: YouTubeIcon, + title: 'YouTube video recap to Notion', + prompt: + 'Build a workflow that takes a YouTube video URL, pulls the video details, description, and top comments, summarizes the highlights and audience reaction, and saves a recap to a Notion page for the marketing team.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'content'], + alsoIntegrations: ['notion'], + }, + ], + skills: [ + { + name: 'find-videos-on-topic', + description: + 'Search YouTube for videos on a topic with filters for duration, recency, and quality.', + content: + '# Find YouTube Videos on a Topic\n\nSurface the most relevant videos for a subject.\n\n## Steps\n1. Build a search query and choose filters: order (relevance, date, view count), duration, and definition.\n2. Call the search operation with a result limit.\n3. For promising results, get video details to read title, channel, view count, and publish date.\n4. Rank the results by relevance and signal.\n\n## Output\nReturn a ranked list of videos with title, channel, URL, view count, and publish date. Note the query and filters applied.', + }, + { + name: 'analyze-channel', + description: + 'Pull a YouTube channel profile and recent uploads to summarize its content and cadence.', + content: + '# Analyze a YouTube Channel\n\nProfile a channel and its recent output.\n\n## Steps\n1. Get channel info to retrieve subscriber count, total views, and description.\n2. Get channel videos to list recent uploads.\n3. Summarize the content themes, upload cadence, and the best-performing recent videos.\n\n## Output\nReturn a channel summary with key stats, dominant content themes, posting frequency, and the top recent videos by views. Cite the channel and video IDs used.', + }, + { + name: 'summarize-video-comments', + description: + 'Fetch comments on a YouTube video and summarize sentiment, questions, and recurring feedback.', + content: + '# Summarize YouTube Video Comments\n\nUnderstand audience reaction to a video.\n\n## Steps\n1. Identify the video ID, searching or using video details if only a title is known.\n2. Call the comments operation to fetch top or recent comments.\n3. Group comments into sentiment, recurring questions, and feature or content requests.\n\n## Output\nReturn a summary with sentiment breakdown, the most common questions, and notable feedback themes. Quote a few representative comments and cite the video ID.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/youtube.ts b/apps/sim/blocks/blocks/youtube.ts index 9b727ed01f4..9257a72231d 100644 --- a/apps/sim/blocks/blocks/youtube.ts +++ b/apps/sim/blocks/blocks/youtube.ts @@ -1,6 +1,5 @@ -import { ElevenLabsIcon, YouTubeIcon } from '@/components/icons' import { YouTubeBlockDisplay } from '@/blocks/blocks/youtube.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { YouTubeResponse } from '@/tools/youtube/types' @@ -540,110 +539,3 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, assignable: { type: 'boolean', description: 'Whether category can be assigned' }, }, } - -export const YouTubeBlockMeta = { - tags: ['marketing', 'content-management'], - url: 'https://www.youtube.com', - templates: [ - { - icon: YouTubeIcon, - title: 'Content repurposer', - prompt: - 'Build a workflow that takes a YouTube video URL, pulls the video details and description, researches the topic on the web for additional context, and generates a Twitter thread, LinkedIn post, and blog summary optimized for each platform.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content', 'automation'], - }, - { - icon: ElevenLabsIcon, - title: 'YouTube video audio brief', - prompt: - 'Build a workflow that takes a YouTube URL, pulls the video details and top comments, summarizes them with an agent, narrates the summary with ElevenLabs, and saves the audio file for distribution.', - modules: ['agent', 'files', 'workflows'], - category: 'marketing', - tags: ['content', 'automation'], - alsoIntegrations: ['elevenlabs'], - }, - { - icon: YouTubeIcon, - title: 'YouTube channel performance digest', - prompt: - 'Create a scheduled weekly workflow that pulls a YouTube channel’s public stats and recent videos, ranks the top performers by views, writes a digest file, and emails it to the content team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'marketing', - tags: ['marketing', 'reporting'], - alsoIntegrations: ['gmail'], - }, - { - icon: YouTubeIcon, - title: 'YouTube comment triage', - prompt: - 'Build a scheduled workflow that pulls recent YouTube comments on a video, classifies each as helpful, question, or spam, drafts suggested answers to questions using a knowledge base, and routes them to the community team in Slack for review.', - modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'community'], - alsoIntegrations: ['slack'], - }, - { - icon: YouTubeIcon, - title: 'YouTube upload-to-blog', - prompt: - 'Create a scheduled workflow that polls a YouTube channel for new uploads, pulls each video’s details and description, generates a long-form blog post with proper SEO structure, and stages it as a WordPress draft.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['wordpress'], - }, - { - icon: YouTubeIcon, - title: 'YouTube competitor watcher', - prompt: - 'Build a scheduled workflow that monitors competitor YouTube channels, flags videos that exceed average performance, and writes outline of their format to a content-research table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'research'], - }, - { - icon: YouTubeIcon, - title: 'YouTube video curation finder', - prompt: - 'Create a workflow that reads a tables-based topic list, finds matching YouTube videos via search, scores each for relevance, writes the candidates back to the table, and pings the editorial team for the final cut.', - modules: ['tables', 'agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - }, - { - icon: YouTubeIcon, - title: 'YouTube video recap to Notion', - prompt: - 'Build a workflow that takes a YouTube video URL, pulls the video details, description, and top comments, summarizes the highlights and audience reaction, and saves a recap to a Notion page for the marketing team.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'content'], - alsoIntegrations: ['notion'], - }, - ], - skills: [ - { - name: 'find-videos-on-topic', - description: - 'Search YouTube for videos on a topic with filters for duration, recency, and quality.', - content: - '# Find YouTube Videos on a Topic\n\nSurface the most relevant videos for a subject.\n\n## Steps\n1. Build a search query and choose filters: order (relevance, date, view count), duration, and definition.\n2. Call the search operation with a result limit.\n3. For promising results, get video details to read title, channel, view count, and publish date.\n4. Rank the results by relevance and signal.\n\n## Output\nReturn a ranked list of videos with title, channel, URL, view count, and publish date. Note the query and filters applied.', - }, - { - name: 'analyze-channel', - description: - 'Pull a YouTube channel profile and recent uploads to summarize its content and cadence.', - content: - '# Analyze a YouTube Channel\n\nProfile a channel and its recent output.\n\n## Steps\n1. Get channel info to retrieve subscriber count, total views, and description.\n2. Get channel videos to list recent uploads.\n3. Summarize the content themes, upload cadence, and the best-performing recent videos.\n\n## Output\nReturn a channel summary with key stats, dominant content themes, posting frequency, and the top recent videos by views. Cite the channel and video IDs used.', - }, - { - name: 'summarize-video-comments', - description: - 'Fetch comments on a YouTube video and summarize sentiment, questions, and recurring feedback.', - content: - '# Summarize YouTube Video Comments\n\nUnderstand audience reaction to a video.\n\n## Steps\n1. Identify the video ID, searching or using video details if only a title is known.\n2. Call the comments operation to fetch top or recent comments.\n3. Group comments into sentiment, recurring questions, and feature or content requests.\n\n## Output\nReturn a summary with sentiment breakdown, the most common questions, and notable feedback themes. Quote a few representative comments and cite the video ID.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zendesk.display.ts b/apps/sim/blocks/blocks/zendesk.display.ts index afd411c747f..171df249bfa 100644 --- a/apps/sim/blocks/blocks/zendesk.display.ts +++ b/apps/sim/blocks/blocks/zendesk.display.ts @@ -1,6 +1,6 @@ import { ZendeskIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ZendeskBlockDisplay = { type: 'zendesk', @@ -15,3 +15,107 @@ export const ZendeskBlockDisplay = { integrationType: IntegrationType.Support, triggerAllowed: true, } satisfies BlockDisplay + +export const ZendeskBlockMeta = { + tags: ['customer-support', 'ticketing'], + url: 'https://www.zendesk.com', + templates: [ + { + icon: ZendeskIcon, + title: 'Support ticket knowledge search', + prompt: + 'Create a knowledge base connected to my Zendesk account so all past tickets, resolutions, and agent notes are automatically synced and searchable. Then build an agent my support team can ask things like "how do we usually resolve the SSO login issue?" or "has anyone reported this billing bug before?" to find past solutions instantly.', + modules: ['knowledge-base', 'agent'], + category: 'support', + tags: ['support', 'research', 'team'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk auto-classifier', + prompt: + 'Build a scheduled workflow that polls Zendesk for new tickets, classifies each one by product area, severity, and intent, applies the matching tags, sets priority, and assigns it to the right group so triage happens automatically.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk SLA breach alert', + prompt: + 'Create a scheduled workflow that searches Zendesk every 15 minutes for tickets at risk of breaching first-response or resolution SLA, summarizes each one, and posts a Slack alert to the responsible group with deep links to the tickets.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'monitoring', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk ticket deflector', + prompt: + 'Create a knowledge base from help center articles and past ticket resolutions, then build a scheduled workflow that polls for new Zendesk tickets, drafts a public reply using the knowledge base with citations, and posts it as an internal note for agents to send with one click.', + modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation', 'communication'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk to Jira engineering bridge', + prompt: + 'Build a scheduled workflow that searches Zendesk for tickets newly tagged as a bug, creates a linked Jira issue with the ticket details and customer impact, and posts the Jira link back as an internal note on the Zendesk ticket.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'engineering', 'automation'], + alsoIntegrations: ['jira'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk weekly CX pulse', + prompt: + 'Create a scheduled weekly workflow that pulls Zendesk ticket volume, CSAT, top tags, and recurring issues, generates a narrative CX pulse with week-over-week deltas, and posts it to Slack with links to the standout tickets.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'reporting', 'analysis'], + alsoIntegrations: ['slack'], + }, + { + icon: ZendeskIcon, + title: 'Zendesk customer record sync', + prompt: + 'Build a workflow that watches my CRM for new or updated accounts, searches Zendesk for the matching user and organization, and creates or updates them in bulk so support agents always see the latest company, plan, and contact details on every ticket.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'crm', 'sync'], + alsoIntegrations: ['salesforce'], + }, + ], + skills: [ + { + name: 'triage-new-ticket', + description: + 'Read a Zendesk ticket, classify it, and update priority, tags, and assignee accordingly.', + content: + '# Triage a Zendesk Ticket\n\nClassify an incoming ticket and route it correctly.\n\n## Steps\n1. Get the ticket by ID to read the subject, description, and requester.\n2. Classify the issue type, urgency, and the team or queue it belongs to.\n3. Update the ticket with the right priority, tags, and assignee or group.\n4. Optionally add an internal note explaining the triage decision.\n\n## Output\nReport the ticket ID, the classification, and the priority, tags, and assignee set. Note anything that needs human review.', + }, + { + name: 'create-support-ticket', + description: + 'Create a Zendesk ticket from an inbound request, linking it to the right requester.', + content: + '# Create a Zendesk Ticket\n\nLog an inbound issue as a support ticket.\n\n## Steps\n1. Gather the subject, description, and requester details.\n2. Look up the requester with search-users, creating the user if they do not exist.\n3. Call create-ticket with the subject, body, requester, priority, and any tags.\n4. Capture the new ticket ID.\n\n## Output\nReturn the created ticket ID, its priority, and the requester it is linked to. Confirm whether a new user was created.', + }, + { + name: 'search-tickets', + description: + 'Run a Zendesk search to find tickets matching status, requester, or keyword criteria.', + content: + '# Search Zendesk Tickets\n\nFind tickets that match a set of conditions.\n\n## Steps\n1. Express the criteria as a Zendesk search query, for example status, tags, requester, or keyword.\n2. Call the search operation, choosing the right sort order.\n3. Read the results and pull the fields needed for the task.\n\n## Output\nReturn the matching tickets with ID, subject, status, priority, and assignee. State the query used and the total count via search-count if a volume figure is needed.', + }, + { + name: 'sync-organization', + description: + 'Create or update a Zendesk organization and its associated users for account hygiene.', + content: + '# Sync a Zendesk Organization\n\nKeep an organization record and its users accurate.\n\n## Steps\n1. Look up the organization with get-organizations or autocomplete-organizations to check if it exists.\n2. Create the organization, or update it with the latest name, domains, and details.\n3. Reconcile the associated users, creating or updating them so they map to the organization.\n\n## Output\nReport the organization ID and whether it was created or updated, plus a count of users created or updated. List any conflicts found.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zendesk.ts b/apps/sim/blocks/blocks/zendesk.ts index 374914b9e96..a4a935f37d3 100644 --- a/apps/sim/blocks/blocks/zendesk.ts +++ b/apps/sim/blocks/blocks/zendesk.ts @@ -1,6 +1,5 @@ -import { ZendeskIcon } from '@/components/icons' import { ZendeskBlockDisplay } from '@/blocks/blocks/zendesk.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import { getTrigger } from '@/triggers' @@ -705,107 +704,3 @@ Return ONLY the search query - no explanations.`, ], }, } - -export const ZendeskBlockMeta = { - tags: ['customer-support', 'ticketing'], - url: 'https://www.zendesk.com', - templates: [ - { - icon: ZendeskIcon, - title: 'Support ticket knowledge search', - prompt: - 'Create a knowledge base connected to my Zendesk account so all past tickets, resolutions, and agent notes are automatically synced and searchable. Then build an agent my support team can ask things like "how do we usually resolve the SSO login issue?" or "has anyone reported this billing bug before?" to find past solutions instantly.', - modules: ['knowledge-base', 'agent'], - category: 'support', - tags: ['support', 'research', 'team'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk auto-classifier', - prompt: - 'Build a scheduled workflow that polls Zendesk for new tickets, classifies each one by product area, severity, and intent, applies the matching tags, sets priority, and assigns it to the right group so triage happens automatically.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk SLA breach alert', - prompt: - 'Create a scheduled workflow that searches Zendesk every 15 minutes for tickets at risk of breaching first-response or resolution SLA, summarizes each one, and posts a Slack alert to the responsible group with deep links to the tickets.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'monitoring', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk ticket deflector', - prompt: - 'Create a knowledge base from help center articles and past ticket resolutions, then build a scheduled workflow that polls for new Zendesk tickets, drafts a public reply using the knowledge base with citations, and posts it as an internal note for agents to send with one click.', - modules: ['scheduled', 'knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation', 'communication'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk to Jira engineering bridge', - prompt: - 'Build a scheduled workflow that searches Zendesk for tickets newly tagged as a bug, creates a linked Jira issue with the ticket details and customer impact, and posts the Jira link back as an internal note on the Zendesk ticket.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'engineering', 'automation'], - alsoIntegrations: ['jira'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk weekly CX pulse', - prompt: - 'Create a scheduled weekly workflow that pulls Zendesk ticket volume, CSAT, top tags, and recurring issues, generates a narrative CX pulse with week-over-week deltas, and posts it to Slack with links to the standout tickets.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'reporting', 'analysis'], - alsoIntegrations: ['slack'], - }, - { - icon: ZendeskIcon, - title: 'Zendesk customer record sync', - prompt: - 'Build a workflow that watches my CRM for new or updated accounts, searches Zendesk for the matching user and organization, and creates or updates them in bulk so support agents always see the latest company, plan, and contact details on every ticket.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'crm', 'sync'], - alsoIntegrations: ['salesforce'], - }, - ], - skills: [ - { - name: 'triage-new-ticket', - description: - 'Read a Zendesk ticket, classify it, and update priority, tags, and assignee accordingly.', - content: - '# Triage a Zendesk Ticket\n\nClassify an incoming ticket and route it correctly.\n\n## Steps\n1. Get the ticket by ID to read the subject, description, and requester.\n2. Classify the issue type, urgency, and the team or queue it belongs to.\n3. Update the ticket with the right priority, tags, and assignee or group.\n4. Optionally add an internal note explaining the triage decision.\n\n## Output\nReport the ticket ID, the classification, and the priority, tags, and assignee set. Note anything that needs human review.', - }, - { - name: 'create-support-ticket', - description: - 'Create a Zendesk ticket from an inbound request, linking it to the right requester.', - content: - '# Create a Zendesk Ticket\n\nLog an inbound issue as a support ticket.\n\n## Steps\n1. Gather the subject, description, and requester details.\n2. Look up the requester with search-users, creating the user if they do not exist.\n3. Call create-ticket with the subject, body, requester, priority, and any tags.\n4. Capture the new ticket ID.\n\n## Output\nReturn the created ticket ID, its priority, and the requester it is linked to. Confirm whether a new user was created.', - }, - { - name: 'search-tickets', - description: - 'Run a Zendesk search to find tickets matching status, requester, or keyword criteria.', - content: - '# Search Zendesk Tickets\n\nFind tickets that match a set of conditions.\n\n## Steps\n1. Express the criteria as a Zendesk search query, for example status, tags, requester, or keyword.\n2. Call the search operation, choosing the right sort order.\n3. Read the results and pull the fields needed for the task.\n\n## Output\nReturn the matching tickets with ID, subject, status, priority, and assignee. State the query used and the total count via search-count if a volume figure is needed.', - }, - { - name: 'sync-organization', - description: - 'Create or update a Zendesk organization and its associated users for account hygiene.', - content: - '# Sync a Zendesk Organization\n\nKeep an organization record and its users accurate.\n\n## Steps\n1. Look up the organization with get-organizations or autocomplete-organizations to check if it exists.\n2. Create the organization, or update it with the latest name, domains, and details.\n3. Reconcile the associated users, creating or updating them so they map to the organization.\n\n## Output\nReport the organization ID and whether it was created or updated, plus a count of users created or updated. List any conflicts found.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zep.display.ts b/apps/sim/blocks/blocks/zep.display.ts index 9f7a01a6fe9..c4bc3f26fc4 100644 --- a/apps/sim/blocks/blocks/zep.display.ts +++ b/apps/sim/blocks/blocks/zep.display.ts @@ -1,6 +1,6 @@ import { ZepIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ZepBlockDisplay = { type: 'zep', @@ -14,3 +14,99 @@ export const ZepBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/zep', integrationType: IntegrationType.AI, } satisfies BlockDisplay + +export const ZepBlockMeta = { + tags: ['knowledge-base', 'agentic'], + url: 'https://www.getzep.com', + templates: [ + { + icon: ZepIcon, + title: 'Zep session memory for chat', + prompt: + 'Create a chat agent that stores every turn in Zep with user metadata, retrieves the most relevant prior context on each new question, and answers with continuity instead of forgetting.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + }, + { + icon: ZepIcon, + title: 'Zep + knowledge base support bot', + prompt: + 'Build a support agent that combines Zep session memory with a knowledge base, so it remembers what the customer has already tried while still grounding answers in product docs.', + modules: ['knowledge-base', 'agent', 'workflows'], + category: 'support', + tags: ['support', 'automation'], + }, + { + icon: ZepIcon, + title: 'Zep + Salesforce account memory', + prompt: + 'Build a workflow that for each Salesforce account writes meeting and email context into Zep keyed by account, so any future agent interaction has full history.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ZepIcon, + title: 'Zep + Intercom support continuity', + prompt: + 'Create a Zep-backed support agent for Intercom that remembers what each customer has tried before, prefers, or escalated, so support conversations never restart from scratch.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'communication'], + alsoIntegrations: ['intercom'], + }, + { + icon: ZepIcon, + title: 'Zep evaluation harness', + prompt: + 'Build a scheduled workflow that evaluates Zep memory recall accuracy weekly against a labeled eval set, captures regressions, and writes a quality report.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'engineering', + tags: ['engineering', 'analysis'], + }, + { + icon: ZepIcon, + title: 'Zep personal-assistant memory', + prompt: + 'Create a personal assistant agent that records preferences, recurring tasks, and prior decisions in Zep, then retrieves the relevant facts on each request so it stays consistent across days instead of asking the same questions again.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['individual', 'automation'], + }, + { + icon: ZepIcon, + title: 'Zep + Slack team-context bot', + prompt: + 'Build a Slack bot that stores each conversation in Zep keyed by channel and user, retrieves the relevant prior context when someone asks a follow-up, and answers in thread with continuity across the whole team’s history.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication', 'automation'], + alsoIntegrations: ['slack'], + }, + ], + skills: [ + { + name: 'persist-conversation-turn', + description: + 'Record the latest user and agent messages into a Zep thread so memory builds over time.', + content: + '# Persist a Conversation Turn in Zep\n\nSave each exchange so the agent remembers it later.\n\n## Steps\n1. Ensure a user exists for the person, adding the user if this is their first interaction.\n2. Ensure a thread exists for this conversation, creating one if needed and tying it to the user.\n3. Add the latest messages to the thread, tagging roles as user or assistant.\n4. Confirm the messages were stored.\n\n## Output\nReturn the thread ID and user ID used, and confirm how many messages were added. These IDs are reused on the next turn.', + }, + { + name: 'recall-user-context', + description: + 'Fetch the assembled memory context for a Zep thread to ground the next agent response.', + content: + '# Recall User Context from Zep\n\nPull relevant long-term memory before the agent replies.\n\n## Steps\n1. Identify the thread for the current conversation, and the user behind it.\n2. Call get-context for the thread, choosing summary mode for natural language or basic mode for raw facts.\n3. Use the returned context block to inform the next response, since it spans all of this user prior threads.\n\n## Output\nReturn the context block as relevant facts and history about the user. Note the thread and user it was drawn from, and feed it into the agent prompt rather than echoing it to the user.', + }, + { + name: 'review-user-memory', + description: + 'List a user threads and messages in Zep to inspect what the agent remembers about them.', + content: + '# Review What Zep Remembers\n\nInspect the stored memory for a user.\n\n## Steps\n1. Get the user to confirm they exist and read their profile.\n2. Get the user threads to see every conversation tied to them.\n3. Get messages from a thread of interest to read the stored history.\n\n## Output\nReturn a summary of the user threads with counts and key facts surfaced, plus the messages from any thread inspected. Cite the user ID and thread IDs.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zep.ts b/apps/sim/blocks/blocks/zep.ts index 0376852d56a..4bdb5a3f447 100644 --- a/apps/sim/blocks/blocks/zep.ts +++ b/apps/sim/blocks/blocks/zep.ts @@ -1,6 +1,5 @@ -import { ZepIcon } from '@/components/icons' import { ZepBlockDisplay } from '@/blocks/blocks/zep.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ZepResponse } from '@/tools/zep/types' export const ZepBlock: BlockConfig = { @@ -292,99 +291,3 @@ export const ZepBlock: BlockConfig = { totalCount: { type: 'number', description: 'Total number of items returned' }, }, } - -export const ZepBlockMeta = { - tags: ['knowledge-base', 'agentic'], - url: 'https://www.getzep.com', - templates: [ - { - icon: ZepIcon, - title: 'Zep session memory for chat', - prompt: - 'Create a chat agent that stores every turn in Zep with user metadata, retrieves the most relevant prior context on each new question, and answers with continuity instead of forgetting.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - }, - { - icon: ZepIcon, - title: 'Zep + knowledge base support bot', - prompt: - 'Build a support agent that combines Zep session memory with a knowledge base, so it remembers what the customer has already tried while still grounding answers in product docs.', - modules: ['knowledge-base', 'agent', 'workflows'], - category: 'support', - tags: ['support', 'automation'], - }, - { - icon: ZepIcon, - title: 'Zep + Salesforce account memory', - prompt: - 'Build a workflow that for each Salesforce account writes meeting and email context into Zep keyed by account, so any future agent interaction has full history.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ZepIcon, - title: 'Zep + Intercom support continuity', - prompt: - 'Create a Zep-backed support agent for Intercom that remembers what each customer has tried before, prefers, or escalated, so support conversations never restart from scratch.', - modules: ['agent', 'workflows'], - category: 'support', - tags: ['support', 'communication'], - alsoIntegrations: ['intercom'], - }, - { - icon: ZepIcon, - title: 'Zep evaluation harness', - prompt: - 'Build a scheduled workflow that evaluates Zep memory recall accuracy weekly against a labeled eval set, captures regressions, and writes a quality report.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'engineering', - tags: ['engineering', 'analysis'], - }, - { - icon: ZepIcon, - title: 'Zep personal-assistant memory', - prompt: - 'Create a personal assistant agent that records preferences, recurring tasks, and prior decisions in Zep, then retrieves the relevant facts on each request so it stays consistent across days instead of asking the same questions again.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['individual', 'automation'], - }, - { - icon: ZepIcon, - title: 'Zep + Slack team-context bot', - prompt: - 'Build a Slack bot that stores each conversation in Zep keyed by channel and user, retrieves the relevant prior context when someone asks a follow-up, and answers in thread with continuity across the whole team’s history.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication', 'automation'], - alsoIntegrations: ['slack'], - }, - ], - skills: [ - { - name: 'persist-conversation-turn', - description: - 'Record the latest user and agent messages into a Zep thread so memory builds over time.', - content: - '# Persist a Conversation Turn in Zep\n\nSave each exchange so the agent remembers it later.\n\n## Steps\n1. Ensure a user exists for the person, adding the user if this is their first interaction.\n2. Ensure a thread exists for this conversation, creating one if needed and tying it to the user.\n3. Add the latest messages to the thread, tagging roles as user or assistant.\n4. Confirm the messages were stored.\n\n## Output\nReturn the thread ID and user ID used, and confirm how many messages were added. These IDs are reused on the next turn.', - }, - { - name: 'recall-user-context', - description: - 'Fetch the assembled memory context for a Zep thread to ground the next agent response.', - content: - '# Recall User Context from Zep\n\nPull relevant long-term memory before the agent replies.\n\n## Steps\n1. Identify the thread for the current conversation, and the user behind it.\n2. Call get-context for the thread, choosing summary mode for natural language or basic mode for raw facts.\n3. Use the returned context block to inform the next response, since it spans all of this user prior threads.\n\n## Output\nReturn the context block as relevant facts and history about the user. Note the thread and user it was drawn from, and feed it into the agent prompt rather than echoing it to the user.', - }, - { - name: 'review-user-memory', - description: - 'List a user threads and messages in Zep to inspect what the agent remembers about them.', - content: - '# Review What Zep Remembers\n\nInspect the stored memory for a user.\n\n## Steps\n1. Get the user to confirm they exist and read their profile.\n2. Get the user threads to see every conversation tied to them.\n3. Get messages from a thread of interest to read the stored history.\n\n## Output\nReturn a summary of the user threads with counts and key facts surfaced, plus the messages from any thread inspected. Cite the user ID and thread IDs.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zerobounce.display.ts b/apps/sim/blocks/blocks/zerobounce.display.ts index db0378f6c05..21b415ed152 100644 --- a/apps/sim/blocks/blocks/zerobounce.display.ts +++ b/apps/sim/blocks/blocks/zerobounce.display.ts @@ -1,6 +1,6 @@ import { ZeroBounceIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ZeroBounceBlockDisplay = { type: 'zerobounce', @@ -14,3 +14,8 @@ export const ZeroBounceBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/zerobounce', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const ZeroBounceBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.zerobounce.net', +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zerobounce.ts b/apps/sim/blocks/blocks/zerobounce.ts index edef766c224..b08faa159af 100644 --- a/apps/sim/blocks/blocks/zerobounce.ts +++ b/apps/sim/blocks/blocks/zerobounce.ts @@ -1,5 +1,5 @@ import { ZeroBounceBlockDisplay } from '@/blocks/blocks/zerobounce.display' -import { AuthMode, type BlockConfig, type BlockMeta } from '@/blocks/types' +import { AuthMode, type BlockConfig } from '@/blocks/types' import type { ZeroBounceResponse } from '@/tools/zerobounce/types' export const ZeroBounceBlock: BlockConfig = { @@ -87,8 +87,3 @@ export const ZeroBounceBlock: BlockConfig = { credits: { type: 'number', description: 'Remaining validation credits' }, }, } - -export const ZeroBounceBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.zerobounce.net', -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zoom.display.ts b/apps/sim/blocks/blocks/zoom.display.ts index 05624364a07..4553ce1c8db 100644 --- a/apps/sim/blocks/blocks/zoom.display.ts +++ b/apps/sim/blocks/blocks/zoom.display.ts @@ -1,6 +1,6 @@ import { ZoomIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ZoomBlockDisplay = { type: 'zoom', @@ -15,3 +15,103 @@ export const ZoomBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/zoom', integrationType: IntegrationType.Communication, } satisfies BlockDisplay + +export const ZoomBlockMeta = { + tags: ['meeting', 'calendar', 'scheduling'], + url: 'https://www.zoom.com', + templates: [ + { + icon: ZoomIcon, + title: 'Zoom recording recap', + prompt: + 'Build a workflow that runs after a Zoom meeting ends, pulls the cloud recording transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: ZoomIcon, + title: 'Zoom meeting prep brief', + prompt: + 'Create a scheduled workflow that runs each morning, lists today’s Zoom meetings, researches attendees with Apollo and the web, and emails a prep brief 30 minutes before each meeting.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'sales'], + alsoIntegrations: ['apollo', 'gmail'], + }, + { + icon: ZoomIcon, + title: 'Zoom webinar follow-up', + prompt: + 'Build a workflow that runs after a Zoom webinar, pulls the registrant and attendee lists, sends a follow-up email with the recording link, and writes attendance into HubSpot for marketing scoring.', + modules: ['agent', 'workflows'], + category: 'marketing', + tags: ['marketing', 'crm'], + alsoIntegrations: ['hubspot', 'gmail'], + }, + { + icon: ZoomIcon, + title: 'Zoom + Notion meeting notes', + prompt: + 'Create a workflow that watches for Zoom recordings, transcribes, and writes a structured meeting-notes page to Notion under the right team space, with action items linked to owners.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'content'], + alsoIntegrations: ['notion'], + }, + { + icon: ZoomIcon, + title: 'Zoom sales-call deal updater', + prompt: + 'Build a workflow that runs after a Zoom sales call, summarizes objections, next steps, and stage signals from the transcript, and updates the linked Salesforce or HubSpot opportunity.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce', 'hubspot'], + }, + { + icon: ZoomIcon, + title: 'Zoom recurring 1:1 logger', + prompt: + 'Create a workflow that captures Zoom 1:1 meeting recaps, appends them to a per-employee log file, and surfaces talking points for the next 1:1 to the manager in Slack.', + modules: ['agent', 'files', 'workflows'], + category: 'productivity', + tags: ['team', 'individual'], + alsoIntegrations: ['slack'], + }, + { + icon: ZoomIcon, + title: 'Zoom + Telegram recap pusher', + prompt: + 'Create a workflow that runs after a Zoom meeting, summarizes the transcript, and pushes the recap to a chosen Telegram channel for asynchronous review.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['team', 'communication'], + alsoIntegrations: ['telegram'], + }, + ], + skills: [ + { + name: 'schedule-meeting', + description: + 'Create a Zoom meeting with a topic, time, and settings, and return the join details.', + content: + '# Schedule a Zoom Meeting\n\nBook a meeting and capture its join link.\n\n## Steps\n1. Gather the host user ID, meeting topic, start time, duration, and timezone.\n2. Choose the meeting type, typically scheduled, and set options like recording and waiting room.\n3. Call the create-meeting operation.\n4. Capture the meeting ID, join URL, and passcode returned.\n\n## Output\nReturn the meeting ID, join URL, passcode, and start time. If you need formatted invite text, fetch the meeting invitation.', + }, + { + name: 'reschedule-meeting', + description: + 'Find a Zoom meeting and update its time, topic, or settings without recreating it.', + content: + '# Reschedule a Zoom Meeting\n\nMove or adjust an existing meeting.\n\n## Steps\n1. Locate the meeting by ID, or list meetings for the host and match on topic.\n2. Get the meeting to read its current settings.\n3. Call update-meeting with only the fields that change, such as start time or duration.\n4. Confirm the update and re-fetch the join details if they changed.\n\n## Output\nReport the meeting ID, the old and new time, and confirm the join URL is unchanged or updated. Note who should be re-notified.', + }, + { + name: 'fetch-meeting-recordings', + description: + 'Retrieve cloud recordings for a past Zoom meeting and return the download links.', + content: + '# Fetch Zoom Meeting Recordings\n\nCollect the recordings from a completed meeting.\n\n## Steps\n1. Identify the meeting ID, or use list-recordings to find recent recorded meetings.\n2. Call get-meeting-recordings for the chosen meeting.\n3. Collect the recording files, their types (video, audio, transcript), and download URLs.\n\n## Output\nReturn each recording file with its type, size, and download URL, plus the meeting topic and date. Note if no recordings exist for the meeting.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zoom.ts b/apps/sim/blocks/blocks/zoom.ts index e408496b774..2742d595d3e 100644 --- a/apps/sim/blocks/blocks/zoom.ts +++ b/apps/sim/blocks/blocks/zoom.ts @@ -1,7 +1,6 @@ -import { ZoomIcon } from '@/components/icons' import { getScopesForService } from '@/lib/oauth/utils' import { ZoomBlockDisplay } from '@/blocks/blocks/zoom.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ZoomResponse } from '@/tools/zoom/types' import { getTrigger } from '@/triggers' @@ -659,103 +658,3 @@ Return ONLY the date string - no explanations, no quotes, no extra text.`, pageInfo: { type: 'json', description: 'Pagination information' }, }, } - -export const ZoomBlockMeta = { - tags: ['meeting', 'calendar', 'scheduling'], - url: 'https://www.zoom.com', - templates: [ - { - icon: ZoomIcon, - title: 'Zoom recording recap', - prompt: - 'Build a workflow that runs after a Zoom meeting ends, pulls the cloud recording transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'reporting'], - alsoIntegrations: ['slack'], - }, - { - icon: ZoomIcon, - title: 'Zoom meeting prep brief', - prompt: - 'Create a scheduled workflow that runs each morning, lists today’s Zoom meetings, researches attendees with Apollo and the web, and emails a prep brief 30 minutes before each meeting.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'productivity', - tags: ['research', 'sales'], - alsoIntegrations: ['apollo', 'gmail'], - }, - { - icon: ZoomIcon, - title: 'Zoom webinar follow-up', - prompt: - 'Build a workflow that runs after a Zoom webinar, pulls the registrant and attendee lists, sends a follow-up email with the recording link, and writes attendance into HubSpot for marketing scoring.', - modules: ['agent', 'workflows'], - category: 'marketing', - tags: ['marketing', 'crm'], - alsoIntegrations: ['hubspot', 'gmail'], - }, - { - icon: ZoomIcon, - title: 'Zoom + Notion meeting notes', - prompt: - 'Create a workflow that watches for Zoom recordings, transcribes, and writes a structured meeting-notes page to Notion under the right team space, with action items linked to owners.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'content'], - alsoIntegrations: ['notion'], - }, - { - icon: ZoomIcon, - title: 'Zoom sales-call deal updater', - prompt: - 'Build a workflow that runs after a Zoom sales call, summarizes objections, next steps, and stage signals from the transcript, and updates the linked Salesforce or HubSpot opportunity.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce', 'hubspot'], - }, - { - icon: ZoomIcon, - title: 'Zoom recurring 1:1 logger', - prompt: - 'Create a workflow that captures Zoom 1:1 meeting recaps, appends them to a per-employee log file, and surfaces talking points for the next 1:1 to the manager in Slack.', - modules: ['agent', 'files', 'workflows'], - category: 'productivity', - tags: ['team', 'individual'], - alsoIntegrations: ['slack'], - }, - { - icon: ZoomIcon, - title: 'Zoom + Telegram recap pusher', - prompt: - 'Create a workflow that runs after a Zoom meeting, summarizes the transcript, and pushes the recap to a chosen Telegram channel for asynchronous review.', - modules: ['agent', 'workflows'], - category: 'productivity', - tags: ['team', 'communication'], - alsoIntegrations: ['telegram'], - }, - ], - skills: [ - { - name: 'schedule-meeting', - description: - 'Create a Zoom meeting with a topic, time, and settings, and return the join details.', - content: - '# Schedule a Zoom Meeting\n\nBook a meeting and capture its join link.\n\n## Steps\n1. Gather the host user ID, meeting topic, start time, duration, and timezone.\n2. Choose the meeting type, typically scheduled, and set options like recording and waiting room.\n3. Call the create-meeting operation.\n4. Capture the meeting ID, join URL, and passcode returned.\n\n## Output\nReturn the meeting ID, join URL, passcode, and start time. If you need formatted invite text, fetch the meeting invitation.', - }, - { - name: 'reschedule-meeting', - description: - 'Find a Zoom meeting and update its time, topic, or settings without recreating it.', - content: - '# Reschedule a Zoom Meeting\n\nMove or adjust an existing meeting.\n\n## Steps\n1. Locate the meeting by ID, or list meetings for the host and match on topic.\n2. Get the meeting to read its current settings.\n3. Call update-meeting with only the fields that change, such as start time or duration.\n4. Confirm the update and re-fetch the join details if they changed.\n\n## Output\nReport the meeting ID, the old and new time, and confirm the join URL is unchanged or updated. Note who should be re-notified.', - }, - { - name: 'fetch-meeting-recordings', - description: - 'Retrieve cloud recordings for a past Zoom meeting and return the download links.', - content: - '# Fetch Zoom Meeting Recordings\n\nCollect the recordings from a completed meeting.\n\n## Steps\n1. Identify the meeting ID, or use list-recordings to find recent recorded meetings.\n2. Call get-meeting-recordings for the chosen meeting.\n3. Collect the recording files, their types (video, audio, transcript), and download URLs.\n\n## Output\nReturn each recording file with its type, size, and download URL, plus the meeting topic and date. Note if no recordings exist for the meeting.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zoominfo.display.ts b/apps/sim/blocks/blocks/zoominfo.display.ts index cb67b3e8bea..66f122597f5 100644 --- a/apps/sim/blocks/blocks/zoominfo.display.ts +++ b/apps/sim/blocks/blocks/zoominfo.display.ts @@ -1,6 +1,6 @@ import { ZoomInfoIcon } from '@/components/icons' import type { BlockDisplay } from '@/blocks/manifest' -import { IntegrationType } from '@/blocks/types' +import { type BlockMeta, IntegrationType } from '@/blocks/types' export const ZoomInfoBlockDisplay = { type: 'zoominfo', @@ -14,3 +14,106 @@ export const ZoomInfoBlockDisplay = { docsLink: 'https://docs.sim.ai/integrations/zoominfo', integrationType: IntegrationType.Sales, } satisfies BlockDisplay + +export const ZoomInfoBlockMeta = { + tags: ['enrichment', 'sales-engagement'], + url: 'https://www.zoominfo.com', + templates: [ + { + icon: ZoomInfoIcon, + title: 'ZoomInfo contact enricher', + prompt: + 'Build a workflow that watches CRM contacts, enriches each via ZoomInfo with title, seniority, and verified contact details, and writes the enriched data back.', + modules: ['agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm', 'research'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo account builder', + prompt: + 'Create a workflow that runs a ZoomInfo company search against my ICP filters, enriches each match with firmographics, and writes the target account list into a tables-based research base.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo intent monitor', + prompt: + 'Build a scheduled workflow that pulls ZoomInfo intent signals for tracked accounts, ranks accounts surging on relevant topics, and posts a daily Slack alert for the sales team.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'monitoring'], + alsoIntegrations: ['slack'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo news digest', + prompt: + 'Create a scheduled weekly workflow that searches ZoomInfo news for tracked accounts, summarizes notable events with an agent, and writes a per-account briefing for the sales team.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo CRM gap-filler', + prompt: + 'Build a scheduled workflow that finds Salesforce contacts missing firmographic or contact fields, runs ZoomInfo enrichment to fill the gaps, and writes coverage metrics to a hygiene table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'crm'], + alsoIntegrations: ['salesforce'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo buying-committee builder', + prompt: + 'Build a workflow that takes a target account, runs a ZoomInfo contact search to find the decision-makers by title and department, enriches each with verified email and phone, and writes the mapped buying committee into a sales table for outreach.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['sales', 'research', 'enrichment'], + }, + { + icon: ZoomInfoIcon, + title: 'ZoomInfo account briefing pack', + prompt: + 'Create a workflow that takes an upcoming meeting account, pulls ZoomInfo company firmographics, recent intent signals, and the latest news for that company, and assembles a one-page pre-meeting briefing document the rep reads before the call.', + modules: ['agent', 'files', 'workflows'], + category: 'sales', + tags: ['sales', 'research'], + }, + ], + skills: [ + { + name: 'enrich-contact', + description: + 'Enrich a known person with ZoomInfo to fill in verified title, email, and company data.', + content: + '# Enrich a Contact with ZoomInfo\n\nFill in verified detail for a known person.\n\n## Steps\n1. Gather the identifiers you have, such as name and company, email, or a profile URL.\n2. Call the enrich-contacts operation.\n3. Extract the returned fields: verified email, direct phone, title, seniority, and company.\n\n## Output\nReturn the enriched contact as structured fields with a match-confidence note. If no match was found, report the input used rather than fabricating values.', + }, + { + name: 'build-target-account-list', + description: + 'Search ZoomInfo companies by firmographic filters to build a list of target accounts.', + content: + '# Build a Target Account List with ZoomInfo\n\nAssemble accounts that fit the ideal-customer profile.\n\n## Steps\n1. Translate the profile into company filters: industry, revenue band, employee size, and location.\n2. Call search-companies with those filters and a result limit, choosing a sort order.\n3. For top accounts, optionally enrich-companies to pull full firmographics.\n\n## Output\nReturn the matched accounts with company name, domain, industry, size, and revenue band. State the filters used and the total match count.', + }, + { + name: 'find-decision-makers', + description: + 'Search ZoomInfo contacts at a target company by title and seniority to find decision makers.', + content: + '# Find Decision Makers with ZoomInfo\n\nLocate the right people inside a target account.\n\n## Steps\n1. Identify the company, then set contact filters for title, department, and seniority.\n2. Call search-contacts scoped to that company.\n3. Enrich the chosen contacts to retrieve verified email and phone.\n\n## Output\nReturn the decision makers with name, title, seniority, and verified contact details. Group by department and note which contacts have verified direct dials.', + }, + { + name: 'compile-account-briefing', + description: + 'Combine ZoomInfo firmographics, intent signals, and news into a pre-meeting account brief.', + content: + '# Compile a ZoomInfo Account Briefing\n\nProduce a one-page brief before an account meeting.\n\n## Steps\n1. Enrich the company to pull firmographics: size, revenue, industry, and location.\n2. Search intent signals for the account to see what topics they are researching.\n3. Search news for recent company developments.\n4. Synthesize these into a concise briefing.\n\n## Output\nReturn a brief with company snapshot, top intent topics, recent news headlines, and two or three suggested talking points. Cite the company referenced.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/zoominfo.ts b/apps/sim/blocks/blocks/zoominfo.ts index 7d6e756297d..81b90cfafe8 100644 --- a/apps/sim/blocks/blocks/zoominfo.ts +++ b/apps/sim/blocks/blocks/zoominfo.ts @@ -1,6 +1,5 @@ -import { ZoomInfoIcon } from '@/components/icons' import { ZoomInfoBlockDisplay } from '@/blocks/blocks/zoominfo.display' -import type { BlockConfig, BlockMeta } from '@/blocks/types' +import type { BlockConfig } from '@/blocks/types' import { AuthMode } from '@/blocks/types' import type { ZoomInfoResponse } from '@/tools/zoominfo/types' @@ -543,106 +542,3 @@ export const ZoomInfoBlock: BlockConfig = { totalPages: { type: 'number', description: 'Total number of pages available' }, }, } - -export const ZoomInfoBlockMeta = { - tags: ['enrichment', 'sales-engagement'], - url: 'https://www.zoominfo.com', - templates: [ - { - icon: ZoomInfoIcon, - title: 'ZoomInfo contact enricher', - prompt: - 'Build a workflow that watches CRM contacts, enriches each via ZoomInfo with title, seniority, and verified contact details, and writes the enriched data back.', - modules: ['agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm', 'research'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo account builder', - prompt: - 'Create a workflow that runs a ZoomInfo company search against my ICP filters, enriches each match with firmographics, and writes the target account list into a tables-based research base.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo intent monitor', - prompt: - 'Build a scheduled workflow that pulls ZoomInfo intent signals for tracked accounts, ranks accounts surging on relevant topics, and posts a daily Slack alert for the sales team.', - modules: ['scheduled', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'monitoring'], - alsoIntegrations: ['slack'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo news digest', - prompt: - 'Create a scheduled weekly workflow that searches ZoomInfo news for tracked accounts, summarizes notable events with an agent, and writes a per-account briefing for the sales team.', - modules: ['scheduled', 'agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo CRM gap-filler', - prompt: - 'Build a scheduled workflow that finds Salesforce contacts missing firmographic or contact fields, runs ZoomInfo enrichment to fill the gaps, and writes coverage metrics to a hygiene table.', - modules: ['scheduled', 'tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'crm'], - alsoIntegrations: ['salesforce'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo buying-committee builder', - prompt: - 'Build a workflow that takes a target account, runs a ZoomInfo contact search to find the decision-makers by title and department, enriches each with verified email and phone, and writes the mapped buying committee into a sales table for outreach.', - modules: ['tables', 'agent', 'workflows'], - category: 'sales', - tags: ['sales', 'research', 'enrichment'], - }, - { - icon: ZoomInfoIcon, - title: 'ZoomInfo account briefing pack', - prompt: - 'Create a workflow that takes an upcoming meeting account, pulls ZoomInfo company firmographics, recent intent signals, and the latest news for that company, and assembles a one-page pre-meeting briefing document the rep reads before the call.', - modules: ['agent', 'files', 'workflows'], - category: 'sales', - tags: ['sales', 'research'], - }, - ], - skills: [ - { - name: 'enrich-contact', - description: - 'Enrich a known person with ZoomInfo to fill in verified title, email, and company data.', - content: - '# Enrich a Contact with ZoomInfo\n\nFill in verified detail for a known person.\n\n## Steps\n1. Gather the identifiers you have, such as name and company, email, or a profile URL.\n2. Call the enrich-contacts operation.\n3. Extract the returned fields: verified email, direct phone, title, seniority, and company.\n\n## Output\nReturn the enriched contact as structured fields with a match-confidence note. If no match was found, report the input used rather than fabricating values.', - }, - { - name: 'build-target-account-list', - description: - 'Search ZoomInfo companies by firmographic filters to build a list of target accounts.', - content: - '# Build a Target Account List with ZoomInfo\n\nAssemble accounts that fit the ideal-customer profile.\n\n## Steps\n1. Translate the profile into company filters: industry, revenue band, employee size, and location.\n2. Call search-companies with those filters and a result limit, choosing a sort order.\n3. For top accounts, optionally enrich-companies to pull full firmographics.\n\n## Output\nReturn the matched accounts with company name, domain, industry, size, and revenue band. State the filters used and the total match count.', - }, - { - name: 'find-decision-makers', - description: - 'Search ZoomInfo contacts at a target company by title and seniority to find decision makers.', - content: - '# Find Decision Makers with ZoomInfo\n\nLocate the right people inside a target account.\n\n## Steps\n1. Identify the company, then set contact filters for title, department, and seniority.\n2. Call search-contacts scoped to that company.\n3. Enrich the chosen contacts to retrieve verified email and phone.\n\n## Output\nReturn the decision makers with name, title, seniority, and verified contact details. Group by department and note which contacts have verified direct dials.', - }, - { - name: 'compile-account-briefing', - description: - 'Combine ZoomInfo firmographics, intent signals, and news into a pre-meeting account brief.', - content: - '# Compile a ZoomInfo Account Briefing\n\nProduce a one-page brief before an account meeting.\n\n## Steps\n1. Enrich the company to pull firmographics: size, revenue, industry, and location.\n2. Search intent signals for the account to see what topics they are researching.\n3. Search news for recent company developments.\n4. Synthesize these into a concise briefing.\n\n## Output\nReturn a brief with company snapshot, top intent topics, recent news headlines, and two or three suggested talking points. Cite the company referenced.', - }, - ], -} as const satisfies BlockMeta diff --git a/apps/sim/blocks/manifest-data.ts b/apps/sim/blocks/manifest-data.ts index 790d6382c70..6ce934fd840 100644 --- a/apps/sim/blocks/manifest-data.ts +++ b/apps/sim/blocks/manifest-data.ts @@ -2,77 +2,95 @@ // Source of truth is each blocks/blocks/.display.ts. Run `bun run blocks:manifest-data`. import { A2ABlockDisplay } from '@/blocks/blocks/a2a.display' import { AgentBlockDisplay } from '@/blocks/blocks/agent.display' -import { AgentMailBlockDisplay } from '@/blocks/blocks/agentmail.display' -import { AgentPhoneBlockDisplay } from '@/blocks/blocks/agentphone.display' -import { AgiloftBlockDisplay } from '@/blocks/blocks/agiloft.display' -import { AhrefsBlockDisplay } from '@/blocks/blocks/ahrefs.display' -import { AirtableBlockDisplay } from '@/blocks/blocks/airtable.display' -import { AirweaveBlockDisplay } from '@/blocks/blocks/airweave.display' -import { AlgoliaBlockDisplay } from '@/blocks/blocks/algolia.display' -import { AmplitudeBlockDisplay } from '@/blocks/blocks/amplitude.display' +import { AgentMailBlockDisplay, AgentMailBlockMeta } from '@/blocks/blocks/agentmail.display' +import { AgentPhoneBlockDisplay, AgentPhoneBlockMeta } from '@/blocks/blocks/agentphone.display' +import { AgiloftBlockDisplay, AgiloftBlockMeta } from '@/blocks/blocks/agiloft.display' +import { AhrefsBlockDisplay, AhrefsBlockMeta } from '@/blocks/blocks/ahrefs.display' +import { AirtableBlockDisplay, AirtableBlockMeta } from '@/blocks/blocks/airtable.display' +import { AirweaveBlockDisplay, AirweaveBlockMeta } from '@/blocks/blocks/airweave.display' +import { AlgoliaBlockDisplay, AlgoliaBlockMeta } from '@/blocks/blocks/algolia.display' +import { AmplitudeBlockDisplay, AmplitudeBlockMeta } from '@/blocks/blocks/amplitude.display' import { ApiBlockDisplay } from '@/blocks/blocks/api.display' import { ApiTriggerBlockDisplay } from '@/blocks/blocks/api_trigger.display' -import { ApifyBlockDisplay } from '@/blocks/blocks/apify.display' -import { ApolloBlockDisplay } from '@/blocks/blocks/apollo.display' -import { AppConfigBlockDisplay } from '@/blocks/blocks/appconfig.display' -import { ArxivBlockDisplay } from '@/blocks/blocks/arxiv.display' -import { AsanaBlockDisplay } from '@/blocks/blocks/asana.display' -import { AshbyBlockDisplay } from '@/blocks/blocks/ashby.display' -import { AthenaBlockDisplay } from '@/blocks/blocks/athena.display' -import { AttioBlockDisplay } from '@/blocks/blocks/attio.display' -import { AzureDevOpsBlockDisplay } from '@/blocks/blocks/azure_devops.display' -import { BoxBlockDisplay } from '@/blocks/blocks/box.display' -import { BrandfetchBlockDisplay } from '@/blocks/blocks/brandfetch.display' -import { BrexBlockDisplay } from '@/blocks/blocks/brex.display' -import { BrightDataBlockDisplay } from '@/blocks/blocks/brightdata.display' -import { BrowserUseBlockDisplay } from '@/blocks/blocks/browser_use.display' -import { CalComBlockDisplay } from '@/blocks/blocks/calcom.display' -import { CalendlyBlockDisplay } from '@/blocks/blocks/calendly.display' +import { ApifyBlockDisplay, ApifyBlockMeta } from '@/blocks/blocks/apify.display' +import { ApolloBlockDisplay, ApolloBlockMeta } from '@/blocks/blocks/apollo.display' +import { AppConfigBlockDisplay, AppConfigBlockMeta } from '@/blocks/blocks/appconfig.display' +import { ArxivBlockDisplay, ArxivBlockMeta } from '@/blocks/blocks/arxiv.display' +import { AsanaBlockDisplay, AsanaBlockMeta } from '@/blocks/blocks/asana.display' +import { AshbyBlockDisplay, AshbyBlockMeta } from '@/blocks/blocks/ashby.display' +import { AthenaBlockDisplay, AthenaBlockMeta } from '@/blocks/blocks/athena.display' +import { AttioBlockDisplay, AttioBlockMeta } from '@/blocks/blocks/attio.display' +import { AzureDevOpsBlockDisplay, AzureDevOpsBlockMeta } from '@/blocks/blocks/azure_devops.display' +import { BoxBlockDisplay, BoxBlockMeta } from '@/blocks/blocks/box.display' +import { BrandfetchBlockDisplay, BrandfetchBlockMeta } from '@/blocks/blocks/brandfetch.display' +import { BrexBlockDisplay, BrexBlockMeta } from '@/blocks/blocks/brex.display' +import { BrightDataBlockDisplay, BrightDataBlockMeta } from '@/blocks/blocks/brightdata.display' +import { BrowserUseBlockDisplay, BrowserUseBlockMeta } from '@/blocks/blocks/browser_use.display' +import { CalComBlockDisplay, CalComBlockMeta } from '@/blocks/blocks/calcom.display' +import { CalendlyBlockDisplay, CalendlyBlockMeta } from '@/blocks/blocks/calendly.display' import { ChatTriggerBlockDisplay } from '@/blocks/blocks/chat_trigger.display' -import { CirclebackBlockDisplay } from '@/blocks/blocks/circleback.display' -import { ClayBlockDisplay } from '@/blocks/blocks/clay.display' -import { ClerkBlockDisplay } from '@/blocks/blocks/clerk.display' -import { ClickHouseBlockDisplay } from '@/blocks/blocks/clickhouse.display' -import { CloudflareBlockDisplay } from '@/blocks/blocks/cloudflare.display' -import { CloudFormationBlockDisplay } from '@/blocks/blocks/cloudformation.display' -import { CloudWatchBlockDisplay } from '@/blocks/blocks/cloudwatch.display' -import { CodePipelineBlockDisplay } from '@/blocks/blocks/codepipeline.display' +import { CirclebackBlockDisplay, CirclebackBlockMeta } from '@/blocks/blocks/circleback.display' +import { ClayBlockDisplay, ClayBlockMeta } from '@/blocks/blocks/clay.display' +import { ClerkBlockDisplay, ClerkBlockMeta } from '@/blocks/blocks/clerk.display' +import { ClickHouseBlockDisplay, ClickHouseBlockMeta } from '@/blocks/blocks/clickhouse.display' +import { CloudflareBlockDisplay, CloudflareBlockMeta } from '@/blocks/blocks/cloudflare.display' +import { + CloudFormationBlockDisplay, + CloudFormationBlockMeta, +} from '@/blocks/blocks/cloudformation.display' +import { CloudWatchBlockDisplay, CloudWatchBlockMeta } from '@/blocks/blocks/cloudwatch.display' +import { + CodePipelineBlockDisplay, + CodePipelineBlockMeta, +} from '@/blocks/blocks/codepipeline.display' import { ConditionBlockDisplay } from '@/blocks/blocks/condition.display' import { ConfluenceBlockDisplay, + ConfluenceBlockMeta, ConfluenceV2BlockDisplay, } from '@/blocks/blocks/confluence.display' -import { ContextDevBlockDisplay } from '@/blocks/blocks/context_dev.display' -import { ConvexBlockDisplay } from '@/blocks/blocks/convex.display' +import { ContextDevBlockDisplay, ContextDevBlockMeta } from '@/blocks/blocks/context_dev.display' +import { ConvexBlockDisplay, ConvexBlockMeta } from '@/blocks/blocks/convex.display' import { CredentialBlockDisplay } from '@/blocks/blocks/credential.display' -import { CrowdStrikeBlockDisplay } from '@/blocks/blocks/crowdstrike.display' -import { CursorBlockDisplay, CursorV2BlockDisplay } from '@/blocks/blocks/cursor.display' -import { DagsterBlockDisplay } from '@/blocks/blocks/dagster.display' -import { DatabricksBlockDisplay } from '@/blocks/blocks/databricks.display' -import { DatadogBlockDisplay } from '@/blocks/blocks/datadog.display' -import { DatagmaBlockDisplay } from '@/blocks/blocks/datagma.display' -import { DaytonaBlockDisplay } from '@/blocks/blocks/daytona.display' +import { CrowdStrikeBlockDisplay, CrowdStrikeBlockMeta } from '@/blocks/blocks/crowdstrike.display' +import { + CursorBlockDisplay, + CursorBlockMeta, + CursorV2BlockDisplay, +} from '@/blocks/blocks/cursor.display' +import { DagsterBlockDisplay, DagsterBlockMeta } from '@/blocks/blocks/dagster.display' +import { DatabricksBlockDisplay, DatabricksBlockMeta } from '@/blocks/blocks/databricks.display' +import { DatadogBlockDisplay, DatadogBlockMeta } from '@/blocks/blocks/datadog.display' +import { DatagmaBlockDisplay, DatagmaBlockMeta } from '@/blocks/blocks/datagma.display' +import { DaytonaBlockDisplay, DaytonaBlockMeta } from '@/blocks/blocks/daytona.display' import { DeploymentsBlockDisplay } from '@/blocks/blocks/deployments.display' -import { DevinBlockDisplay } from '@/blocks/blocks/devin.display' -import { DiscordBlockDisplay } from '@/blocks/blocks/discord.display' -import { DocuSignBlockDisplay } from '@/blocks/blocks/docusign.display' -import { DropboxBlockDisplay } from '@/blocks/blocks/dropbox.display' -import { DropcontactBlockDisplay } from '@/blocks/blocks/dropcontact.display' -import { DSPyBlockDisplay } from '@/blocks/blocks/dspy.display' -import { DubBlockDisplay } from '@/blocks/blocks/dub.display' -import { DuckDuckGoBlockDisplay } from '@/blocks/blocks/duckduckgo.display' -import { DynamoDBBlockDisplay } from '@/blocks/blocks/dynamodb.display' -import { ElasticsearchBlockDisplay } from '@/blocks/blocks/elasticsearch.display' -import { ElevenLabsBlockDisplay } from '@/blocks/blocks/elevenlabs.display' -import { EmailBisonBlockDisplay } from '@/blocks/blocks/emailbison.display' -import { EnrichBlockDisplay } from '@/blocks/blocks/enrich.display' -import { EnrichmentBlockDisplay } from '@/blocks/blocks/enrichment.display' -import { EnrowBlockDisplay } from '@/blocks/blocks/enrow.display' +import { DevinBlockDisplay, DevinBlockMeta } from '@/blocks/blocks/devin.display' +import { DiscordBlockDisplay, DiscordBlockMeta } from '@/blocks/blocks/discord.display' +import { DocuSignBlockDisplay, DocuSignBlockMeta } from '@/blocks/blocks/docusign.display' +import { DropboxBlockDisplay, DropboxBlockMeta } from '@/blocks/blocks/dropbox.display' +import { DropcontactBlockDisplay, DropcontactBlockMeta } from '@/blocks/blocks/dropcontact.display' +import { DSPyBlockDisplay, DSPyBlockMeta } from '@/blocks/blocks/dspy.display' +import { DubBlockDisplay, DubBlockMeta } from '@/blocks/blocks/dub.display' +import { DuckDuckGoBlockDisplay, DuckDuckGoBlockMeta } from '@/blocks/blocks/duckduckgo.display' +import { DynamoDBBlockDisplay, DynamoDBBlockMeta } from '@/blocks/blocks/dynamodb.display' +import { + ElasticsearchBlockDisplay, + ElasticsearchBlockMeta, +} from '@/blocks/blocks/elasticsearch.display' +import { ElevenLabsBlockDisplay, ElevenLabsBlockMeta } from '@/blocks/blocks/elevenlabs.display' +import { EmailBisonBlockDisplay, EmailBisonBlockMeta } from '@/blocks/blocks/emailbison.display' +import { EnrichBlockDisplay, EnrichBlockMeta } from '@/blocks/blocks/enrich.display' +import { EnrichmentBlockDisplay, EnrichmentBlockMeta } from '@/blocks/blocks/enrichment.display' +import { EnrowBlockDisplay, EnrowBlockMeta } from '@/blocks/blocks/enrow.display' import { EvaluatorBlockDisplay } from '@/blocks/blocks/evaluator.display' -import { EvernoteBlockDisplay } from '@/blocks/blocks/evernote.display' -import { ExaBlockDisplay } from '@/blocks/blocks/exa.display' -import { ExtendBlockDisplay, ExtendV2BlockDisplay } from '@/blocks/blocks/extend.display' -import { FathomBlockDisplay } from '@/blocks/blocks/fathom.display' +import { EvernoteBlockDisplay, EvernoteBlockMeta } from '@/blocks/blocks/evernote.display' +import { ExaBlockDisplay, ExaBlockMeta } from '@/blocks/blocks/exa.display' +import { + ExtendBlockDisplay, + ExtendBlockMeta, + ExtendV2BlockDisplay, +} from '@/blocks/blocks/extend.display' +import { FathomBlockDisplay, FathomBlockMeta } from '@/blocks/blocks/fathom.display' import { FileBlockDisplay, FileV2BlockDisplay, @@ -80,206 +98,304 @@ import { FileV4BlockDisplay, FileV5BlockDisplay, } from '@/blocks/blocks/file.display' -import { FindymailBlockDisplay } from '@/blocks/blocks/findymail.display' -import { FirecrawlBlockDisplay } from '@/blocks/blocks/firecrawl.display' -import { FirefliesBlockDisplay, FirefliesV2BlockDisplay } from '@/blocks/blocks/fireflies.display' +import { FindymailBlockDisplay, FindymailBlockMeta } from '@/blocks/blocks/findymail.display' +import { FirecrawlBlockDisplay, FirecrawlBlockMeta } from '@/blocks/blocks/firecrawl.display' +import { + FirefliesBlockDisplay, + FirefliesBlockMeta, + FirefliesV2BlockDisplay, + FirefliesV2BlockMeta, +} from '@/blocks/blocks/fireflies.display' import { FunctionBlockDisplay } from '@/blocks/blocks/function.display' -import { GammaBlockDisplay } from '@/blocks/blocks/gamma.display' +import { GammaBlockDisplay, GammaBlockMeta } from '@/blocks/blocks/gamma.display' import { GenericWebhookBlockDisplay } from '@/blocks/blocks/generic_webhook.display' -import { GitHubBlockDisplay, GitHubV2BlockDisplay } from '@/blocks/blocks/github.display' -import { GitLabBlockDisplay } from '@/blocks/blocks/gitlab.display' -import { GmailBlockDisplay, GmailV2BlockDisplay } from '@/blocks/blocks/gmail.display' -import { GongBlockDisplay } from '@/blocks/blocks/gong.display' -import { GoogleSearchBlockDisplay } from '@/blocks/blocks/google.display' -import { GoogleAdsBlockDisplay } from '@/blocks/blocks/google_ads.display' -import { GoogleBigQueryBlockDisplay } from '@/blocks/blocks/google_bigquery.display' -import { GoogleBooksBlockDisplay } from '@/blocks/blocks/google_books.display' +import { + GitHubBlockDisplay, + GitHubBlockMeta, + GitHubV2BlockDisplay, + GitHubV2BlockMeta, +} from '@/blocks/blocks/github.display' +import { GitLabBlockDisplay, GitLabBlockMeta } from '@/blocks/blocks/gitlab.display' +import { + GmailBlockDisplay, + GmailBlockMeta, + GmailV2BlockDisplay, + GmailV2BlockMeta, +} from '@/blocks/blocks/gmail.display' +import { GongBlockDisplay, GongBlockMeta } from '@/blocks/blocks/gong.display' +import { GoogleSearchBlockDisplay, GoogleSearchBlockMeta } from '@/blocks/blocks/google.display' +import { GoogleAdsBlockDisplay, GoogleAdsBlockMeta } from '@/blocks/blocks/google_ads.display' +import { + GoogleBigQueryBlockDisplay, + GoogleBigQueryBlockMeta, +} from '@/blocks/blocks/google_bigquery.display' +import { GoogleBooksBlockDisplay, GoogleBooksBlockMeta } from '@/blocks/blocks/google_books.display' import { GoogleCalendarBlockDisplay, + GoogleCalendarBlockMeta, GoogleCalendarV2BlockDisplay, + GoogleCalendarV2BlockMeta, } from '@/blocks/blocks/google_calendar.display' -import { GoogleContactsBlockDisplay } from '@/blocks/blocks/google_contacts.display' -import { GoogleDocsBlockDisplay } from '@/blocks/blocks/google_docs.display' -import { GoogleDriveBlockDisplay } from '@/blocks/blocks/google_drive.display' -import { GoogleFormsBlockDisplay } from '@/blocks/blocks/google_forms.display' -import { GoogleGroupsBlockDisplay } from '@/blocks/blocks/google_groups.display' -import { GoogleMapsBlockDisplay } from '@/blocks/blocks/google_maps.display' -import { GoogleMeetBlockDisplay } from '@/blocks/blocks/google_meet.display' -import { GooglePagespeedBlockDisplay } from '@/blocks/blocks/google_pagespeed.display' +import { + GoogleContactsBlockDisplay, + GoogleContactsBlockMeta, +} from '@/blocks/blocks/google_contacts.display' +import { GoogleDocsBlockDisplay, GoogleDocsBlockMeta } from '@/blocks/blocks/google_docs.display' +import { GoogleDriveBlockDisplay, GoogleDriveBlockMeta } from '@/blocks/blocks/google_drive.display' +import { GoogleFormsBlockDisplay, GoogleFormsBlockMeta } from '@/blocks/blocks/google_forms.display' +import { + GoogleGroupsBlockDisplay, + GoogleGroupsBlockMeta, +} from '@/blocks/blocks/google_groups.display' +import { GoogleMapsBlockDisplay, GoogleMapsBlockMeta } from '@/blocks/blocks/google_maps.display' +import { GoogleMeetBlockDisplay, GoogleMeetBlockMeta } from '@/blocks/blocks/google_meet.display' +import { + GooglePagespeedBlockDisplay, + GooglePagespeedBlockMeta, +} from '@/blocks/blocks/google_pagespeed.display' import { GoogleSheetsBlockDisplay, + GoogleSheetsBlockMeta, GoogleSheetsV2BlockDisplay, + GoogleSheetsV2BlockMeta, } from '@/blocks/blocks/google_sheets.display' import { GoogleSlidesBlockDisplay, + GoogleSlidesBlockMeta, GoogleSlidesV2BlockDisplay, + GoogleSlidesV2BlockMeta, } from '@/blocks/blocks/google_slides.display' -import { GoogleTasksBlockDisplay } from '@/blocks/blocks/google_tasks.display' -import { GoogleTranslateBlockDisplay } from '@/blocks/blocks/google_translate.display' -import { GoogleVaultBlockDisplay } from '@/blocks/blocks/google_vault.display' -import { GrafanaBlockDisplay } from '@/blocks/blocks/grafana.display' -import { GrainBlockDisplay } from '@/blocks/blocks/grain.display' -import { GranolaBlockDisplay } from '@/blocks/blocks/granola.display' -import { GreenhouseBlockDisplay } from '@/blocks/blocks/greenhouse.display' -import { GreptileBlockDisplay } from '@/blocks/blocks/greptile.display' +import { GoogleTasksBlockDisplay, GoogleTasksBlockMeta } from '@/blocks/blocks/google_tasks.display' +import { + GoogleTranslateBlockDisplay, + GoogleTranslateBlockMeta, +} from '@/blocks/blocks/google_translate.display' +import { GoogleVaultBlockDisplay, GoogleVaultBlockMeta } from '@/blocks/blocks/google_vault.display' +import { GrafanaBlockDisplay, GrafanaBlockMeta } from '@/blocks/blocks/grafana.display' +import { GrainBlockDisplay, GrainBlockMeta } from '@/blocks/blocks/grain.display' +import { GranolaBlockDisplay, GranolaBlockMeta } from '@/blocks/blocks/granola.display' +import { GreenhouseBlockDisplay, GreenhouseBlockMeta } from '@/blocks/blocks/greenhouse.display' +import { GreptileBlockDisplay, GreptileBlockMeta } from '@/blocks/blocks/greptile.display' import { GuardrailsBlockDisplay } from '@/blocks/blocks/guardrails.display' -import { HexBlockDisplay } from '@/blocks/blocks/hex.display' -import { HubSpotBlockDisplay } from '@/blocks/blocks/hubspot.display' -import { HuggingFaceBlockDisplay } from '@/blocks/blocks/huggingface.display' +import { HexBlockDisplay, HexBlockMeta } from '@/blocks/blocks/hex.display' +import { HubSpotBlockDisplay, HubSpotBlockMeta } from '@/blocks/blocks/hubspot.display' +import { HuggingFaceBlockDisplay, HuggingFaceBlockMeta } from '@/blocks/blocks/huggingface.display' import { HumanInTheLoopBlockDisplay } from '@/blocks/blocks/human_in_the_loop.display' -import { HunterBlockDisplay } from '@/blocks/blocks/hunter.display' -import { IAMBlockDisplay } from '@/blocks/blocks/iam.display' -import { IcypeasBlockDisplay } from '@/blocks/blocks/icypeas.display' -import { IdentityCenterBlockDisplay } from '@/blocks/blocks/identity_center.display' +import { HunterBlockDisplay, HunterBlockMeta } from '@/blocks/blocks/hunter.display' +import { IAMBlockDisplay, IAMBlockMeta } from '@/blocks/blocks/iam.display' +import { IcypeasBlockDisplay, IcypeasBlockMeta } from '@/blocks/blocks/icypeas.display' +import { + IdentityCenterBlockDisplay, + IdentityCenterBlockMeta, +} from '@/blocks/blocks/identity_center.display' import { ImageGeneratorBlockDisplay, ImageGeneratorV2BlockDisplay, } from '@/blocks/blocks/image_generator.display' -import { ImapBlockDisplay } from '@/blocks/blocks/imap.display' -import { IncidentioBlockDisplay } from '@/blocks/blocks/incidentio.display' -import { InfisicalBlockDisplay } from '@/blocks/blocks/infisical.display' +import { ImapBlockDisplay, ImapBlockMeta } from '@/blocks/blocks/imap.display' +import { IncidentioBlockDisplay, IncidentioBlockMeta } from '@/blocks/blocks/incidentio.display' +import { InfisicalBlockDisplay, InfisicalBlockMeta } from '@/blocks/blocks/infisical.display' import { InputTriggerBlockDisplay } from '@/blocks/blocks/input_trigger.display' -import { InstantlyBlockDisplay } from '@/blocks/blocks/instantly.display' -import { IntercomBlockDisplay, IntercomV2BlockDisplay } from '@/blocks/blocks/intercom.display' -import { JinaBlockDisplay } from '@/blocks/blocks/jina.display' -import { JiraBlockDisplay } from '@/blocks/blocks/jira.display' -import { JiraServiceManagementBlockDisplay } from '@/blocks/blocks/jira_service_management.display' -import { KalshiBlockDisplay, KalshiV2BlockDisplay } from '@/blocks/blocks/kalshi.display' -import { KetchBlockDisplay } from '@/blocks/blocks/ketch.display' +import { InstantlyBlockDisplay, InstantlyBlockMeta } from '@/blocks/blocks/instantly.display' +import { + IntercomBlockDisplay, + IntercomBlockMeta, + IntercomV2BlockDisplay, + IntercomV2BlockMeta, +} from '@/blocks/blocks/intercom.display' +import { JinaBlockDisplay, JinaBlockMeta } from '@/blocks/blocks/jina.display' +import { JiraBlockDisplay, JiraBlockMeta } from '@/blocks/blocks/jira.display' +import { + JiraServiceManagementBlockDisplay, + JiraServiceManagementBlockMeta, +} from '@/blocks/blocks/jira_service_management.display' +import { + KalshiBlockDisplay, + KalshiBlockMeta, + KalshiV2BlockDisplay, + KalshiV2BlockMeta, +} from '@/blocks/blocks/kalshi.display' +import { KetchBlockDisplay, KetchBlockMeta } from '@/blocks/blocks/ketch.display' import { KnowledgeBlockDisplay } from '@/blocks/blocks/knowledge.display' -import { LangsmithBlockDisplay } from '@/blocks/blocks/langsmith.display' -import { LatexBlockDisplay } from '@/blocks/blocks/latex.display' -import { LaunchDarklyBlockDisplay } from '@/blocks/blocks/launchdarkly.display' -import { LeadMagicBlockDisplay } from '@/blocks/blocks/leadmagic.display' -import { LemlistBlockDisplay } from '@/blocks/blocks/lemlist.display' -import { LinearBlockDisplay, LinearV2BlockDisplay } from '@/blocks/blocks/linear.display' -import { LinkedInBlockDisplay } from '@/blocks/blocks/linkedin.display' -import { LinkupBlockDisplay } from '@/blocks/blocks/linkup.display' -import { LinqBlockDisplay } from '@/blocks/blocks/linq.display' +import { LangsmithBlockDisplay, LangsmithBlockMeta } from '@/blocks/blocks/langsmith.display' +import { LatexBlockDisplay, LatexBlockMeta } from '@/blocks/blocks/latex.display' +import { + LaunchDarklyBlockDisplay, + LaunchDarklyBlockMeta, +} from '@/blocks/blocks/launchdarkly.display' +import { LeadMagicBlockDisplay, LeadMagicBlockMeta } from '@/blocks/blocks/leadmagic.display' +import { LemlistBlockDisplay, LemlistBlockMeta } from '@/blocks/blocks/lemlist.display' +import { + LinearBlockDisplay, + LinearBlockMeta, + LinearV2BlockDisplay, +} from '@/blocks/blocks/linear.display' +import { LinkedInBlockDisplay, LinkedInBlockMeta } from '@/blocks/blocks/linkedin.display' +import { LinkupBlockDisplay, LinkupBlockMeta } from '@/blocks/blocks/linkup.display' +import { LinqBlockDisplay, LinqBlockMeta } from '@/blocks/blocks/linq.display' import { LogsBlockDisplay, LogsV2BlockDisplay } from '@/blocks/blocks/logs.display' -import { LoopsBlockDisplay } from '@/blocks/blocks/loops.display' -import { LumaBlockDisplay } from '@/blocks/blocks/luma.display' -import { MailchimpBlockDisplay } from '@/blocks/blocks/mailchimp.display' -import { MailgunBlockDisplay } from '@/blocks/blocks/mailgun.display' +import { LoopsBlockDisplay, LoopsBlockMeta } from '@/blocks/blocks/loops.display' +import { LumaBlockDisplay, LumaBlockMeta } from '@/blocks/blocks/luma.display' +import { MailchimpBlockDisplay, MailchimpBlockMeta } from '@/blocks/blocks/mailchimp.display' +import { MailgunBlockDisplay, MailgunBlockMeta } from '@/blocks/blocks/mailgun.display' import { ManualTriggerBlockDisplay } from '@/blocks/blocks/manual_trigger.display' import { McpBlockDisplay } from '@/blocks/blocks/mcp.display' -import { Mem0BlockDisplay } from '@/blocks/blocks/mem0.display' +import { Mem0BlockDisplay, Mem0BlockMeta } from '@/blocks/blocks/mem0.display' import { MemoryBlockDisplay } from '@/blocks/blocks/memory.display' -import { MicrosoftAdBlockDisplay } from '@/blocks/blocks/microsoft_ad.display' -import { MicrosoftDataverseBlockDisplay } from '@/blocks/blocks/microsoft_dataverse.display' +import { MicrosoftAdBlockDisplay, MicrosoftAdBlockMeta } from '@/blocks/blocks/microsoft_ad.display' +import { + MicrosoftDataverseBlockDisplay, + MicrosoftDataverseBlockMeta, +} from '@/blocks/blocks/microsoft_dataverse.display' import { MicrosoftExcelBlockDisplay, + MicrosoftExcelBlockMeta, MicrosoftExcelV2BlockDisplay, + MicrosoftExcelV2BlockMeta, } from '@/blocks/blocks/microsoft_excel.display' -import { MicrosoftPlannerBlockDisplay } from '@/blocks/blocks/microsoft_planner.display' -import { MicrosoftTeamsBlockDisplay } from '@/blocks/blocks/microsoft_teams.display' -import { MillionVerifierBlockDisplay } from '@/blocks/blocks/millionverifier.display' +import { + MicrosoftPlannerBlockDisplay, + MicrosoftPlannerBlockMeta, +} from '@/blocks/blocks/microsoft_planner.display' +import { + MicrosoftTeamsBlockDisplay, + MicrosoftTeamsBlockMeta, +} from '@/blocks/blocks/microsoft_teams.display' +import { + MillionVerifierBlockDisplay, + MillionVerifierBlockMeta, +} from '@/blocks/blocks/millionverifier.display' import { MistralParseBlockDisplay, + MistralParseBlockMeta, MistralParseV2BlockDisplay, MistralParseV3BlockDisplay, } from '@/blocks/blocks/mistral_parse.display' -import { MondayBlockDisplay } from '@/blocks/blocks/monday.display' -import { MongoDBBlockDisplay } from '@/blocks/blocks/mongodb.display' +import { MondayBlockDisplay, MondayBlockMeta } from '@/blocks/blocks/monday.display' +import { MongoDBBlockDisplay, MongoDBBlockMeta } from '@/blocks/blocks/mongodb.display' import { MothershipBlockDisplay } from '@/blocks/blocks/mothership.display' import { MySQLBlockDisplay } from '@/blocks/blocks/mysql.display' -import { Neo4jBlockDisplay } from '@/blocks/blocks/neo4j.display' -import { NeverBounceBlockDisplay } from '@/blocks/blocks/neverbounce.display' -import { NewRelicBlockDisplay } from '@/blocks/blocks/new_relic.display' +import { Neo4jBlockDisplay, Neo4jBlockMeta } from '@/blocks/blocks/neo4j.display' +import { NeverBounceBlockDisplay, NeverBounceBlockMeta } from '@/blocks/blocks/neverbounce.display' +import { NewRelicBlockDisplay, NewRelicBlockMeta } from '@/blocks/blocks/new_relic.display' import { NoteBlockDisplay } from '@/blocks/blocks/note.display' -import { NotionBlockDisplay, NotionV2BlockDisplay } from '@/blocks/blocks/notion.display' -import { ObsidianBlockDisplay } from '@/blocks/blocks/obsidian.display' -import { OktaBlockDisplay } from '@/blocks/blocks/okta.display' -import { OneDriveBlockDisplay } from '@/blocks/blocks/onedrive.display' -import { OnePasswordBlockDisplay } from '@/blocks/blocks/onepassword.display' -import { OpenAIBlockDisplay } from '@/blocks/blocks/openai.display' -import { OutlookBlockDisplay } from '@/blocks/blocks/outlook.display' -import { PagerDutyBlockDisplay } from '@/blocks/blocks/pagerduty.display' -import { ParallelBlockDisplay } from '@/blocks/blocks/parallel.display' -import { PeopleDataLabsBlockDisplay } from '@/blocks/blocks/peopledatalabs.display' -import { PerplexityBlockDisplay } from '@/blocks/blocks/perplexity.display' -import { PersonaBlockDisplay } from '@/blocks/blocks/persona.display' +import { + NotionBlockDisplay, + NotionBlockMeta, + NotionV2BlockDisplay, + NotionV2BlockMeta, +} from '@/blocks/blocks/notion.display' +import { ObsidianBlockDisplay, ObsidianBlockMeta } from '@/blocks/blocks/obsidian.display' +import { OktaBlockDisplay, OktaBlockMeta } from '@/blocks/blocks/okta.display' +import { OneDriveBlockDisplay, OneDriveBlockMeta } from '@/blocks/blocks/onedrive.display' +import { OnePasswordBlockDisplay, OnePasswordBlockMeta } from '@/blocks/blocks/onepassword.display' +import { OpenAIBlockDisplay, OpenAIBlockMeta } from '@/blocks/blocks/openai.display' +import { OutlookBlockDisplay, OutlookBlockMeta } from '@/blocks/blocks/outlook.display' +import { PagerDutyBlockDisplay, PagerDutyBlockMeta } from '@/blocks/blocks/pagerduty.display' +import { ParallelBlockDisplay, ParallelBlockMeta } from '@/blocks/blocks/parallel.display' +import { + PeopleDataLabsBlockDisplay, + PeopleDataLabsBlockMeta, +} from '@/blocks/blocks/peopledatalabs.display' +import { PerplexityBlockDisplay, PerplexityBlockMeta } from '@/blocks/blocks/perplexity.display' +import { PersonaBlockDisplay, PersonaBlockMeta } from '@/blocks/blocks/persona.display' import { PiBlockDisplay } from '@/blocks/blocks/pi.display' -import { PineconeBlockDisplay } from '@/blocks/blocks/pinecone.display' -import { PipedriveBlockDisplay } from '@/blocks/blocks/pipedrive.display' -import { PolymarketBlockDisplay } from '@/blocks/blocks/polymarket.display' +import { PineconeBlockDisplay, PineconeBlockMeta } from '@/blocks/blocks/pinecone.display' +import { PipedriveBlockDisplay, PipedriveBlockMeta } from '@/blocks/blocks/pipedrive.display' +import { PolymarketBlockDisplay, PolymarketBlockMeta } from '@/blocks/blocks/polymarket.display' import { PostgreSQLBlockDisplay } from '@/blocks/blocks/postgresql.display' -import { PostHogBlockDisplay } from '@/blocks/blocks/posthog.display' -import { ProfoundBlockDisplay } from '@/blocks/blocks/profound.display' -import { ProspeoBlockDisplay } from '@/blocks/blocks/prospeo.display' -import { PulseBlockDisplay, PulseV2BlockDisplay } from '@/blocks/blocks/pulse.display' -import { QdrantBlockDisplay } from '@/blocks/blocks/qdrant.display' -import { QuartrBlockDisplay } from '@/blocks/blocks/quartr.display' -import { QuiverBlockDisplay } from '@/blocks/blocks/quiver.display' -import { RailwayBlockDisplay } from '@/blocks/blocks/railway.display' -import { RB2BBlockDisplay } from '@/blocks/blocks/rb2b.display' -import { RDSBlockDisplay } from '@/blocks/blocks/rds.display' -import { RedditBlockDisplay } from '@/blocks/blocks/reddit.display' -import { RedisBlockDisplay } from '@/blocks/blocks/redis.display' -import { ReductoBlockDisplay, ReductoV2BlockDisplay } from '@/blocks/blocks/reducto.display' -import { ResendBlockDisplay } from '@/blocks/blocks/resend.display' +import { PostHogBlockDisplay, PostHogBlockMeta } from '@/blocks/blocks/posthog.display' +import { ProfoundBlockDisplay, ProfoundBlockMeta } from '@/blocks/blocks/profound.display' +import { ProspeoBlockDisplay, ProspeoBlockMeta } from '@/blocks/blocks/prospeo.display' +import { + PulseBlockDisplay, + PulseBlockMeta, + PulseV2BlockDisplay, +} from '@/blocks/blocks/pulse.display' +import { QdrantBlockDisplay, QdrantBlockMeta } from '@/blocks/blocks/qdrant.display' +import { QuartrBlockDisplay, QuartrBlockMeta } from '@/blocks/blocks/quartr.display' +import { QuiverBlockDisplay, QuiverBlockMeta } from '@/blocks/blocks/quiver.display' +import { RailwayBlockDisplay, RailwayBlockMeta } from '@/blocks/blocks/railway.display' +import { RB2BBlockDisplay, RB2BBlockMeta } from '@/blocks/blocks/rb2b.display' +import { RDSBlockDisplay, RDSBlockMeta } from '@/blocks/blocks/rds.display' +import { RedditBlockDisplay, RedditBlockMeta } from '@/blocks/blocks/reddit.display' +import { RedisBlockDisplay, RedisBlockMeta } from '@/blocks/blocks/redis.display' +import { + ReductoBlockDisplay, + ReductoBlockMeta, + ReductoV2BlockDisplay, +} from '@/blocks/blocks/reducto.display' +import { ResendBlockDisplay, ResendBlockMeta } from '@/blocks/blocks/resend.display' import { ResponseBlockDisplay } from '@/blocks/blocks/response.display' -import { RevenueCatBlockDisplay } from '@/blocks/blocks/revenuecat.display' -import { RipplingBlockDisplay } from '@/blocks/blocks/rippling.display' -import { RootlyBlockDisplay } from '@/blocks/blocks/rootly.display' +import { RevenueCatBlockDisplay, RevenueCatBlockMeta } from '@/blocks/blocks/revenuecat.display' +import { RipplingBlockDisplay, RipplingBlockMeta } from '@/blocks/blocks/rippling.display' +import { RootlyBlockDisplay, RootlyBlockMeta } from '@/blocks/blocks/rootly.display' import { RouterBlockDisplay, RouterV2BlockDisplay } from '@/blocks/blocks/router.display' -import { RssBlockDisplay } from '@/blocks/blocks/rss.display' -import { S3BlockDisplay } from '@/blocks/blocks/s3.display' -import { SalesforceBlockDisplay } from '@/blocks/blocks/salesforce.display' -import { SapConcurBlockDisplay } from '@/blocks/blocks/sap_concur.display' -import { SapS4HanaBlockDisplay } from '@/blocks/blocks/sap_s4hana.display' +import { RssBlockDisplay, RssBlockMeta } from '@/blocks/blocks/rss.display' +import { S3BlockDisplay, S3BlockMeta } from '@/blocks/blocks/s3.display' +import { SalesforceBlockDisplay, SalesforceBlockMeta } from '@/blocks/blocks/salesforce.display' +import { SapConcurBlockDisplay, SapConcurBlockMeta } from '@/blocks/blocks/sap_concur.display' +import { SapS4HanaBlockDisplay, SapS4HanaBlockMeta } from '@/blocks/blocks/sap_s4hana.display' import { ScheduleBlockDisplay } from '@/blocks/blocks/schedule.display' import { SearchBlockDisplay } from '@/blocks/blocks/search.display' -import { SecretsManagerBlockDisplay } from '@/blocks/blocks/secrets_manager.display' -import { SendblueBlockDisplay } from '@/blocks/blocks/sendblue.display' -import { SendGridBlockDisplay } from '@/blocks/blocks/sendgrid.display' -import { SentryBlockDisplay } from '@/blocks/blocks/sentry.display' -import { SerperBlockDisplay } from '@/blocks/blocks/serper.display' -import { ServiceNowBlockDisplay } from '@/blocks/blocks/servicenow.display' -import { SESBlockDisplay } from '@/blocks/blocks/ses.display' +import { + SecretsManagerBlockDisplay, + SecretsManagerBlockMeta, +} from '@/blocks/blocks/secrets_manager.display' +import { SendblueBlockDisplay, SendblueBlockMeta } from '@/blocks/blocks/sendblue.display' +import { SendGridBlockDisplay, SendGridBlockMeta } from '@/blocks/blocks/sendgrid.display' +import { SentryBlockDisplay, SentryBlockMeta } from '@/blocks/blocks/sentry.display' +import { SerperBlockDisplay, SerperBlockMeta } from '@/blocks/blocks/serper.display' +import { ServiceNowBlockDisplay, ServiceNowBlockMeta } from '@/blocks/blocks/servicenow.display' +import { SESBlockDisplay, SESBlockMeta } from '@/blocks/blocks/ses.display' import { SftpBlockDisplay } from '@/blocks/blocks/sftp.display' import { SharepointBlockDisplay, + SharepointBlockMeta, SharepointV2BlockDisplay, } from '@/blocks/blocks/sharepoint.display' -import { ShopifyBlockDisplay } from '@/blocks/blocks/shopify.display' +import { ShopifyBlockDisplay, ShopifyBlockMeta } from '@/blocks/blocks/shopify.display' import { SimWorkspaceEventBlockDisplay } from '@/blocks/blocks/sim_workspace_event.display' -import { SimilarwebBlockDisplay } from '@/blocks/blocks/similarweb.display' -import { SixtyfourBlockDisplay } from '@/blocks/blocks/sixtyfour.display' -import { SlackBlockDisplay } from '@/blocks/blocks/slack.display' +import { SimilarwebBlockDisplay, SimilarwebBlockMeta } from '@/blocks/blocks/similarweb.display' +import { SixtyfourBlockDisplay, SixtyfourBlockMeta } from '@/blocks/blocks/sixtyfour.display' +import { SlackBlockDisplay, SlackBlockMeta } from '@/blocks/blocks/slack.display' import { SmtpBlockDisplay } from '@/blocks/blocks/smtp.display' -import { SportmonksBlockDisplay } from '@/blocks/blocks/sportmonks.display' -import { SpotifyBlockDisplay } from '@/blocks/blocks/spotify.display' -import { SQSBlockDisplay } from '@/blocks/blocks/sqs.display' -import { SquareBlockDisplay } from '@/blocks/blocks/square.display' +import { SportmonksBlockDisplay, SportmonksBlockMeta } from '@/blocks/blocks/sportmonks.display' +import { SpotifyBlockDisplay, SpotifyBlockMeta } from '@/blocks/blocks/spotify.display' +import { SQSBlockDisplay, SQSBlockMeta } from '@/blocks/blocks/sqs.display' +import { SquareBlockDisplay, SquareBlockMeta } from '@/blocks/blocks/square.display' import { SSHBlockDisplay } from '@/blocks/blocks/ssh.display' -import { StagehandBlockDisplay } from '@/blocks/blocks/stagehand.display' +import { StagehandBlockDisplay, StagehandBlockMeta } from '@/blocks/blocks/stagehand.display' import { StartTriggerBlockDisplay } from '@/blocks/blocks/start_trigger.display' import { StarterBlockDisplay } from '@/blocks/blocks/starter.display' -import { StripeBlockDisplay } from '@/blocks/blocks/stripe.display' -import { STSBlockDisplay } from '@/blocks/blocks/sts.display' +import { StripeBlockDisplay, StripeBlockMeta } from '@/blocks/blocks/stripe.display' +import { STSBlockDisplay, STSBlockMeta } from '@/blocks/blocks/sts.display' import { SttBlockDisplay, SttV2BlockDisplay } from '@/blocks/blocks/stt.display' -import { SupabaseBlockDisplay } from '@/blocks/blocks/supabase.display' +import { SupabaseBlockDisplay, SupabaseBlockMeta } from '@/blocks/blocks/supabase.display' import { TableBlockDisplay } from '@/blocks/blocks/table.display' -import { TailscaleBlockDisplay } from '@/blocks/blocks/tailscale.display' -import { TavilyBlockDisplay } from '@/blocks/blocks/tavily.display' -import { TelegramBlockDisplay } from '@/blocks/blocks/telegram.display' -import { TemporalBlockDisplay } from '@/blocks/blocks/temporal.display' -import { TextractBlockDisplay, TextractV2BlockDisplay } from '@/blocks/blocks/textract.display' +import { TailscaleBlockDisplay, TailscaleBlockMeta } from '@/blocks/blocks/tailscale.display' +import { TavilyBlockDisplay, TavilyBlockMeta } from '@/blocks/blocks/tavily.display' +import { TelegramBlockDisplay, TelegramBlockMeta } from '@/blocks/blocks/telegram.display' +import { TemporalBlockDisplay, TemporalBlockMeta } from '@/blocks/blocks/temporal.display' +import { + TextractBlockDisplay, + TextractBlockMeta, + TextractV2BlockDisplay, +} from '@/blocks/blocks/textract.display' import { ThinkingBlockDisplay } from '@/blocks/blocks/thinking.display' -import { ThriveBlockDisplay } from '@/blocks/blocks/thrive.display' -import { TinybirdBlockDisplay } from '@/blocks/blocks/tinybird.display' +import { ThriveBlockDisplay, ThriveBlockMeta } from '@/blocks/blocks/thrive.display' +import { TinybirdBlockDisplay, TinybirdBlockMeta } from '@/blocks/blocks/tinybird.display' import { TranslateBlockDisplay } from '@/blocks/blocks/translate.display' -import { TrelloBlockDisplay } from '@/blocks/blocks/trello.display' -import { TriggerDevBlockDisplay } from '@/blocks/blocks/trigger_dev.display' +import { TrelloBlockDisplay, TrelloBlockMeta } from '@/blocks/blocks/trello.display' +import { TriggerDevBlockDisplay, TriggerDevBlockMeta } from '@/blocks/blocks/trigger_dev.display' import { TtsBlockDisplay } from '@/blocks/blocks/tts.display' -import { TwilioSMSBlockDisplay } from '@/blocks/blocks/twilio.display' -import { TwilioVoiceBlockDisplay } from '@/blocks/blocks/twilio_voice.display' -import { TypeformBlockDisplay } from '@/blocks/blocks/typeform.display' -import { UpstashBlockDisplay } from '@/blocks/blocks/upstash.display' -import { VantaBlockDisplay } from '@/blocks/blocks/vanta.display' +import { TwilioSMSBlockDisplay, TwilioSMSBlockMeta } from '@/blocks/blocks/twilio.display' +import { TwilioVoiceBlockDisplay, TwilioVoiceBlockMeta } from '@/blocks/blocks/twilio_voice.display' +import { TypeformBlockDisplay, TypeformBlockMeta } from '@/blocks/blocks/typeform.display' +import { UpstashBlockDisplay, UpstashBlockMeta } from '@/blocks/blocks/upstash.display' +import { VantaBlockDisplay, VantaBlockMeta } from '@/blocks/blocks/vanta.display' import { VariablesBlockDisplay } from '@/blocks/blocks/variables.display' -import { VercelBlockDisplay } from '@/blocks/blocks/vercel.display' +import { VercelBlockDisplay, VercelBlockMeta } from '@/blocks/blocks/vercel.display' import { VideoGeneratorBlockDisplay, VideoGeneratorV2BlockDisplay, @@ -287,23 +403,23 @@ import { } from '@/blocks/blocks/video_generator.display' import { VisionBlockDisplay, VisionV2BlockDisplay } from '@/blocks/blocks/vision.display' import { WaitBlockDisplay } from '@/blocks/blocks/wait.display' -import { WealthboxBlockDisplay } from '@/blocks/blocks/wealthbox.display' -import { WebflowBlockDisplay } from '@/blocks/blocks/webflow.display' +import { WealthboxBlockDisplay, WealthboxBlockMeta } from '@/blocks/blocks/wealthbox.display' +import { WebflowBlockDisplay, WebflowBlockMeta } from '@/blocks/blocks/webflow.display' import { WebhookRequestBlockDisplay } from '@/blocks/blocks/webhook_request.display' -import { WhatsAppBlockDisplay } from '@/blocks/blocks/whatsapp.display' -import { WikipediaBlockDisplay } from '@/blocks/blocks/wikipedia.display' -import { WizaBlockDisplay } from '@/blocks/blocks/wiza.display' -import { WordPressBlockDisplay } from '@/blocks/blocks/wordpress.display' -import { WorkdayBlockDisplay } from '@/blocks/blocks/workday.display' +import { WhatsAppBlockDisplay, WhatsAppBlockMeta } from '@/blocks/blocks/whatsapp.display' +import { WikipediaBlockDisplay, WikipediaBlockMeta } from '@/blocks/blocks/wikipedia.display' +import { WizaBlockDisplay, WizaBlockMeta } from '@/blocks/blocks/wiza.display' +import { WordPressBlockDisplay, WordPressBlockMeta } from '@/blocks/blocks/wordpress.display' +import { WorkdayBlockDisplay, WorkdayBlockMeta } from '@/blocks/blocks/workday.display' import { WorkflowBlockDisplay } from '@/blocks/blocks/workflow.display' import { WorkflowInputBlockDisplay } from '@/blocks/blocks/workflow_input.display' -import { XBlockDisplay } from '@/blocks/blocks/x.display' -import { YouTubeBlockDisplay } from '@/blocks/blocks/youtube.display' -import { ZendeskBlockDisplay } from '@/blocks/blocks/zendesk.display' -import { ZepBlockDisplay } from '@/blocks/blocks/zep.display' -import { ZeroBounceBlockDisplay } from '@/blocks/blocks/zerobounce.display' -import { ZoomBlockDisplay } from '@/blocks/blocks/zoom.display' -import { ZoomInfoBlockDisplay } from '@/blocks/blocks/zoominfo.display' +import { XBlockDisplay, XBlockMeta } from '@/blocks/blocks/x.display' +import { YouTubeBlockDisplay, YouTubeBlockMeta } from '@/blocks/blocks/youtube.display' +import { ZendeskBlockDisplay, ZendeskBlockMeta } from '@/blocks/blocks/zendesk.display' +import { ZepBlockDisplay, ZepBlockMeta } from '@/blocks/blocks/zep.display' +import { ZeroBounceBlockDisplay, ZeroBounceBlockMeta } from '@/blocks/blocks/zerobounce.display' +import { ZoomBlockDisplay, ZoomBlockMeta } from '@/blocks/blocks/zoom.display' +import { ZoomInfoBlockDisplay, ZoomInfoBlockMeta } from '@/blocks/blocks/zoominfo.display' import type { BlockDisplay } from '@/blocks/manifest' import type { BlockMeta } from '@/blocks/types' @@ -4331,8 +4447,237 @@ export const TOOL_TO_BLOCK: Record = { zoominfo_search_news: 'zoominfo', } -/** - * Catalog meta (tags/templates/skills). Empty until each block's {Service}BlockMeta - * moves into its .display.ts (Phase 1b); catalog accessors fall back to @/blocks/registry. - */ -export const BLOCK_CATALOG: Record = {} +/** Catalog meta (tags/templates/skills) keyed by base block type. */ +export const BLOCK_CATALOG: Record = { + agentmail: AgentMailBlockMeta, + agentphone: AgentPhoneBlockMeta, + agiloft: AgiloftBlockMeta, + ahrefs: AhrefsBlockMeta, + airtable: AirtableBlockMeta, + airweave: AirweaveBlockMeta, + algolia: AlgoliaBlockMeta, + amplitude: AmplitudeBlockMeta, + apify: ApifyBlockMeta, + apollo: ApolloBlockMeta, + appconfig: AppConfigBlockMeta, + arxiv: ArxivBlockMeta, + asana: AsanaBlockMeta, + ashby: AshbyBlockMeta, + athena: AthenaBlockMeta, + attio: AttioBlockMeta, + azure_devops: AzureDevOpsBlockMeta, + box: BoxBlockMeta, + brandfetch: BrandfetchBlockMeta, + brex: BrexBlockMeta, + brightdata: BrightDataBlockMeta, + browser_use: BrowserUseBlockMeta, + calcom: CalComBlockMeta, + calendly: CalendlyBlockMeta, + circleback: CirclebackBlockMeta, + clay: ClayBlockMeta, + clerk: ClerkBlockMeta, + clickhouse: ClickHouseBlockMeta, + cloudflare: CloudflareBlockMeta, + cloudformation: CloudFormationBlockMeta, + cloudwatch: CloudWatchBlockMeta, + codepipeline: CodePipelineBlockMeta, + confluence: ConfluenceBlockMeta, + context_dev: ContextDevBlockMeta, + convex: ConvexBlockMeta, + crowdstrike: CrowdStrikeBlockMeta, + cursor: CursorBlockMeta, + dagster: DagsterBlockMeta, + databricks: DatabricksBlockMeta, + datadog: DatadogBlockMeta, + datagma: DatagmaBlockMeta, + daytona: DaytonaBlockMeta, + devin: DevinBlockMeta, + discord: DiscordBlockMeta, + docusign: DocuSignBlockMeta, + dropbox: DropboxBlockMeta, + dropcontact: DropcontactBlockMeta, + dspy: DSPyBlockMeta, + dub: DubBlockMeta, + duckduckgo: DuckDuckGoBlockMeta, + dynamodb: DynamoDBBlockMeta, + elasticsearch: ElasticsearchBlockMeta, + elevenlabs: ElevenLabsBlockMeta, + emailbison: EmailBisonBlockMeta, + enrich: EnrichBlockMeta, + enrichment: EnrichmentBlockMeta, + enrow: EnrowBlockMeta, + evernote: EvernoteBlockMeta, + exa: ExaBlockMeta, + extend: ExtendBlockMeta, + fathom: FathomBlockMeta, + findymail: FindymailBlockMeta, + firecrawl: FirecrawlBlockMeta, + fireflies: FirefliesBlockMeta, + fireflies_v2: FirefliesV2BlockMeta, + gamma: GammaBlockMeta, + github: GitHubBlockMeta, + github_v2: GitHubV2BlockMeta, + gitlab: GitLabBlockMeta, + gmail: GmailBlockMeta, + gmail_v2: GmailV2BlockMeta, + gong: GongBlockMeta, + google_ads: GoogleAdsBlockMeta, + google_bigquery: GoogleBigQueryBlockMeta, + google_books: GoogleBooksBlockMeta, + google_calendar: GoogleCalendarBlockMeta, + google_calendar_v2: GoogleCalendarV2BlockMeta, + google_contacts: GoogleContactsBlockMeta, + google_docs: GoogleDocsBlockMeta, + google_drive: GoogleDriveBlockMeta, + google_forms: GoogleFormsBlockMeta, + google_groups: GoogleGroupsBlockMeta, + google_maps: GoogleMapsBlockMeta, + google_meet: GoogleMeetBlockMeta, + google_pagespeed: GooglePagespeedBlockMeta, + google_search: GoogleSearchBlockMeta, + google_sheets: GoogleSheetsBlockMeta, + google_sheets_v2: GoogleSheetsV2BlockMeta, + google_slides: GoogleSlidesBlockMeta, + google_slides_v2: GoogleSlidesV2BlockMeta, + google_tasks: GoogleTasksBlockMeta, + google_translate: GoogleTranslateBlockMeta, + google_vault: GoogleVaultBlockMeta, + grafana: GrafanaBlockMeta, + grain: GrainBlockMeta, + granola: GranolaBlockMeta, + greenhouse: GreenhouseBlockMeta, + greptile: GreptileBlockMeta, + hex: HexBlockMeta, + hubspot: HubSpotBlockMeta, + huggingface: HuggingFaceBlockMeta, + hunter: HunterBlockMeta, + iam: IAMBlockMeta, + icypeas: IcypeasBlockMeta, + identity_center: IdentityCenterBlockMeta, + imap: ImapBlockMeta, + incidentio: IncidentioBlockMeta, + infisical: InfisicalBlockMeta, + instantly: InstantlyBlockMeta, + intercom: IntercomBlockMeta, + intercom_v2: IntercomV2BlockMeta, + jina: JinaBlockMeta, + jira: JiraBlockMeta, + jira_service_management: JiraServiceManagementBlockMeta, + kalshi: KalshiBlockMeta, + kalshi_v2: KalshiV2BlockMeta, + ketch: KetchBlockMeta, + langsmith: LangsmithBlockMeta, + latex: LatexBlockMeta, + launchdarkly: LaunchDarklyBlockMeta, + leadmagic: LeadMagicBlockMeta, + lemlist: LemlistBlockMeta, + linear: LinearBlockMeta, + linkedin: LinkedInBlockMeta, + linkup: LinkupBlockMeta, + linq: LinqBlockMeta, + loops: LoopsBlockMeta, + luma: LumaBlockMeta, + mailchimp: MailchimpBlockMeta, + mailgun: MailgunBlockMeta, + mem0: Mem0BlockMeta, + microsoft_ad: MicrosoftAdBlockMeta, + microsoft_dataverse: MicrosoftDataverseBlockMeta, + microsoft_excel: MicrosoftExcelBlockMeta, + microsoft_excel_v2: MicrosoftExcelV2BlockMeta, + microsoft_planner: MicrosoftPlannerBlockMeta, + microsoft_teams: MicrosoftTeamsBlockMeta, + millionverifier: MillionVerifierBlockMeta, + mistral_parse: MistralParseBlockMeta, + monday: MondayBlockMeta, + mongodb: MongoDBBlockMeta, + neo4j: Neo4jBlockMeta, + neverbounce: NeverBounceBlockMeta, + new_relic: NewRelicBlockMeta, + notion: NotionBlockMeta, + notion_v2: NotionV2BlockMeta, + obsidian: ObsidianBlockMeta, + okta: OktaBlockMeta, + onedrive: OneDriveBlockMeta, + onepassword: OnePasswordBlockMeta, + openai: OpenAIBlockMeta, + outlook: OutlookBlockMeta, + pagerduty: PagerDutyBlockMeta, + parallel_ai: ParallelBlockMeta, + peopledatalabs: PeopleDataLabsBlockMeta, + perplexity: PerplexityBlockMeta, + persona: PersonaBlockMeta, + pinecone: PineconeBlockMeta, + pipedrive: PipedriveBlockMeta, + polymarket: PolymarketBlockMeta, + posthog: PostHogBlockMeta, + profound: ProfoundBlockMeta, + prospeo: ProspeoBlockMeta, + pulse: PulseBlockMeta, + qdrant: QdrantBlockMeta, + quartr: QuartrBlockMeta, + quiver: QuiverBlockMeta, + railway: RailwayBlockMeta, + rb2b: RB2BBlockMeta, + rds: RDSBlockMeta, + reddit: RedditBlockMeta, + redis: RedisBlockMeta, + reducto: ReductoBlockMeta, + resend: ResendBlockMeta, + revenuecat: RevenueCatBlockMeta, + rippling: RipplingBlockMeta, + rootly: RootlyBlockMeta, + rss: RssBlockMeta, + s3: S3BlockMeta, + salesforce: SalesforceBlockMeta, + sap_concur: SapConcurBlockMeta, + sap_s4hana: SapS4HanaBlockMeta, + secrets_manager: SecretsManagerBlockMeta, + sendblue: SendblueBlockMeta, + sendgrid: SendGridBlockMeta, + sentry: SentryBlockMeta, + serper: SerperBlockMeta, + servicenow: ServiceNowBlockMeta, + ses: SESBlockMeta, + sharepoint: SharepointBlockMeta, + shopify: ShopifyBlockMeta, + similarweb: SimilarwebBlockMeta, + sixtyfour: SixtyfourBlockMeta, + slack: SlackBlockMeta, + sportmonks: SportmonksBlockMeta, + spotify: SpotifyBlockMeta, + sqs: SQSBlockMeta, + square: SquareBlockMeta, + stagehand: StagehandBlockMeta, + stripe: StripeBlockMeta, + sts: STSBlockMeta, + supabase: SupabaseBlockMeta, + tailscale: TailscaleBlockMeta, + tavily: TavilyBlockMeta, + telegram: TelegramBlockMeta, + temporal: TemporalBlockMeta, + textract: TextractBlockMeta, + thrive: ThriveBlockMeta, + tinybird: TinybirdBlockMeta, + trello: TrelloBlockMeta, + trigger_dev: TriggerDevBlockMeta, + twilio_sms: TwilioSMSBlockMeta, + twilio_voice: TwilioVoiceBlockMeta, + typeform: TypeformBlockMeta, + upstash: UpstashBlockMeta, + vanta: VantaBlockMeta, + vercel: VercelBlockMeta, + wealthbox: WealthboxBlockMeta, + webflow: WebflowBlockMeta, + whatsapp: WhatsAppBlockMeta, + wikipedia: WikipediaBlockMeta, + wiza: WizaBlockMeta, + wordpress: WordPressBlockMeta, + workday: WorkdayBlockMeta, + x: XBlockMeta, + youtube: YouTubeBlockMeta, + zendesk: ZendeskBlockMeta, + zep: ZepBlockMeta, + zerobounce: ZeroBounceBlockMeta, + zoom: ZoomBlockMeta, + zoominfo: ZoomInfoBlockMeta, +} diff --git a/apps/sim/blocks/manifest.ts b/apps/sim/blocks/manifest.ts index 05ced1367ae..f3b82fa956b 100644 --- a/apps/sim/blocks/manifest.ts +++ b/apps/sim/blocks/manifest.ts @@ -108,6 +108,14 @@ export function getBlockCatalog(type: string): BlockMeta | undefined { ) } +/** Alias of {@link getBlockCatalog}: catalog meta for a block type. */ +export const getBlockMeta = getBlockCatalog + +/** Every block's catalog meta, keyed by base block type. */ +export function getAllBlockMeta(): Record { + return BLOCK_CATALOG +} + /** * All templates whose owner block is `type` or which list `type` in their * `alsoIntegrations`. Each returned template carries `otherBlockTypes` — the diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index faf42594905..3fb6cb78afc 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -1,309 +1,257 @@ import { stripVersionSuffix } from '@sim/utils/string' import { A2ABlock } from '@/blocks/blocks/a2a' import { AgentBlock } from '@/blocks/blocks/agent' -import { AgentMailBlock, AgentMailBlockMeta } from '@/blocks/blocks/agentmail' -import { AgentPhoneBlock, AgentPhoneBlockMeta } from '@/blocks/blocks/agentphone' -import { AgiloftBlock, AgiloftBlockMeta } from '@/blocks/blocks/agiloft' -import { AhrefsBlock, AhrefsBlockMeta } from '@/blocks/blocks/ahrefs' -import { AirtableBlock, AirtableBlockMeta } from '@/blocks/blocks/airtable' -import { AirweaveBlock, AirweaveBlockMeta } from '@/blocks/blocks/airweave' -import { AlgoliaBlock, AlgoliaBlockMeta } from '@/blocks/blocks/algolia' -import { AmplitudeBlock, AmplitudeBlockMeta } from '@/blocks/blocks/amplitude' +import { AgentMailBlock } from '@/blocks/blocks/agentmail' +import { AgentPhoneBlock } from '@/blocks/blocks/agentphone' +import { AgiloftBlock } from '@/blocks/blocks/agiloft' +import { AhrefsBlock } from '@/blocks/blocks/ahrefs' +import { AirtableBlock } from '@/blocks/blocks/airtable' +import { AirweaveBlock } from '@/blocks/blocks/airweave' +import { AlgoliaBlock } from '@/blocks/blocks/algolia' +import { AmplitudeBlock } from '@/blocks/blocks/amplitude' import { ApiBlock } from '@/blocks/blocks/api' import { ApiTriggerBlock } from '@/blocks/blocks/api_trigger' -import { ApifyBlock, ApifyBlockMeta } from '@/blocks/blocks/apify' -import { ApolloBlock, ApolloBlockMeta } from '@/blocks/blocks/apollo' -import { AppConfigBlock, AppConfigBlockMeta } from '@/blocks/blocks/appconfig' -import { ArxivBlock, ArxivBlockMeta } from '@/blocks/blocks/arxiv' -import { AsanaBlock, AsanaBlockMeta } from '@/blocks/blocks/asana' -import { AshbyBlock, AshbyBlockMeta } from '@/blocks/blocks/ashby' -import { AthenaBlock, AthenaBlockMeta } from '@/blocks/blocks/athena' -import { AttioBlock, AttioBlockMeta } from '@/blocks/blocks/attio' -import { AzureDevOpsBlock, AzureDevOpsBlockMeta } from '@/blocks/blocks/azure_devops' -import { BoxBlock, BoxBlockMeta } from '@/blocks/blocks/box' -import { BrandfetchBlock, BrandfetchBlockMeta } from '@/blocks/blocks/brandfetch' -import { BrexBlock, BrexBlockMeta } from '@/blocks/blocks/brex' -import { BrightDataBlock, BrightDataBlockMeta } from '@/blocks/blocks/brightdata' -import { BrowserUseBlock, BrowserUseBlockMeta } from '@/blocks/blocks/browser_use' -import { CalComBlock, CalComBlockMeta } from '@/blocks/blocks/calcom' -import { CalendlyBlock, CalendlyBlockMeta } from '@/blocks/blocks/calendly' +import { ApifyBlock } from '@/blocks/blocks/apify' +import { ApolloBlock } from '@/blocks/blocks/apollo' +import { AppConfigBlock } from '@/blocks/blocks/appconfig' +import { ArxivBlock } from '@/blocks/blocks/arxiv' +import { AsanaBlock } from '@/blocks/blocks/asana' +import { AshbyBlock } from '@/blocks/blocks/ashby' +import { AthenaBlock } from '@/blocks/blocks/athena' +import { AttioBlock } from '@/blocks/blocks/attio' +import { AzureDevOpsBlock } from '@/blocks/blocks/azure_devops' +import { BoxBlock } from '@/blocks/blocks/box' +import { BrandfetchBlock } from '@/blocks/blocks/brandfetch' +import { BrexBlock } from '@/blocks/blocks/brex' +import { BrightDataBlock } from '@/blocks/blocks/brightdata' +import { BrowserUseBlock } from '@/blocks/blocks/browser_use' +import { CalComBlock } from '@/blocks/blocks/calcom' +import { CalendlyBlock } from '@/blocks/blocks/calendly' import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger' -import { CirclebackBlock, CirclebackBlockMeta } from '@/blocks/blocks/circleback' -import { ClayBlock, ClayBlockMeta } from '@/blocks/blocks/clay' -import { ClerkBlock, ClerkBlockMeta } from '@/blocks/blocks/clerk' -import { ClickHouseBlock, ClickHouseBlockMeta } from '@/blocks/blocks/clickhouse' -import { CloudflareBlock, CloudflareBlockMeta } from '@/blocks/blocks/cloudflare' -import { CloudFormationBlock, CloudFormationBlockMeta } from '@/blocks/blocks/cloudformation' -import { CloudWatchBlock, CloudWatchBlockMeta } from '@/blocks/blocks/cloudwatch' -import { CodePipelineBlock, CodePipelineBlockMeta } from '@/blocks/blocks/codepipeline' +import { CirclebackBlock } from '@/blocks/blocks/circleback' +import { ClayBlock } from '@/blocks/blocks/clay' +import { ClerkBlock } from '@/blocks/blocks/clerk' +import { ClickHouseBlock } from '@/blocks/blocks/clickhouse' +import { CloudflareBlock } from '@/blocks/blocks/cloudflare' +import { CloudFormationBlock } from '@/blocks/blocks/cloudformation' +import { CloudWatchBlock } from '@/blocks/blocks/cloudwatch' +import { CodePipelineBlock } from '@/blocks/blocks/codepipeline' import { ConditionBlock } from '@/blocks/blocks/condition' -import { ConfluenceBlock, ConfluenceBlockMeta, ConfluenceV2Block } from '@/blocks/blocks/confluence' -import { ContextDevBlock, ContextDevBlockMeta } from '@/blocks/blocks/context_dev' -import { ConvexBlock, ConvexBlockMeta } from '@/blocks/blocks/convex' +import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence' +import { ContextDevBlock } from '@/blocks/blocks/context_dev' +import { ConvexBlock } from '@/blocks/blocks/convex' import { CredentialBlock } from '@/blocks/blocks/credential' -import { CrowdStrikeBlock, CrowdStrikeBlockMeta } from '@/blocks/blocks/crowdstrike' -import { CursorBlock, CursorBlockMeta, CursorV2Block } from '@/blocks/blocks/cursor' -import { DagsterBlock, DagsterBlockMeta } from '@/blocks/blocks/dagster' -import { DatabricksBlock, DatabricksBlockMeta } from '@/blocks/blocks/databricks' -import { DatadogBlock, DatadogBlockMeta } from '@/blocks/blocks/datadog' -import { DatagmaBlock, DatagmaBlockMeta } from '@/blocks/blocks/datagma' -import { DaytonaBlock, DaytonaBlockMeta } from '@/blocks/blocks/daytona' +import { CrowdStrikeBlock } from '@/blocks/blocks/crowdstrike' +import { CursorBlock, CursorV2Block } from '@/blocks/blocks/cursor' +import { DagsterBlock } from '@/blocks/blocks/dagster' +import { DatabricksBlock } from '@/blocks/blocks/databricks' +import { DatadogBlock } from '@/blocks/blocks/datadog' +import { DatagmaBlock } from '@/blocks/blocks/datagma' +import { DaytonaBlock } from '@/blocks/blocks/daytona' import { DeploymentsBlock } from '@/blocks/blocks/deployments' -import { DevinBlock, DevinBlockMeta } from '@/blocks/blocks/devin' -import { DiscordBlock, DiscordBlockMeta } from '@/blocks/blocks/discord' -import { DocuSignBlock, DocuSignBlockMeta } from '@/blocks/blocks/docusign' -import { DropboxBlock, DropboxBlockMeta } from '@/blocks/blocks/dropbox' -import { DropcontactBlock, DropcontactBlockMeta } from '@/blocks/blocks/dropcontact' -import { DSPyBlock, DSPyBlockMeta } from '@/blocks/blocks/dspy' -import { DubBlock, DubBlockMeta } from '@/blocks/blocks/dub' -import { DuckDuckGoBlock, DuckDuckGoBlockMeta } from '@/blocks/blocks/duckduckgo' -import { DynamoDBBlock, DynamoDBBlockMeta } from '@/blocks/blocks/dynamodb' -import { ElasticsearchBlock, ElasticsearchBlockMeta } from '@/blocks/blocks/elasticsearch' -import { ElevenLabsBlock, ElevenLabsBlockMeta } from '@/blocks/blocks/elevenlabs' -import { EmailBisonBlock, EmailBisonBlockMeta } from '@/blocks/blocks/emailbison' -import { EnrichBlock, EnrichBlockMeta } from '@/blocks/blocks/enrich' -import { EnrichmentBlock, EnrichmentBlockMeta } from '@/blocks/blocks/enrichment' -import { EnrowBlock, EnrowBlockMeta } from '@/blocks/blocks/enrow' +import { DevinBlock } from '@/blocks/blocks/devin' +import { DiscordBlock } from '@/blocks/blocks/discord' +import { DocuSignBlock } from '@/blocks/blocks/docusign' +import { DropboxBlock } from '@/blocks/blocks/dropbox' +import { DropcontactBlock } from '@/blocks/blocks/dropcontact' +import { DSPyBlock } from '@/blocks/blocks/dspy' +import { DubBlock } from '@/blocks/blocks/dub' +import { DuckDuckGoBlock } from '@/blocks/blocks/duckduckgo' +import { DynamoDBBlock } from '@/blocks/blocks/dynamodb' +import { ElasticsearchBlock } from '@/blocks/blocks/elasticsearch' +import { ElevenLabsBlock } from '@/blocks/blocks/elevenlabs' +import { EmailBisonBlock } from '@/blocks/blocks/emailbison' +import { EnrichBlock } from '@/blocks/blocks/enrich' +import { EnrichmentBlock } from '@/blocks/blocks/enrichment' +import { EnrowBlock } from '@/blocks/blocks/enrow' import { EvaluatorBlock } from '@/blocks/blocks/evaluator' -import { EvernoteBlock, EvernoteBlockMeta } from '@/blocks/blocks/evernote' -import { ExaBlock, ExaBlockMeta } from '@/blocks/blocks/exa' -import { ExtendBlock, ExtendBlockMeta, ExtendV2Block } from '@/blocks/blocks/extend' -import { FathomBlock, FathomBlockMeta } from '@/blocks/blocks/fathom' +import { EvernoteBlock } from '@/blocks/blocks/evernote' +import { ExaBlock } from '@/blocks/blocks/exa' +import { ExtendBlock, ExtendV2Block } from '@/blocks/blocks/extend' +import { FathomBlock } from '@/blocks/blocks/fathom' import { FileBlock, FileV2Block, FileV3Block, FileV4Block, FileV5Block } from '@/blocks/blocks/file' -import { FindymailBlock, FindymailBlockMeta } from '@/blocks/blocks/findymail' -import { FirecrawlBlock, FirecrawlBlockMeta } from '@/blocks/blocks/firecrawl' -import { - FirefliesBlock, - FirefliesBlockMeta, - FirefliesV2Block, - FirefliesV2BlockMeta, -} from '@/blocks/blocks/fireflies' +import { FindymailBlock } from '@/blocks/blocks/findymail' +import { FirecrawlBlock } from '@/blocks/blocks/firecrawl' +import { FirefliesBlock, FirefliesV2Block } from '@/blocks/blocks/fireflies' import { FunctionBlock } from '@/blocks/blocks/function' -import { GammaBlock, GammaBlockMeta } from '@/blocks/blocks/gamma' +import { GammaBlock } from '@/blocks/blocks/gamma' import { GenericWebhookBlock } from '@/blocks/blocks/generic_webhook' -import { - GitHubBlock, - GitHubBlockMeta, - GitHubV2Block, - GitHubV2BlockMeta, -} from '@/blocks/blocks/github' -import { GitLabBlock, GitLabBlockMeta } from '@/blocks/blocks/gitlab' -import { GmailBlock, GmailBlockMeta, GmailV2Block, GmailV2BlockMeta } from '@/blocks/blocks/gmail' -import { GongBlock, GongBlockMeta } from '@/blocks/blocks/gong' -import { GoogleSearchBlock, GoogleSearchBlockMeta } from '@/blocks/blocks/google' -import { GoogleAdsBlock, GoogleAdsBlockMeta } from '@/blocks/blocks/google_ads' -import { GoogleBigQueryBlock, GoogleBigQueryBlockMeta } from '@/blocks/blocks/google_bigquery' -import { GoogleBooksBlock, GoogleBooksBlockMeta } from '@/blocks/blocks/google_books' -import { - GoogleCalendarBlock, - GoogleCalendarBlockMeta, - GoogleCalendarV2Block, - GoogleCalendarV2BlockMeta, -} from '@/blocks/blocks/google_calendar' -import { GoogleContactsBlock, GoogleContactsBlockMeta } from '@/blocks/blocks/google_contacts' -import { GoogleDocsBlock, GoogleDocsBlockMeta } from '@/blocks/blocks/google_docs' -import { GoogleDriveBlock, GoogleDriveBlockMeta } from '@/blocks/blocks/google_drive' -import { GoogleFormsBlock, GoogleFormsBlockMeta } from '@/blocks/blocks/google_forms' -import { GoogleGroupsBlock, GoogleGroupsBlockMeta } from '@/blocks/blocks/google_groups' -import { GoogleMapsBlock, GoogleMapsBlockMeta } from '@/blocks/blocks/google_maps' -import { GoogleMeetBlock, GoogleMeetBlockMeta } from '@/blocks/blocks/google_meet' -import { GooglePagespeedBlock, GooglePagespeedBlockMeta } from '@/blocks/blocks/google_pagespeed' -import { - GoogleSheetsBlock, - GoogleSheetsBlockMeta, - GoogleSheetsV2Block, - GoogleSheetsV2BlockMeta, -} from '@/blocks/blocks/google_sheets' -import { - GoogleSlidesBlock, - GoogleSlidesBlockMeta, - GoogleSlidesV2Block, - GoogleSlidesV2BlockMeta, -} from '@/blocks/blocks/google_slides' -import { GoogleTasksBlock, GoogleTasksBlockMeta } from '@/blocks/blocks/google_tasks' -import { GoogleTranslateBlock, GoogleTranslateBlockMeta } from '@/blocks/blocks/google_translate' -import { GoogleVaultBlock, GoogleVaultBlockMeta } from '@/blocks/blocks/google_vault' -import { GrafanaBlock, GrafanaBlockMeta } from '@/blocks/blocks/grafana' -import { GrainBlock, GrainBlockMeta } from '@/blocks/blocks/grain' -import { GranolaBlock, GranolaBlockMeta } from '@/blocks/blocks/granola' -import { GreenhouseBlock, GreenhouseBlockMeta } from '@/blocks/blocks/greenhouse' -import { GreptileBlock, GreptileBlockMeta } from '@/blocks/blocks/greptile' +import { GitHubBlock, GitHubV2Block } from '@/blocks/blocks/github' +import { GitLabBlock } from '@/blocks/blocks/gitlab' +import { GmailBlock, GmailV2Block } from '@/blocks/blocks/gmail' +import { GongBlock } from '@/blocks/blocks/gong' +import { GoogleSearchBlock } from '@/blocks/blocks/google' +import { GoogleAdsBlock } from '@/blocks/blocks/google_ads' +import { GoogleBigQueryBlock } from '@/blocks/blocks/google_bigquery' +import { GoogleBooksBlock } from '@/blocks/blocks/google_books' +import { GoogleCalendarBlock, GoogleCalendarV2Block } from '@/blocks/blocks/google_calendar' +import { GoogleContactsBlock } from '@/blocks/blocks/google_contacts' +import { GoogleDocsBlock } from '@/blocks/blocks/google_docs' +import { GoogleDriveBlock } from '@/blocks/blocks/google_drive' +import { GoogleFormsBlock } from '@/blocks/blocks/google_forms' +import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups' +import { GoogleMapsBlock } from '@/blocks/blocks/google_maps' +import { GoogleMeetBlock } from '@/blocks/blocks/google_meet' +import { GooglePagespeedBlock } from '@/blocks/blocks/google_pagespeed' +import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets' +import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides' +import { GoogleTasksBlock } from '@/blocks/blocks/google_tasks' +import { GoogleTranslateBlock } from '@/blocks/blocks/google_translate' +import { GoogleVaultBlock } from '@/blocks/blocks/google_vault' +import { GrafanaBlock } from '@/blocks/blocks/grafana' +import { GrainBlock } from '@/blocks/blocks/grain' +import { GranolaBlock } from '@/blocks/blocks/granola' +import { GreenhouseBlock } from '@/blocks/blocks/greenhouse' +import { GreptileBlock } from '@/blocks/blocks/greptile' import { GuardrailsBlock } from '@/blocks/blocks/guardrails' -import { HexBlock, HexBlockMeta } from '@/blocks/blocks/hex' -import { HubSpotBlock, HubSpotBlockMeta } from '@/blocks/blocks/hubspot' -import { HuggingFaceBlock, HuggingFaceBlockMeta } from '@/blocks/blocks/huggingface' +import { HexBlock } from '@/blocks/blocks/hex' +import { HubSpotBlock } from '@/blocks/blocks/hubspot' +import { HuggingFaceBlock } from '@/blocks/blocks/huggingface' import { HumanInTheLoopBlock } from '@/blocks/blocks/human_in_the_loop' -import { HunterBlock, HunterBlockMeta } from '@/blocks/blocks/hunter' -import { IAMBlock, IAMBlockMeta } from '@/blocks/blocks/iam' -import { IcypeasBlock, IcypeasBlockMeta } from '@/blocks/blocks/icypeas' -import { IdentityCenterBlock, IdentityCenterBlockMeta } from '@/blocks/blocks/identity_center' +import { HunterBlock } from '@/blocks/blocks/hunter' +import { IAMBlock } from '@/blocks/blocks/iam' +import { IcypeasBlock } from '@/blocks/blocks/icypeas' +import { IdentityCenterBlock } from '@/blocks/blocks/identity_center' import { ImageGeneratorBlock, ImageGeneratorV2Block } from '@/blocks/blocks/image_generator' -import { ImapBlock, ImapBlockMeta } from '@/blocks/blocks/imap' -import { IncidentioBlock, IncidentioBlockMeta } from '@/blocks/blocks/incidentio' -import { InfisicalBlock, InfisicalBlockMeta } from '@/blocks/blocks/infisical' +import { ImapBlock } from '@/blocks/blocks/imap' +import { IncidentioBlock } from '@/blocks/blocks/incidentio' +import { InfisicalBlock } from '@/blocks/blocks/infisical' import { InputTriggerBlock } from '@/blocks/blocks/input_trigger' -import { InstantlyBlock, InstantlyBlockMeta } from '@/blocks/blocks/instantly' -import { - IntercomBlock, - IntercomBlockMeta, - IntercomV2Block, - IntercomV2BlockMeta, -} from '@/blocks/blocks/intercom' -import { JinaBlock, JinaBlockMeta } from '@/blocks/blocks/jina' -import { JiraBlock, JiraBlockMeta } from '@/blocks/blocks/jira' -import { - JiraServiceManagementBlock, - JiraServiceManagementBlockMeta, -} from '@/blocks/blocks/jira_service_management' -import { - KalshiBlock, - KalshiBlockMeta, - KalshiV2Block, - KalshiV2BlockMeta, -} from '@/blocks/blocks/kalshi' -import { KetchBlock, KetchBlockMeta } from '@/blocks/blocks/ketch' +import { InstantlyBlock } from '@/blocks/blocks/instantly' +import { IntercomBlock, IntercomV2Block } from '@/blocks/blocks/intercom' +import { JinaBlock } from '@/blocks/blocks/jina' +import { JiraBlock } from '@/blocks/blocks/jira' +import { JiraServiceManagementBlock } from '@/blocks/blocks/jira_service_management' +import { KalshiBlock, KalshiV2Block } from '@/blocks/blocks/kalshi' +import { KetchBlock } from '@/blocks/blocks/ketch' import { KnowledgeBlock } from '@/blocks/blocks/knowledge' -import { LangsmithBlock, LangsmithBlockMeta } from '@/blocks/blocks/langsmith' -import { LatexBlock, LatexBlockMeta } from '@/blocks/blocks/latex' -import { LaunchDarklyBlock, LaunchDarklyBlockMeta } from '@/blocks/blocks/launchdarkly' -import { LeadMagicBlock, LeadMagicBlockMeta } from '@/blocks/blocks/leadmagic' -import { LemlistBlock, LemlistBlockMeta } from '@/blocks/blocks/lemlist' -import { LinearBlock, LinearBlockMeta, LinearV2Block } from '@/blocks/blocks/linear' -import { LinkedInBlock, LinkedInBlockMeta } from '@/blocks/blocks/linkedin' -import { LinkupBlock, LinkupBlockMeta } from '@/blocks/blocks/linkup' -import { LinqBlock, LinqBlockMeta } from '@/blocks/blocks/linq' +import { LangsmithBlock } from '@/blocks/blocks/langsmith' +import { LatexBlock } from '@/blocks/blocks/latex' +import { LaunchDarklyBlock } from '@/blocks/blocks/launchdarkly' +import { LeadMagicBlock } from '@/blocks/blocks/leadmagic' +import { LemlistBlock } from '@/blocks/blocks/lemlist' +import { LinearBlock, LinearV2Block } from '@/blocks/blocks/linear' +import { LinkedInBlock } from '@/blocks/blocks/linkedin' +import { LinkupBlock } from '@/blocks/blocks/linkup' +import { LinqBlock } from '@/blocks/blocks/linq' import { LogsBlock, LogsV2Block } from '@/blocks/blocks/logs' -import { LoopsBlock, LoopsBlockMeta } from '@/blocks/blocks/loops' -import { LumaBlock, LumaBlockMeta } from '@/blocks/blocks/luma' -import { MailchimpBlock, MailchimpBlockMeta } from '@/blocks/blocks/mailchimp' -import { MailgunBlock, MailgunBlockMeta } from '@/blocks/blocks/mailgun' +import { LoopsBlock } from '@/blocks/blocks/loops' +import { LumaBlock } from '@/blocks/blocks/luma' +import { MailchimpBlock } from '@/blocks/blocks/mailchimp' +import { MailgunBlock } from '@/blocks/blocks/mailgun' import { ManualTriggerBlock } from '@/blocks/blocks/manual_trigger' import { McpBlock } from '@/blocks/blocks/mcp' -import { Mem0Block, Mem0BlockMeta } from '@/blocks/blocks/mem0' +import { Mem0Block } from '@/blocks/blocks/mem0' import { MemoryBlock } from '@/blocks/blocks/memory' -import { MicrosoftAdBlock, MicrosoftAdBlockMeta } from '@/blocks/blocks/microsoft_ad' -import { - MicrosoftDataverseBlock, - MicrosoftDataverseBlockMeta, -} from '@/blocks/blocks/microsoft_dataverse' -import { - MicrosoftExcelBlock, - MicrosoftExcelBlockMeta, - MicrosoftExcelV2Block, - MicrosoftExcelV2BlockMeta, -} from '@/blocks/blocks/microsoft_excel' -import { MicrosoftPlannerBlock, MicrosoftPlannerBlockMeta } from '@/blocks/blocks/microsoft_planner' -import { MicrosoftTeamsBlock, MicrosoftTeamsBlockMeta } from '@/blocks/blocks/microsoft_teams' -import { MillionVerifierBlock, MillionVerifierBlockMeta } from '@/blocks/blocks/millionverifier' +import { MicrosoftAdBlock } from '@/blocks/blocks/microsoft_ad' +import { MicrosoftDataverseBlock } from '@/blocks/blocks/microsoft_dataverse' +import { MicrosoftExcelBlock, MicrosoftExcelV2Block } from '@/blocks/blocks/microsoft_excel' +import { MicrosoftPlannerBlock } from '@/blocks/blocks/microsoft_planner' +import { MicrosoftTeamsBlock } from '@/blocks/blocks/microsoft_teams' +import { MillionVerifierBlock } from '@/blocks/blocks/millionverifier' import { MistralParseBlock, - MistralParseBlockMeta, MistralParseV2Block, MistralParseV3Block, } from '@/blocks/blocks/mistral_parse' -import { MondayBlock, MondayBlockMeta } from '@/blocks/blocks/monday' -import { MongoDBBlock, MongoDBBlockMeta } from '@/blocks/blocks/mongodb' +import { MondayBlock } from '@/blocks/blocks/monday' +import { MongoDBBlock } from '@/blocks/blocks/mongodb' import { MothershipBlock } from '@/blocks/blocks/mothership' import { MySQLBlock } from '@/blocks/blocks/mysql' -import { Neo4jBlock, Neo4jBlockMeta } from '@/blocks/blocks/neo4j' -import { NeverBounceBlock, NeverBounceBlockMeta } from '@/blocks/blocks/neverbounce' -import { NewRelicBlock, NewRelicBlockMeta } from '@/blocks/blocks/new_relic' +import { Neo4jBlock } from '@/blocks/blocks/neo4j' +import { NeverBounceBlock } from '@/blocks/blocks/neverbounce' +import { NewRelicBlock } from '@/blocks/blocks/new_relic' import { NoteBlock } from '@/blocks/blocks/note' -import { - NotionBlock, - NotionBlockMeta, - NotionV2Block, - NotionV2BlockMeta, -} from '@/blocks/blocks/notion' -import { ObsidianBlock, ObsidianBlockMeta } from '@/blocks/blocks/obsidian' -import { OktaBlock, OktaBlockMeta } from '@/blocks/blocks/okta' -import { OneDriveBlock, OneDriveBlockMeta } from '@/blocks/blocks/onedrive' -import { OnePasswordBlock, OnePasswordBlockMeta } from '@/blocks/blocks/onepassword' -import { OpenAIBlock, OpenAIBlockMeta } from '@/blocks/blocks/openai' -import { OutlookBlock, OutlookBlockMeta } from '@/blocks/blocks/outlook' -import { PagerDutyBlock, PagerDutyBlockMeta } from '@/blocks/blocks/pagerduty' -import { ParallelBlock, ParallelBlockMeta } from '@/blocks/blocks/parallel' -import { PeopleDataLabsBlock, PeopleDataLabsBlockMeta } from '@/blocks/blocks/peopledatalabs' -import { PerplexityBlock, PerplexityBlockMeta } from '@/blocks/blocks/perplexity' -import { PersonaBlock, PersonaBlockMeta } from '@/blocks/blocks/persona' +import { NotionBlock, NotionV2Block } from '@/blocks/blocks/notion' +import { ObsidianBlock } from '@/blocks/blocks/obsidian' +import { OktaBlock } from '@/blocks/blocks/okta' +import { OneDriveBlock } from '@/blocks/blocks/onedrive' +import { OnePasswordBlock } from '@/blocks/blocks/onepassword' +import { OpenAIBlock } from '@/blocks/blocks/openai' +import { OutlookBlock } from '@/blocks/blocks/outlook' +import { PagerDutyBlock } from '@/blocks/blocks/pagerduty' +import { ParallelBlock } from '@/blocks/blocks/parallel' +import { PeopleDataLabsBlock } from '@/blocks/blocks/peopledatalabs' +import { PerplexityBlock } from '@/blocks/blocks/perplexity' +import { PersonaBlock } from '@/blocks/blocks/persona' import { PiBlock } from '@/blocks/blocks/pi' -import { PineconeBlock, PineconeBlockMeta } from '@/blocks/blocks/pinecone' -import { PipedriveBlock, PipedriveBlockMeta } from '@/blocks/blocks/pipedrive' -import { PolymarketBlock, PolymarketBlockMeta } from '@/blocks/blocks/polymarket' +import { PineconeBlock } from '@/blocks/blocks/pinecone' +import { PipedriveBlock } from '@/blocks/blocks/pipedrive' +import { PolymarketBlock } from '@/blocks/blocks/polymarket' import { PostgreSQLBlock } from '@/blocks/blocks/postgresql' -import { PostHogBlock, PostHogBlockMeta } from '@/blocks/blocks/posthog' -import { ProfoundBlock, ProfoundBlockMeta } from '@/blocks/blocks/profound' -import { ProspeoBlock, ProspeoBlockMeta } from '@/blocks/blocks/prospeo' -import { PulseBlock, PulseBlockMeta, PulseV2Block } from '@/blocks/blocks/pulse' -import { QdrantBlock, QdrantBlockMeta } from '@/blocks/blocks/qdrant' -import { QuartrBlock, QuartrBlockMeta } from '@/blocks/blocks/quartr' -import { QuiverBlock, QuiverBlockMeta } from '@/blocks/blocks/quiver' -import { RailwayBlock, RailwayBlockMeta } from '@/blocks/blocks/railway' -import { RB2BBlock, RB2BBlockMeta } from '@/blocks/blocks/rb2b' -import { RDSBlock, RDSBlockMeta } from '@/blocks/blocks/rds' -import { RedditBlock, RedditBlockMeta } from '@/blocks/blocks/reddit' -import { RedisBlock, RedisBlockMeta } from '@/blocks/blocks/redis' -import { ReductoBlock, ReductoBlockMeta, ReductoV2Block } from '@/blocks/blocks/reducto' -import { ResendBlock, ResendBlockMeta } from '@/blocks/blocks/resend' +import { PostHogBlock } from '@/blocks/blocks/posthog' +import { ProfoundBlock } from '@/blocks/blocks/profound' +import { ProspeoBlock } from '@/blocks/blocks/prospeo' +import { PulseBlock, PulseV2Block } from '@/blocks/blocks/pulse' +import { QdrantBlock } from '@/blocks/blocks/qdrant' +import { QuartrBlock } from '@/blocks/blocks/quartr' +import { QuiverBlock } from '@/blocks/blocks/quiver' +import { RailwayBlock } from '@/blocks/blocks/railway' +import { RB2BBlock } from '@/blocks/blocks/rb2b' +import { RDSBlock } from '@/blocks/blocks/rds' +import { RedditBlock } from '@/blocks/blocks/reddit' +import { RedisBlock } from '@/blocks/blocks/redis' +import { ReductoBlock, ReductoV2Block } from '@/blocks/blocks/reducto' +import { ResendBlock } from '@/blocks/blocks/resend' import { ResponseBlock } from '@/blocks/blocks/response' -import { RevenueCatBlock, RevenueCatBlockMeta } from '@/blocks/blocks/revenuecat' -import { RipplingBlock, RipplingBlockMeta } from '@/blocks/blocks/rippling' -import { RootlyBlock, RootlyBlockMeta } from '@/blocks/blocks/rootly' +import { RevenueCatBlock } from '@/blocks/blocks/revenuecat' +import { RipplingBlock } from '@/blocks/blocks/rippling' +import { RootlyBlock } from '@/blocks/blocks/rootly' import { RouterBlock, RouterV2Block } from '@/blocks/blocks/router' -import { RssBlock, RssBlockMeta } from '@/blocks/blocks/rss' -import { S3Block, S3BlockMeta } from '@/blocks/blocks/s3' -import { SalesforceBlock, SalesforceBlockMeta } from '@/blocks/blocks/salesforce' -import { SapConcurBlock, SapConcurBlockMeta } from '@/blocks/blocks/sap_concur' -import { SapS4HanaBlock, SapS4HanaBlockMeta } from '@/blocks/blocks/sap_s4hana' +import { RssBlock } from '@/blocks/blocks/rss' +import { S3Block } from '@/blocks/blocks/s3' +import { SalesforceBlock } from '@/blocks/blocks/salesforce' +import { SapConcurBlock } from '@/blocks/blocks/sap_concur' +import { SapS4HanaBlock } from '@/blocks/blocks/sap_s4hana' import { ScheduleBlock } from '@/blocks/blocks/schedule' import { SearchBlock } from '@/blocks/blocks/search' -import { SecretsManagerBlock, SecretsManagerBlockMeta } from '@/blocks/blocks/secrets_manager' -import { SendblueBlock, SendblueBlockMeta } from '@/blocks/blocks/sendblue' -import { SendGridBlock, SendGridBlockMeta } from '@/blocks/blocks/sendgrid' -import { SentryBlock, SentryBlockMeta } from '@/blocks/blocks/sentry' -import { SerperBlock, SerperBlockMeta } from '@/blocks/blocks/serper' -import { ServiceNowBlock, ServiceNowBlockMeta } from '@/blocks/blocks/servicenow' -import { SESBlock, SESBlockMeta } from '@/blocks/blocks/ses' +import { SecretsManagerBlock } from '@/blocks/blocks/secrets_manager' +import { SendblueBlock } from '@/blocks/blocks/sendblue' +import { SendGridBlock } from '@/blocks/blocks/sendgrid' +import { SentryBlock } from '@/blocks/blocks/sentry' +import { SerperBlock } from '@/blocks/blocks/serper' +import { ServiceNowBlock } from '@/blocks/blocks/servicenow' +import { SESBlock } from '@/blocks/blocks/ses' import { SftpBlock } from '@/blocks/blocks/sftp' -import { SharepointBlock, SharepointBlockMeta, SharepointV2Block } from '@/blocks/blocks/sharepoint' -import { ShopifyBlock, ShopifyBlockMeta } from '@/blocks/blocks/shopify' +import { SharepointBlock, SharepointV2Block } from '@/blocks/blocks/sharepoint' +import { ShopifyBlock } from '@/blocks/blocks/shopify' import { SimWorkspaceEventBlock } from '@/blocks/blocks/sim_workspace_event' -import { SimilarwebBlock, SimilarwebBlockMeta } from '@/blocks/blocks/similarweb' -import { SixtyfourBlock, SixtyfourBlockMeta } from '@/blocks/blocks/sixtyfour' -import { SlackBlock, SlackBlockMeta } from '@/blocks/blocks/slack' +import { SimilarwebBlock } from '@/blocks/blocks/similarweb' +import { SixtyfourBlock } from '@/blocks/blocks/sixtyfour' +import { SlackBlock } from '@/blocks/blocks/slack' import { SmtpBlock } from '@/blocks/blocks/smtp' -import { SportmonksBlock, SportmonksBlockMeta } from '@/blocks/blocks/sportmonks' -import { SpotifyBlock, SpotifyBlockMeta } from '@/blocks/blocks/spotify' -import { SQSBlock, SQSBlockMeta } from '@/blocks/blocks/sqs' -import { SquareBlock, SquareBlockMeta } from '@/blocks/blocks/square' +import { SportmonksBlock } from '@/blocks/blocks/sportmonks' +import { SpotifyBlock } from '@/blocks/blocks/spotify' +import { SQSBlock } from '@/blocks/blocks/sqs' +import { SquareBlock } from '@/blocks/blocks/square' import { SSHBlock } from '@/blocks/blocks/ssh' -import { StagehandBlock, StagehandBlockMeta } from '@/blocks/blocks/stagehand' +import { StagehandBlock } from '@/blocks/blocks/stagehand' import { StartTriggerBlock } from '@/blocks/blocks/start_trigger' import { StarterBlock } from '@/blocks/blocks/starter' -import { StripeBlock, StripeBlockMeta } from '@/blocks/blocks/stripe' -import { STSBlock, STSBlockMeta } from '@/blocks/blocks/sts' +import { StripeBlock } from '@/blocks/blocks/stripe' +import { STSBlock } from '@/blocks/blocks/sts' import { SttBlock, SttV2Block } from '@/blocks/blocks/stt' -import { SupabaseBlock, SupabaseBlockMeta } from '@/blocks/blocks/supabase' +import { SupabaseBlock } from '@/blocks/blocks/supabase' import { TableBlock } from '@/blocks/blocks/table' -import { TailscaleBlock, TailscaleBlockMeta } from '@/blocks/blocks/tailscale' -import { TavilyBlock, TavilyBlockMeta } from '@/blocks/blocks/tavily' -import { TelegramBlock, TelegramBlockMeta } from '@/blocks/blocks/telegram' -import { TemporalBlock, TemporalBlockMeta } from '@/blocks/blocks/temporal' -import { TextractBlock, TextractBlockMeta, TextractV2Block } from '@/blocks/blocks/textract' +import { TailscaleBlock } from '@/blocks/blocks/tailscale' +import { TavilyBlock } from '@/blocks/blocks/tavily' +import { TelegramBlock } from '@/blocks/blocks/telegram' +import { TemporalBlock } from '@/blocks/blocks/temporal' +import { TextractBlock, TextractV2Block } from '@/blocks/blocks/textract' import { ThinkingBlock } from '@/blocks/blocks/thinking' -import { ThriveBlock, ThriveBlockMeta } from '@/blocks/blocks/thrive' -import { TinybirdBlock, TinybirdBlockMeta } from '@/blocks/blocks/tinybird' +import { ThriveBlock } from '@/blocks/blocks/thrive' +import { TinybirdBlock } from '@/blocks/blocks/tinybird' import { TranslateBlock } from '@/blocks/blocks/translate' -import { TrelloBlock, TrelloBlockMeta } from '@/blocks/blocks/trello' -import { TriggerDevBlock, TriggerDevBlockMeta } from '@/blocks/blocks/trigger_dev' +import { TrelloBlock } from '@/blocks/blocks/trello' +import { TriggerDevBlock } from '@/blocks/blocks/trigger_dev' import { TtsBlock } from '@/blocks/blocks/tts' -import { TwilioSMSBlock, TwilioSMSBlockMeta } from '@/blocks/blocks/twilio' -import { TwilioVoiceBlock, TwilioVoiceBlockMeta } from '@/blocks/blocks/twilio_voice' -import { TypeformBlock, TypeformBlockMeta } from '@/blocks/blocks/typeform' -import { UpstashBlock, UpstashBlockMeta } from '@/blocks/blocks/upstash' -import { VantaBlock, VantaBlockMeta } from '@/blocks/blocks/vanta' +import { TwilioSMSBlock } from '@/blocks/blocks/twilio' +import { TwilioVoiceBlock } from '@/blocks/blocks/twilio_voice' +import { TypeformBlock } from '@/blocks/blocks/typeform' +import { UpstashBlock } from '@/blocks/blocks/upstash' +import { VantaBlock } from '@/blocks/blocks/vanta' import { VariablesBlock } from '@/blocks/blocks/variables' -import { VercelBlock, VercelBlockMeta } from '@/blocks/blocks/vercel' +import { VercelBlock } from '@/blocks/blocks/vercel' import { VideoGeneratorBlock, VideoGeneratorV2Block, @@ -311,23 +259,24 @@ import { } from '@/blocks/blocks/video_generator' import { VisionBlock, VisionV2Block } from '@/blocks/blocks/vision' import { WaitBlock } from '@/blocks/blocks/wait' -import { WealthboxBlock, WealthboxBlockMeta } from '@/blocks/blocks/wealthbox' -import { WebflowBlock, WebflowBlockMeta } from '@/blocks/blocks/webflow' +import { WealthboxBlock } from '@/blocks/blocks/wealthbox' +import { WebflowBlock } from '@/blocks/blocks/webflow' import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request' -import { WhatsAppBlock, WhatsAppBlockMeta } from '@/blocks/blocks/whatsapp' -import { WikipediaBlock, WikipediaBlockMeta } from '@/blocks/blocks/wikipedia' -import { WizaBlock, WizaBlockMeta } from '@/blocks/blocks/wiza' -import { WordPressBlock, WordPressBlockMeta } from '@/blocks/blocks/wordpress' -import { WorkdayBlock, WorkdayBlockMeta } from '@/blocks/blocks/workday' +import { WhatsAppBlock } from '@/blocks/blocks/whatsapp' +import { WikipediaBlock } from '@/blocks/blocks/wikipedia' +import { WizaBlock } from '@/blocks/blocks/wiza' +import { WordPressBlock } from '@/blocks/blocks/wordpress' +import { WorkdayBlock } from '@/blocks/blocks/workday' import { WorkflowBlock } from '@/blocks/blocks/workflow' import { WorkflowInputBlock } from '@/blocks/blocks/workflow_input' -import { XBlock, XBlockMeta } from '@/blocks/blocks/x' -import { YouTubeBlock, YouTubeBlockMeta } from '@/blocks/blocks/youtube' -import { ZendeskBlock, ZendeskBlockMeta } from '@/blocks/blocks/zendesk' -import { ZepBlock, ZepBlockMeta } from '@/blocks/blocks/zep' -import { ZeroBounceBlock, ZeroBounceBlockMeta } from '@/blocks/blocks/zerobounce' -import { ZoomBlock, ZoomBlockMeta } from '@/blocks/blocks/zoom' -import { ZoomInfoBlock, ZoomInfoBlockMeta } from '@/blocks/blocks/zoominfo' +import { XBlock } from '@/blocks/blocks/x' +import { YouTubeBlock } from '@/blocks/blocks/youtube' +import { ZendeskBlock } from '@/blocks/blocks/zendesk' +import { ZepBlock } from '@/blocks/blocks/zep' +import { ZeroBounceBlock } from '@/blocks/blocks/zerobounce' +import { ZoomBlock } from '@/blocks/blocks/zoom' +import { ZoomInfoBlock } from '@/blocks/blocks/zoominfo' +import { BLOCK_CATALOG } from '@/blocks/manifest-data' import type { BlockCategory, BlockConfig, @@ -640,253 +589,6 @@ const BLOCK_REGISTRY: Record = { zoominfo: ZoomInfoBlock, } -/** - * Block presentation/catalog metas (`{ tags, templates }`) keyed by block - * type. Sibling to `BLOCK_REGISTRY`; pulled from the same block files so the - * two stay in lockstep without a separate registry to maintain. - * - * `BlockMeta` exists only for catalog-visible integrations — every key here - * has a corresponding entry in `lib/integrations/integrations.json`. Blocks - * absent from the catalog (core blocks like `agent`/`api`, superseded base - * versions, and hidden tools) carry no meta because the only consumers are - * integration surfaces: `getTemplatesForBlock` (the two integration detail - * pages) and `getAllBlockMeta()` → `POPULAR_WORKFLOWS` (landing integrations - * index). The toolbar and search modal read block *configs*, not metas. - */ -const BLOCK_META_REGISTRY: Record = { - agentmail: AgentMailBlockMeta, - agentphone: AgentPhoneBlockMeta, - agiloft: AgiloftBlockMeta, - ahrefs: AhrefsBlockMeta, - airtable: AirtableBlockMeta, - airweave: AirweaveBlockMeta, - algolia: AlgoliaBlockMeta, - amplitude: AmplitudeBlockMeta, - apify: ApifyBlockMeta, - appconfig: AppConfigBlockMeta, - apollo: ApolloBlockMeta, - arxiv: ArxivBlockMeta, - asana: AsanaBlockMeta, - ashby: AshbyBlockMeta, - athena: AthenaBlockMeta, - attio: AttioBlockMeta, - azure_devops: AzureDevOpsBlockMeta, - box: BoxBlockMeta, - brandfetch: BrandfetchBlockMeta, - brex: BrexBlockMeta, - brightdata: BrightDataBlockMeta, - browser_use: BrowserUseBlockMeta, - calcom: CalComBlockMeta, - calendly: CalendlyBlockMeta, - circleback: CirclebackBlockMeta, - clay: ClayBlockMeta, - clerk: ClerkBlockMeta, - clickhouse: ClickHouseBlockMeta, - cloudflare: CloudflareBlockMeta, - cloudformation: CloudFormationBlockMeta, - cloudwatch: CloudWatchBlockMeta, - codepipeline: CodePipelineBlockMeta, - confluence: ConfluenceBlockMeta, - context_dev: ContextDevBlockMeta, - convex: ConvexBlockMeta, - crowdstrike: CrowdStrikeBlockMeta, - cursor: CursorBlockMeta, - dagster: DagsterBlockMeta, - databricks: DatabricksBlockMeta, - datadog: DatadogBlockMeta, - datagma: DatagmaBlockMeta, - daytona: DaytonaBlockMeta, - devin: DevinBlockMeta, - discord: DiscordBlockMeta, - docusign: DocuSignBlockMeta, - dropbox: DropboxBlockMeta, - dropcontact: DropcontactBlockMeta, - dspy: DSPyBlockMeta, - dub: DubBlockMeta, - duckduckgo: DuckDuckGoBlockMeta, - dynamodb: DynamoDBBlockMeta, - elasticsearch: ElasticsearchBlockMeta, - elevenlabs: ElevenLabsBlockMeta, - emailbison: EmailBisonBlockMeta, - enrich: EnrichBlockMeta, - enrichment: EnrichmentBlockMeta, - enrow: EnrowBlockMeta, - evernote: EvernoteBlockMeta, - exa: ExaBlockMeta, - extend: ExtendBlockMeta, - fathom: FathomBlockMeta, - findymail: FindymailBlockMeta, - firecrawl: FirecrawlBlockMeta, - fireflies: FirefliesBlockMeta, - fireflies_v2: FirefliesV2BlockMeta, - gamma: GammaBlockMeta, - github: GitHubBlockMeta, - github_v2: GitHubV2BlockMeta, - gitlab: GitLabBlockMeta, - gmail: GmailBlockMeta, - gmail_v2: GmailV2BlockMeta, - gong: GongBlockMeta, - google_ads: GoogleAdsBlockMeta, - google_bigquery: GoogleBigQueryBlockMeta, - google_books: GoogleBooksBlockMeta, - google_calendar: GoogleCalendarBlockMeta, - google_calendar_v2: GoogleCalendarV2BlockMeta, - google_contacts: GoogleContactsBlockMeta, - google_docs: GoogleDocsBlockMeta, - google_drive: GoogleDriveBlockMeta, - google_forms: GoogleFormsBlockMeta, - google_groups: GoogleGroupsBlockMeta, - google_maps: GoogleMapsBlockMeta, - google_meet: GoogleMeetBlockMeta, - google_pagespeed: GooglePagespeedBlockMeta, - google_search: GoogleSearchBlockMeta, - google_sheets: GoogleSheetsBlockMeta, - google_sheets_v2: GoogleSheetsV2BlockMeta, - google_slides: GoogleSlidesBlockMeta, - google_slides_v2: GoogleSlidesV2BlockMeta, - google_tasks: GoogleTasksBlockMeta, - google_translate: GoogleTranslateBlockMeta, - google_vault: GoogleVaultBlockMeta, - grafana: GrafanaBlockMeta, - grain: GrainBlockMeta, - granola: GranolaBlockMeta, - greenhouse: GreenhouseBlockMeta, - greptile: GreptileBlockMeta, - hex: HexBlockMeta, - hubspot: HubSpotBlockMeta, - huggingface: HuggingFaceBlockMeta, - hunter: HunterBlockMeta, - iam: IAMBlockMeta, - icypeas: IcypeasBlockMeta, - identity_center: IdentityCenterBlockMeta, - imap: ImapBlockMeta, - incidentio: IncidentioBlockMeta, - infisical: InfisicalBlockMeta, - instantly: InstantlyBlockMeta, - intercom: IntercomBlockMeta, - intercom_v2: IntercomV2BlockMeta, - jina: JinaBlockMeta, - jira: JiraBlockMeta, - jira_service_management: JiraServiceManagementBlockMeta, - kalshi: KalshiBlockMeta, - kalshi_v2: KalshiV2BlockMeta, - ketch: KetchBlockMeta, - langsmith: LangsmithBlockMeta, - latex: LatexBlockMeta, - launchdarkly: LaunchDarklyBlockMeta, - leadmagic: LeadMagicBlockMeta, - lemlist: LemlistBlockMeta, - linear: LinearBlockMeta, - linkedin: LinkedInBlockMeta, - linkup: LinkupBlockMeta, - linq: LinqBlockMeta, - loops: LoopsBlockMeta, - luma: LumaBlockMeta, - mailchimp: MailchimpBlockMeta, - mailgun: MailgunBlockMeta, - mem0: Mem0BlockMeta, - microsoft_ad: MicrosoftAdBlockMeta, - microsoft_dataverse: MicrosoftDataverseBlockMeta, - microsoft_excel: MicrosoftExcelBlockMeta, - microsoft_excel_v2: MicrosoftExcelV2BlockMeta, - microsoft_planner: MicrosoftPlannerBlockMeta, - microsoft_teams: MicrosoftTeamsBlockMeta, - millionverifier: MillionVerifierBlockMeta, - mistral_parse: MistralParseBlockMeta, - monday: MondayBlockMeta, - mongodb: MongoDBBlockMeta, - neo4j: Neo4jBlockMeta, - neverbounce: NeverBounceBlockMeta, - new_relic: NewRelicBlockMeta, - notion: NotionBlockMeta, - notion_v2: NotionV2BlockMeta, - obsidian: ObsidianBlockMeta, - okta: OktaBlockMeta, - onedrive: OneDriveBlockMeta, - onepassword: OnePasswordBlockMeta, - openai: OpenAIBlockMeta, - outlook: OutlookBlockMeta, - pagerduty: PagerDutyBlockMeta, - parallel_ai: ParallelBlockMeta, - peopledatalabs: PeopleDataLabsBlockMeta, - perplexity: PerplexityBlockMeta, - persona: PersonaBlockMeta, - pinecone: PineconeBlockMeta, - pipedrive: PipedriveBlockMeta, - polymarket: PolymarketBlockMeta, - posthog: PostHogBlockMeta, - profound: ProfoundBlockMeta, - prospeo: ProspeoBlockMeta, - pulse: PulseBlockMeta, - qdrant: QdrantBlockMeta, - quartr: QuartrBlockMeta, - quiver: QuiverBlockMeta, - railway: RailwayBlockMeta, - rb2b: RB2BBlockMeta, - rds: RDSBlockMeta, - reddit: RedditBlockMeta, - redis: RedisBlockMeta, - reducto: ReductoBlockMeta, - resend: ResendBlockMeta, - revenuecat: RevenueCatBlockMeta, - rippling: RipplingBlockMeta, - rootly: RootlyBlockMeta, - rss: RssBlockMeta, - s3: S3BlockMeta, - salesforce: SalesforceBlockMeta, - sap_concur: SapConcurBlockMeta, - sap_s4hana: SapS4HanaBlockMeta, - secrets_manager: SecretsManagerBlockMeta, - sendblue: SendblueBlockMeta, - sendgrid: SendGridBlockMeta, - sentry: SentryBlockMeta, - serper: SerperBlockMeta, - servicenow: ServiceNowBlockMeta, - ses: SESBlockMeta, - sharepoint: SharepointBlockMeta, - shopify: ShopifyBlockMeta, - similarweb: SimilarwebBlockMeta, - sixtyfour: SixtyfourBlockMeta, - slack: SlackBlockMeta, - sportmonks: SportmonksBlockMeta, - spotify: SpotifyBlockMeta, - sqs: SQSBlockMeta, - square: SquareBlockMeta, - stagehand: StagehandBlockMeta, - stripe: StripeBlockMeta, - sts: STSBlockMeta, - supabase: SupabaseBlockMeta, - tailscale: TailscaleBlockMeta, - tavily: TavilyBlockMeta, - telegram: TelegramBlockMeta, - temporal: TemporalBlockMeta, - textract: TextractBlockMeta, - thrive: ThriveBlockMeta, - tinybird: TinybirdBlockMeta, - trello: TrelloBlockMeta, - trigger_dev: TriggerDevBlockMeta, - twilio_sms: TwilioSMSBlockMeta, - twilio_voice: TwilioVoiceBlockMeta, - typeform: TypeformBlockMeta, - upstash: UpstashBlockMeta, - vanta: VantaBlockMeta, - vercel: VercelBlockMeta, - wealthbox: WealthboxBlockMeta, - webflow: WebflowBlockMeta, - whatsapp: WhatsAppBlockMeta, - wikipedia: WikipediaBlockMeta, - wiza: WizaBlockMeta, - wordpress: WordPressBlockMeta, - workday: WorkdayBlockMeta, - x: XBlockMeta, - youtube: YouTubeBlockMeta, - zendesk: ZendeskBlockMeta, - zep: ZepBlockMeta, - zerobounce: ZeroBounceBlockMeta, - zoom: ZoomBlockMeta, - zoominfo: ZoomInfoBlockMeta, -} - /** * Normalize an external block type to its registry key form: dashes become * underscores (some external sources use either form). @@ -984,15 +686,15 @@ export function isValidBlockType(type: string): type is string { export function getBlockMeta(type: string): BlockMeta | undefined { const normalized = normalizeType(type) return ( - BLOCK_META_REGISTRY[type] ?? - BLOCK_META_REGISTRY[normalized] ?? - BLOCK_META_REGISTRY[stripVersionSuffix(normalized)] + BLOCK_CATALOG[type] ?? + BLOCK_CATALOG[normalized] ?? + BLOCK_CATALOG[stripVersionSuffix(normalized)] ) } /** All block metas keyed by block type. */ export function getAllBlockMeta(): Record { - return BLOCK_META_REGISTRY + return BLOCK_CATALOG } /** @@ -1014,7 +716,7 @@ export interface ScopedBlockTemplate extends BlockTemplate { export function getTemplatesForBlock(type: string): ScopedBlockTemplate[] { const base = stripVersionSuffix(type) const collected: ScopedBlockTemplate[] = [] - for (const [ownerType, meta] of Object.entries(BLOCK_META_REGISTRY)) { + for (const [ownerType, meta] of Object.entries(BLOCK_CATALOG)) { if (!meta.templates) continue const ownerBase = stripVersionSuffix(ownerType) const isOwnerMatch = ownerBase === base @@ -1045,7 +747,7 @@ export function getSuggestedSkillsForBlock(type: string): readonly SuggestedSkil const direct = getBlockMeta(type)?.skills if (direct && direct.length > 0) return direct const base = stripVersionSuffix(normalizeType(type)) - return BLOCK_META_REGISTRY[base]?.skills ?? [] + return BLOCK_CATALOG[base]?.skills ?? [] } /** diff --git a/apps/sim/lib/integrations/index.ts b/apps/sim/lib/integrations/index.ts index 926f466ff78..b2396c44d66 100644 --- a/apps/sim/lib/integrations/index.ts +++ b/apps/sim/lib/integrations/index.ts @@ -15,7 +15,7 @@ import { stripVersionSuffix } from '@sim/utils/string' import integrationsJson from '@/lib/integrations/integrations.json' import type { Integration } from '@/lib/integrations/types' -import { getAllBlockMeta } from '@/blocks/registry' +import { getAllBlockMeta } from '@/blocks/manifest' /** All integrations surfaced in the catalog, ordered by `scripts/generate-docs.ts`. */ export const INTEGRATIONS: readonly Integration[] = @@ -74,6 +74,6 @@ export { resolveOAuthServiceForSlug, } from '@/lib/integrations/oauth-service' export type { AuthType, FAQItem, Integration } from '@/lib/integrations/types' -export { getAllBlockMeta, getBlockMeta, getTemplatesForBlock } from '@/blocks/registry' +export { getAllBlockMeta, getBlockMeta, getTemplatesForBlock } from '@/blocks/manifest' export type { BlockMeta, BlockTemplate } from '@/blocks/types' export { formatIntegrationType } from '@/blocks/types' diff --git a/apps/sim/scripts/codemod-block-meta.ts b/apps/sim/scripts/codemod-block-meta.ts new file mode 100644 index 00000000000..339770ec5dc --- /dev/null +++ b/apps/sim/scripts/codemod-block-meta.ts @@ -0,0 +1,113 @@ +// @ts-nocheck — one-time codemod, run via a scratch `bun add ts-morph` (ts-morph is intentionally +// not a project dependency). Moves each blocks/blocks/.ts `export const BlockMeta = {...}` +// into the existing .display.ts (merging the icon/type imports it references), and removes it +// from .ts. Idempotent: a file whose meta is already gone is skipped. +import { readdirSync } from 'node:fs' +import path from 'node:path' +import { Node, Project } from 'ts-morph' + +const APP = process.cwd() +const BLOCK_DIR = path.join(APP, 'blocks/blocks') +const onlyArg = process.argv[2] // optional single-file test, e.g. slack.ts + +const project = new Project({ + tsConfigFilePath: path.join(APP, 'tsconfig.json'), + skipAddingFilesFromTsConfig: true, +}) + +function referencedIdents(node: Node): Set { + const out = new Set() + node.forEachDescendant((d) => { + if (Node.isIdentifier(d)) out.add(d.getText()) + }) + return out +} + +const results: { file: string; status: string; note?: string }[] = [] + +const files = readdirSync(BLOCK_DIR) + .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && !f.endsWith('.display.ts')) + .filter((f) => (onlyArg ? f === onlyArg : true)) + +for (const file of files) { + const base = file.replace(/\.ts$/, '') + const sf = project.addSourceFileAtPath(path.join(BLOCK_DIR, file)) + try { + // collect exported `BlockMeta` object-literal consts + const metas: { name: string; stmt: ReturnType[number] }[] = [] + for (const vs of sf.getVariableStatements()) { + if (!vs.isExported()) continue + for (const decl of vs.getDeclarations()) { + if (!decl.getName().endsWith('BlockMeta')) continue + if (!decl.getInitializer()) continue // value const (incl. `{...} satisfies BlockMeta`) + metas.push({ name: decl.getName(), stmt: vs }) + } + } + if (metas.length === 0) { + results.push({ file, status: 'skip' }) + project.removeSourceFile(sf) + continue + } + + const displayPath = path.join(BLOCK_DIR, `${base}.display.ts`) + let displaySf + try { + displaySf = project.addSourceFileAtPath(displayPath) + } catch { + results.push({ file, status: 'ERROR', note: 'no .display.ts to append to' }) + project.removeSourceFile(sf) + continue + } + + // identifiers referenced by all metas → resolve to block.ts imports (icons + BlockMeta type). + // Merge as plain named imports keyed by module (type names work in `satisfies` position). + const wantByModule = new Map>() + for (const m of metas) { + for (const id of referencedIdents(m.stmt)) { + if (id === m.name) continue + const imp = sf + .getImportDeclarations() + .find((d) => + d.getNamedImports().some((n) => (n.getAliasNode()?.getText() ?? n.getName()) === id) + ) + if (!imp) continue + const mod = imp.getModuleSpecifierValue() + if (!wantByModule.has(mod)) wantByModule.set(mod, new Set()) + wantByModule.get(mod)!.add(id) + } + } + + // merge into .display.ts: extend an existing same-module decl, else create one WITH its names + for (const [mod, names] of wantByModule) { + const decl = displaySf + .getImportDeclarations() + .find((d) => d.getModuleSpecifierValue() === mod) + const present = new Set( + decl?.getNamedImports().map((n) => n.getAliasNode()?.getText() ?? n.getName()) ?? [] + ) + const toAdd = [...names].filter((n) => !present.has(n)).sort() + if (toAdd.length === 0) continue + if (decl) decl.addNamedImports(toAdd) + else displaySf.addImportDeclaration({ moduleSpecifier: mod, namedImports: toAdd }) + } + + // append the meta const(s) to .display.ts, then remove from block.ts + for (const m of metas) { + displaySf.addStatements(`\n${m.stmt.getText()}`) + m.stmt.remove() + } + + results.push({ file, status: 'ok', note: `${metas.length} meta(s)` }) + } catch (e) { + results.push({ file, status: 'ERROR', note: String(e).slice(0, 140) }) + } +} + +project.saveSync() + +const ok = results.filter((r) => r.status === 'ok') +const err = results.filter((r) => r.status === 'ERROR') +console.log( + `ok=${ok.length} skip=${results.filter((r) => r.status === 'skip').length} err=${err.length}` +) +for (const r of err) console.log(` ERROR ${r.file} — ${r.note}`) diff --git a/apps/sim/scripts/generate-block-manifest-data.ts b/apps/sim/scripts/generate-block-manifest-data.ts index 8b521df8178..45b86b02e6a 100644 --- a/apps/sim/scripts/generate-block-manifest-data.ts +++ b/apps/sim/scripts/generate-block-manifest-data.ts @@ -1,13 +1,12 @@ /** * Generates `apps/sim/blocks/manifest-data.ts` — the registry-free aggregation * index over the per-block `.display.ts` files (the source of truth). Run - * after adding/renaming a block: `bun run scripts/generate-block-manifest-data.ts`. + * after adding/renaming a block: `bun run blocks:manifest-data`. * CI re-runs it and fails if `git diff` is non-empty. * - * `BLOCK_DISPLAY`/`TOOL_TO_BLOCK` are populated; `BLOCK_CATALOG` is intentionally - * empty until the per-block `{Service}BlockMeta` is moved into `.display.ts` - * (Phase 1b) — the catalog accessors (`getBlockCatalog`, `getTemplatesForBlock`) - * stay on `@/blocks/registry` until then. + * `BLOCK_DISPLAY` (light presentation slice), `TOOL_TO_BLOCK` (tool id → block), + * and `BLOCK_CATALOG` (the `{Service}BlockMeta` catalog data) are all aggregated + * from the `.display.ts` files — none of the heavy block configs are imported. */ import { readdirSync, readFileSync, writeFileSync } from 'node:fs' import path from 'node:path' @@ -24,6 +23,7 @@ interface DisplayEntry { } const entries: DisplayEntry[] = [] +const metaRaw: { constName: string; base: string }[] = [] for (const file of readdirSync(BLOCK_DIR).filter((f) => f.endsWith('.display.ts'))) { const base = file.replace(/\.display\.ts$/, '') const src = readFileSync(path.join(BLOCK_DIR, file), 'utf8') @@ -35,9 +35,26 @@ for (const file of readdirSync(BLOCK_DIR).filter((f) => f.endsWith('.display.ts' if (!typeMatch) throw new Error(`No type field in ${file} const ${constName}`) entries.push({ constName, type: typeMatch[1], base }) } + for (const mm of src.matchAll(/export const (\w+BlockMeta)\b/g)) { + metaRaw.push({ constName: mm[1], base }) + } } entries.sort((a, b) => a.type.localeCompare(b.type)) +// Each `BlockMeta` belongs to its sibling `BlockDisplay`; key the catalog by that display's type. +const displayByConst = new Map(entries.map((e) => [e.constName, e])) +const metaEntries = metaRaw + .map((mr) => { + const displayConst = mr.constName.replace(/Meta$/, 'Display') + const e = displayByConst.get(displayConst) + if (!e) + throw new Error( + `Meta ${mr.constName} in ${mr.base}.display.ts has no sibling display ${displayConst}` + ) + return { constName: mr.constName, base: mr.base, key: e.type } + }) + .sort((a, b) => a.key.localeCompare(b.key)) + // TOOL_TO_BLOCK from the registry (offline; the generated map is plain data) const toolToBlock: Record = {} for (const type of getAllBlockTypes()) { @@ -45,14 +62,26 @@ for (const type of getAllBlockTypes()) { for (const tool of cfg?.tools?.access ?? []) toolToBlock[tool] = type } -const imports = entries - .map((e) => `import { ${e.constName} } from '@/blocks/blocks/${e.base}.display'`) +// One import per base, combining its display + meta consts. +const importsByBase = new Map>() +for (const e of [...entries, ...metaEntries]) { + if (!importsByBase.has(e.base)) importsByBase.set(e.base, new Set()) + importsByBase.get(e.base)!.add(e.constName) +} +const imports = [...importsByBase] + .sort(([a], [b]) => a.localeCompare(b)) + .map( + ([base, names]) => + `import { ${[...names].sort().join(', ')} } from '@/blocks/blocks/${base}.display'` + ) .join('\n') + const displayMap = entries.map((e) => ` ${JSON.stringify(e.type)}: ${e.constName},`).join('\n') const toolMap = Object.keys(toolToBlock) .sort() .map((t) => ` ${JSON.stringify(t)}: ${JSON.stringify(toolToBlock[t])},`) .join('\n') +const catalogMap = metaEntries.map((e) => ` ${JSON.stringify(e.key)}: ${e.constName},`).join('\n') const body = `// @generated by scripts/generate-block-manifest-data.ts — do not edit by hand. // Source of truth is each blocks/blocks/.display.ts. Run \`bun run blocks:manifest-data\`. @@ -70,14 +99,13 @@ export const TOOL_TO_BLOCK: Record = { ${toolMap} } -/** - * Catalog meta (tags/templates/skills). Empty until each block's {Service}BlockMeta - * moves into its .display.ts (Phase 1b); catalog accessors fall back to @/blocks/registry. - */ -export const BLOCK_CATALOG: Record = {} +/** Catalog meta (tags/templates/skills) keyed by base block type. */ +export const BLOCK_CATALOG: Record = { +${catalogMap} +} ` writeFileSync(OUT, body) console.log( - `Wrote blocks/manifest-data.ts — ${entries.length} display entries, ${Object.keys(toolToBlock).length} tool mappings.` + `Wrote blocks/manifest-data.ts — ${entries.length} display, ${metaEntries.length} catalog, ${Object.keys(toolToBlock).length} tool mappings.` ) From cc94d5f2ed1370a69ed007845a10c0e8bf7aac4c Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 27 Jun 2026 09:37:14 -0700 Subject: [PATCH 3/4] =?UTF-8?q?perf(blocks):=20WIP=20Phase=202=20lazy=20co?= =?UTF-8?q?re=20=E2=80=94=20registry.ts=20=E2=86=92=20BLOCK=5FLOADERS=20+?= =?UTF-8?q?=20cache=20+=20loadBlockConfigs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit registry.ts no longer statically imports the 300 block configs. Each is now a lazy import() thunk in BLOCK_LOADERS; configs resolve into a sync cache via loadBlockConfig/ loadBlockConfigs/loadAllBlockConfigs. getBlock & co. read the cache synchronously and fail loud (dev warn) on a miss for a known type. Catalog accessors unchanged (read BLOCK_CATALOG). Dropped the `registry` raw-map alias; its 3 callers were display/existence checks → moved to getBlockDisplay (manifest) / isValidBlockType. type-check 0 errors. RUNTIME-BROKEN until preload wiring (next commit): every getBlock caller now needs its types preloaded. registry.ts compiles WITHOUT the 300 configs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../chat-context-kind-registry.tsx | 4 +- .../user-input/hooks/use-mention-data.ts | 4 +- apps/sim/blocks/registry.ts | 1030 +++++++---------- apps/sim/lib/copilot/chat/process-contents.ts | 4 +- 4 files changed, 423 insertions(+), 619 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/chat-context-kind-registry/chat-context-kind-registry.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/chat-context-kind-registry/chat-context-kind-registry.tsx index e01cbc5f80d..94c0dbdfe25 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/chat-context-kind-registry/chat-context-kind-registry.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/chat-context-kind-registry/chat-context-kind-registry.tsx @@ -12,7 +12,7 @@ import { AgentSkillsIcon } from '@/components/icons' import { getDocumentIcon } from '@/components/icons/document-icons' import type { ChatContextKind, ChatMessageContext } from '@/app/workspace/[workspaceId]/home/types' import { getBareIconStyle } from '@/blocks/icon-color' -import { registry as blockRegistry } from '@/blocks/registry' +import { getBlockDisplay } from '@/blocks/manifest' interface RenderIconArgs { context: ChatMessageContext @@ -39,7 +39,7 @@ function renderWorkflowIcon({ className }: RenderIconArgs): ReactNode | null { function renderIntegrationTile({ context, className }: RenderIconArgs): ReactNode | null { if (context.kind !== 'integration') return null if (!context.blockType) return null - const block = blockRegistry[context.blockType] + const block = getBlockDisplay(context.blockType) if (!block) return null const Icon = block.icon return diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/hooks/use-mention-data.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/hooks/use-mention-data.ts index 95508ac4102..15853c6dcb5 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/hooks/use-mention-data.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/hooks/use-mention-data.ts @@ -8,6 +8,7 @@ import { listCopilotChatsContract } from '@/lib/api/contracts/copilot' import { listKnowledgeBasesContract } from '@/lib/api/contracts/knowledge/base' import { listLogsContract } from '@/lib/api/contracts/logs' import { type IntegrationDescriptor, listIntegrations } from '@/blocks/integration-matcher' +import { getBlockDisplay } from '@/blocks/manifest' import { useWorkflows } from '@/hooks/queries/workflows' import { usePermissionConfig } from '@/hooks/use-permission-config' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' @@ -188,9 +189,8 @@ export function useMentionData(props: UseMentionDataProps): MentionDataReturn { // Fetch current blocks from store const workflowStoreBlocks = useWorkflowStore.getState().blocks - const { registry: blockRegistry } = await import('@/blocks/registry') const mapped = Object.values(workflowStoreBlocks).map((b: any) => { - const reg = (blockRegistry as any)[b.type] + const reg = getBlockDisplay(b.type) return { id: b.id, name: b.name || b.id, diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 3fb6cb78afc..609118a03e9 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -1,281 +1,5 @@ +import { createLogger } from '@sim/logger' import { stripVersionSuffix } from '@sim/utils/string' -import { A2ABlock } from '@/blocks/blocks/a2a' -import { AgentBlock } from '@/blocks/blocks/agent' -import { AgentMailBlock } from '@/blocks/blocks/agentmail' -import { AgentPhoneBlock } from '@/blocks/blocks/agentphone' -import { AgiloftBlock } from '@/blocks/blocks/agiloft' -import { AhrefsBlock } from '@/blocks/blocks/ahrefs' -import { AirtableBlock } from '@/blocks/blocks/airtable' -import { AirweaveBlock } from '@/blocks/blocks/airweave' -import { AlgoliaBlock } from '@/blocks/blocks/algolia' -import { AmplitudeBlock } from '@/blocks/blocks/amplitude' -import { ApiBlock } from '@/blocks/blocks/api' -import { ApiTriggerBlock } from '@/blocks/blocks/api_trigger' -import { ApifyBlock } from '@/blocks/blocks/apify' -import { ApolloBlock } from '@/blocks/blocks/apollo' -import { AppConfigBlock } from '@/blocks/blocks/appconfig' -import { ArxivBlock } from '@/blocks/blocks/arxiv' -import { AsanaBlock } from '@/blocks/blocks/asana' -import { AshbyBlock } from '@/blocks/blocks/ashby' -import { AthenaBlock } from '@/blocks/blocks/athena' -import { AttioBlock } from '@/blocks/blocks/attio' -import { AzureDevOpsBlock } from '@/blocks/blocks/azure_devops' -import { BoxBlock } from '@/blocks/blocks/box' -import { BrandfetchBlock } from '@/blocks/blocks/brandfetch' -import { BrexBlock } from '@/blocks/blocks/brex' -import { BrightDataBlock } from '@/blocks/blocks/brightdata' -import { BrowserUseBlock } from '@/blocks/blocks/browser_use' -import { CalComBlock } from '@/blocks/blocks/calcom' -import { CalendlyBlock } from '@/blocks/blocks/calendly' -import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger' -import { CirclebackBlock } from '@/blocks/blocks/circleback' -import { ClayBlock } from '@/blocks/blocks/clay' -import { ClerkBlock } from '@/blocks/blocks/clerk' -import { ClickHouseBlock } from '@/blocks/blocks/clickhouse' -import { CloudflareBlock } from '@/blocks/blocks/cloudflare' -import { CloudFormationBlock } from '@/blocks/blocks/cloudformation' -import { CloudWatchBlock } from '@/blocks/blocks/cloudwatch' -import { CodePipelineBlock } from '@/blocks/blocks/codepipeline' -import { ConditionBlock } from '@/blocks/blocks/condition' -import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence' -import { ContextDevBlock } from '@/blocks/blocks/context_dev' -import { ConvexBlock } from '@/blocks/blocks/convex' -import { CredentialBlock } from '@/blocks/blocks/credential' -import { CrowdStrikeBlock } from '@/blocks/blocks/crowdstrike' -import { CursorBlock, CursorV2Block } from '@/blocks/blocks/cursor' -import { DagsterBlock } from '@/blocks/blocks/dagster' -import { DatabricksBlock } from '@/blocks/blocks/databricks' -import { DatadogBlock } from '@/blocks/blocks/datadog' -import { DatagmaBlock } from '@/blocks/blocks/datagma' -import { DaytonaBlock } from '@/blocks/blocks/daytona' -import { DeploymentsBlock } from '@/blocks/blocks/deployments' -import { DevinBlock } from '@/blocks/blocks/devin' -import { DiscordBlock } from '@/blocks/blocks/discord' -import { DocuSignBlock } from '@/blocks/blocks/docusign' -import { DropboxBlock } from '@/blocks/blocks/dropbox' -import { DropcontactBlock } from '@/blocks/blocks/dropcontact' -import { DSPyBlock } from '@/blocks/blocks/dspy' -import { DubBlock } from '@/blocks/blocks/dub' -import { DuckDuckGoBlock } from '@/blocks/blocks/duckduckgo' -import { DynamoDBBlock } from '@/blocks/blocks/dynamodb' -import { ElasticsearchBlock } from '@/blocks/blocks/elasticsearch' -import { ElevenLabsBlock } from '@/blocks/blocks/elevenlabs' -import { EmailBisonBlock } from '@/blocks/blocks/emailbison' -import { EnrichBlock } from '@/blocks/blocks/enrich' -import { EnrichmentBlock } from '@/blocks/blocks/enrichment' -import { EnrowBlock } from '@/blocks/blocks/enrow' -import { EvaluatorBlock } from '@/blocks/blocks/evaluator' -import { EvernoteBlock } from '@/blocks/blocks/evernote' -import { ExaBlock } from '@/blocks/blocks/exa' -import { ExtendBlock, ExtendV2Block } from '@/blocks/blocks/extend' -import { FathomBlock } from '@/blocks/blocks/fathom' -import { FileBlock, FileV2Block, FileV3Block, FileV4Block, FileV5Block } from '@/blocks/blocks/file' -import { FindymailBlock } from '@/blocks/blocks/findymail' -import { FirecrawlBlock } from '@/blocks/blocks/firecrawl' -import { FirefliesBlock, FirefliesV2Block } from '@/blocks/blocks/fireflies' -import { FunctionBlock } from '@/blocks/blocks/function' -import { GammaBlock } from '@/blocks/blocks/gamma' -import { GenericWebhookBlock } from '@/blocks/blocks/generic_webhook' -import { GitHubBlock, GitHubV2Block } from '@/blocks/blocks/github' -import { GitLabBlock } from '@/blocks/blocks/gitlab' -import { GmailBlock, GmailV2Block } from '@/blocks/blocks/gmail' -import { GongBlock } from '@/blocks/blocks/gong' -import { GoogleSearchBlock } from '@/blocks/blocks/google' -import { GoogleAdsBlock } from '@/blocks/blocks/google_ads' -import { GoogleBigQueryBlock } from '@/blocks/blocks/google_bigquery' -import { GoogleBooksBlock } from '@/blocks/blocks/google_books' -import { GoogleCalendarBlock, GoogleCalendarV2Block } from '@/blocks/blocks/google_calendar' -import { GoogleContactsBlock } from '@/blocks/blocks/google_contacts' -import { GoogleDocsBlock } from '@/blocks/blocks/google_docs' -import { GoogleDriveBlock } from '@/blocks/blocks/google_drive' -import { GoogleFormsBlock } from '@/blocks/blocks/google_forms' -import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups' -import { GoogleMapsBlock } from '@/blocks/blocks/google_maps' -import { GoogleMeetBlock } from '@/blocks/blocks/google_meet' -import { GooglePagespeedBlock } from '@/blocks/blocks/google_pagespeed' -import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets' -import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides' -import { GoogleTasksBlock } from '@/blocks/blocks/google_tasks' -import { GoogleTranslateBlock } from '@/blocks/blocks/google_translate' -import { GoogleVaultBlock } from '@/blocks/blocks/google_vault' -import { GrafanaBlock } from '@/blocks/blocks/grafana' -import { GrainBlock } from '@/blocks/blocks/grain' -import { GranolaBlock } from '@/blocks/blocks/granola' -import { GreenhouseBlock } from '@/blocks/blocks/greenhouse' -import { GreptileBlock } from '@/blocks/blocks/greptile' -import { GuardrailsBlock } from '@/blocks/blocks/guardrails' -import { HexBlock } from '@/blocks/blocks/hex' -import { HubSpotBlock } from '@/blocks/blocks/hubspot' -import { HuggingFaceBlock } from '@/blocks/blocks/huggingface' -import { HumanInTheLoopBlock } from '@/blocks/blocks/human_in_the_loop' -import { HunterBlock } from '@/blocks/blocks/hunter' -import { IAMBlock } from '@/blocks/blocks/iam' -import { IcypeasBlock } from '@/blocks/blocks/icypeas' -import { IdentityCenterBlock } from '@/blocks/blocks/identity_center' -import { ImageGeneratorBlock, ImageGeneratorV2Block } from '@/blocks/blocks/image_generator' -import { ImapBlock } from '@/blocks/blocks/imap' -import { IncidentioBlock } from '@/blocks/blocks/incidentio' -import { InfisicalBlock } from '@/blocks/blocks/infisical' -import { InputTriggerBlock } from '@/blocks/blocks/input_trigger' -import { InstantlyBlock } from '@/blocks/blocks/instantly' -import { IntercomBlock, IntercomV2Block } from '@/blocks/blocks/intercom' -import { JinaBlock } from '@/blocks/blocks/jina' -import { JiraBlock } from '@/blocks/blocks/jira' -import { JiraServiceManagementBlock } from '@/blocks/blocks/jira_service_management' -import { KalshiBlock, KalshiV2Block } from '@/blocks/blocks/kalshi' -import { KetchBlock } from '@/blocks/blocks/ketch' -import { KnowledgeBlock } from '@/blocks/blocks/knowledge' -import { LangsmithBlock } from '@/blocks/blocks/langsmith' -import { LatexBlock } from '@/blocks/blocks/latex' -import { LaunchDarklyBlock } from '@/blocks/blocks/launchdarkly' -import { LeadMagicBlock } from '@/blocks/blocks/leadmagic' -import { LemlistBlock } from '@/blocks/blocks/lemlist' -import { LinearBlock, LinearV2Block } from '@/blocks/blocks/linear' -import { LinkedInBlock } from '@/blocks/blocks/linkedin' -import { LinkupBlock } from '@/blocks/blocks/linkup' -import { LinqBlock } from '@/blocks/blocks/linq' -import { LogsBlock, LogsV2Block } from '@/blocks/blocks/logs' -import { LoopsBlock } from '@/blocks/blocks/loops' -import { LumaBlock } from '@/blocks/blocks/luma' -import { MailchimpBlock } from '@/blocks/blocks/mailchimp' -import { MailgunBlock } from '@/blocks/blocks/mailgun' -import { ManualTriggerBlock } from '@/blocks/blocks/manual_trigger' -import { McpBlock } from '@/blocks/blocks/mcp' -import { Mem0Block } from '@/blocks/blocks/mem0' -import { MemoryBlock } from '@/blocks/blocks/memory' -import { MicrosoftAdBlock } from '@/blocks/blocks/microsoft_ad' -import { MicrosoftDataverseBlock } from '@/blocks/blocks/microsoft_dataverse' -import { MicrosoftExcelBlock, MicrosoftExcelV2Block } from '@/blocks/blocks/microsoft_excel' -import { MicrosoftPlannerBlock } from '@/blocks/blocks/microsoft_planner' -import { MicrosoftTeamsBlock } from '@/blocks/blocks/microsoft_teams' -import { MillionVerifierBlock } from '@/blocks/blocks/millionverifier' -import { - MistralParseBlock, - MistralParseV2Block, - MistralParseV3Block, -} from '@/blocks/blocks/mistral_parse' -import { MondayBlock } from '@/blocks/blocks/monday' -import { MongoDBBlock } from '@/blocks/blocks/mongodb' -import { MothershipBlock } from '@/blocks/blocks/mothership' -import { MySQLBlock } from '@/blocks/blocks/mysql' -import { Neo4jBlock } from '@/blocks/blocks/neo4j' -import { NeverBounceBlock } from '@/blocks/blocks/neverbounce' -import { NewRelicBlock } from '@/blocks/blocks/new_relic' -import { NoteBlock } from '@/blocks/blocks/note' -import { NotionBlock, NotionV2Block } from '@/blocks/blocks/notion' -import { ObsidianBlock } from '@/blocks/blocks/obsidian' -import { OktaBlock } from '@/blocks/blocks/okta' -import { OneDriveBlock } from '@/blocks/blocks/onedrive' -import { OnePasswordBlock } from '@/blocks/blocks/onepassword' -import { OpenAIBlock } from '@/blocks/blocks/openai' -import { OutlookBlock } from '@/blocks/blocks/outlook' -import { PagerDutyBlock } from '@/blocks/blocks/pagerduty' -import { ParallelBlock } from '@/blocks/blocks/parallel' -import { PeopleDataLabsBlock } from '@/blocks/blocks/peopledatalabs' -import { PerplexityBlock } from '@/blocks/blocks/perplexity' -import { PersonaBlock } from '@/blocks/blocks/persona' -import { PiBlock } from '@/blocks/blocks/pi' -import { PineconeBlock } from '@/blocks/blocks/pinecone' -import { PipedriveBlock } from '@/blocks/blocks/pipedrive' -import { PolymarketBlock } from '@/blocks/blocks/polymarket' -import { PostgreSQLBlock } from '@/blocks/blocks/postgresql' -import { PostHogBlock } from '@/blocks/blocks/posthog' -import { ProfoundBlock } from '@/blocks/blocks/profound' -import { ProspeoBlock } from '@/blocks/blocks/prospeo' -import { PulseBlock, PulseV2Block } from '@/blocks/blocks/pulse' -import { QdrantBlock } from '@/blocks/blocks/qdrant' -import { QuartrBlock } from '@/blocks/blocks/quartr' -import { QuiverBlock } from '@/blocks/blocks/quiver' -import { RailwayBlock } from '@/blocks/blocks/railway' -import { RB2BBlock } from '@/blocks/blocks/rb2b' -import { RDSBlock } from '@/blocks/blocks/rds' -import { RedditBlock } from '@/blocks/blocks/reddit' -import { RedisBlock } from '@/blocks/blocks/redis' -import { ReductoBlock, ReductoV2Block } from '@/blocks/blocks/reducto' -import { ResendBlock } from '@/blocks/blocks/resend' -import { ResponseBlock } from '@/blocks/blocks/response' -import { RevenueCatBlock } from '@/blocks/blocks/revenuecat' -import { RipplingBlock } from '@/blocks/blocks/rippling' -import { RootlyBlock } from '@/blocks/blocks/rootly' -import { RouterBlock, RouterV2Block } from '@/blocks/blocks/router' -import { RssBlock } from '@/blocks/blocks/rss' -import { S3Block } from '@/blocks/blocks/s3' -import { SalesforceBlock } from '@/blocks/blocks/salesforce' -import { SapConcurBlock } from '@/blocks/blocks/sap_concur' -import { SapS4HanaBlock } from '@/blocks/blocks/sap_s4hana' -import { ScheduleBlock } from '@/blocks/blocks/schedule' -import { SearchBlock } from '@/blocks/blocks/search' -import { SecretsManagerBlock } from '@/blocks/blocks/secrets_manager' -import { SendblueBlock } from '@/blocks/blocks/sendblue' -import { SendGridBlock } from '@/blocks/blocks/sendgrid' -import { SentryBlock } from '@/blocks/blocks/sentry' -import { SerperBlock } from '@/blocks/blocks/serper' -import { ServiceNowBlock } from '@/blocks/blocks/servicenow' -import { SESBlock } from '@/blocks/blocks/ses' -import { SftpBlock } from '@/blocks/blocks/sftp' -import { SharepointBlock, SharepointV2Block } from '@/blocks/blocks/sharepoint' -import { ShopifyBlock } from '@/blocks/blocks/shopify' -import { SimWorkspaceEventBlock } from '@/blocks/blocks/sim_workspace_event' -import { SimilarwebBlock } from '@/blocks/blocks/similarweb' -import { SixtyfourBlock } from '@/blocks/blocks/sixtyfour' -import { SlackBlock } from '@/blocks/blocks/slack' -import { SmtpBlock } from '@/blocks/blocks/smtp' -import { SportmonksBlock } from '@/blocks/blocks/sportmonks' -import { SpotifyBlock } from '@/blocks/blocks/spotify' -import { SQSBlock } from '@/blocks/blocks/sqs' -import { SquareBlock } from '@/blocks/blocks/square' -import { SSHBlock } from '@/blocks/blocks/ssh' -import { StagehandBlock } from '@/blocks/blocks/stagehand' -import { StartTriggerBlock } from '@/blocks/blocks/start_trigger' -import { StarterBlock } from '@/blocks/blocks/starter' -import { StripeBlock } from '@/blocks/blocks/stripe' -import { STSBlock } from '@/blocks/blocks/sts' -import { SttBlock, SttV2Block } from '@/blocks/blocks/stt' -import { SupabaseBlock } from '@/blocks/blocks/supabase' -import { TableBlock } from '@/blocks/blocks/table' -import { TailscaleBlock } from '@/blocks/blocks/tailscale' -import { TavilyBlock } from '@/blocks/blocks/tavily' -import { TelegramBlock } from '@/blocks/blocks/telegram' -import { TemporalBlock } from '@/blocks/blocks/temporal' -import { TextractBlock, TextractV2Block } from '@/blocks/blocks/textract' -import { ThinkingBlock } from '@/blocks/blocks/thinking' -import { ThriveBlock } from '@/blocks/blocks/thrive' -import { TinybirdBlock } from '@/blocks/blocks/tinybird' -import { TranslateBlock } from '@/blocks/blocks/translate' -import { TrelloBlock } from '@/blocks/blocks/trello' -import { TriggerDevBlock } from '@/blocks/blocks/trigger_dev' -import { TtsBlock } from '@/blocks/blocks/tts' -import { TwilioSMSBlock } from '@/blocks/blocks/twilio' -import { TwilioVoiceBlock } from '@/blocks/blocks/twilio_voice' -import { TypeformBlock } from '@/blocks/blocks/typeform' -import { UpstashBlock } from '@/blocks/blocks/upstash' -import { VantaBlock } from '@/blocks/blocks/vanta' -import { VariablesBlock } from '@/blocks/blocks/variables' -import { VercelBlock } from '@/blocks/blocks/vercel' -import { - VideoGeneratorBlock, - VideoGeneratorV2Block, - VideoGeneratorV3Block, -} from '@/blocks/blocks/video_generator' -import { VisionBlock, VisionV2Block } from '@/blocks/blocks/vision' -import { WaitBlock } from '@/blocks/blocks/wait' -import { WealthboxBlock } from '@/blocks/blocks/wealthbox' -import { WebflowBlock } from '@/blocks/blocks/webflow' -import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request' -import { WhatsAppBlock } from '@/blocks/blocks/whatsapp' -import { WikipediaBlock } from '@/blocks/blocks/wikipedia' -import { WizaBlock } from '@/blocks/blocks/wiza' -import { WordPressBlock } from '@/blocks/blocks/wordpress' -import { WorkdayBlock } from '@/blocks/blocks/workday' -import { WorkflowBlock } from '@/blocks/blocks/workflow' -import { WorkflowInputBlock } from '@/blocks/blocks/workflow_input' -import { XBlock } from '@/blocks/blocks/x' -import { YouTubeBlock } from '@/blocks/blocks/youtube' -import { ZendeskBlock } from '@/blocks/blocks/zendesk' -import { ZepBlock } from '@/blocks/blocks/zep' -import { ZeroBounceBlock } from '@/blocks/blocks/zerobounce' -import { ZoomBlock } from '@/blocks/blocks/zoom' -import { ZoomInfoBlock } from '@/blocks/blocks/zoominfo' import { BLOCK_CATALOG } from '@/blocks/manifest-data' import type { BlockCategory, @@ -285,310 +9,356 @@ import type { SuggestedSkill, } from '@/blocks/types' -/** All block configs keyed by block type. The execution source of truth. */ -const BLOCK_REGISTRY: Record = { - a2a: A2ABlock, - agent: AgentBlock, - agentmail: AgentMailBlock, - agentphone: AgentPhoneBlock, - agiloft: AgiloftBlock, - ahrefs: AhrefsBlock, - airtable: AirtableBlock, - airweave: AirweaveBlock, - algolia: AlgoliaBlock, - amplitude: AmplitudeBlock, - api: ApiBlock, - api_trigger: ApiTriggerBlock, - apify: ApifyBlock, - appconfig: AppConfigBlock, - apollo: ApolloBlock, - arxiv: ArxivBlock, - asana: AsanaBlock, - ashby: AshbyBlock, - athena: AthenaBlock, - attio: AttioBlock, - azure_devops: AzureDevOpsBlock, - box: BoxBlock, - brandfetch: BrandfetchBlock, - brex: BrexBlock, - brightdata: BrightDataBlock, - browser_use: BrowserUseBlock, - calcom: CalComBlock, - calendly: CalendlyBlock, - chat_trigger: ChatTriggerBlock, - circleback: CirclebackBlock, - clay: ClayBlock, - clerk: ClerkBlock, - clickhouse: ClickHouseBlock, - cloudflare: CloudflareBlock, - cloudformation: CloudFormationBlock, - cloudwatch: CloudWatchBlock, - codepipeline: CodePipelineBlock, - condition: ConditionBlock, - confluence: ConfluenceBlock, - confluence_v2: ConfluenceV2Block, - context_dev: ContextDevBlock, - convex: ConvexBlock, - credential: CredentialBlock, - crowdstrike: CrowdStrikeBlock, - cursor: CursorBlock, - cursor_v2: CursorV2Block, - dagster: DagsterBlock, - databricks: DatabricksBlock, - datadog: DatadogBlock, - datagma: DatagmaBlock, - daytona: DaytonaBlock, - deployments: DeploymentsBlock, - devin: DevinBlock, - discord: DiscordBlock, - docusign: DocuSignBlock, - dropbox: DropboxBlock, - dropcontact: DropcontactBlock, - dspy: DSPyBlock, - dub: DubBlock, - duckduckgo: DuckDuckGoBlock, - dynamodb: DynamoDBBlock, - elasticsearch: ElasticsearchBlock, - elevenlabs: ElevenLabsBlock, - emailbison: EmailBisonBlock, - enrich: EnrichBlock, - enrichment: EnrichmentBlock, - enrow: EnrowBlock, - evaluator: EvaluatorBlock, - evernote: EvernoteBlock, - exa: ExaBlock, - extend: ExtendBlock, - extend_v2: ExtendV2Block, - fathom: FathomBlock, - file: FileBlock, - file_v2: FileV2Block, - file_v3: FileV3Block, - file_v4: FileV4Block, - file_v5: FileV5Block, - findymail: FindymailBlock, - zerobounce: ZeroBounceBlock, - neverbounce: NeverBounceBlock, - millionverifier: MillionVerifierBlock, - firecrawl: FirecrawlBlock, - fireflies: FirefliesBlock, - fireflies_v2: FirefliesV2Block, - function: FunctionBlock, - gamma: GammaBlock, - generic_webhook: GenericWebhookBlock, - github: GitHubBlock, - github_v2: GitHubV2Block, - gitlab: GitLabBlock, - gmail: GmailBlock, - gmail_v2: GmailV2Block, - gong: GongBlock, - google_ads: GoogleAdsBlock, - google_bigquery: GoogleBigQueryBlock, - google_books: GoogleBooksBlock, - google_calendar: GoogleCalendarBlock, - google_calendar_v2: GoogleCalendarV2Block, - google_contacts: GoogleContactsBlock, - google_docs: GoogleDocsBlock, - google_drive: GoogleDriveBlock, - google_forms: GoogleFormsBlock, - google_groups: GoogleGroupsBlock, - google_maps: GoogleMapsBlock, - google_meet: GoogleMeetBlock, - google_pagespeed: GooglePagespeedBlock, - google_search: GoogleSearchBlock, - google_sheets: GoogleSheetsBlock, - google_sheets_v2: GoogleSheetsV2Block, - google_slides: GoogleSlidesBlock, - google_slides_v2: GoogleSlidesV2Block, - google_tasks: GoogleTasksBlock, - google_translate: GoogleTranslateBlock, - google_vault: GoogleVaultBlock, - grafana: GrafanaBlock, - grain: GrainBlock, - granola: GranolaBlock, - greenhouse: GreenhouseBlock, - greptile: GreptileBlock, - guardrails: GuardrailsBlock, - hex: HexBlock, - hubspot: HubSpotBlock, - huggingface: HuggingFaceBlock, - human_in_the_loop: HumanInTheLoopBlock, - hunter: HunterBlock, - iam: IAMBlock, - icypeas: IcypeasBlock, - identity_center: IdentityCenterBlock, - image_generator: ImageGeneratorBlock, - image_generator_v2: ImageGeneratorV2Block, - imap: ImapBlock, - incidentio: IncidentioBlock, - infisical: InfisicalBlock, - input_trigger: InputTriggerBlock, - instantly: InstantlyBlock, - intercom: IntercomBlock, - intercom_v2: IntercomV2Block, - jina: JinaBlock, - jira: JiraBlock, - jira_service_management: JiraServiceManagementBlock, - kalshi: KalshiBlock, - kalshi_v2: KalshiV2Block, - ketch: KetchBlock, - knowledge: KnowledgeBlock, - langsmith: LangsmithBlock, - latex: LatexBlock, - launchdarkly: LaunchDarklyBlock, - leadmagic: LeadMagicBlock, - lemlist: LemlistBlock, - linear: LinearBlock, - linear_v2: LinearV2Block, - linkedin: LinkedInBlock, - linkup: LinkupBlock, - linq: LinqBlock, - logs: LogsBlock, - logs_v2: LogsV2Block, - loops: LoopsBlock, - luma: LumaBlock, - mailchimp: MailchimpBlock, - mailgun: MailgunBlock, - manual_trigger: ManualTriggerBlock, - mcp: McpBlock, - mem0: Mem0Block, - memory: MemoryBlock, - microsoft_ad: MicrosoftAdBlock, - microsoft_dataverse: MicrosoftDataverseBlock, - microsoft_excel: MicrosoftExcelBlock, - microsoft_excel_v2: MicrosoftExcelV2Block, - microsoft_planner: MicrosoftPlannerBlock, - microsoft_teams: MicrosoftTeamsBlock, - mistral_parse: MistralParseBlock, - mistral_parse_v2: MistralParseV2Block, - mistral_parse_v3: MistralParseV3Block, - monday: MondayBlock, - mongodb: MongoDBBlock, - mothership: MothershipBlock, - mysql: MySQLBlock, - neo4j: Neo4jBlock, - new_relic: NewRelicBlock, - note: NoteBlock, - notion: NotionBlock, - notion_v2: NotionV2Block, - obsidian: ObsidianBlock, - okta: OktaBlock, - onedrive: OneDriveBlock, - onepassword: OnePasswordBlock, - openai: OpenAIBlock, - outlook: OutlookBlock, - pagerduty: PagerDutyBlock, - parallel_ai: ParallelBlock, - peopledatalabs: PeopleDataLabsBlock, - perplexity: PerplexityBlock, - persona: PersonaBlock, - pi: PiBlock, - pinecone: PineconeBlock, - pipedrive: PipedriveBlock, - polymarket: PolymarketBlock, - postgresql: PostgreSQLBlock, - posthog: PostHogBlock, - profound: ProfoundBlock, - prospeo: ProspeoBlock, - pulse: PulseBlock, - pulse_v2: PulseV2Block, - qdrant: QdrantBlock, - quartr: QuartrBlock, - quiver: QuiverBlock, - railway: RailwayBlock, - rb2b: RB2BBlock, - rds: RDSBlock, - reddit: RedditBlock, - redis: RedisBlock, - reducto: ReductoBlock, - reducto_v2: ReductoV2Block, - resend: ResendBlock, - response: ResponseBlock, - revenuecat: RevenueCatBlock, - rippling: RipplingBlock, - rootly: RootlyBlock, - router: RouterBlock, - router_v2: RouterV2Block, - rss: RssBlock, - s3: S3Block, - salesforce: SalesforceBlock, - sap_concur: SapConcurBlock, - sap_s4hana: SapS4HanaBlock, - schedule: ScheduleBlock, - search: SearchBlock, - secrets_manager: SecretsManagerBlock, - sendblue: SendblueBlock, - sendgrid: SendGridBlock, - sentry: SentryBlock, - serper: SerperBlock, - servicenow: ServiceNowBlock, - ses: SESBlock, - sftp: SftpBlock, - sharepoint: SharepointBlock, - sharepoint_v2: SharepointV2Block, - shopify: ShopifyBlock, - sim_workspace_event: SimWorkspaceEventBlock, - similarweb: SimilarwebBlock, - sixtyfour: SixtyfourBlock, - slack: SlackBlock, - smtp: SmtpBlock, - sportmonks: SportmonksBlock, - spotify: SpotifyBlock, - sqs: SQSBlock, - square: SquareBlock, - ssh: SSHBlock, - stagehand: StagehandBlock, - start_trigger: StartTriggerBlock, - starter: StarterBlock, - stripe: StripeBlock, - sts: STSBlock, - stt: SttBlock, - stt_v2: SttV2Block, - supabase: SupabaseBlock, - table: TableBlock, - tailscale: TailscaleBlock, - tavily: TavilyBlock, - telegram: TelegramBlock, - temporal: TemporalBlock, - textract: TextractBlock, - textract_v2: TextractV2Block, - thinking: ThinkingBlock, - thrive: ThriveBlock, - tinybird: TinybirdBlock, - translate: TranslateBlock, - trello: TrelloBlock, - trigger_dev: TriggerDevBlock, - tts: TtsBlock, - twilio_sms: TwilioSMSBlock, - twilio_voice: TwilioVoiceBlock, - typeform: TypeformBlock, - upstash: UpstashBlock, - vanta: VantaBlock, - variables: VariablesBlock, - vercel: VercelBlock, - video_generator: VideoGeneratorBlock, - video_generator_v2: VideoGeneratorV2Block, - video_generator_v3: VideoGeneratorV3Block, - vision: VisionBlock, - vision_v2: VisionV2Block, - wait: WaitBlock, - wealthbox: WealthboxBlock, - webflow: WebflowBlock, - webhook_request: WebhookRequestBlock, - whatsapp: WhatsAppBlock, - wikipedia: WikipediaBlock, - wiza: WizaBlock, - wordpress: WordPressBlock, - workday: WorkdayBlock, - workflow: WorkflowBlock, - workflow_input: WorkflowInputBlock, - x: XBlock, - youtube: YouTubeBlock, - zendesk: ZendeskBlock, - zep: ZepBlock, - zoom: ZoomBlock, - zoominfo: ZoomInfoBlock, +const logger = createLogger('BlockRegistry') + +/** + * Lazy loaders for every block config, keyed by block type. The full configs + * (subBlocks/tools/inputs/outputs) are loaded on demand via dynamic import into + * {@link blockCache}; display/catalog metadata lives in the registry-free + * `@/blocks/manifest`. Callers that read a config synchronously + * (`getBlock`/`getAllBlocks`) must first `await loadBlockConfigs([...])` for + * the types they need — the canvas does this at workflow-open, the add-block + * handlers per placement, and backend paths at their async entry. + */ +const BLOCK_LOADERS: Record Promise> = { + a2a: () => import('@/blocks/blocks/a2a').then((mod) => mod.A2ABlock), + agent: () => import('@/blocks/blocks/agent').then((mod) => mod.AgentBlock), + agentmail: () => import('@/blocks/blocks/agentmail').then((mod) => mod.AgentMailBlock), + agentphone: () => import('@/blocks/blocks/agentphone').then((mod) => mod.AgentPhoneBlock), + agiloft: () => import('@/blocks/blocks/agiloft').then((mod) => mod.AgiloftBlock), + ahrefs: () => import('@/blocks/blocks/ahrefs').then((mod) => mod.AhrefsBlock), + airtable: () => import('@/blocks/blocks/airtable').then((mod) => mod.AirtableBlock), + airweave: () => import('@/blocks/blocks/airweave').then((mod) => mod.AirweaveBlock), + algolia: () => import('@/blocks/blocks/algolia').then((mod) => mod.AlgoliaBlock), + amplitude: () => import('@/blocks/blocks/amplitude').then((mod) => mod.AmplitudeBlock), + api: () => import('@/blocks/blocks/api').then((mod) => mod.ApiBlock), + api_trigger: () => import('@/blocks/blocks/api_trigger').then((mod) => mod.ApiTriggerBlock), + apify: () => import('@/blocks/blocks/apify').then((mod) => mod.ApifyBlock), + appconfig: () => import('@/blocks/blocks/appconfig').then((mod) => mod.AppConfigBlock), + apollo: () => import('@/blocks/blocks/apollo').then((mod) => mod.ApolloBlock), + arxiv: () => import('@/blocks/blocks/arxiv').then((mod) => mod.ArxivBlock), + asana: () => import('@/blocks/blocks/asana').then((mod) => mod.AsanaBlock), + ashby: () => import('@/blocks/blocks/ashby').then((mod) => mod.AshbyBlock), + athena: () => import('@/blocks/blocks/athena').then((mod) => mod.AthenaBlock), + attio: () => import('@/blocks/blocks/attio').then((mod) => mod.AttioBlock), + azure_devops: () => import('@/blocks/blocks/azure_devops').then((mod) => mod.AzureDevOpsBlock), + box: () => import('@/blocks/blocks/box').then((mod) => mod.BoxBlock), + brandfetch: () => import('@/blocks/blocks/brandfetch').then((mod) => mod.BrandfetchBlock), + brex: () => import('@/blocks/blocks/brex').then((mod) => mod.BrexBlock), + brightdata: () => import('@/blocks/blocks/brightdata').then((mod) => mod.BrightDataBlock), + browser_use: () => import('@/blocks/blocks/browser_use').then((mod) => mod.BrowserUseBlock), + calcom: () => import('@/blocks/blocks/calcom').then((mod) => mod.CalComBlock), + calendly: () => import('@/blocks/blocks/calendly').then((mod) => mod.CalendlyBlock), + chat_trigger: () => import('@/blocks/blocks/chat_trigger').then((mod) => mod.ChatTriggerBlock), + circleback: () => import('@/blocks/blocks/circleback').then((mod) => mod.CirclebackBlock), + clay: () => import('@/blocks/blocks/clay').then((mod) => mod.ClayBlock), + clerk: () => import('@/blocks/blocks/clerk').then((mod) => mod.ClerkBlock), + clickhouse: () => import('@/blocks/blocks/clickhouse').then((mod) => mod.ClickHouseBlock), + cloudflare: () => import('@/blocks/blocks/cloudflare').then((mod) => mod.CloudflareBlock), + cloudformation: () => + import('@/blocks/blocks/cloudformation').then((mod) => mod.CloudFormationBlock), + cloudwatch: () => import('@/blocks/blocks/cloudwatch').then((mod) => mod.CloudWatchBlock), + codepipeline: () => import('@/blocks/blocks/codepipeline').then((mod) => mod.CodePipelineBlock), + condition: () => import('@/blocks/blocks/condition').then((mod) => mod.ConditionBlock), + confluence: () => import('@/blocks/blocks/confluence').then((mod) => mod.ConfluenceBlock), + confluence_v2: () => import('@/blocks/blocks/confluence').then((mod) => mod.ConfluenceV2Block), + context_dev: () => import('@/blocks/blocks/context_dev').then((mod) => mod.ContextDevBlock), + convex: () => import('@/blocks/blocks/convex').then((mod) => mod.ConvexBlock), + credential: () => import('@/blocks/blocks/credential').then((mod) => mod.CredentialBlock), + crowdstrike: () => import('@/blocks/blocks/crowdstrike').then((mod) => mod.CrowdStrikeBlock), + cursor: () => import('@/blocks/blocks/cursor').then((mod) => mod.CursorBlock), + cursor_v2: () => import('@/blocks/blocks/cursor').then((mod) => mod.CursorV2Block), + dagster: () => import('@/blocks/blocks/dagster').then((mod) => mod.DagsterBlock), + databricks: () => import('@/blocks/blocks/databricks').then((mod) => mod.DatabricksBlock), + datadog: () => import('@/blocks/blocks/datadog').then((mod) => mod.DatadogBlock), + datagma: () => import('@/blocks/blocks/datagma').then((mod) => mod.DatagmaBlock), + daytona: () => import('@/blocks/blocks/daytona').then((mod) => mod.DaytonaBlock), + deployments: () => import('@/blocks/blocks/deployments').then((mod) => mod.DeploymentsBlock), + devin: () => import('@/blocks/blocks/devin').then((mod) => mod.DevinBlock), + discord: () => import('@/blocks/blocks/discord').then((mod) => mod.DiscordBlock), + docusign: () => import('@/blocks/blocks/docusign').then((mod) => mod.DocuSignBlock), + dropbox: () => import('@/blocks/blocks/dropbox').then((mod) => mod.DropboxBlock), + dropcontact: () => import('@/blocks/blocks/dropcontact').then((mod) => mod.DropcontactBlock), + dspy: () => import('@/blocks/blocks/dspy').then((mod) => mod.DSPyBlock), + dub: () => import('@/blocks/blocks/dub').then((mod) => mod.DubBlock), + duckduckgo: () => import('@/blocks/blocks/duckduckgo').then((mod) => mod.DuckDuckGoBlock), + dynamodb: () => import('@/blocks/blocks/dynamodb').then((mod) => mod.DynamoDBBlock), + elasticsearch: () => + import('@/blocks/blocks/elasticsearch').then((mod) => mod.ElasticsearchBlock), + elevenlabs: () => import('@/blocks/blocks/elevenlabs').then((mod) => mod.ElevenLabsBlock), + emailbison: () => import('@/blocks/blocks/emailbison').then((mod) => mod.EmailBisonBlock), + enrich: () => import('@/blocks/blocks/enrich').then((mod) => mod.EnrichBlock), + enrichment: () => import('@/blocks/blocks/enrichment').then((mod) => mod.EnrichmentBlock), + enrow: () => import('@/blocks/blocks/enrow').then((mod) => mod.EnrowBlock), + evaluator: () => import('@/blocks/blocks/evaluator').then((mod) => mod.EvaluatorBlock), + evernote: () => import('@/blocks/blocks/evernote').then((mod) => mod.EvernoteBlock), + exa: () => import('@/blocks/blocks/exa').then((mod) => mod.ExaBlock), + extend: () => import('@/blocks/blocks/extend').then((mod) => mod.ExtendBlock), + extend_v2: () => import('@/blocks/blocks/extend').then((mod) => mod.ExtendV2Block), + fathom: () => import('@/blocks/blocks/fathom').then((mod) => mod.FathomBlock), + file: () => import('@/blocks/blocks/file').then((mod) => mod.FileBlock), + file_v2: () => import('@/blocks/blocks/file').then((mod) => mod.FileV2Block), + file_v3: () => import('@/blocks/blocks/file').then((mod) => mod.FileV3Block), + file_v4: () => import('@/blocks/blocks/file').then((mod) => mod.FileV4Block), + file_v5: () => import('@/blocks/blocks/file').then((mod) => mod.FileV5Block), + findymail: () => import('@/blocks/blocks/findymail').then((mod) => mod.FindymailBlock), + zerobounce: () => import('@/blocks/blocks/zerobounce').then((mod) => mod.ZeroBounceBlock), + neverbounce: () => import('@/blocks/blocks/neverbounce').then((mod) => mod.NeverBounceBlock), + millionverifier: () => + import('@/blocks/blocks/millionverifier').then((mod) => mod.MillionVerifierBlock), + firecrawl: () => import('@/blocks/blocks/firecrawl').then((mod) => mod.FirecrawlBlock), + fireflies: () => import('@/blocks/blocks/fireflies').then((mod) => mod.FirefliesBlock), + fireflies_v2: () => import('@/blocks/blocks/fireflies').then((mod) => mod.FirefliesV2Block), + function: () => import('@/blocks/blocks/function').then((mod) => mod.FunctionBlock), + gamma: () => import('@/blocks/blocks/gamma').then((mod) => mod.GammaBlock), + generic_webhook: () => + import('@/blocks/blocks/generic_webhook').then((mod) => mod.GenericWebhookBlock), + github: () => import('@/blocks/blocks/github').then((mod) => mod.GitHubBlock), + github_v2: () => import('@/blocks/blocks/github').then((mod) => mod.GitHubV2Block), + gitlab: () => import('@/blocks/blocks/gitlab').then((mod) => mod.GitLabBlock), + gmail: () => import('@/blocks/blocks/gmail').then((mod) => mod.GmailBlock), + gmail_v2: () => import('@/blocks/blocks/gmail').then((mod) => mod.GmailV2Block), + gong: () => import('@/blocks/blocks/gong').then((mod) => mod.GongBlock), + google_ads: () => import('@/blocks/blocks/google_ads').then((mod) => mod.GoogleAdsBlock), + google_bigquery: () => + import('@/blocks/blocks/google_bigquery').then((mod) => mod.GoogleBigQueryBlock), + google_books: () => import('@/blocks/blocks/google_books').then((mod) => mod.GoogleBooksBlock), + google_calendar: () => + import('@/blocks/blocks/google_calendar').then((mod) => mod.GoogleCalendarBlock), + google_calendar_v2: () => + import('@/blocks/blocks/google_calendar').then((mod) => mod.GoogleCalendarV2Block), + google_contacts: () => + import('@/blocks/blocks/google_contacts').then((mod) => mod.GoogleContactsBlock), + google_docs: () => import('@/blocks/blocks/google_docs').then((mod) => mod.GoogleDocsBlock), + google_drive: () => import('@/blocks/blocks/google_drive').then((mod) => mod.GoogleDriveBlock), + google_forms: () => import('@/blocks/blocks/google_forms').then((mod) => mod.GoogleFormsBlock), + google_groups: () => import('@/blocks/blocks/google_groups').then((mod) => mod.GoogleGroupsBlock), + google_maps: () => import('@/blocks/blocks/google_maps').then((mod) => mod.GoogleMapsBlock), + google_meet: () => import('@/blocks/blocks/google_meet').then((mod) => mod.GoogleMeetBlock), + google_pagespeed: () => + import('@/blocks/blocks/google_pagespeed').then((mod) => mod.GooglePagespeedBlock), + google_search: () => import('@/blocks/blocks/google').then((mod) => mod.GoogleSearchBlock), + google_sheets: () => import('@/blocks/blocks/google_sheets').then((mod) => mod.GoogleSheetsBlock), + google_sheets_v2: () => + import('@/blocks/blocks/google_sheets').then((mod) => mod.GoogleSheetsV2Block), + google_slides: () => import('@/blocks/blocks/google_slides').then((mod) => mod.GoogleSlidesBlock), + google_slides_v2: () => + import('@/blocks/blocks/google_slides').then((mod) => mod.GoogleSlidesV2Block), + google_tasks: () => import('@/blocks/blocks/google_tasks').then((mod) => mod.GoogleTasksBlock), + google_translate: () => + import('@/blocks/blocks/google_translate').then((mod) => mod.GoogleTranslateBlock), + google_vault: () => import('@/blocks/blocks/google_vault').then((mod) => mod.GoogleVaultBlock), + grafana: () => import('@/blocks/blocks/grafana').then((mod) => mod.GrafanaBlock), + grain: () => import('@/blocks/blocks/grain').then((mod) => mod.GrainBlock), + granola: () => import('@/blocks/blocks/granola').then((mod) => mod.GranolaBlock), + greenhouse: () => import('@/blocks/blocks/greenhouse').then((mod) => mod.GreenhouseBlock), + greptile: () => import('@/blocks/blocks/greptile').then((mod) => mod.GreptileBlock), + guardrails: () => import('@/blocks/blocks/guardrails').then((mod) => mod.GuardrailsBlock), + hex: () => import('@/blocks/blocks/hex').then((mod) => mod.HexBlock), + hubspot: () => import('@/blocks/blocks/hubspot').then((mod) => mod.HubSpotBlock), + huggingface: () => import('@/blocks/blocks/huggingface').then((mod) => mod.HuggingFaceBlock), + human_in_the_loop: () => + import('@/blocks/blocks/human_in_the_loop').then((mod) => mod.HumanInTheLoopBlock), + hunter: () => import('@/blocks/blocks/hunter').then((mod) => mod.HunterBlock), + iam: () => import('@/blocks/blocks/iam').then((mod) => mod.IAMBlock), + icypeas: () => import('@/blocks/blocks/icypeas').then((mod) => mod.IcypeasBlock), + identity_center: () => + import('@/blocks/blocks/identity_center').then((mod) => mod.IdentityCenterBlock), + image_generator: () => + import('@/blocks/blocks/image_generator').then((mod) => mod.ImageGeneratorBlock), + image_generator_v2: () => + import('@/blocks/blocks/image_generator').then((mod) => mod.ImageGeneratorV2Block), + imap: () => import('@/blocks/blocks/imap').then((mod) => mod.ImapBlock), + incidentio: () => import('@/blocks/blocks/incidentio').then((mod) => mod.IncidentioBlock), + infisical: () => import('@/blocks/blocks/infisical').then((mod) => mod.InfisicalBlock), + input_trigger: () => import('@/blocks/blocks/input_trigger').then((mod) => mod.InputTriggerBlock), + instantly: () => import('@/blocks/blocks/instantly').then((mod) => mod.InstantlyBlock), + intercom: () => import('@/blocks/blocks/intercom').then((mod) => mod.IntercomBlock), + intercom_v2: () => import('@/blocks/blocks/intercom').then((mod) => mod.IntercomV2Block), + jina: () => import('@/blocks/blocks/jina').then((mod) => mod.JinaBlock), + jira: () => import('@/blocks/blocks/jira').then((mod) => mod.JiraBlock), + jira_service_management: () => + import('@/blocks/blocks/jira_service_management').then((mod) => mod.JiraServiceManagementBlock), + kalshi: () => import('@/blocks/blocks/kalshi').then((mod) => mod.KalshiBlock), + kalshi_v2: () => import('@/blocks/blocks/kalshi').then((mod) => mod.KalshiV2Block), + ketch: () => import('@/blocks/blocks/ketch').then((mod) => mod.KetchBlock), + knowledge: () => import('@/blocks/blocks/knowledge').then((mod) => mod.KnowledgeBlock), + langsmith: () => import('@/blocks/blocks/langsmith').then((mod) => mod.LangsmithBlock), + latex: () => import('@/blocks/blocks/latex').then((mod) => mod.LatexBlock), + launchdarkly: () => import('@/blocks/blocks/launchdarkly').then((mod) => mod.LaunchDarklyBlock), + leadmagic: () => import('@/blocks/blocks/leadmagic').then((mod) => mod.LeadMagicBlock), + lemlist: () => import('@/blocks/blocks/lemlist').then((mod) => mod.LemlistBlock), + linear: () => import('@/blocks/blocks/linear').then((mod) => mod.LinearBlock), + linear_v2: () => import('@/blocks/blocks/linear').then((mod) => mod.LinearV2Block), + linkedin: () => import('@/blocks/blocks/linkedin').then((mod) => mod.LinkedInBlock), + linkup: () => import('@/blocks/blocks/linkup').then((mod) => mod.LinkupBlock), + linq: () => import('@/blocks/blocks/linq').then((mod) => mod.LinqBlock), + logs: () => import('@/blocks/blocks/logs').then((mod) => mod.LogsBlock), + logs_v2: () => import('@/blocks/blocks/logs').then((mod) => mod.LogsV2Block), + loops: () => import('@/blocks/blocks/loops').then((mod) => mod.LoopsBlock), + luma: () => import('@/blocks/blocks/luma').then((mod) => mod.LumaBlock), + mailchimp: () => import('@/blocks/blocks/mailchimp').then((mod) => mod.MailchimpBlock), + mailgun: () => import('@/blocks/blocks/mailgun').then((mod) => mod.MailgunBlock), + manual_trigger: () => + import('@/blocks/blocks/manual_trigger').then((mod) => mod.ManualTriggerBlock), + mcp: () => import('@/blocks/blocks/mcp').then((mod) => mod.McpBlock), + mem0: () => import('@/blocks/blocks/mem0').then((mod) => mod.Mem0Block), + memory: () => import('@/blocks/blocks/memory').then((mod) => mod.MemoryBlock), + microsoft_ad: () => import('@/blocks/blocks/microsoft_ad').then((mod) => mod.MicrosoftAdBlock), + microsoft_dataverse: () => + import('@/blocks/blocks/microsoft_dataverse').then((mod) => mod.MicrosoftDataverseBlock), + microsoft_excel: () => + import('@/blocks/blocks/microsoft_excel').then((mod) => mod.MicrosoftExcelBlock), + microsoft_excel_v2: () => + import('@/blocks/blocks/microsoft_excel').then((mod) => mod.MicrosoftExcelV2Block), + microsoft_planner: () => + import('@/blocks/blocks/microsoft_planner').then((mod) => mod.MicrosoftPlannerBlock), + microsoft_teams: () => + import('@/blocks/blocks/microsoft_teams').then((mod) => mod.MicrosoftTeamsBlock), + mistral_parse: () => import('@/blocks/blocks/mistral_parse').then((mod) => mod.MistralParseBlock), + mistral_parse_v2: () => + import('@/blocks/blocks/mistral_parse').then((mod) => mod.MistralParseV2Block), + mistral_parse_v3: () => + import('@/blocks/blocks/mistral_parse').then((mod) => mod.MistralParseV3Block), + monday: () => import('@/blocks/blocks/monday').then((mod) => mod.MondayBlock), + mongodb: () => import('@/blocks/blocks/mongodb').then((mod) => mod.MongoDBBlock), + mothership: () => import('@/blocks/blocks/mothership').then((mod) => mod.MothershipBlock), + mysql: () => import('@/blocks/blocks/mysql').then((mod) => mod.MySQLBlock), + neo4j: () => import('@/blocks/blocks/neo4j').then((mod) => mod.Neo4jBlock), + new_relic: () => import('@/blocks/blocks/new_relic').then((mod) => mod.NewRelicBlock), + note: () => import('@/blocks/blocks/note').then((mod) => mod.NoteBlock), + notion: () => import('@/blocks/blocks/notion').then((mod) => mod.NotionBlock), + notion_v2: () => import('@/blocks/blocks/notion').then((mod) => mod.NotionV2Block), + obsidian: () => import('@/blocks/blocks/obsidian').then((mod) => mod.ObsidianBlock), + okta: () => import('@/blocks/blocks/okta').then((mod) => mod.OktaBlock), + onedrive: () => import('@/blocks/blocks/onedrive').then((mod) => mod.OneDriveBlock), + onepassword: () => import('@/blocks/blocks/onepassword').then((mod) => mod.OnePasswordBlock), + openai: () => import('@/blocks/blocks/openai').then((mod) => mod.OpenAIBlock), + outlook: () => import('@/blocks/blocks/outlook').then((mod) => mod.OutlookBlock), + pagerduty: () => import('@/blocks/blocks/pagerduty').then((mod) => mod.PagerDutyBlock), + parallel_ai: () => import('@/blocks/blocks/parallel').then((mod) => mod.ParallelBlock), + peopledatalabs: () => + import('@/blocks/blocks/peopledatalabs').then((mod) => mod.PeopleDataLabsBlock), + perplexity: () => import('@/blocks/blocks/perplexity').then((mod) => mod.PerplexityBlock), + persona: () => import('@/blocks/blocks/persona').then((mod) => mod.PersonaBlock), + pi: () => import('@/blocks/blocks/pi').then((mod) => mod.PiBlock), + pinecone: () => import('@/blocks/blocks/pinecone').then((mod) => mod.PineconeBlock), + pipedrive: () => import('@/blocks/blocks/pipedrive').then((mod) => mod.PipedriveBlock), + polymarket: () => import('@/blocks/blocks/polymarket').then((mod) => mod.PolymarketBlock), + postgresql: () => import('@/blocks/blocks/postgresql').then((mod) => mod.PostgreSQLBlock), + posthog: () => import('@/blocks/blocks/posthog').then((mod) => mod.PostHogBlock), + profound: () => import('@/blocks/blocks/profound').then((mod) => mod.ProfoundBlock), + prospeo: () => import('@/blocks/blocks/prospeo').then((mod) => mod.ProspeoBlock), + pulse: () => import('@/blocks/blocks/pulse').then((mod) => mod.PulseBlock), + pulse_v2: () => import('@/blocks/blocks/pulse').then((mod) => mod.PulseV2Block), + qdrant: () => import('@/blocks/blocks/qdrant').then((mod) => mod.QdrantBlock), + quartr: () => import('@/blocks/blocks/quartr').then((mod) => mod.QuartrBlock), + quiver: () => import('@/blocks/blocks/quiver').then((mod) => mod.QuiverBlock), + railway: () => import('@/blocks/blocks/railway').then((mod) => mod.RailwayBlock), + rb2b: () => import('@/blocks/blocks/rb2b').then((mod) => mod.RB2BBlock), + rds: () => import('@/blocks/blocks/rds').then((mod) => mod.RDSBlock), + reddit: () => import('@/blocks/blocks/reddit').then((mod) => mod.RedditBlock), + redis: () => import('@/blocks/blocks/redis').then((mod) => mod.RedisBlock), + reducto: () => import('@/blocks/blocks/reducto').then((mod) => mod.ReductoBlock), + reducto_v2: () => import('@/blocks/blocks/reducto').then((mod) => mod.ReductoV2Block), + resend: () => import('@/blocks/blocks/resend').then((mod) => mod.ResendBlock), + response: () => import('@/blocks/blocks/response').then((mod) => mod.ResponseBlock), + revenuecat: () => import('@/blocks/blocks/revenuecat').then((mod) => mod.RevenueCatBlock), + rippling: () => import('@/blocks/blocks/rippling').then((mod) => mod.RipplingBlock), + rootly: () => import('@/blocks/blocks/rootly').then((mod) => mod.RootlyBlock), + router: () => import('@/blocks/blocks/router').then((mod) => mod.RouterBlock), + router_v2: () => import('@/blocks/blocks/router').then((mod) => mod.RouterV2Block), + rss: () => import('@/blocks/blocks/rss').then((mod) => mod.RssBlock), + s3: () => import('@/blocks/blocks/s3').then((mod) => mod.S3Block), + salesforce: () => import('@/blocks/blocks/salesforce').then((mod) => mod.SalesforceBlock), + sap_concur: () => import('@/blocks/blocks/sap_concur').then((mod) => mod.SapConcurBlock), + sap_s4hana: () => import('@/blocks/blocks/sap_s4hana').then((mod) => mod.SapS4HanaBlock), + schedule: () => import('@/blocks/blocks/schedule').then((mod) => mod.ScheduleBlock), + search: () => import('@/blocks/blocks/search').then((mod) => mod.SearchBlock), + secrets_manager: () => + import('@/blocks/blocks/secrets_manager').then((mod) => mod.SecretsManagerBlock), + sendblue: () => import('@/blocks/blocks/sendblue').then((mod) => mod.SendblueBlock), + sendgrid: () => import('@/blocks/blocks/sendgrid').then((mod) => mod.SendGridBlock), + sentry: () => import('@/blocks/blocks/sentry').then((mod) => mod.SentryBlock), + serper: () => import('@/blocks/blocks/serper').then((mod) => mod.SerperBlock), + servicenow: () => import('@/blocks/blocks/servicenow').then((mod) => mod.ServiceNowBlock), + ses: () => import('@/blocks/blocks/ses').then((mod) => mod.SESBlock), + sftp: () => import('@/blocks/blocks/sftp').then((mod) => mod.SftpBlock), + sharepoint: () => import('@/blocks/blocks/sharepoint').then((mod) => mod.SharepointBlock), + sharepoint_v2: () => import('@/blocks/blocks/sharepoint').then((mod) => mod.SharepointV2Block), + shopify: () => import('@/blocks/blocks/shopify').then((mod) => mod.ShopifyBlock), + sim_workspace_event: () => + import('@/blocks/blocks/sim_workspace_event').then((mod) => mod.SimWorkspaceEventBlock), + similarweb: () => import('@/blocks/blocks/similarweb').then((mod) => mod.SimilarwebBlock), + sixtyfour: () => import('@/blocks/blocks/sixtyfour').then((mod) => mod.SixtyfourBlock), + slack: () => import('@/blocks/blocks/slack').then((mod) => mod.SlackBlock), + smtp: () => import('@/blocks/blocks/smtp').then((mod) => mod.SmtpBlock), + sportmonks: () => import('@/blocks/blocks/sportmonks').then((mod) => mod.SportmonksBlock), + spotify: () => import('@/blocks/blocks/spotify').then((mod) => mod.SpotifyBlock), + sqs: () => import('@/blocks/blocks/sqs').then((mod) => mod.SQSBlock), + square: () => import('@/blocks/blocks/square').then((mod) => mod.SquareBlock), + ssh: () => import('@/blocks/blocks/ssh').then((mod) => mod.SSHBlock), + stagehand: () => import('@/blocks/blocks/stagehand').then((mod) => mod.StagehandBlock), + start_trigger: () => import('@/blocks/blocks/start_trigger').then((mod) => mod.StartTriggerBlock), + starter: () => import('@/blocks/blocks/starter').then((mod) => mod.StarterBlock), + stripe: () => import('@/blocks/blocks/stripe').then((mod) => mod.StripeBlock), + sts: () => import('@/blocks/blocks/sts').then((mod) => mod.STSBlock), + stt: () => import('@/blocks/blocks/stt').then((mod) => mod.SttBlock), + stt_v2: () => import('@/blocks/blocks/stt').then((mod) => mod.SttV2Block), + supabase: () => import('@/blocks/blocks/supabase').then((mod) => mod.SupabaseBlock), + table: () => import('@/blocks/blocks/table').then((mod) => mod.TableBlock), + tailscale: () => import('@/blocks/blocks/tailscale').then((mod) => mod.TailscaleBlock), + tavily: () => import('@/blocks/blocks/tavily').then((mod) => mod.TavilyBlock), + telegram: () => import('@/blocks/blocks/telegram').then((mod) => mod.TelegramBlock), + temporal: () => import('@/blocks/blocks/temporal').then((mod) => mod.TemporalBlock), + textract: () => import('@/blocks/blocks/textract').then((mod) => mod.TextractBlock), + textract_v2: () => import('@/blocks/blocks/textract').then((mod) => mod.TextractV2Block), + thinking: () => import('@/blocks/blocks/thinking').then((mod) => mod.ThinkingBlock), + thrive: () => import('@/blocks/blocks/thrive').then((mod) => mod.ThriveBlock), + tinybird: () => import('@/blocks/blocks/tinybird').then((mod) => mod.TinybirdBlock), + translate: () => import('@/blocks/blocks/translate').then((mod) => mod.TranslateBlock), + trello: () => import('@/blocks/blocks/trello').then((mod) => mod.TrelloBlock), + trigger_dev: () => import('@/blocks/blocks/trigger_dev').then((mod) => mod.TriggerDevBlock), + tts: () => import('@/blocks/blocks/tts').then((mod) => mod.TtsBlock), + twilio_sms: () => import('@/blocks/blocks/twilio').then((mod) => mod.TwilioSMSBlock), + twilio_voice: () => import('@/blocks/blocks/twilio_voice').then((mod) => mod.TwilioVoiceBlock), + typeform: () => import('@/blocks/blocks/typeform').then((mod) => mod.TypeformBlock), + upstash: () => import('@/blocks/blocks/upstash').then((mod) => mod.UpstashBlock), + vanta: () => import('@/blocks/blocks/vanta').then((mod) => mod.VantaBlock), + variables: () => import('@/blocks/blocks/variables').then((mod) => mod.VariablesBlock), + vercel: () => import('@/blocks/blocks/vercel').then((mod) => mod.VercelBlock), + video_generator: () => + import('@/blocks/blocks/video_generator').then((mod) => mod.VideoGeneratorBlock), + video_generator_v2: () => + import('@/blocks/blocks/video_generator').then((mod) => mod.VideoGeneratorV2Block), + video_generator_v3: () => + import('@/blocks/blocks/video_generator').then((mod) => mod.VideoGeneratorV3Block), + vision: () => import('@/blocks/blocks/vision').then((mod) => mod.VisionBlock), + vision_v2: () => import('@/blocks/blocks/vision').then((mod) => mod.VisionV2Block), + wait: () => import('@/blocks/blocks/wait').then((mod) => mod.WaitBlock), + wealthbox: () => import('@/blocks/blocks/wealthbox').then((mod) => mod.WealthboxBlock), + webflow: () => import('@/blocks/blocks/webflow').then((mod) => mod.WebflowBlock), + webhook_request: () => + import('@/blocks/blocks/webhook_request').then((mod) => mod.WebhookRequestBlock), + whatsapp: () => import('@/blocks/blocks/whatsapp').then((mod) => mod.WhatsAppBlock), + wikipedia: () => import('@/blocks/blocks/wikipedia').then((mod) => mod.WikipediaBlock), + wiza: () => import('@/blocks/blocks/wiza').then((mod) => mod.WizaBlock), + wordpress: () => import('@/blocks/blocks/wordpress').then((mod) => mod.WordPressBlock), + workday: () => import('@/blocks/blocks/workday').then((mod) => mod.WorkdayBlock), + workflow: () => import('@/blocks/blocks/workflow').then((mod) => mod.WorkflowBlock), + workflow_input: () => + import('@/blocks/blocks/workflow_input').then((mod) => mod.WorkflowInputBlock), + x: () => import('@/blocks/blocks/x').then((mod) => mod.XBlock), + youtube: () => import('@/blocks/blocks/youtube').then((mod) => mod.YouTubeBlock), + zendesk: () => import('@/blocks/blocks/zendesk').then((mod) => mod.ZendeskBlock), + zep: () => import('@/blocks/blocks/zep').then((mod) => mod.ZepBlock), + zoom: () => import('@/blocks/blocks/zoom').then((mod) => mod.ZoomBlock), + zoominfo: () => import('@/blocks/blocks/zoominfo').then((mod) => mod.ZoomInfoBlock), } +/** Configs resolved so far. Populated by {@link loadBlockConfigs}. */ +const blockCache = new Map() + /** * Normalize an external block type to its registry key form: dashes become * underscores (some external sources use either form). @@ -597,34 +367,75 @@ function normalizeType(type: string): string { return type.replace(/-/g, '_') } -/** Get the block config for a single block type. */ +/** Resolve the loader key for a type, accepting the dash-form alias. */ +function loaderKey(type: string): string | undefined { + if (type in BLOCK_LOADERS) return type + const normalized = normalizeType(type) + return normalized in BLOCK_LOADERS ? normalized : undefined +} + +/** Load a single block config into the cache (idempotent). */ +export async function loadBlockConfig(type: string): Promise { + const key = loaderKey(type) + if (!key) return undefined + const cached = blockCache.get(key) + if (cached) return cached + const config = await BLOCK_LOADERS[key]() + blockCache.set(key, config) + return config +} + +/** Preload many block configs into the cache. Unknown types are ignored. */ +export async function loadBlockConfigs(types: Iterable): Promise { + await Promise.all([...new Set(types)].map((type) => loadBlockConfig(type))) +} + +/** Eagerly load every block config — for backend paths that genuinely need all. */ +export async function loadAllBlockConfigs(): Promise { + await loadBlockConfigs(Object.keys(BLOCK_LOADERS)) +} + +/** Whether a block config has been loaded into the cache. */ +export function isBlockLoaded(type: string): boolean { + const key = loaderKey(type) + return key ? blockCache.has(key) : false +} + +/** + * Get a loaded block config. Returns `undefined` if the type isn't preloaded; + * in dev that's logged loudly (a missed preload) for known types. + */ export function getBlock(type: string): BlockConfig | undefined { - return BLOCK_REGISTRY[type] ?? BLOCK_REGISTRY[normalizeType(type)] + const config = blockCache.get(type) ?? blockCache.get(normalizeType(type)) + if (!config && process.env.NODE_ENV !== 'production' && loaderKey(type)) { + logger.warn( + `getBlock("${type}") called before its config was preloaded; call loadBlockConfigs([...]) at the async boundary first` + ) + } + return config } -/** All block configs. */ +/** All loaded block configs. Callers needing every block must preload first (`loadAllBlockConfigs`). */ export function getAllBlocks(): BlockConfig[] { - return Object.values(BLOCK_REGISTRY) + return [...blockCache.values()] } -/** Find the block whose `tools.access` contains the given tool id. */ +/** Find a loaded block whose `tools.access` contains the given tool id. */ export function getBlockByToolName(toolName: string): BlockConfig | undefined { - return Object.values(BLOCK_REGISTRY).find((b) => b.tools?.access?.includes(toolName)) + return [...blockCache.values()].find((b) => b.tools?.access?.includes(toolName)) } /** - * Resolve the canonical (highest-version) block for a base type. Handles - * versioned variants like `confluence_v2`: callers pass `confluence` and - * receive the latest implementation. Returns the registry key alongside the - * config so callers that need the canonical type identifier avoid re-deriving - * it. + * Resolve the canonical (highest-version) block for a base type. Version keys + * are known synchronously from the loader map; the config is read from the + * cache (so the latest type must be preloaded). */ function resolveLatest(baseType: string): { type: string; config: BlockConfig } | undefined { const normalized = normalizeType(baseType) const versionPattern = new RegExp(`^${normalized}_v(\\d+)$`) let latestKey: string | undefined let latestVersion = -1 - for (const key of Object.keys(BLOCK_REGISTRY)) { + for (const key of Object.keys(BLOCK_LOADERS)) { const match = key.match(versionPattern) if (!match) continue const version = Number.parseInt(match[1]!, 10) @@ -633,8 +444,11 @@ function resolveLatest(baseType: string): { type: string; config: BlockConfig } latestKey = key } } - if (latestKey) return { type: latestKey, config: BLOCK_REGISTRY[latestKey]! } - const config = BLOCK_REGISTRY[normalized] + if (latestKey) { + const config = getBlock(latestKey) + return config ? { type: latestKey, config } : undefined + } + const config = getBlock(normalized) return config ? { type: normalized, config } : undefined } @@ -647,34 +461,31 @@ export function getLatestBlock(baseType: string): BlockConfig | undefined { return resolveLatest(baseType)?.config } -/** All blocks in a given category. */ +/** Loaded blocks in a given category. */ export function getBlocksByCategory(category: BlockCategory): BlockConfig[] { - return Object.values(BLOCK_REGISTRY).filter((block) => block.category === category) + return [...blockCache.values()].filter((block) => block.category === category) } /** - * The canonical "latest-version, toolbar-visible" set of blocks for a - * category. This is the single source of truth shared by every surface that - * extracts blocks for presentation — the toolbar, the search/mention engine, - * and the integrations catalog. A block is included when its `category` - * matches and it is not hidden from the toolbar (i.e. it is the latest - * version under the upgrade paradigm, since superseded versions set - * `hideFromToolbar: true`). + * The canonical "latest-version, toolbar-visible" set of LOADED blocks for a + * category. Display surfaces (toolbar, search, catalog) should use the + * registry-free `getCanonicalBlockDisplayByCategory` from `@/blocks/manifest` + * instead; this returns only configs already in the cache. */ export function getCanonicalBlocksByCategory(category: BlockCategory): BlockConfig[] { - return Object.values(BLOCK_REGISTRY).filter( + return [...blockCache.values()].filter( (block) => block.category === category && !block.hideFromToolbar ) } -/** All registered block type identifiers. */ +/** All registered block type identifiers (known without loading configs). */ export function getAllBlockTypes(): string[] { - return Object.keys(BLOCK_REGISTRY) + return Object.keys(BLOCK_LOADERS) } /** Whether the given string is a registered block type. Accepts hyphens as a dash-form alias. */ export function isValidBlockType(type: string): type is string { - return type in BLOCK_REGISTRY || normalizeType(type) in BLOCK_REGISTRY + return loaderKey(type) !== undefined } /** @@ -750,11 +561,4 @@ export function getSuggestedSkillsForBlock(type: string): readonly SuggestedSkil return BLOCK_CATALOG[base]?.skills ?? [] } -/** - * Raw block registry map keyed by block type. Prefer the typed accessors - * (`getBlock`, `getAllBlocks`, `getCanonicalBlocksByCategory`); this alias is - * retained for callers that need the underlying record directly. - */ -export const registry: Record = BLOCK_REGISTRY - export type { BlockCategory } diff --git a/apps/sim/lib/copilot/chat/process-contents.ts b/apps/sim/lib/copilot/chat/process-contents.ts index ef33580211c..8c87042ee3d 100644 --- a/apps/sim/lib/copilot/chat/process-contents.ts +++ b/apps/sim/lib/copilot/chat/process-contents.ts @@ -504,8 +504,8 @@ async function processBlockMetadata( return null } - const { registry: blockRegistry } = await import('@/blocks/registry') - if (!(blockRegistry as any)[blockId]) { + const { isValidBlockType } = await import('@/blocks/registry') + if (!isValidBlockType(blockId)) { return null } From f51757abde6f894ee3bfa4dbfbc45fd26d70b3cb Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 27 Jun 2026 09:42:40 -0700 Subject: [PATCH 4/4] =?UTF-8?q?perf(blocks):=20WIP=20Phase=202=20=E2=80=94?= =?UTF-8?q?=20preload=20workflow=20block=20configs=20at=20loadWorkflowStat?= =?UTF-8?q?e=20(canvas)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit await loadBlockConfigs(workflow block types) before the hydration ready-gate so the canvas renders synchronously from a warm cache. Covers the editor's initial open. Add-path + ~74 backend getBlock callers still need preload (next). Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/sim/stores/workflows/registry/store.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/sim/stores/workflows/registry/store.ts b/apps/sim/stores/workflows/registry/store.ts index 97a0b556728..08ffed5ce46 100644 --- a/apps/sim/stores/workflows/registry/store.ts +++ b/apps/sim/stores/workflows/registry/store.ts @@ -4,6 +4,7 @@ import { create } from 'zustand' import { devtools } from 'zustand/middleware' import { DEFAULT_DUPLICATE_OFFSET } from '@/lib/workflows/autolayout/constants' import { getQueryClient } from '@/app/_shell/providers/get-query-client' +import { loadBlockConfigs } from '@/blocks/registry' import type { WorkflowDeploymentInfo } from '@/hooks/queries/deployments' import { deploymentKeys } from '@/hooks/queries/deployments' import { fetchWorkflowEnvelope } from '@/hooks/queries/utils/fetch-workflow-envelope' @@ -147,6 +148,10 @@ export const useWorkflowRegistry = create()( ) } + // Preload this workflow's block configs so the canvas renders synchronously + // (getBlock reads a warm cache). The hydration gate below re-validates after the await. + await loadBlockConfigs(Object.values(workflowState.blocks).map((b) => b.type)) + const currentHydration = get().hydration if ( currentHydration.requestId !== requestId ||