@keystrokehq/skills 0.0.1

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.
Files changed (44) hide show
  1. package/AGENTS-blurb.md +123 -0
  2. package/LICENSE +21 -0
  3. package/README.md +63 -0
  4. package/keystroke-agent-authoring/SKILL.md +225 -0
  5. package/keystroke-agent-authoring/evals/evals.json +29 -0
  6. package/keystroke-agent-authoring/references/messaging-gateways.md +242 -0
  7. package/keystroke-agent-authoring/references/patterns.md +417 -0
  8. package/keystroke-agent-authoring/references/prebuilt-integrations.md +879 -0
  9. package/keystroke-agent-authoring/references/sandbox-and-mcp.md +214 -0
  10. package/keystroke-agent-authoring/references/source-map.md +182 -0
  11. package/keystroke-agent-authoring/references/testing.md +85 -0
  12. package/keystroke-cli-workspace/SKILL.md +93 -0
  13. package/keystroke-cli-workspace/evals/evals.json +23 -0
  14. package/keystroke-cli-workspace/references/command-map.md +50 -0
  15. package/keystroke-cli-workspace/references/credentials-and-connect.md +79 -0
  16. package/keystroke-cli-workspace/references/project-lifecycle.md +85 -0
  17. package/keystroke-credential-binding/SKILL.md +509 -0
  18. package/keystroke-credential-binding/evals/evals.json +29 -0
  19. package/keystroke-credential-binding/references/cli.md +85 -0
  20. package/keystroke-credential-binding/references/patterns.md +878 -0
  21. package/keystroke-credential-binding/references/source-map.md +69 -0
  22. package/keystroke-data-toolkit/SKILL.md +59 -0
  23. package/keystroke-data-toolkit/evals/evals.json +23 -0
  24. package/keystroke-data-toolkit/references/usage.md +79 -0
  25. package/keystroke-task-authoring/SKILL.md +124 -0
  26. package/keystroke-task-authoring/evals/evals.json +23 -0
  27. package/keystroke-task-authoring/references/patterns.md +132 -0
  28. package/keystroke-task-authoring/references/source-map.md +61 -0
  29. package/keystroke-trigger-authoring/SKILL.md +189 -0
  30. package/keystroke-trigger-authoring/evals/evals.json +29 -0
  31. package/keystroke-trigger-authoring/references/patterns.md +265 -0
  32. package/keystroke-trigger-authoring/references/source-map.md +128 -0
  33. package/keystroke-trigger-authoring/references/testing.md +148 -0
  34. package/keystroke-workflow-as-tool-debugging/SKILL.md +52 -0
  35. package/keystroke-workflow-as-tool-debugging/evals/evals.json +23 -0
  36. package/keystroke-workflow-as-tool-debugging/references/playbook.md +77 -0
  37. package/keystroke-workflow-authoring/SKILL.md +234 -0
  38. package/keystroke-workflow-authoring/evals/evals.json +29 -0
  39. package/keystroke-workflow-authoring/references/patterns.md +265 -0
  40. package/keystroke-workflow-authoring/references/prebuilt-integrations.md +811 -0
  41. package/keystroke-workflow-authoring/references/runtime-helpers.md +264 -0
  42. package/keystroke-workflow-authoring/references/source-map.md +108 -0
  43. package/keystroke-workflow-authoring/references/testing.md +108 -0
  44. package/package.json +26 -0
