testdriverai 6.0.28 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,190 @@
1
+ ---
2
+ description: Only the most important rules for writing basic Trigger.dev tasks
3
+ globs: **/trigger/**/*.ts
4
+ alwaysApply: false
5
+ ---
6
+ # Trigger.dev Basic Tasks (v4)
7
+
8
+ **MUST use `@trigger.dev/sdk` (v4), NEVER `client.defineJob`**
9
+
10
+ ## Basic Task
11
+
12
+ ```ts
13
+ import { task } from "@trigger.dev/sdk";
14
+
15
+ export const processData = task({
16
+ id: "process-data",
17
+ retry: {
18
+ maxAttempts: 10,
19
+ factor: 1.8,
20
+ minTimeoutInMs: 500,
21
+ maxTimeoutInMs: 30_000,
22
+ randomize: false,
23
+ },
24
+ run: async (payload: { userId: string; data: any[] }) => {
25
+ // Task logic - runs for long time, no timeouts
26
+ console.log(`Processing ${payload.data.length} items for user ${payload.userId}`);
27
+ return { processed: payload.data.length };
28
+ },
29
+ });
30
+ ```
31
+
32
+ ## Schema Task (with validation)
33
+
34
+ ```ts
35
+ import { schemaTask } from "@trigger.dev/sdk";
36
+ import { z } from "zod";
37
+
38
+ export const validatedTask = schemaTask({
39
+ id: "validated-task",
40
+ schema: z.object({
41
+ name: z.string(),
42
+ age: z.number(),
43
+ email: z.string().email(),
44
+ }),
45
+ run: async (payload) => {
46
+ // Payload is automatically validated and typed
47
+ return { message: `Hello ${payload.name}, age ${payload.age}` };
48
+ },
49
+ });
50
+ ```
51
+
52
+ ## Scheduled Task
53
+
54
+ ```ts
55
+ import { schedules } from "@trigger.dev/sdk";
56
+
57
+ const dailyReport = schedules.task({
58
+ id: "daily-report",
59
+ cron: "0 9 * * *", // Daily at 9:00 AM UTC
60
+ // or with timezone: cron: { pattern: "0 9 * * *", timezone: "America/New_York" },
61
+ run: async (payload) => {
62
+ console.log("Scheduled run at:", payload.timestamp);
63
+ console.log("Last run was:", payload.lastTimestamp);
64
+ console.log("Next 5 runs:", payload.upcoming);
65
+
66
+ // Generate daily report logic
67
+ return { reportGenerated: true, date: payload.timestamp };
68
+ },
69
+ });
70
+ ```
71
+
72
+ ## Triggering Tasks
73
+
74
+ ### From Backend Code
75
+
76
+ ```ts
77
+ import { tasks } from "@trigger.dev/sdk";
78
+ import type { processData } from "./trigger/tasks";
79
+
80
+ // Single trigger
81
+ const handle = await tasks.trigger<typeof processData>("process-data", {
82
+ userId: "123",
83
+ data: [{ id: 1 }, { id: 2 }],
84
+ });
85
+
86
+ // Batch trigger
87
+ const batchHandle = await tasks.batchTrigger<typeof processData>("process-data", [
88
+ { payload: { userId: "123", data: [{ id: 1 }] } },
89
+ { payload: { userId: "456", data: [{ id: 2 }] } },
90
+ ]);
91
+ ```
92
+
93
+ ### From Inside Tasks (with Result handling)
94
+
95
+ ```ts
96
+ export const parentTask = task({
97
+ id: "parent-task",
98
+ run: async (payload) => {
99
+ // Trigger and continue
100
+ const handle = await childTask.trigger({ data: "value" });
101
+
102
+ // Trigger and wait - returns Result object, NOT task output
103
+ const result = await childTask.triggerAndWait({ data: "value" });
104
+ if (result.ok) {
105
+ console.log("Task output:", result.output); // Actual task return value
106
+ } else {
107
+ console.error("Task failed:", result.error);
108
+ }
109
+
110
+ // Quick unwrap (throws on error)
111
+ const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
112
+
113
+ // Batch trigger and wait
114
+ const results = await childTask.batchTriggerAndWait([
115
+ { payload: { data: "item1" } },
116
+ { payload: { data: "item2" } },
117
+ ]);
118
+
119
+ for (const run of results) {
120
+ if (run.ok) {
121
+ console.log("Success:", run.output);
122
+ } else {
123
+ console.log("Failed:", run.error);
124
+ }
125
+ }
126
+ },
127
+ });
128
+
129
+ export const childTask = task({
130
+ id: "child-task",
131
+ run: async (payload: { data: string }) => {
132
+ return { processed: payload.data };
133
+ },
134
+ });
135
+ ```
136
+
137
+ > Never wrap triggerAndWait or batchTriggerAndWait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
138
+
139
+ ## Waits
140
+
141
+ ```ts
142
+ import { task, wait } from "@trigger.dev/sdk";
143
+
144
+ export const taskWithWaits = task({
145
+ id: "task-with-waits",
146
+ run: async (payload) => {
147
+ console.log("Starting task");
148
+
149
+ // Wait for specific duration
150
+ await wait.for({ seconds: 30 });
151
+ await wait.for({ minutes: 5 });
152
+ await wait.for({ hours: 1 });
153
+ await wait.for({ days: 1 });
154
+
155
+ // Wait until specific date
156
+ await wait.until({ date: new Date("2024-12-25") });
157
+
158
+ // Wait for token (from external system)
159
+ await wait.forToken({
160
+ token: "user-approval-token",
161
+ timeoutInSeconds: 3600, // 1 hour timeout
162
+ });
163
+
164
+ console.log("All waits completed");
165
+ return { status: "completed" };
166
+ },
167
+ });
168
+ ```
169
+
170
+ > Never wrap wait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
171
+
172
+ ## Key Points
173
+
174
+ - **Result vs Output**: `triggerAndWait()` returns a `Result` object with `ok`, `output`, `error` properties - NOT the direct task output
175
+ - **Type safety**: Use `import type` for task references when triggering from backend
176
+ - **Waits > 5 seconds**: Automatically checkpointed, don't count toward compute usage
177
+
178
+ ## NEVER Use (v2 deprecated)
179
+
180
+ ```ts
181
+ // BREAKS APPLICATION
182
+ client.defineJob({
183
+ id: "job-id",
184
+ run: async (payload, io) => {
185
+ /* ... */
186
+ },
187
+ });
188
+ ```
189
+
190
+ Use v4 SDK (`@trigger.dev/sdk`), check `result.ok` before accessing `result.output`
@@ -0,0 +1,188 @@
1
+ ---
2
+ applyTo: **/trigger/**/*.ts
3
+ ---
4
+ # Trigger.dev Basic Tasks (v4)
5
+
6
+ **MUST use `@trigger.dev/sdk` (v4), NEVER `client.defineJob`**
7
+
8
+ ## Basic Task
9
+
10
+ ```ts
11
+ import { task } from "@trigger.dev/sdk";
12
+
13
+ export const processData = task({
14
+ id: "process-data",
15
+ retry: {
16
+ maxAttempts: 10,
17
+ factor: 1.8,
18
+ minTimeoutInMs: 500,
19
+ maxTimeoutInMs: 30_000,
20
+ randomize: false,
21
+ },
22
+ run: async (payload: { userId: string; data: any[] }) => {
23
+ // Task logic - runs for long time, no timeouts
24
+ console.log(`Processing ${payload.data.length} items for user ${payload.userId}`);
25
+ return { processed: payload.data.length };
26
+ },
27
+ });
28
+ ```
29
+
30
+ ## Schema Task (with validation)
31
+
32
+ ```ts
33
+ import { schemaTask } from "@trigger.dev/sdk";
34
+ import { z } from "zod";
35
+
36
+ export const validatedTask = schemaTask({
37
+ id: "validated-task",
38
+ schema: z.object({
39
+ name: z.string(),
40
+ age: z.number(),
41
+ email: z.string().email(),
42
+ }),
43
+ run: async (payload) => {
44
+ // Payload is automatically validated and typed
45
+ return { message: `Hello ${payload.name}, age ${payload.age}` };
46
+ },
47
+ });
48
+ ```
49
+
50
+ ## Scheduled Task
51
+
52
+ ```ts
53
+ import { schedules } from "@trigger.dev/sdk";
54
+
55
+ const dailyReport = schedules.task({
56
+ id: "daily-report",
57
+ cron: "0 9 * * *", // Daily at 9:00 AM UTC
58
+ // or with timezone: cron: { pattern: "0 9 * * *", timezone: "America/New_York" },
59
+ run: async (payload) => {
60
+ console.log("Scheduled run at:", payload.timestamp);
61
+ console.log("Last run was:", payload.lastTimestamp);
62
+ console.log("Next 5 runs:", payload.upcoming);
63
+
64
+ // Generate daily report logic
65
+ return { reportGenerated: true, date: payload.timestamp };
66
+ },
67
+ });
68
+ ```
69
+
70
+ ## Triggering Tasks
71
+
72
+ ### From Backend Code
73
+
74
+ ```ts
75
+ import { tasks } from "@trigger.dev/sdk";
76
+ import type { processData } from "./trigger/tasks";
77
+
78
+ // Single trigger
79
+ const handle = await tasks.trigger<typeof processData>("process-data", {
80
+ userId: "123",
81
+ data: [{ id: 1 }, { id: 2 }],
82
+ });
83
+
84
+ // Batch trigger
85
+ const batchHandle = await tasks.batchTrigger<typeof processData>("process-data", [
86
+ { payload: { userId: "123", data: [{ id: 1 }] } },
87
+ { payload: { userId: "456", data: [{ id: 2 }] } },
88
+ ]);
89
+ ```
90
+
91
+ ### From Inside Tasks (with Result handling)
92
+
93
+ ```ts
94
+ export const parentTask = task({
95
+ id: "parent-task",
96
+ run: async (payload) => {
97
+ // Trigger and continue
98
+ const handle = await childTask.trigger({ data: "value" });
99
+
100
+ // Trigger and wait - returns Result object, NOT task output
101
+ const result = await childTask.triggerAndWait({ data: "value" });
102
+ if (result.ok) {
103
+ console.log("Task output:", result.output); // Actual task return value
104
+ } else {
105
+ console.error("Task failed:", result.error);
106
+ }
107
+
108
+ // Quick unwrap (throws on error)
109
+ const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
110
+
111
+ // Batch trigger and wait
112
+ const results = await childTask.batchTriggerAndWait([
113
+ { payload: { data: "item1" } },
114
+ { payload: { data: "item2" } },
115
+ ]);
116
+
117
+ for (const run of results) {
118
+ if (run.ok) {
119
+ console.log("Success:", run.output);
120
+ } else {
121
+ console.log("Failed:", run.error);
122
+ }
123
+ }
124
+ },
125
+ });
126
+
127
+ export const childTask = task({
128
+ id: "child-task",
129
+ run: async (payload: { data: string }) => {
130
+ return { processed: payload.data };
131
+ },
132
+ });
133
+ ```
134
+
135
+ > Never wrap triggerAndWait or batchTriggerAndWait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
136
+
137
+ ## Waits
138
+
139
+ ```ts
140
+ import { task, wait } from "@trigger.dev/sdk";
141
+
142
+ export const taskWithWaits = task({
143
+ id: "task-with-waits",
144
+ run: async (payload) => {
145
+ console.log("Starting task");
146
+
147
+ // Wait for specific duration
148
+ await wait.for({ seconds: 30 });
149
+ await wait.for({ minutes: 5 });
150
+ await wait.for({ hours: 1 });
151
+ await wait.for({ days: 1 });
152
+
153
+ // Wait until specific date
154
+ await wait.until({ date: new Date("2024-12-25") });
155
+
156
+ // Wait for token (from external system)
157
+ await wait.forToken({
158
+ token: "user-approval-token",
159
+ timeoutInSeconds: 3600, // 1 hour timeout
160
+ });
161
+
162
+ console.log("All waits completed");
163
+ return { status: "completed" };
164
+ },
165
+ });
166
+ ```
167
+
168
+ > Never wrap wait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
169
+
170
+ ## Key Points
171
+
172
+ - **Result vs Output**: `triggerAndWait()` returns a `Result` object with `ok`, `output`, `error` properties - NOT the direct task output
173
+ - **Type safety**: Use `import type` for task references when triggering from backend
174
+ - **Waits > 5 seconds**: Automatically checkpointed, don't count toward compute usage
175
+
176
+ ## NEVER Use (v2 deprecated)
177
+
178
+ ```ts
179
+ // BREAKS APPLICATION
180
+ client.defineJob({
181
+ id: "job-id",
182
+ run: async (payload, io) => {
183
+ /* ... */
184
+ },
185
+ });
186
+ ```
187
+
188
+ Use v4 SDK (`@trigger.dev/sdk`), check `result.ok` before accessing `result.output`
package/CLAUDE.md ADDED
@@ -0,0 +1,188 @@
1
+ <!-- TRIGGER.DEV basic START -->
2
+ # Trigger.dev Basic Tasks (v4)
3
+
4
+ **MUST use `@trigger.dev/sdk` (v4), NEVER `client.defineJob`**
5
+
6
+ ## Basic Task
7
+
8
+ ```ts
9
+ import { task } from "@trigger.dev/sdk";
10
+
11
+ export const processData = task({
12
+ id: "process-data",
13
+ retry: {
14
+ maxAttempts: 10,
15
+ factor: 1.8,
16
+ minTimeoutInMs: 500,
17
+ maxTimeoutInMs: 30_000,
18
+ randomize: false,
19
+ },
20
+ run: async (payload: { userId: string; data: any[] }) => {
21
+ // Task logic - runs for long time, no timeouts
22
+ console.log(`Processing ${payload.data.length} items for user ${payload.userId}`);
23
+ return { processed: payload.data.length };
24
+ },
25
+ });
26
+ ```
27
+
28
+ ## Schema Task (with validation)
29
+
30
+ ```ts
31
+ import { schemaTask } from "@trigger.dev/sdk";
32
+ import { z } from "zod";
33
+
34
+ export const validatedTask = schemaTask({
35
+ id: "validated-task",
36
+ schema: z.object({
37
+ name: z.string(),
38
+ age: z.number(),
39
+ email: z.string().email(),
40
+ }),
41
+ run: async (payload) => {
42
+ // Payload is automatically validated and typed
43
+ return { message: `Hello ${payload.name}, age ${payload.age}` };
44
+ },
45
+ });
46
+ ```
47
+
48
+ ## Scheduled Task
49
+
50
+ ```ts
51
+ import { schedules } from "@trigger.dev/sdk";
52
+
53
+ const dailyReport = schedules.task({
54
+ id: "daily-report",
55
+ cron: "0 9 * * *", // Daily at 9:00 AM UTC
56
+ // or with timezone: cron: { pattern: "0 9 * * *", timezone: "America/New_York" },
57
+ run: async (payload) => {
58
+ console.log("Scheduled run at:", payload.timestamp);
59
+ console.log("Last run was:", payload.lastTimestamp);
60
+ console.log("Next 5 runs:", payload.upcoming);
61
+
62
+ // Generate daily report logic
63
+ return { reportGenerated: true, date: payload.timestamp };
64
+ },
65
+ });
66
+ ```
67
+
68
+ ## Triggering Tasks
69
+
70
+ ### From Backend Code
71
+
72
+ ```ts
73
+ import { tasks } from "@trigger.dev/sdk";
74
+ import type { processData } from "./trigger/tasks";
75
+
76
+ // Single trigger
77
+ const handle = await tasks.trigger<typeof processData>("process-data", {
78
+ userId: "123",
79
+ data: [{ id: 1 }, { id: 2 }],
80
+ });
81
+
82
+ // Batch trigger
83
+ const batchHandle = await tasks.batchTrigger<typeof processData>("process-data", [
84
+ { payload: { userId: "123", data: [{ id: 1 }] } },
85
+ { payload: { userId: "456", data: [{ id: 2 }] } },
86
+ ]);
87
+ ```
88
+
89
+ ### From Inside Tasks (with Result handling)
90
+
91
+ ```ts
92
+ export const parentTask = task({
93
+ id: "parent-task",
94
+ run: async (payload) => {
95
+ // Trigger and continue
96
+ const handle = await childTask.trigger({ data: "value" });
97
+
98
+ // Trigger and wait - returns Result object, NOT task output
99
+ const result = await childTask.triggerAndWait({ data: "value" });
100
+ if (result.ok) {
101
+ console.log("Task output:", result.output); // Actual task return value
102
+ } else {
103
+ console.error("Task failed:", result.error);
104
+ }
105
+
106
+ // Quick unwrap (throws on error)
107
+ const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
108
+
109
+ // Batch trigger and wait
110
+ const results = await childTask.batchTriggerAndWait([
111
+ { payload: { data: "item1" } },
112
+ { payload: { data: "item2" } },
113
+ ]);
114
+
115
+ for (const run of results) {
116
+ if (run.ok) {
117
+ console.log("Success:", run.output);
118
+ } else {
119
+ console.log("Failed:", run.error);
120
+ }
121
+ }
122
+ },
123
+ });
124
+
125
+ export const childTask = task({
126
+ id: "child-task",
127
+ run: async (payload: { data: string }) => {
128
+ return { processed: payload.data };
129
+ },
130
+ });
131
+ ```
132
+
133
+ > Never wrap triggerAndWait or batchTriggerAndWait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
134
+
135
+ ## Waits
136
+
137
+ ```ts
138
+ import { task, wait } from "@trigger.dev/sdk";
139
+
140
+ export const taskWithWaits = task({
141
+ id: "task-with-waits",
142
+ run: async (payload) => {
143
+ console.log("Starting task");
144
+
145
+ // Wait for specific duration
146
+ await wait.for({ seconds: 30 });
147
+ await wait.for({ minutes: 5 });
148
+ await wait.for({ hours: 1 });
149
+ await wait.for({ days: 1 });
150
+
151
+ // Wait until specific date
152
+ await wait.until({ date: new Date("2024-12-25") });
153
+
154
+ // Wait for token (from external system)
155
+ await wait.forToken({
156
+ token: "user-approval-token",
157
+ timeoutInSeconds: 3600, // 1 hour timeout
158
+ });
159
+
160
+ console.log("All waits completed");
161
+ return { status: "completed" };
162
+ },
163
+ });
164
+ ```
165
+
166
+ > Never wrap wait calls in a Promise.all or Promise.allSettled as this is not supported in Trigger.dev tasks.
167
+
168
+ ## Key Points
169
+
170
+ - **Result vs Output**: `triggerAndWait()` returns a `Result` object with `ok`, `output`, `error` properties - NOT the direct task output
171
+ - **Type safety**: Use `import type` for task references when triggering from backend
172
+ - **Waits > 5 seconds**: Automatically checkpointed, don't count toward compute usage
173
+
174
+ ## NEVER Use (v2 deprecated)
175
+
176
+ ```ts
177
+ // BREAKS APPLICATION
178
+ client.defineJob({
179
+ id: "job-id",
180
+ run: async (payload, io) => {
181
+ /* ... */
182
+ },
183
+ });
184
+ ```
185
+
186
+ Use v4 SDK (`@trigger.dev/sdk`), check `result.ok` before accessing `result.output`
187
+
188
+ <!-- TRIGGER.DEV basic END -->