dust-temporal
Provides a framework for building durable, deterministic workflows with Temporal in Dust.
Install
mkdir -p .claude/skills/dust-temporal && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5939" && unzip -o skill.zip -d .claude/skills/dust-temporal && rm skill.zipInstalls to .claude/skills/dust-temporal
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Step-by-step guide for creating Temporal workflows in Dust. Use when adding background jobs, async processing, durable workflows, or task queues.Key capabilities
- →Create versioned Temporal queue configurations
- →Implement idempotent workflow ID generators
- →Define activities for side-effect operations
- →Orchestrate workflows with proxyActivities
- →Register workers in the application registry
How it works
It structures Temporal code into specific modules for configuration, activities, workflows, and clients, ensuring idempotency and proper worker registration.
Inputs & outputs
When to use dust-temporal
- →Create Temporal workflow
- →Set up background job
- →Define task activity
About this skill
Creating Temporal Workflows
This skill guides you through creating Temporal workflows for durable background processing.
Quick Reference
Files Structure (per queue)
temporal/your_queue/
├── config.ts # Queue name and version
├── helpers.ts # Workflow ID generators
├── activities.ts # Activity implementations (DB, API calls)
├── workflows.ts # Workflow orchestration
├── worker.ts # Worker setup
└── client.ts # Workflow launcher functions
Key Concepts
- Workflow: Durable, deterministic function that orchestrates activities
- Activity: Non-deterministic function with side effects (DB, API calls)
- Task Queue: Named queue where workflows/activities execute
- Workflow ID: Unique identifier for idempotency
Step-by-Step Implementation
Step 1: Create Queue Configuration
Create temporal/your_queue/config.ts:
const QUEUE_VERSION = 1;
export const QUEUE_NAME = `your-queue-v${QUEUE_VERSION}`;
Step 2: Create Workflow ID Helper
Create temporal/your_queue/helpers.ts:
export function makeYourWorkflowId({ entityId }: { entityId: string }): string {
return `your-workflow-${entityId}`;
}
Important: Workflow IDs must be deterministic (same inputs = same ID) for idempotency.
Step 3: Create Activities
Create temporal/your_queue/activities.ts:
import { YourResource } from "@app/lib/resources/your_resource";
import logger from "@app/logger/logger";
export async function yourActivity({
entityId,
workspaceId,
}: {
entityId: string;
workspaceId: number;
}): Promise<void> {
const entity = await YourResource.fetchById(entityId);
if (!entity) {
throw new Error(`Entity not found: ${entityId}`);
}
const result = await entity.doSomething();
if (result.isErr()) {
logger.error({ entityId, error: result.error }, "Failed to process entity");
throw new Error(`Failed to process: ${result.error.message}`);
}
}
Guidelines: Activities perform side effects, can throw (Temporal retries), should be idempotent.
Step 4: Create Workflow
Create temporal/your_queue/workflows.ts:
import { proxyActivities } from "@temporalio/workflow";
import type * as activities from "@app/temporal/your_queue/activities";
const { yourActivity } = proxyActivities<typeof activities>({
startToCloseTimeout: "5 minutes",
});
export async function yourWorkflow({
entityId,
workspaceId,
}: {
entityId: string;
workspaceId: number;
}): Promise<void> {
await yourActivity({ entityId, workspaceId });
}
Guidelines: Workflows are deterministic - no Math.random(), Date.now(), etc.
Step 5: Create Client Launcher
Create temporal/your_queue/client.ts:
import { WorkflowExecutionAlreadyStartedError } from "@temporalio/client";
import { getTemporalClientForFrontNamespace } from "@app/lib/temporal";
import logger from "@app/logger/logger";
import { QUEUE_NAME } from "@app/temporal/your_queue/config";
import { makeYourWorkflowId } from "@app/temporal/your_queue/helpers";
import { yourWorkflow } from "@app/temporal/your_queue/workflows";
import type { Result } from "@app/types";
import { Err, normalizeError, Ok } from "@app/types";
export async function launchYourWorkflow({
entityId,
workspaceId,
}: {
entityId: string;
workspaceId: number;
}): Promise<Result<undefined, Error>> {
const client = await getTemporalClientForFrontNamespace();
const workflowId = makeYourWorkflowId({ entityId });
try {
await client.workflow.start(yourWorkflow, {
args: [{ entityId, workspaceId }],
taskQueue: QUEUE_NAME,
workflowId,
memo: { entityId, workspaceId },
});
return new Ok(undefined);
} catch (e) {
if (!(e instanceof WorkflowExecutionAlreadyStartedError)) {
logger.error({ workflowId, entityId, workspaceId, error: e }, "Failed starting workflow");
}
return new Err(normalizeError(e));
}
}
Step 6: Create Worker
Create temporal/your_queue/worker.ts:
import type { Context } from "@temporalio/activity";
import { Worker } from "@temporalio/worker";
import { getTemporalWorkerConnection, TEMPORAL_MAXED_CACHED_WORKFLOWS } from "@app/lib/temporal";
import { ActivityInboundLogInterceptor } from "@app/lib/temporal_monitoring";
import logger from "@app/logger/logger";
import * as activities from "@app/temporal/your_queue/activities";
import { getWorkflowConfig } from "@app/temporal/bundle_helper";
import { QUEUE_NAME } from "./config";
export async function runYourQueueWorker() {
const { connection, namespace } = await getTemporalWorkerConnection();
const worker = await Worker.create({
...getWorkflowConfig({
workerName: "your_queue",
getWorkflowsPath: () => require.resolve("./workflows"),
}),
activities,
taskQueue: QUEUE_NAME,
maxCachedWorkflows: TEMPORAL_MAXED_CACHED_WORKFLOWS,
maxConcurrentActivityTaskExecutions: 16,
connection,
namespace,
interceptors: {
activityInbound: [(ctx: Context) => new ActivityInboundLogInterceptor(ctx, logger)],
},
});
await worker.run();
}
Step 7: Register Worker (Critical!)
Edit temporal/worker_registry.ts:
// 1. Add import
import { runYourQueueWorker } from "@app/temporal/your_queue/worker";
// 2. Add to WorkerName type
export type WorkerName =
| "agent_loop"
// ... existing workers
| "your_queue"; // <- Add this
// 3. Add to workerFunctions mapping
export const workerFunctions: Record<WorkerName, () => Promise<void>> = {
// ... existing workers
your_queue: runYourQueueWorker, // <- Add this
};
Without registration, workflows will never execute!
Timeout & Retry Configuration
const { yourActivity } = proxyActivities<typeof activities>({
startToCloseTimeout: "5 minutes",
retry: {
maximumAttempts: 3,
initialInterval: "1s",
backoffCoefficient: 2,
maximumInterval: "1m",
nonRetryableErrorTypes: ["ValidationError"],
},
});
Validation Checklist
- Queue config created with versioned name
- Workflow ID helper is deterministic
- Activities handle errors properly
- Workflow uses
proxyActivitieswith appropriate timeouts - Client returns
Result<>and handlesWorkflowExecutionAlreadyStartedError - Worker registered in
worker_registry.ts - Tested locally
Reference Examples
See temporal/ directory for existing implementations.
When not to use it
- →Using non-deterministic functions in workflows
- →Skipping worker registration
Limitations
- →Workflows must be strictly deterministic
- →Requires manual registration in worker_registry.ts
How it compares
It provides a rigid, project-specific directory structure and registration pattern for Temporal workflows rather than generic implementation.
Compared to similar skills
dust-temporal side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| dust-temporal (this skill) | 1 | 6mo | No flags | Advanced |
| telegram-bot-builder | 106 | 6mo | Review | Intermediate |
| workflow-orchestration-patterns | 10 | 2mo | No flags | Advanced |
| bullmq-specialist | 25 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by dust-tt
View all by dust-tt →You might also like
telegram-bot-builder
davila7
Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot.
workflow-orchestration-patterns
wshobson
Design durable workflows with Temporal for distributed systems. Covers workflow vs activity separation, saga patterns, state management, and determinism constraints. Use when building long-running processes, distributed transactions, or microservice orchestration.
bullmq-specialist
davila7
BullMQ expert for Redis-backed job queues, background processing, and reliable async execution in Node.js/TypeScript applications. Use when: bullmq, bull queue, redis queue, background job, job queue.
unity-mcp-orchestrator
CoplayDev
Orchestrate Unity Editor via MCP (Model Context Protocol) tools and resources. Use when working with Unity projects through MCP for Unity - creating/modifying GameObjects, editing scripts, managing scenes, running tests, or any Unity Editor automation. Provides best practices, tool schemas, and workflow patterns for effective Unity-MCP integration.
async-python-patterns
wshobson
Master Python asyncio, concurrent programming, and async/await patterns for high-performance applications. Use when building async APIs, concurrent systems, or I/O-bound applications requiring non-blocking operations.
modal
davila7
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.