@@ -0,0 +1,265 @@
1
+ # Workflow And Step / Operation Examples
2
+
3
+ Use these examples when the user needs a concrete pattern instead of only rules.
4
+
5
+ `Operation`, `Step`, and `Tool` are aliases for the same class. In this workflow reference, examples default to `Step` because that name reads best from workflow context.
6
+
7
+ File layout reminder:
8
+
9
+ - keep every exported primitive in its own typed file
10
+ - `*.workflow.ts` exports one workflow
11
+ - `*.step.ts`, `*.tool.ts`, or `*.operation.ts` exports one operation
12
+ - if a snippet shows multiple primitives together, treat it as a multi-file excerpt and import the reused symbols from their own files
13
+
14
+ ## Minimal workflow
15
+
16
+ ```ts
17
+ import { Workflow } from '@keystrokehq/core';
18
+ import { z } from 'zod';
19
+
20
+ export const helloWorkflow = new Workflow({
21
+ id: 'hello-workflow',
22
+ name: 'Hello Workflow',
23
+ description: 'Returns a greeting.',
24
+ input: z.object({
25
+ name: z.string(),
26
+ }),
27
+ output: z.object({
28
+ message: z.string(),
29
+ }),
30
+ run: async (input) => {
31
+ return {
32
+ message: `Hello, ${input.name}!`,
33
+ };
34
+ },
35
+ });
36
+ ```
37
+
38
+ In normal Keystroke usage, deploy the workflow and enter it through triggers, endpoints, or the UI. Direct `workflow.run(...)` calls are mainly for tests and local authoring.
39
+
40
+ Author workflows as top-level exports like this. Do not hide workflow definitions inside factory functions.
41
+
42
+ ## Workflow with triggers
43
+
44
+ ```ts
45
+ import { cronTrigger, webhookTrigger, Workflow } from '@keystrokehq/core';
46
+ import { z } from 'zod';
47
+
48
+ const PayloadSchema = z.object({ accountId: z.string() });
49
+
50
+ const accountCron = cronTrigger({
51
+ name: 'Nightly Account Sync',
52
+ schedule: '0 0 * * *',
53
+ input: PayloadSchema,
54
+ payload: { accountId: 'default' },
55
+ });
56
+
57
+ const accountWebhook = webhookTrigger({
58
+ name: 'Account Webhook',
59
+ source: {
60
+ type: 'custom',
61
+ method: 'POST',
62
+ path: '/accounts',
63
+ },
64
+ payload: z.object({ id: z.string(), action: z.string() }),
65
+ filter: (p) => p.action === 'sync',
66
+ });
67
+
68
+ export const accountSyncWorkflow = new Workflow({
69
+ id: 'account-sync',
70
+ name: 'Account Sync',
71
+ input: PayloadSchema,
72
+ output: z.object({ ok: z.boolean() }),
73
+ triggers: [
74
+ accountCron,
75
+ accountWebhook({
76
+ transform: (payload) => ({ accountId: payload.id }),
77
+ }),
78
+ ],
79
+ run: async () => ({ ok: true }),
80
+ });
81
+ ```
82
+
83
+ Bare triggers (like `accountCron` above) pass their payload directly as workflow input. Call the trigger with `{ transform }` when the payload shape differs from the workflow input.
84
+
85
+ ## Workflow metadata fields
86
+
87
+ ```ts
88
+ import { Workflow } from '@keystrokehq/core';
89
+ import { z } from 'zod';
90
+
91
+ export const versionedWorkflow = new Workflow({
92
+ id: 'billing-digest',
93
+ name: 'Billing Digest',
94
+ description: 'Builds a digest for the billing team.',
95
+ author: 'Keystroke Team',
96
+ version: '1.0.0',
97
+ tags: ['billing', 'digest'],
98
+ timeout: '15m',
99
+ retries: {
100
+ exponential: { attempts: 2, base: 2, multiplier: 2 },
101
+ },
102
+ input: z.object({
103
+ tenantId: z.string(),
104
+ }),
105
+ output: z.object({
106
+ ok: z.boolean(),
107
+ }),
108
+ run: async () => ({ ok: true }),
109
+ });
110
+ ```
111
+
112
+ ## Step with retries and timeout
113
+
114
+ ```ts
115
+ import { Step } from '@keystrokehq/core';
116
+ import { z } from 'zod';
117
+
118
+ export const fetchInvoice = new Step({
119
+ name: 'Fetch Invoice',
120
+ description: 'Loads the current invoice.',
121
+ input: z.object({
122
+ invoiceId: z.string(),
123
+ }),
124
+ output: z.object({
125
+ invoiceId: z.string(),
126
+ amount: z.number(),
127
+ }),
128
+ timeout: '2m',
129
+ retries: {
130
+ constant: { attempts: 3, seconds: 30 },
131
+ },
132
+ tags: ['billing'],
133
+ run: async (input) => {
134
+ return {
135
+ invoiceId: input.invoiceId,
136
+ amount: 100,
137
+ };
138
+ },
139
+ });
140
+ ```
141
+
142
+ This is the normal place for side effects such as API calls, database writes, or non-deterministic work.
143
+
144
+ The same example could also be written with `new Operation({...})` if the unit is shared outside workflow code.
145
+
146
+ ## Step with workflow globals
147
+
148
+ ```ts
149
+ import { Step, Workflow } from '@keystrokehq/core';
150
+ import { z } from 'zod';
151
+
152
+ const sendDigest = new Step({
153
+ name: 'Send Digest',
154
+ description: 'Uses workflow globals to decide where to send the digest.',
155
+ workflowGlobals: z.object({
156
+ defaultChannel: z.string(),
157
+ }),
158
+ input: z.object({
159
+ message: z.string(),
160
+ }),
161
+ output: z.object({
162
+ channel: z.string(),
163
+ }),
164
+ run: async (_input, ctx) => {
165
+ return {
166
+ channel: ctx.workflowGlobals.defaultChannel,
167
+ };
168
+ },
169
+ });
170
+
171
+ export const digestWorkflow = new Workflow({
172
+ id: 'digest',
173
+ name: 'Digest',
174
+ input: z.object({}),
175
+ output: z.object({
176
+ channel: z.string(),
177
+ }),
178
+ workflowGlobals: z.object({
179
+ defaultChannel: z.string(),
180
+ }),
181
+ run: async () => sendDigest.run({ message: 'hello' }),
182
+ });
183
+ ```
184
+
185
+ ## Step with credentials
186
+
187
+ ```ts
188
+ import { CredentialSet, Step } from '@keystrokehq/core';
189
+ import { z } from 'zod';
190
+
191
+ const crmCredentials = new CredentialSet({
192
+ id: 'crmApi',
193
+ name: 'CRM API',
194
+ auth: z.object({
195
+ apiKey: z.string(),
196
+ }),
197
+ });
198
+
199
+ export const loadCustomer = new Step({
200
+ name: 'Load Customer',
201
+ description: 'Uses a credential set from step context.',
202
+ credentialSets: [crmCredentials],
203
+ input: z.object({
204
+ customerId: z.string(),
205
+ }),
206
+ output: z.object({
207
+ customerId: z.string(),
208
+ usedKey: z.string(),
209
+ }),
210
+ run: async (input, ctx) => {
211
+ return {
212
+ customerId: input.customerId,
213
+ usedKey: ctx.credentials.crmApi.apiKey,
214
+ };
215
+ },
216
+ });
217
+ ```
218
+
219
+ ## Parallel orchestration
220
+
221
+ ```ts
222
+ const [a, b] = await Promise.all([
223
+ fetchInvoice.run({ invoiceId: 'inv_1' }),
224
+ fetchInvoice.run({ invoiceId: 'inv_2' }),
225
+ ]);
226
+ ```
227
+
228
+ Use `Promise.all`, `Promise.race`, loops, and branches in the workflow. Keep network calls, database calls, and other side effects inside operations used as steps.
229
+
230
+ ## Child workflow composition
231
+
232
+ ```ts
233
+ const prepareInvoice = new Workflow({
234
+ id: 'prepare-invoice',
235
+ name: 'Prepare Invoice',
236
+ input: z.object({ invoiceId: z.string() }),
237
+ output: z.object({ invoiceId: z.string() }),
238
+ run: async (input) => ({ invoiceId: input.invoiceId }),
239
+ });
240
+
241
+ const invoicePipeline = new Workflow({
242
+ id: 'invoice-pipeline',
243
+ name: 'Invoice Pipeline',
244
+ input: z.object({ invoiceId: z.string() }),
245
+ output: z.object({ invoiceId: z.string() }),
246
+ run: async (input) => {
247
+ return prepareInvoice.run(input);
248
+ },
249
+ });
250
+ ```
251
+
252
+ ## `withTimeout(...)` and `retry(...)`
253
+
254
+ ```ts
255
+ const fastHelloWorkflow = helloWorkflow.withTimeout('30s');
256
+ const retriedHelloWorkflow = helloWorkflow.retry({
257
+ constant: { attempts: 2, seconds: 5 },
258
+ });
259
+ ```
260
+
261
+ ## Replay-safe reminder
262
+
263
+ - keep orchestration in `Workflow.run`
264
+ - keep external effects in `Step.run` or `Operation.run`
265
+ - keep random values and changing state out of the workflow body