{"id":"f3a0c9b2-dff4-4ac0-b120-cd903f83c20a","shortId":"ePfbuD","kind":"skill","title":"workflow-automation","tagline":"Workflow automation is the infrastructure that makes AI agents","description":"# Workflow Automation\n\nWorkflow automation is the infrastructure that makes AI agents reliable.\nWithout durable execution, a network hiccup during a 10-step payment\nflow means lost money and angry customers. With it, workflows resume\nexactly where they left off.\n\nThis skill covers the platforms (n8n, Temporal, Inngest) and patterns\n(sequential, parallel, orchestrator-worker) that turn brittle scripts\ninto production-grade automation.\n\nKey insight: The platforms make different tradeoffs. n8n optimizes for\naccessibility, Temporal for correctness, Inngest for developer experience.\nPick based on your actual needs, not hype.\n\n## Principles\n\n- Durable execution is non-negotiable for money or state-critical workflows\n- Events are the universal language of workflow triggers\n- Steps are checkpoints - each should be independently retryable\n- Start simple, add complexity only when reliability demands it\n- Observability isn't optional - you need to see where workflows fail\n- Workflows and agents co-evolve - design for both\n\n## Capabilities\n\n- workflow-automation\n- workflow-orchestration\n- durable-execution\n- event-driven-workflows\n- step-functions\n- job-queues\n- background-jobs\n- scheduled-tasks\n\n## Scope\n\n- multi-agent-coordination → multi-agent-orchestration\n- ci-cd-pipelines → devops\n- data-pipelines → data-engineer\n- api-design → api-designer\n\n## Tooling\n\n### Platforms\n\n- n8n - When: Low-code automation, quick prototyping, non-technical users Note: Self-hostable, 400+ integrations, great for visual workflows\n- Temporal - When: Mission-critical workflows, financial transactions, microservices Note: Strongest durability guarantees, steeper learning curve\n- Inngest - When: Event-driven serverless, TypeScript codebases, AI workflows Note: Best developer experience, works with any hosting\n- AWS Step Functions - When: AWS-native stacks, existing Lambda functions Note: Tight AWS integration, JSON-based workflow definition\n- Azure Durable Functions - When: Azure stacks, .NET or TypeScript Note: Good AI agent support, checkpoint and replay\n\n## Patterns\n\n### Sequential Workflow Pattern\n\nSteps execute in order, each output becomes next input\n\n**When to use**: Content pipelines, data processing, ordered operations\n\n# SEQUENTIAL WORKFLOW:\n\n\"\"\"\nStep 1 → Step 2 → Step 3 → Output\n  ↓         ↓         ↓\n(checkpoint at each step)\n\"\"\"\n\n## Inngest Example (TypeScript)\n\"\"\"\nimport { inngest } from \"./client\";\n\nexport const processOrder = inngest.createFunction(\n  { id: \"process-order\" },\n  { event: \"order/created\" },\n  async ({ event, step }) => {\n    // Step 1: Validate order\n    const validated = await step.run(\"validate-order\", async () => {\n      return validateOrder(event.data.order);\n    });\n\n    // Step 2: Process payment (durable - survives crashes)\n    const payment = await step.run(\"process-payment\", async () => {\n      return chargeCard(validated.paymentMethod, validated.total);\n    });\n\n    // Step 3: Create shipment\n    const shipment = await step.run(\"create-shipment\", async () => {\n      return createShipment(validated.items, validated.address);\n    });\n\n    // Step 4: Send confirmation\n    await step.run(\"send-confirmation\", async () => {\n      return sendEmail(validated.email, { payment, shipment });\n    });\n\n    return { success: true, orderId: event.data.orderId };\n  }\n);\n\"\"\"\n\n## Temporal Example (TypeScript)\n\"\"\"\nimport { proxyActivities } from '@temporalio/workflow';\nimport type * as activities from './activities';\n\nconst { validateOrder, chargeCard, createShipment, sendEmail } =\n  proxyActivities<typeof activities>({\n    startToCloseTimeout: '30 seconds',\n    retry: {\n      maximumAttempts: 3,\n      backoffCoefficient: 2,\n    }\n  });\n\nexport async function processOrderWorkflow(order: Order): Promise<void> {\n  const validated = await validateOrder(order);\n  const payment = await chargeCard(validated.paymentMethod, validated.total);\n  const shipment = await createShipment(validated.items, validated.address);\n  await sendEmail(validated.email, { payment, shipment });\n}\n\"\"\"\n\n## n8n Pattern\n\"\"\"\n[Webhook: order.created]\n    ↓\n[HTTP Request: Validate Order]\n    ↓\n[HTTP Request: Process Payment]\n    ↓\n[HTTP Request: Create Shipment]\n    ↓\n[Send Email: Confirmation]\n\nConfigure each node with retry on failure.\nUse Error Trigger for dead letter handling.\n\"\"\"\n\n### Parallel Workflow Pattern\n\nIndependent steps run simultaneously, aggregate results\n\n**When to use**: Multiple independent analyses, data from multiple sources\n\n# PARALLEL WORKFLOW:\n\n\"\"\"\n        ┌→ Step A ─┐\nInput ──┼→ Step B ─┼→ Aggregate → Output\n        └→ Step C ─┘\n\"\"\"\n\n## Inngest Example\n\"\"\"\nexport const analyzeDocument = inngest.createFunction(\n  { id: \"analyze-document\" },\n  { event: \"document/uploaded\" },\n  async ({ event, step }) => {\n    // Run analyses in parallel\n    const [security, performance, compliance] = await Promise.all([\n      step.run(\"security-analysis\", () =>\n        analyzeForSecurityIssues(event.data.document)\n      ),\n      step.run(\"performance-analysis\", () =>\n        analyzeForPerformance(event.data.document)\n      ),\n      step.run(\"compliance-analysis\", () =>\n        analyzeForCompliance(event.data.document)\n      ),\n    ]);\n\n    // Aggregate results\n    const report = await step.run(\"generate-report\", () =>\n      generateReport({ security, performance, compliance })\n    );\n\n    return report;\n  }\n);\n\"\"\"\n\n## AWS Step Functions (Amazon States Language)\n\"\"\"\n{\n  \"Type\": \"Parallel\",\n  \"Branches\": [\n    {\n      \"StartAt\": \"SecurityAnalysis\",\n      \"States\": {\n        \"SecurityAnalysis\": {\n          \"Type\": \"Task\",\n          \"Resource\": \"arn:aws:lambda:...:security-analyzer\",\n          \"End\": true\n        }\n      }\n    },\n    {\n      \"StartAt\": \"PerformanceAnalysis\",\n      \"States\": {\n        \"PerformanceAnalysis\": {\n          \"Type\": \"Task\",\n          \"Resource\": \"arn:aws:lambda:...:performance-analyzer\",\n          \"End\": true\n        }\n      }\n    }\n  ],\n  \"Next\": \"AggregateResults\"\n}\n\"\"\"\n\n### Orchestrator-Worker Pattern\n\nCentral coordinator dispatches work to specialized workers\n\n**When to use**: Complex tasks requiring different expertise, dynamic subtask creation\n\n# ORCHESTRATOR-WORKER PATTERN:\n\n\"\"\"\n┌─────────────────────────────────────┐\n│          ORCHESTRATOR               │\n│  - Analyzes task                    │\n│  - Creates subtasks                 │\n│  - Dispatches to workers            │\n│  - Aggregates results               │\n└─────────────────────────────────────┘\n                │\n    ┌───────────┼───────────┐\n    ▼           ▼           ▼\n┌───────┐  ┌───────┐  ┌───────┐\n│Worker1│  │Worker2│  │Worker3│\n│Create │  │Modify │  │Delete │\n└───────┘  └───────┘  └───────┘\n\"\"\"\n\n## Temporal Example\n\"\"\"\nexport async function orchestratorWorkflow(task: ComplexTask) {\n  // Orchestrator decides what work needs to be done\n  const plan = await analyzeTask(task);\n\n  // Dispatch to specialized worker workflows\n  const results = await Promise.all(\n    plan.subtasks.map(subtask => {\n      switch (subtask.type) {\n        case 'create':\n          return executeChild(createWorkerWorkflow, { args: [subtask] });\n        case 'modify':\n          return executeChild(modifyWorkerWorkflow, { args: [subtask] });\n        case 'delete':\n          return executeChild(deleteWorkerWorkflow, { args: [subtask] });\n      }\n    })\n  );\n\n  // Aggregate results\n  return aggregateResults(results);\n}\n\"\"\"\n\n## Inngest with AI Orchestration\n\"\"\"\nexport const aiOrchestrator = inngest.createFunction(\n  { id: \"ai-orchestrator\" },\n  { event: \"task/complex\" },\n  async ({ event, step }) => {\n    // AI decides what needs to be done\n    const plan = await step.run(\"create-plan\", async () => {\n      return await llm.chat({\n        messages: [\n          { role: \"system\", content: \"Break this task into subtasks...\" },\n          { role: \"user\", content: event.data.task }\n        ]\n      });\n    });\n\n    // Execute each subtask as a durable step\n    const results = [];\n    for (const subtask of plan.subtasks) {\n      const result = await step.run(`execute-${subtask.id}`, async () => {\n        return executeSubtask(subtask);\n      });\n      results.push(result);\n    }\n\n    // Final synthesis\n    return await step.run(\"synthesize\", async () => {\n      return synthesizeResults(results);\n    });\n  }\n);\n\"\"\"\n\n### Event-Driven Trigger Pattern\n\nWorkflows triggered by events, not schedules\n\n**When to use**: Reactive systems, user actions, webhook integrations\n\n# EVENT-DRIVEN TRIGGERS:\n\n## Inngest Event-Based\n\"\"\"\n// Define events with TypeScript types\ntype Events = {\n  \"user/signed.up\": {\n    data: { userId: string; email: string };\n  };\n  \"order/completed\": {\n    data: { orderId: string; total: number };\n  };\n};\n\n// Function triggered by event\nexport const onboardUser = inngest.createFunction(\n  { id: \"onboard-user\" },\n  { event: \"user/signed.up\" },  // Trigger on this event\n  async ({ event, step }) => {\n    // Wait 1 hour, then send welcome email\n    await step.sleep(\"wait-for-exploration\", \"1 hour\");\n\n    await step.run(\"send-welcome\", async () => {\n      return sendWelcomeEmail(event.data.email);\n    });\n\n    // Wait 3 days for engagement check\n    await step.sleep(\"wait-for-engagement\", \"3 days\");\n\n    const engaged = await step.run(\"check-engagement\", async () => {\n      return checkUserEngagement(event.data.userId);\n    });\n\n    if (!engaged) {\n      await step.run(\"send-nudge\", async () => {\n        return sendNudgeEmail(event.data.email);\n      });\n    }\n  }\n);\n\n// Send events from anywhere\nawait inngest.send({\n  name: \"user/signed.up\",\n  data: { userId: \"123\", email: \"user@example.com\" }\n});\n\"\"\"\n\n## n8n Webhook Trigger\n\"\"\"\n[Webhook: POST /api/webhooks/order]\n    ↓\n[Switch: event.type]\n    ↓ order.created\n[Process New Order Subworkflow]\n    ↓ order.cancelled\n[Handle Cancellation Subworkflow]\n\"\"\"\n\n### Retry and Recovery Pattern\n\nAutomatic retry with backoff, dead letter handling\n\n**When to use**: Any workflow with external dependencies\n\n# RETRY AND RECOVERY:\n\n## Temporal Retry Configuration\n\"\"\"\nconst activities = proxyActivities<typeof activitiesType>({\n  startToCloseTimeout: '30 seconds',\n  retry: {\n    initialInterval: '1 second',\n    backoffCoefficient: 2,\n    maximumInterval: '1 minute',\n    maximumAttempts: 5,\n    nonRetryableErrorTypes: [\n      'ValidationError',      // Don't retry validation failures\n      'InsufficientFunds',    // Don't retry payment failures\n    ]\n  }\n});\n\"\"\"\n\n## Inngest Retry Configuration\n\"\"\"\nexport const processPayment = inngest.createFunction(\n  {\n    id: \"process-payment\",\n    retries: 5,  // Retry up to 5 times\n  },\n  { event: \"payment/initiated\" },\n  async ({ event, step, attempt }) => {\n    // attempt is 0-indexed retry count\n\n    const result = await step.run(\"charge-card\", async () => {\n      try {\n        return await stripe.charges.create({...});\n      } catch (error) {\n        if (error.code === 'card_declined') {\n          // Don't retry card declines\n          throw new NonRetriableError(\"Card declined\");\n        }\n        throw error;  // Retry other errors\n      }\n    });\n\n    return result;\n  }\n);\n\"\"\"\n\n## Dead Letter Handling\n\"\"\"\n// n8n: Use Error Trigger node\n[Error Trigger]\n    ↓\n[Log to Error Database]\n    ↓\n[Send Alert to Slack]\n    ↓\n[Create Ticket in Jira]\n\n// Inngest: Handle in onFailure\nexport const myFunction = inngest.createFunction(\n  {\n    id: \"my-function\",\n    onFailure: async ({ error, event, step }) => {\n      await step.run(\"alert-team\", async () => {\n        await slack.postMessage({\n          channel: \"#errors\",\n          text: `Function failed: ${error.message}`\n        });\n      });\n    }\n  },\n  { event: \"...\" },\n  async ({ step }) => { ... }\n);\n\"\"\"\n\n### Scheduled Workflow Pattern\n\nTime-based triggers for recurring tasks\n\n**When to use**: Daily reports, periodic sync, batch processing\n\n# SCHEDULED WORKFLOWS:\n\n## Inngest Cron\n\"\"\"\nexport const dailyReport = inngest.createFunction(\n  { id: \"daily-report\" },\n  { cron: \"0 9 * * *\" },  // Every day at 9 AM\n  async ({ step }) => {\n    const data = await step.run(\"gather-metrics\", async () => {\n      return gatherDailyMetrics();\n    });\n\n    await step.run(\"generate-report\", async () => {\n      return generateAndSendReport(data);\n    });\n  }\n);\n\nexport const syncInventory = inngest.createFunction(\n  { id: \"sync-inventory\" },\n  { cron: \"*/15 * * * *\" },  // Every 15 minutes\n  async ({ step }) => {\n    await step.run(\"sync\", async () => {\n      return syncWithSupplier();\n    });\n  }\n);\n\"\"\"\n\n## Temporal Cron Workflow\n\"\"\"\n// Schedule workflow to run on cron\nconst handle = await client.workflow.start(dailyReportWorkflow, {\n  taskQueue: 'reports',\n  workflowId: 'daily-report',\n  cronSchedule: '0 9 * * *',  // 9 AM daily\n});\n\"\"\"\n\n## n8n Schedule Trigger\n\"\"\"\n[Schedule Trigger: Every day at 9:00 AM]\n    ↓\n[HTTP Request: Get Metrics]\n    ↓\n[Code Node: Generate Report]\n    ↓\n[Send Email: Report]\n\"\"\"\n\n## Sharp Edges\n\n### Non-Idempotent Steps in Durable Workflows\n\nSeverity: CRITICAL\n\nSituation: Writing workflow steps that modify external state\n\nSymptoms:\nCustomer charged twice. Email sent three times. Database record\ncreated multiple times. Workflow retries cause duplicate side effects.\n\nWhy this breaks:\nDurable execution replays workflows from the beginning on restart.\nIf step 3 crashes and the workflow resumes, steps 1 and 2 run again.\nWithout idempotency keys, external services don't know these are retries.\n\nRecommended fix:\n\n# ALWAYS use idempotency keys for external calls:\n\n## Stripe example:\nawait stripe.paymentIntents.create({\n  amount: 1000,\n  currency: 'usd',\n  idempotency_key: `order-${orderId}-payment`  # Critical!\n});\n\n## Email example:\nawait step.run(\"send-confirmation\", async () => {\n  const alreadySent = await checkEmailSent(orderId);\n  if (alreadySent) return { skipped: true };\n  return sendEmail(customer, orderId);\n});\n\n## Database example:\nawait db.query(`\n  INSERT INTO orders (id, ...) VALUES ($1, ...)\n  ON CONFLICT (id) DO NOTHING\n`, [orderId]);\n\n# Generate idempotency key from stable inputs, not random values\n\n### Workflow Runs for Hours/Days Without Checkpoints\n\nSeverity: HIGH\n\nSituation: Long-running workflows with infrequent steps\n\nSymptoms:\nMemory consumption grows. Worker timeouts. Lost progress after\ncrashes. \"Workflow exceeded maximum duration\" errors.\n\nWhy this breaks:\nWorkflows hold state in memory until checkpointed. A workflow that\nruns for 24 hours with one step per hour accumulates state for 24h.\nWorkers have memory limits. Functions have execution time limits.\n\nRecommended fix:\n\n# Break long workflows into checkpointed steps:\n\n## WRONG - one long step:\nawait step.run(\"process-all\", async () => {\n  for (const item of thousandItems) {\n    await processItem(item);  // Hours of work, one checkpoint\n  }\n});\n\n## CORRECT - many small steps:\nfor (const item of thousandItems) {\n  await step.run(`process-${item.id}`, async () => {\n    return processItem(item);  // Checkpoint after each\n  });\n}\n\n## For very long waits, use sleep:\nawait step.sleep(\"wait-for-trial\", \"14 days\");\n// Doesn't consume resources while waiting\n\n## Consider child workflows for long processes:\nawait step.invoke(\"process-batch\", {\n  function: batchProcessor,\n  data: { items: batch }\n});\n\n### Activities Without Timeout Configuration\n\nSeverity: HIGH\n\nSituation: Calling external services from workflow activities\n\nSymptoms:\nWorkflows hang indefinitely. Worker pool exhausted. Dead workflows\nthat never complete or fail. Manual intervention needed to kill stuck\nworkflows.\n\nWhy this breaks:\nExternal APIs can hang forever. Without timeout, your workflow waits\nforever. Unlike HTTP clients, workflow activities don't have default\ntimeouts in most platforms.\n\nRecommended fix:\n\n# ALWAYS set timeouts on activities:\n\n## Temporal:\nconst activities = proxyActivities<typeof activitiesType>({\n  startToCloseTimeout: '30 seconds',  # Required!\n  scheduleToCloseTimeout: '5 minutes',\n  heartbeatTimeout: '10 seconds',  # For long activities\n  retry: {\n    maximumAttempts: 3,\n    initialInterval: '1 second',\n  }\n});\n\n## Inngest:\nawait step.run(\"call-api\", { timeout: \"30s\" }, async () => {\n  return fetch(url, { signal: AbortSignal.timeout(25000) });\n});\n\n## AWS Step Functions:\n{\n  \"Type\": \"Task\",\n  \"TimeoutSeconds\": 30,\n  \"HeartbeatSeconds\": 10,\n  \"Resource\": \"arn:aws:lambda:...\"\n}\n\n# Rule: Activity timeout < Workflow timeout\n\n### Side Effects Outside Step/Activity Boundaries\n\nSeverity: CRITICAL\n\nSituation: Writing code that runs during workflow replay\n\nSymptoms:\nRandom failures on replay. \"Workflow corrupted\" errors. Different\nbehavior on replay than initial run. Non-determinism errors.\n\nWhy this breaks:\nWorkflow code runs on EVERY replay. If you generate a random ID in\nworkflow code, you get a different ID each replay. If you read the\ncurrent time, you get a different time. This breaks determinism.\n\nRecommended fix:\n\n# WRONG - side effects in workflow code:\nexport async function orderWorkflow(order) {\n  const orderId = uuid();  // Different every replay!\n  const now = new Date();  // Different every replay!\n  await activities.process(orderId, now);\n}\n\n# CORRECT - side effects in activities:\nexport async function orderWorkflow(order) {\n  const orderId = await activities.generateOrderId();  # Recorded\n  const now = await activities.getCurrentTime();       # Recorded\n  await activities.process(orderId, now);\n}\n\n# Also CORRECT - Temporal workflow.now() and sideEffect:\nimport { sideEffect } from '@temporalio/workflow';\n\nconst orderId = await sideEffect(() => uuid());\nconst now = workflow.now();  # Deterministic replay-safe time\n\n# Side effects that are safe in workflow code:\n# - Reading function arguments\n# - Simple calculations (no randomness)\n# - Logging (usually)\n\n### Retry Configuration Without Exponential Backoff\n\nSeverity: MEDIUM\n\nSituation: Configuring retry behavior for failing steps\n\nSymptoms:\nOverwhelming failing services. Rate limiting. Cascading failures.\nRetry storms causing outages. Being blocked by external APIs.\n\nWhy this breaks:\nWhen a service is struggling, immediate retries make it worse.\n100 workflows retrying instantly = 100 requests hitting a service\nthat's already failing. Backoff gives the service time to recover.\n\nRecommended fix:\n\n# ALWAYS use exponential backoff:\n\n## Temporal:\nconst activities = proxyActivities({\n  retry: {\n    initialInterval: '1 second',\n    backoffCoefficient: 2,       # 1s, 2s, 4s, 8s, 16s...\n    maximumInterval: '1 minute',  # Cap the backoff\n    maximumAttempts: 5,\n  }\n});\n\n## Inngest (built-in backoff):\n{\n  id: \"my-function\",\n  retries: 5,  # Uses exponential backoff by default\n}\n\n## Manual backoff:\nconst backoff = (attempt) => {\n  const base = 1000;\n  const max = 60000;\n  const delay = Math.min(base * Math.pow(2, attempt), max);\n  const jitter = delay * 0.1 * Math.random();\n  return delay + jitter;\n};\n\n# Add jitter to prevent thundering herd\n\n### Storing Large Data in Workflow State\n\nSeverity: HIGH\n\nSituation: Passing large payloads between workflow steps\n\nSymptoms:\nSlow workflow execution. Memory errors. \"Payload too large\" errors.\nExpensive storage costs. Slow replays.\n\nWhy this breaks:\nWorkflow state is persisted and replayed. A 10MB payload is stored,\nserialized, and deserialized on every step. This adds latency and\ncost. Some platforms have hard limits (e.g., Step Functions 256KB).\n\nRecommended fix:\n\n# WRONG - large data in workflow:\nawait step.run(\"fetch-data\", async () => {\n  const largeDataset = await fetchAllRecords();  // 100MB!\n  return largeDataset;  // Stored in workflow state\n});\n\n# CORRECT - store reference, not data:\nawait step.run(\"fetch-data\", async () => {\n  const largeDataset = await fetchAllRecords();\n  const s3Key = await uploadToS3(largeDataset);\n  return { s3Key };  // Just the reference\n});\n\nconst processed = await step.run(\"process-data\", async () => {\n  const data = await downloadFromS3(fetchResult.s3Key);\n  return processData(data);\n});\n\n# For Step Functions, use S3 for large payloads:\n{\n  \"Type\": \"Task\",\n  \"Resource\": \"arn:aws:states:::s3:putObject\",\n  \"Parameters\": {\n    \"Bucket\": \"my-bucket\",\n    \"Key.$\": \"$.outputKey\",\n    \"Body.$\": \"$.largeData\"\n  }\n}\n\n### Missing Dead Letter Queue or Failure Handler\n\nSeverity: HIGH\n\nSituation: Workflows that exhaust all retries\n\nSymptoms:\nFailed workflows silently disappear. No alerts when things break.\nCustomer issues discovered days later. Manual recovery impossible.\n\nWhy this breaks:\nEven with retries, some workflows will fail permanently. Without\ndead letter handling, you don't know they failed. The customer\nwaits forever, you're unaware, and there's no data to debug.\n\nRecommended fix:\n\n# Inngest onFailure handler:\nexport const myFunction = inngest.createFunction(\n  {\n    id: \"process-order\",\n    onFailure: async ({ error, event, step }) => {\n      // Log to error tracking\n      await step.run(\"log-error\", () =>\n        sentry.captureException(error, { extra: { event } })\n      );\n\n      // Alert team\n      await step.run(\"alert\", () =>\n        slack.postMessage({\n          channel: \"#alerts\",\n          text: `Order ${event.data.orderId} failed: ${error.message}`\n        })\n      );\n\n      // Queue for manual review\n      await step.run(\"queue-review\", () =>\n        db.insert(failedOrders, { orderId, error, event })\n      );\n    }\n  },\n  { event: \"order/created\" },\n  async ({ event, step }) => { ... }\n);\n\n# n8n Error Trigger:\n[Error Trigger]  →  [Log to DB]  →  [Slack Alert]  →  [Create Ticket]\n\n# Temporal: Use workflow.failed or workflow signals\n\n### n8n Workflow Without Error Trigger\n\nSeverity: MEDIUM\n\nSituation: Building production n8n workflows\n\nSymptoms:\nWorkflow fails silently. Errors only visible in execution logs.\nNo alerts, no recovery, no visibility until someone notices.\n\nWhy this breaks:\nn8n doesn't notify on failure by default. Without an Error Trigger\nnode connected to alerting, failures are only visible in the UI.\nProduction failures go unnoticed.\n\nRecommended fix:\n\n# Every production n8n workflow needs:\n\n1. Error Trigger node\n   - Catches any node failure in the workflow\n   - Provides error details and context\n\n2. Connected error handling:\n   [Error Trigger]\n       ↓\n   [Set: Extract Error Details]\n       ↓\n   [HTTP: Log to Error Service]\n       ↓\n   [Slack/Email: Alert Team]\n\n3. Consider dead letter pattern:\n   [Error Trigger]\n       ↓\n   [Redis/Postgres: Store Failed Job]\n       ↓\n   [Separate Recovery Workflow]\n\n# Also use:\n- Retry on node failures (built-in)\n- Node timeout settings\n- Workflow timeout\n\n### Long-Running Temporal Activities Without Heartbeat\n\nSeverity: MEDIUM\n\nSituation: Activities that run for more than a few seconds\n\nSymptoms:\nActivity timeouts even when work is progressing. Lost work when\nworkers restart. Can't cancel long-running activities.\n\nWhy this breaks:\nTemporal detects stuck activities via heartbeat. Without heartbeat,\nTemporal can't tell if activity is working or stuck. Long activities\nappear hung, may timeout, and can't be gracefully cancelled.\n\nRecommended fix:\n\n# For any activity > 10 seconds, add heartbeat:\n\nimport { heartbeat, activityInfo } from '@temporalio/activity';\n\nexport async function processLargeFile(fileUrl: string): Promise<void> {\n  const chunks = await downloadChunks(fileUrl);\n\n  for (let i = 0; i < chunks.length; i++) {\n    // Check for cancellation\n    const { cancelled } = activityInfo();\n    if (cancelled) {\n      throw new CancelledFailure('Activity cancelled');\n    }\n\n    await processChunk(chunks[i]);\n\n    // Report progress\n    heartbeat({ progress: (i + 1) / chunks.length });\n  }\n}\n\n# Configure heartbeat timeout:\nconst activities = proxyActivities({\n  startToCloseTimeout: '10 minutes',\n  heartbeatTimeout: '30 seconds',  # Must heartbeat every 30s\n});\n\n# If no heartbeat for 30s, activity is considered stuck\n\n## Validation Checks\n\n### External Calls Without Idempotency Key\n\nSeverity: ERROR\n\nStripe/payment calls should use idempotency keys\n\nMessage: Payment call without idempotency_key. Add idempotency key to prevent duplicate charges on retry.\n\n### Email Sending Without Deduplication\n\nSeverity: WARNING\n\nEmail sends in workflows should check for already-sent\n\nMessage: Email sent in workflow without deduplication check. Retries may send duplicate emails.\n\n### Temporal Activities Without Timeout\n\nSeverity: ERROR\n\nAll Temporal activities need timeout configuration\n\nMessage: proxyActivities without timeout. Add startToCloseTimeout to prevent indefinite hangs.\n\n### Inngest Steps Calling External APIs Without Timeout\n\nSeverity: WARNING\n\nExternal API calls should have timeouts\n\nMessage: External API call in step without timeout. Add timeout to prevent workflow hangs.\n\n### Random Values in Workflow Code\n\nSeverity: ERROR\n\nRandom values break determinism on replay\n\nMessage: Random value in workflow code. Move to activity/step or use sideEffect.\n\n### Date.now() in Workflow Code\n\nSeverity: ERROR\n\nCurrent time breaks determinism on replay\n\nMessage: Current time in workflow code. Use workflow.now() or move to activity/step.\n\n### Inngest Function Without onFailure Handler\n\nSeverity: WARNING\n\nProduction functions should have failure handlers\n\nMessage: Inngest function without onFailure handler. Add failure handling for production reliability.\n\n### Step Without Error Handling\n\nSeverity: WARNING\n\nSteps should handle errors gracefully\n\nMessage: Step without try/catch. Consider handling specific error cases.\n\n### Potentially Large Data Returned from Step\n\nSeverity: INFO\n\nLarge data in workflow state slows execution\n\nMessage: Returning potentially large data from step. Consider storing in S3/DB and returning reference.\n\n### Retry Without Backoff Configuration\n\nSeverity: WARNING\n\nRetries should use exponential backoff\n\nMessage: Retry configured without backoff. Add backoffCoefficient and initialInterval.\n\n## Collaboration\n\n### Delegation Triggers\n\n- user needs multi-agent coordination -> multi-agent-orchestration (Workflow provides infrastructure, orchestration provides patterns)\n- user needs tool building for workflows -> agent-tool-builder (Tools that workflows can invoke)\n- user needs Zapier/Make integration -> zapier-make-patterns (No-code automation platforms)\n- user needs browser automation in workflow -> browser-automation (Playwright/Puppeteer activities)\n- user needs computer control in workflow -> computer-use-agents (Desktop automation activities)\n- user needs LLM integration in workflow -> llm-architect (AI-powered workflow steps)\n\n## Related Skills\n\nWorks well with: `multi-agent-orchestration`, `agent-tool-builder`, `backend`, `devops`\n\n## When to Use\n- User mentions or implies: workflow\n- User mentions or implies: automation\n- User mentions or implies: n8n\n- User mentions or implies: temporal\n- User mentions or implies: inngest\n- User mentions or implies: step function\n- User mentions or implies: background job\n- User mentions or implies: durable execution\n- User mentions or implies: event-driven\n- User mentions or implies: scheduled task\n- User mentions or implies: job queue\n- User mentions or implies: cron\n- User mentions or implies: trigger\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["workflow","automation","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-workflow-automation","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/workflow-automation","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34404 github stars · SKILL.md body (27,352 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:52:00.069Z","embedding":null,"createdAt":"2026-04-18T21:47:44.378Z","updatedAt":"2026-04-22T00:52:00.069Z","lastSeenAt":"2026-04-22T00:52:00.069Z","tsv":"'/15':1240 '/activities':445 '/api/webhooks/order':983 '/client':349 '0':1076,1203,1273,2565 '0.1':2020 '00':1287 '1':333,364,906,918,1028,1033,1359,1429,1687,1965,1975,2402,2591 '10':33,1678,1712,2541,2600 '100':1933,1937 '1000':1389,2005 '100mb':2112 '10mb':2071 '123':975 '14':1574 '15':1242 '16s':1973 '1s':1969 '2':335,379,459,1031,1361,1968,2014,2418 '24':1491 '24h':1501 '25000':1703 '256kb':2094 '2s':1970 '3':337,398,457,930,941,1352,1685,2436 '30':453,1024,1671,1710,2603 '30s':1696,2608,2613 '4':414 '400':231 '4s':1971 '5':1036,1062,1066,1675,1981,1992 '60000':2008 '8s':1972 '9':1204,1208,1274,1275,1286 'abortsignal.timeout':1702 'access':86 'accumul':1498 'action':854 'activ':443,1021,1598,1610,1650,1665,1668,1682,1718,1829,1961,2468,2474,2484,2502,2509,2519,2525,2540,2580,2597,2614,2678,2685,2928,2941 'activities.generateorderid':1838 'activities.getcurrenttime':1843 'activities.process':1822,1846 'activity/step':2749,2776 'activityinfo':2547,2574 'actual':98 'add':134,2025,2082,2543,2639,2693,2722,2796,2867 'agent':12,23,154,190,194,303,2878,2882,2897,2938,2963,2966 'agent-tool-build':2896,2965 'aggreg':529,548,595,685,748 'aggregateresult':650,751 'ai':11,22,261,302,755,763,770,2952 'ai-orchestr':762 'ai-pow':2951 'aiorchestr':759 'alert':1130,1157,2206,2284,2288,2291,2325,2357,2383,2434 'alert-team':1156 'alreadi':1944,2662 'already-s':2661 'alreadys':1407,1412 'also':1849,2450 'alway':1377,1661,1955 'amazon':613 'amount':1388 'analys':536,568 'analysi':580,586,592 'analyz':560,631,646,678 'analyze-docu':559 'analyzedocu':556 'analyzeforcompli':593 'analyzeforperform':587 'analyzeforsecurityissu':581 'analyzetask':712 'angri':41 'anywher':968 'api':208,211,1636,1694,1919,2703,2709,2716 'api-design':207,210 'appear':2526 'architect':2950 'arg':732,739,746 'argument':1882 'arn':626,641,1714,2171 'ask':3079 'async':360,374,392,408,422,461,564,696,767,784,821,833,902,925,950,961,1070,1087,1150,1159,1169,1210,1219,1227,1244,1249,1405,1528,1555,1697,1804,1831,2107,2129,2151,2267,2313,2551 'attempt':1073,1074,2002,2015 'autom':3,5,14,16,75,164,220,2916,2921,2926,2940,2983 'automat':999 'aw':271,276,284,610,627,642,1704,1715,2172 'await':369,387,403,417,469,474,480,484,575,599,711,721,779,786,817,830,912,920,935,945,956,969,1082,1090,1154,1160,1214,1222,1246,1263,1386,1400,1408,1422,1523,1534,1551,1568,1588,1690,1821,1837,1842,1845,1861,2102,2110,2124,2132,2136,2146,2154,2275,2286,2301,2559,2582 'aws-nat':275 'azur':291,295 'b':547 'backend':2969 'background':182,3009 'background-job':181 'backoff':1002,1893,1946,1958,1979,1986,1995,1999,2001,2853,2861,2866 'backoffcoeffici':458,1030,1967,2868 'base':95,288,864,1176,2004,2012 'batch':1188,1592,1597 'batchprocessor':1594 'becom':318 'begin':1347 'behavior':1746,1899 'best':264 'block':1916 'bodi':2183 'boundari':1726,3087 'branch':618 'break':792,1340,1478,1513,1634,1758,1793,1922,2063,2209,2220,2367,2505,2737,2761 'brittl':69 'browser':2920,2925 'browser-autom':2924 'bucket':2177,2180 'build':2342,2893 'builder':2899,2968 'built':1984,2457 'built-in':1983,2456 'c':551 'calcul':1884 'call':1383,1605,1693,2621,2628,2635,2701,2710,2717 'call-api':1692 'cancel':993,2498,2535,2571,2573,2576,2581 'cancelledfailur':2579 'cap':1977 'capabl':161 'card':1086,1096,1101,1106 'cascad':1909 'case':727,734,741,2821 'catch':1092,2406 'caus':1334,1913 'cd':198 'central':655 'channel':1162,2290 'charg':1085,1321,2645 'charge-card':1084 'chargecard':394,448,475 'check':934,948,2569,2619,2659,2671 'check-engag':947 'checkemails':1409 'checkpoint':126,305,339,1450,1485,1517,1541,1559 'checkuserengag':952 'child':1583 'chunk':2558,2584 'chunks.length':2567,2592 'ci':197 'ci-cd-pipelin':196 'clarif':3081 'clear':3054 'client':1648 'client.workflow.start':1264 'co':156 'co-evolv':155 'code':219,1293,1731,1760,1773,1802,1879,2732,2746,2756,2770,2915 'codebas':260 'collabor':2871 'complet':1622 'complex':135,665 'complextask':700 'complianc':574,591,607 'compliance-analysi':590 'comput':2931,2936 'computer-use-ag':2935 'configur':508,1019,1052,1601,1890,1897,2593,2688,2854,2864 'confirm':416,421,507,1404 'conflict':1431 'connect':2381,2419 'consid':1582,2437,2616,2817,2844 'const':351,367,385,401,446,467,472,478,555,571,597,709,719,758,777,808,811,815,889,943,1020,1054,1080,1142,1195,1212,1232,1261,1406,1530,1547,1667,1808,1814,1835,1840,1859,1864,1960,2000,2003,2006,2009,2017,2108,2130,2134,2144,2152,2259,2557,2572,2596 'consum':1578 'consumpt':1463 'content':324,791,799 'context':2417 'control':2932 'coordin':191,656,2879 'correct':89,1542,1825,1850,2119 'corrupt':1743 'cost':2058,2085 'count':1079 'cover':54 'crash':384,1353,1470 'creat':399,406,503,680,690,728,782,1133,1329,2326 'create-plan':781 'create-ship':405 'createship':410,449,481 'createworkerworkflow':731 'creation':672 'criteria':3090 'critic':114,241,1310,1397,1728 'cron':1193,1202,1239,1253,1260,3040 'cronschedul':1272 'currenc':1390 'current':1785,2759,2766 'curv':252 'custom':42,1320,1418,2210,2240 'daili':1184,1200,1270,1277 'daily-report':1199,1269 'dailyreport':1196 'dailyreportworkflow':1265 'data':202,205,326,537,873,879,973,1213,1230,1595,2033,2099,2106,2123,2128,2150,2153,2159,2250,2824,2831,2841 'data-engin':204 'data-pipelin':201 'databas':1128,1327,1420 'date':1817 'date.now':2753 'day':931,942,1206,1284,1575,2213 'db':2323 'db.insert':2306 'db.query':1423 'dead':519,1003,1115,1618,2186,2230,2438 'debug':2252 'decid':702,771 'declin':1097,1102,1107 'dedupl':2651,2670 'default':1654,1997,2375 'defin':865 'definit':290 'delay':2010,2019,2023 'deleg':2872 'delet':692,742 'deleteworkerworkflow':745 'demand':139 'depend':1013 'describ':3058 'deseri':2077 'design':158,209,212 'desktop':2939 'detail':2415,2427 'detect':2507 'determin':1754,1794,2738,2762 'determinist':1867 'develop':92,265 'devop':200,2970 'differ':81,668,1745,1777,1790,1811,1818 'disappear':2204 'discov':2212 'dispatch':657,682,714 'document':561 'document/uploaded':563 'doesn':1576,2369 'done':708,776 'downloadchunk':2560 'downloadfroms3':2155 'driven':173,257,839,859,3023 'duplic':1335,2644,2675 'durabl':26,103,169,248,292,382,806,1307,1341,3015 'durable-execut':168 'durat':1474 'dynam':670 'e.g':2091 'edg':1301 'effect':1337,1723,1799,1827,1873 'email':506,876,911,976,1298,1323,1398,2648,2654,2665,2676 'end':632,647 'engag':933,940,944,949,955 'engin':206 'environ':3070 'environment-specif':3069 'error':516,1093,1109,1112,1120,1123,1127,1151,1163,1475,1744,1755,2051,2055,2268,2273,2279,2281,2309,2317,2319,2337,2350,2378,2403,2414,2420,2422,2426,2431,2441,2626,2682,2734,2758,2804,2811,2820 'error.code':1095 'error.message':1167,2296 'even':2221,2486 'event':116,172,256,358,361,562,565,765,768,838,845,858,863,866,871,887,896,901,903,966,1068,1071,1152,1168,2269,2283,2310,2311,2314,3022 'event-bas':862 'event-driven':255,837,857,3021 'event-driven-workflow':171 'event.data.document':582,588,594 'event.data.email':928,964 'event.data.order':377 'event.data.orderid':432,2294 'event.data.task':800 'event.data.userid':953 'event.type':985 'everi':1205,1241,1283,1763,1812,1819,2079,2397,2607 'evolv':157 'exact':47 'exampl':344,434,553,694,1385,1399,1421 'exceed':1472 'execut':27,104,170,313,801,819,1342,1508,2049,2354,2836,3016 'executechild':730,737,744 'executesubtask':823 'exhaust':1617,2197 'exist':279 'expens':2056 'experi':93,266 'expert':3075 'expertis':669 'explor':917 'exponenti':1892,1957,1994,2860 'export':350,460,554,695,757,888,1053,1141,1194,1231,1803,1830,2258,2550 'extern':1012,1317,1367,1382,1606,1635,1918,2620,2702,2708,2715 'extra':2282 'extract':2425 'fail':151,1166,1624,1901,1905,1945,2201,2227,2238,2295,2348,2445 'failedord':2307 'failur':514,1043,1049,1739,1910,2190,2373,2384,2392,2409,2455,2788,2797 'fetch':1699,2105,2127 'fetch-data':2104,2126 'fetchallrecord':2111,2133 'fetchresult.s3key':2156 'fileurl':2554,2561 'final':827 'financi':243 'fix':1376,1512,1660,1796,1954,2096,2254,2396,2537 'flow':36 'forev':1639,1645,2242 'function':177,273,281,293,462,612,697,884,1148,1165,1506,1593,1706,1805,1832,1881,1990,2093,2162,2552,2778,2785,2792,3004 'gather':1217 'gather-metr':1216 'gatherdailymetr':1221 'generat':602,1225,1295,1436,1767 'generate-report':601,1224 'generateandsendreport':1229 'generatereport':604 'get':1291,1775,1788 'give':1947 'go':2393 'good':301 'grace':2534,2812 'grade':74 'great':233 'grow':1464 'guarante':249 'handl':521,992,1005,1117,1138,1262,2232,2421,2798,2805,2810,2818 'handler':2191,2257,2781,2789,2795 'hang':1613,1638,2698,2727 'hard':2089 'heartbeat':2470,2511,2513,2544,2546,2588,2594,2606,2611 'heartbeatsecond':1711 'heartbeattimeout':1677,2602 'herd':2030 'hiccup':30 'high':1452,1603,2038,2193 'hit':1939 'hold':1480 'host':270 'hostabl':230 'hour':907,919,1492,1497,1537 'hours/days':1448 'http':493,497,501,1289,1647,2428 'hung':2527 'hype':101 'id':354,558,761,892,1057,1145,1198,1235,1427,1432,1770,1778,1987,2262 'idempot':1304,1365,1379,1392,1437,2623,2631,2637,2640 'immedi':1928 'impli':2977,2982,2987,2992,2997,3002,3008,3014,3020,3027,3033,3039,3044 'import':346,436,440,1855,2545 'imposs':2217 'indefinit':1614,2697 'independ':130,525,535 'index':1077 'info':2829 'infrastructur':8,19,2886 'infrequ':1459 'initi':1750 'initialinterv':1027,1686,1964,2870 'inngest':59,90,253,343,347,552,753,861,1050,1137,1192,1689,1982,2255,2699,2777,2791,2998 'inngest.createfunction':353,557,760,891,1056,1144,1197,1234,2261 'inngest.send':970 'input':320,545,1441,3084 'insert':1424 'insight':77 'instant':1936 'insufficientfund':1044 'integr':232,285,856,2908,2945 'intervent':1626 'inventori':1238 'invok':2904 'isn':142 'issu':2211 'item':1531,1536,1548,1558,1596 'item.id':1554 'jira':1136 'jitter':2018,2024,2026 'job':179,183,2446,3010,3034 'job-queu':178 'json':287 'json-bas':286 'key':76,1366,1380,1393,1438,2181,2624,2632,2638,2641 'kill':1629 'know':1371,2236 'lambda':280,628,643,1716 'languag':120,615 'larg':2032,2041,2054,2098,2166,2823,2830,2840 'largedata':2184 'largedataset':2109,2114,2131,2138 'latenc':2083 'later':2214 'learn':251 'left':50 'let':2563 'letter':520,1004,1116,2187,2231,2439 'limit':1505,1510,1908,2090,3046 'llm':2944,2949 'llm-architect':2948 'llm.chat':787 'log':1125,1887,2271,2278,2321,2355,2429 'log-error':2277 'long':1455,1514,1521,1564,1586,1681,2465,2500,2524 'long-run':1454,2464,2499 'lost':38,1467,2491 'low':218 'low-cod':217 'make':10,21,80,1930,2911 'mani':1543 'manual':1625,1998,2215,2299 'match':3055 'math.min':2011 'math.pow':2013 'math.random':2021 'max':2007,2016 'maximum':1473 'maximumattempt':456,1035,1684,1980 'maximuminterv':1032,1974 'may':2528,2673 'mean':37 'medium':1895,2340,2472 'memori':1462,1483,1504,2050 'mention':2975,2980,2985,2990,2995,3000,3006,3012,3018,3025,3031,3037,3042 'messag':788,2633,2664,2689,2714,2741,2765,2790,2813,2837,2862 'metric':1218,1292 'microservic':245 'minut':1034,1243,1676,1976,2601 'miss':2185,3092 'mission':240 'mission-crit':239 'modifi':691,735,1316 'modifyworkerworkflow':738 'money':39,110 'move':2747,2774 'multi':189,193,2877,2881,2962 'multi-ag':2876 'multi-agent-coordin':188 'multi-agent-orchestr':192,2880,2961 'multipl':534,539,1330 'must':2605 'my-bucket':2178 'my-funct':1146,1988 'myfunct':1143,2260 'n8n':57,83,215,489,978,1118,1278,2316,2334,2344,2368,2399,2988 'name':971 'nativ':277 'need':99,146,705,773,1627,2401,2686,2875,2891,2906,2919,2930,2943 'negoti':108 'net':297 'network':29 'never':1621 'new':988,1104,1816,2578 'next':319,649 'no-cod':2913 'node':510,1122,1294,2380,2405,2408,2454,2459 'non':107,224,1303,1753 'non-determin':1752 'non-idempot':1302 'non-negoti':106 'non-techn':223 'nonretriableerror':1105 'nonretryableerrortyp':1037 'note':227,246,263,282,300 'noth':1434 'notic':2364 'notifi':2371 'nudg':960 'number':883 'observ':141 'onboard':894 'onboard-us':893 'onboardus':890 'one':1494,1520,1540 'onfailur':1140,1149,2256,2266,2780,2794 'oper':329 'optim':84 'option':144 'orchestr':65,167,195,652,674,677,701,756,764,2883,2887,2964 'orchestrator-work':64,651,673 'orchestratorworkflow':698 'order':315,328,357,366,373,464,465,471,496,989,1394,1426,1807,1834,2265,2293 'order.cancelled':991 'order.created':492,986 'order/completed':878 'order/created':359,2312 'orderid':431,880,1395,1410,1419,1435,1809,1823,1836,1847,1860,2308 'orderworkflow':1806,1833 'outag':1914 'output':317,338,549,3064 'outputkey':2182 'outsid':1724 'overwhelm':1904 'parallel':63,522,541,570,617 'paramet':2176 'pass':2040 'pattern':61,308,311,490,524,654,676,841,998,1173,2440,2889,2912 'payload':2042,2052,2072,2167 'payment':35,381,386,391,426,473,487,500,1048,1060,1396,2634 'payment/initiated':1069 'per':1496 'perform':573,585,606,645 'performance-analysi':584 'performance-analyz':644 'performanceanalysi':635,637 'period':1186 'perman':2228 'permiss':3085 'persist':2067 'pick':94 'pipelin':199,203,325 'plan':710,778,783 'plan.subtasks':814 'plan.subtasks.map':723 'platform':56,79,214,1658,2087,2917 'playwright/puppeteer':2927 'pool':1616 'post':982 'potenti':2822,2839 'power':2953 'prevent':2028,2643,2696,2725 'principl':102 'process':327,356,380,390,499,987,1059,1189,1526,1553,1587,1591,2145,2149,2264 'process-al':1525 'process-batch':1590 'process-data':2148 'process-ord':355,2263 'process-pay':389,1058 'processchunk':2583 'processdata':2158 'processitem':1535,1557 'processlargefil':2553 'processord':352 'processorderworkflow':463 'processpay':1055 'product':73,2343,2391,2398,2784,2800 'production-grad':72 'progress':1468,2490,2587,2589 'promis':466,2556 'promise.all':576,722 'prototyp':222 'provid':2413,2885,2888 'proxyact':437,451,1022,1669,1962,2598,2690 'putobject':2175 'queue':180,2188,2297,2304,3035 'queue-review':2303 'quick':221 'random':1443,1738,1769,1886,2728,2735,2742 'rate':1907 're':2244 'reactiv':851 'read':1783,1880 'recommend':1375,1511,1659,1795,1953,2095,2253,2395,2536 'record':1328,1839,1844 'recov':1952 'recoveri':997,1016,2216,2359,2448 'recur':1179 'redis/postgres':2443 'refer':2121,2143,2850 'relat':2956 'reliabl':24,138,2801 'replay':307,1343,1736,1741,1748,1764,1780,1813,1820,1869,2060,2069,2740,2764 'replay-saf':1868 'report':598,603,609,1185,1201,1226,1267,1271,1296,1299,2586 'request':494,498,502,1290,1938 'requir':667,1673,3083 'resourc':625,640,1579,1713,2170 'restart':1349,2495 'result':530,596,686,720,749,752,809,816,826,836,1081,1114 'results.push':825 'resum':46,1357 'retri':455,512,995,1000,1014,1018,1026,1041,1047,1051,1061,1063,1078,1100,1110,1333,1374,1683,1889,1898,1911,1929,1935,1963,1991,2199,2223,2452,2647,2672,2851,2857,2863 'retryabl':131 'return':375,393,409,423,428,608,729,736,743,750,785,822,829,834,926,951,962,1089,1113,1220,1228,1250,1413,1416,1556,1698,2022,2113,2139,2157,2825,2838,2849 'review':2300,2305,3076 'role':789,797 'rule':1717 'run':527,567,1258,1362,1446,1456,1489,1733,1751,1761,2466,2476,2501 's3':2164,2174 's3/db':2847 's3key':2135,2140 'safe':1870,1876 'safeti':3086 'schedul':185,847,1171,1190,1255,1279,1281,3028 'scheduled-task':184 'scheduletoclosetimeout':1674 'scope':187,3057 'script':70 'second':454,1025,1029,1672,1679,1688,1966,2482,2542,2604 'secur':572,579,605,630 'security-analysi':578 'security-analyz':629 'securityanalysi':620,622 'see':148 'self':229 'self-host':228 'send':415,420,505,909,923,959,965,1129,1297,1403,2649,2655,2674 'send-confirm':419,1402 'send-nudg':958 'send-welcom':922 'sendemail':424,450,485,1417 'sendnudgeemail':963 'sendwelcomeemail':927 'sent':1324,2663,2666 'sentry.captureexception':2280 'separ':2447 'sequenti':62,309,330 'serial':2075 'serverless':258 'servic':1368,1607,1906,1925,1941,1949,2432 'set':1662,2424,2461 'sever':1309,1451,1602,1727,1894,2037,2192,2339,2471,2625,2652,2681,2706,2733,2757,2782,2806,2828,2855 'sharp':1300 'shipment':400,402,407,427,479,488,504 'side':1336,1722,1798,1826,1872 'sideeffect':1854,1856,1862,2752 'signal':1701,2333 'silent':2203,2349 'simpl':133,1883 'simultan':528 'situat':1311,1453,1604,1729,1896,2039,2194,2341,2473 'skill':53,2957,3049 'skill-workflow-automation' 'skip':1414 'slack':1132,2324 'slack.postmessage':1161,2289 'slack/email':2433 'sleep':1567 'slow':2047,2059,2835 'small':1544 'someon':2363 'sourc':540 'source-sickn33' 'special':660,716 'specif':2819,3071 'stabl':1440 'stack':278,296 'start':132 'startat':619,634 'starttoclosetimeout':452,1023,1670,2599,2694 'state':113,614,621,636,1318,1481,1499,2036,2065,2118,2173,2834 'state-crit':112 'steeper':250 'step':34,124,176,272,312,332,334,336,342,362,363,378,397,413,526,543,546,550,566,611,769,807,904,1072,1153,1170,1211,1245,1305,1314,1351,1358,1460,1495,1518,1522,1545,1705,1902,2045,2080,2092,2161,2270,2315,2700,2719,2802,2808,2814,2827,2843,2955,3003 'step-funct':175 'step.invoke':1589 'step.run':370,388,404,418,577,583,589,600,780,818,831,921,946,957,1083,1155,1215,1223,1247,1401,1524,1552,1691,2103,2125,2147,2276,2287,2302 'step.sleep':913,936,1569 'step/activity':1725 'stop':3077 'storag':2057 'store':2031,2074,2115,2120,2444,2845 'storm':1912 'string':875,877,881,2555 'stripe':1384 'stripe.charges.create':1091 'stripe.paymentintents.create':1387 'stripe/payment':2627 'strongest':247 'struggl':1927 'stuck':1630,2508,2523,2617 'substitut':3067 'subtask':671,681,724,733,740,747,796,803,812,824 'subtask.id':820 'subtask.type':726 'subworkflow':990,994 'success':429,3089 'support':304 'surviv':383 'switch':725,984 'symptom':1319,1461,1611,1737,1903,2046,2200,2346,2483 'sync':1187,1237,1248 'sync-inventori':1236 'syncinventori':1233 'syncwithsuppli':1251 'synthes':832 'synthesi':828 'synthesizeresult':835 'system':790,852 'task':186,624,639,666,679,699,713,794,1180,1708,2169,3029,3053 'task/complex':766 'taskqueu':1266 'team':1158,2285,2435 'technic':225 'tell':2517 'tempor':58,87,237,433,693,1017,1252,1666,1851,1959,2328,2467,2506,2514,2677,2684,2993 'temporalio/activity':2549 'temporalio/workflow':439,1858 'test':3073 'text':1164,2292 'thing':2208 'thousanditem':1533,1550 'three':1325 'throw':1103,1108,2577 'thunder':2029 'ticket':1134,2327 'tight':283 'time':1067,1175,1326,1331,1509,1786,1791,1871,1950,2760,2767 'time-bas':1174 'timeout':1466,1600,1641,1655,1663,1695,1719,1721,2460,2463,2485,2529,2595,2680,2687,2692,2705,2713,2721,2723 'timeoutsecond':1709 'tool':213,2892,2898,2900,2967 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'total':882 'track':2274 'tradeoff':82 'transact':244 'treat':3062 'tri':1088 'trial':1573 'trigger':123,517,840,843,860,885,898,980,1121,1124,1177,1280,1282,2318,2320,2338,2379,2404,2423,2442,2873,3045 'true':430,633,648,1415 'try/catch':2816 'turn':68 'twice':1322 'type':441,616,623,638,869,870,1707,2168 'typescript':259,299,345,435,868 'ui':2390 'unawar':2245 'univers':119 'unlik':1646 'unnot':2394 'uploadtos3':2137 'url':1700 'usd':1391 'use':323,515,533,664,850,1008,1119,1183,1378,1566,1956,1993,2163,2329,2451,2630,2751,2771,2859,2937,2973,3047 'user':226,798,853,895,2874,2890,2905,2918,2929,2942,2974,2979,2984,2989,2994,2999,3005,3011,3017,3024,3030,3036,3041 'user/signed.up':872,897,972 'user@example.com':977 'userid':874,974 'usual':1888 'uuid':1810,1863 'valid':365,368,372,468,495,1042,2618,3072 'validate-ord':371 'validated.address':412,483 'validated.email':425,486 'validated.items':411,482 'validated.paymentmethod':395,476 'validated.total':396,477 'validateord':376,447,470 'validationerror':1038 'valu':1428,1444,2729,2736,2743 'via':2510 'visibl':2352,2361,2387 'visual':235 'wait':905,915,929,938,1565,1571,1581,1644,2241 'wait-for-engag':937 'wait-for-explor':914 'wait-for-tri':1570 'warn':2653,2707,2783,2807,2856 'webhook':491,855,979,981 'welcom':910,924 'well':2959 'without':25,1364,1449,1599,1640,1891,2229,2336,2376,2469,2512,2622,2636,2650,2669,2679,2691,2704,2720,2779,2793,2803,2815,2852,2865 'work':267,658,704,1539,2488,2492,2521,2958 'worker':66,653,661,675,684,717,1465,1502,1615,2494 'worker1':687 'worker2':688 'worker3':689 'workflow':2,4,13,15,45,115,122,150,152,163,166,174,236,242,262,289,310,331,523,542,718,842,1010,1172,1191,1254,1256,1308,1313,1332,1344,1356,1445,1457,1471,1479,1487,1515,1584,1609,1612,1619,1631,1643,1649,1720,1735,1742,1759,1772,1801,1878,1934,2035,2044,2048,2064,2101,2117,2195,2202,2225,2332,2335,2345,2347,2400,2412,2449,2462,2657,2668,2726,2731,2745,2755,2769,2833,2884,2895,2902,2923,2934,2947,2954,2978 'workflow-autom':1,162 'workflow-orchestr':165 'workflow.failed':2330 'workflow.now':1852,1866,2772 'workflowid':1268 'wors':1932 'write':1312,1730 'wrong':1519,1797,2097 'zapier':2910 'zapier-make-pattern':2909 'zapier/make':2907","prices":[{"id":"8c81ff2d-9f61-4746-b955-dc735a3bd0ce","listingId":"f3a0c9b2-dff4-4ac0-b120-cd903f83c20a","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:47:44.378Z"}],"sources":[{"listingId":"f3a0c9b2-dff4-4ac0-b120-cd903f83c20a","source":"github","sourceId":"sickn33/antigravity-awesome-skills/workflow-automation","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/workflow-automation","isPrimary":false,"firstSeenAt":"2026-04-18T21:47:44.378Z","lastSeenAt":"2026-04-22T00:52:00.069Z"}],"details":{"listingId":"f3a0c9b2-dff4-4ac0-b120-cd903f83c20a","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"workflow-automation","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34404,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-21T16:43:40Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"497727c3df1cfd880239998c7fc3f2218276bb06","skill_md_path":"skills/workflow-automation/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/workflow-automation"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"workflow-automation","description":"Workflow automation is the infrastructure that makes AI agents"},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/workflow-automation"},"updatedAt":"2026-04-22T00:52:00.069Z"}}