@tailor-platform/sdk 2.0.0-next.10 → 2.0.0-next.11

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 (129) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/dist/{application-miwiXtB4.mjs → application-CM6hKnSK.mjs} +312 -89
  3. package/dist/application-CM6hKnSK.mjs.map +1 -0
  4. package/dist/application-CXNaUNhv.mjs +3 -0
  5. package/dist/cli/commands/deploy/aigateway.d.mts +1 -1
  6. package/dist/cli/commands/deploy/application.d.mts +1 -1
  7. package/dist/cli/commands/deploy/auth.d.mts +1 -1
  8. package/dist/cli/commands/deploy/deploy.d.mts +1 -0
  9. package/dist/cli/commands/deploy/executor.d.mts +1 -1
  10. package/dist/cli/commands/deploy/function-registry.d.mts +1 -2
  11. package/dist/cli/commands/deploy/idp.d.mts +1 -1
  12. package/dist/cli/commands/deploy/label.d.mts +2 -0
  13. package/dist/cli/commands/deploy/resolver.d.mts +1 -1
  14. package/dist/cli/commands/deploy/staticwebsite.d.mts +1 -1
  15. package/dist/cli/commands/deploy/tailordb/index.d.mts +2 -1
  16. package/dist/cli/commands/deploy/types.d.mts +2 -1
  17. package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +1 -2
  18. package/dist/cli/commands/deploy/workflow.d.mts +1 -1
  19. package/dist/cli/commands/executor/get.d.mts +1 -10
  20. package/dist/cli/commands/executor/jobs.d.mts +1 -38
  21. package/dist/cli/commands/executor/trigger.d.mts +1 -11
  22. package/dist/cli/commands/generate/seed/bundler.d.mts +2 -1
  23. package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +5 -0
  24. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
  25. package/dist/cli/commands/workflow/executions.d.mts +1 -13
  26. package/dist/cli/commands/workflow/get.d.mts +1 -10
  27. package/dist/cli/commands/workflow/start.d.mts +2 -14
  28. package/dist/cli/lib.d.mts +7 -11
  29. package/dist/cli/lib.mjs +99 -42
  30. package/dist/cli/lib.mjs.map +1 -1
  31. package/dist/cli/main.mjs +318 -124
  32. package/dist/cli/main.mjs.map +1 -1
  33. package/dist/cli/services/http-adapter/bundler.d.mts +1 -0
  34. package/dist/cli/services/workflow/bundler.d.mts +2 -1
  35. package/dist/cli/shared/client.d.mts +28 -3
  36. package/dist/cli/shared/config-loader.d.mts +11 -4
  37. package/dist/cli/shared/tsconfig-paths-plugin.d.mts +2 -0
  38. package/dist/cli/shared/type-generator.d.mts +4 -3
  39. package/dist/completion/zsh-worker.zsh +82 -22
  40. package/dist/configure/config/types.d.mts +26 -3
  41. package/dist/configure/index.d.mts +2 -2
  42. package/dist/configure/index.mjs +171 -3
  43. package/dist/configure/index.mjs.map +1 -1
  44. package/dist/configure/services/executor/index.d.mts +2 -2
  45. package/dist/configure/services/executor/trigger/event.d.mts +245 -2
  46. package/dist/configure/services/executor/trigger/index.d.mts +3 -3
  47. package/dist/configure/services/idp/index.d.mts +1 -1
  48. package/dist/configure/services/index.d.mts +2 -2
  49. package/dist/configure/services/tailordb/index.d.mts +0 -1
  50. package/dist/configure/services/workflow/execution-policy.d.mts +1 -1
  51. package/dist/configure/services/workflow/execution-policy.types.d.mts +1 -1
  52. package/dist/configure/services/workflow/job.d.mts +11 -2
  53. package/dist/configure/services/workflow/workflow.d.mts +10 -0
  54. package/dist/{globals-DQotNuwK.mjs → globals-TfAVItuK.mjs} +1 -2
  55. package/dist/globals-TfAVItuK.mjs.map +1 -0
  56. package/dist/node-builtins-CmaL2Cbq.mjs +36 -0
  57. package/dist/node-builtins-CmaL2Cbq.mjs.map +1 -0
  58. package/dist/plugin/builtin/enum-constants/index.mjs +115 -2
  59. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -0
  60. package/dist/plugin/builtin/file-utils/index.mjs +149 -2
  61. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -0
  62. package/dist/plugin/builtin/kysely-type/index.mjs +274 -2
  63. package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -0
  64. package/dist/plugin/builtin/seed/index.mjs +1 -1
  65. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +2 -0
  66. package/dist/{register-ts-hook-BAHMwxfG.mjs → register-ts-hook-LYV7zH-e.mjs} +2252 -797
  67. package/dist/register-ts-hook-LYV7zH-e.mjs.map +1 -0
  68. package/dist/registry-BIGVUrMB.mjs.map +1 -1
  69. package/dist/runtime/index.mjs +1 -1
  70. package/dist/runtime/workflow.d.mts +2 -20
  71. package/dist/runtime/workflow.mjs +1 -1
  72. package/dist/{seed-LUVr7jHL.mjs → seed-B-yckgQY.mjs} +42 -3
  73. package/dist/seed-B-yckgQY.mjs.map +1 -0
  74. package/dist/service-M7OYziQP.mjs +3 -0
  75. package/dist/{service-BNtPsK9Q.mjs → service-k1xy_A5G.mjs} +29 -2
  76. package/dist/{service-BNtPsK9Q.mjs.map → service-k1xy_A5G.mjs.map} +1 -1
  77. package/dist/{service_pb-BwZRiNug.mjs → service_pb-D5--My_M.mjs} +5 -5
  78. package/dist/service_pb-D5--My_M.mjs.map +1 -0
  79. package/dist/{service_pb-wRkxUta6.mjs → service_pb-i8CmnQP4.mjs} +1 -1
  80. package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +106 -1
  81. package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +24 -1
  82. package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +49 -1
  83. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +89 -6
  84. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +26 -1
  85. package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +101 -1
  86. package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +22 -1
  87. package/dist/types/executor.generated.d.mts +23 -3
  88. package/dist/types/idp.generated.d.mts +1 -1
  89. package/dist/utils/test/index.d.mts +1 -2
  90. package/dist/utils/test/index.mjs +1 -173
  91. package/dist/utils/test/index.mjs.map +1 -1
  92. package/dist/vitest/environment.mjs +1 -1
  93. package/dist/vitest/index.d.mts +2 -2
  94. package/dist/vitest/index.mjs +10 -52
  95. package/dist/vitest/index.mjs.map +1 -1
  96. package/dist/vitest/mocks/workflow.d.mts +0 -9
  97. package/dist/vitest/setup.mjs +1 -1
  98. package/dist/{workflow-CsaQ9qK-.mjs → workflow-Bamae_Yc.mjs} +1 -9
  99. package/dist/workflow-Bamae_Yc.mjs.map +1 -0
  100. package/dist/{workspace_resource_pb-UGK1SSn_.mjs → workspace_resource_pb-DXnO2AT-.mjs} +7 -7
  101. package/dist/workspace_resource_pb-DXnO2AT-.mjs.map +1 -0
  102. package/docs/cli/tailordb.md +39 -7
  103. package/docs/cli-reference.md +11 -10
  104. package/docs/configuration.md +50 -0
  105. package/docs/migration/v2.md +306 -9
  106. package/docs/runtime.md +1 -1
  107. package/docs/services/executor.md +83 -3
  108. package/docs/services/idp.md +8 -6
  109. package/docs/services/resolver.md +6 -4
  110. package/docs/services/tailordb-migration.md +17 -6
  111. package/docs/services/tailordb.md +6 -4
  112. package/docs/services/workflow.md +33 -3
  113. package/package.json +19 -17
  114. package/dist/application-DArFTTJ9.mjs +0 -3
  115. package/dist/application-miwiXtB4.mjs.map +0 -1
  116. package/dist/enum-constants-j9QBF0cB.mjs +0 -116
  117. package/dist/enum-constants-j9QBF0cB.mjs.map +0 -1
  118. package/dist/file-utils-yEiIS4nJ.mjs +0 -150
  119. package/dist/file-utils-yEiIS4nJ.mjs.map +0 -1
  120. package/dist/globals-DQotNuwK.mjs.map +0 -1
  121. package/dist/kysely-type-DqIRgDYR.mjs +0 -275
  122. package/dist/kysely-type-DqIRgDYR.mjs.map +0 -1
  123. package/dist/register-ts-hook-BAHMwxfG.mjs.map +0 -1
  124. package/dist/seed-LUVr7jHL.mjs.map +0 -1
  125. package/dist/service-D5jn05ZI.mjs +0 -3
  126. package/dist/service_pb-BwZRiNug.mjs.map +0 -1
  127. package/dist/utils/test/mock.d.mts +0 -86
  128. package/dist/workflow-CsaQ9qK-.mjs.map +0 -1
  129. package/dist/workspace_resource_pb-UGK1SSn_.mjs.map +0 -1
@@ -136,9 +136,9 @@ When the project defines multiple IdPs, pass `idp` to target a specific one. The
136
136
  idpUserCreatedTrigger({ idp: "my-idp" });
137
137
  ```
138
138
 
139
- Omitting `idp` is allowed only when the project has exactly one IdP; otherwise `apply` fails with an error listing the configured IdPs.
139
+ Omitting `idp` is allowed only when the project has exactly one IdP; otherwise `deploy` fails with an error listing the configured IdPs.
140
140
 
141
- These triggers require the IdP to publish user lifecycle events. The SDK enables `publishUserEvents` automatically during `apply` on each IdP that is targeted by an `idpUser` trigger; set the value explicitly on `defineIdp()` to override. See [IdP service - publishUserEvents](./idp.md#publishuserevents).
141
+ These triggers require the IdP to publish user lifecycle events. `deploy` enables `publishEvents` automatically on each IdP targeted by an `idpUser` trigger taking part in the same run, and turns it back off once no such trigger remains; set the value explicitly on `defineIdp()` to pin it. See [IdP service - publishEvents](./idp.md#publishevents).
142
142
 
143
143
  ### Auth Access Token Triggers
144
144
 
@@ -152,6 +152,37 @@ Fire on auth access token lifecycle events:
152
152
  authAccessTokenIssuedTrigger();
153
153
  ```
154
154
 
155
+ ### Workflow Execution Triggers
156
+
157
+ Fire when a workflow execution changes state. Use the single-event helpers or `workflowExecutionTrigger()` for multiple events:
158
+
159
+ ```typescript
160
+ import { createExecutor, workflowExecutionTrigger } from "@tailor-platform/sdk";
161
+ import orderWorkflow from "../workflows/order";
162
+
163
+ export default createExecutor({
164
+ name: "order-workflow-finished",
165
+ trigger: workflowExecutionTrigger({
166
+ workflow: orderWorkflow,
167
+ events: ["completed", "retried"],
168
+ }),
169
+ operation: {
170
+ kind: "function",
171
+ body: async (args) => {
172
+ if (args.event === "completed" && !args.success) {
173
+ console.error(args.error);
174
+ }
175
+ },
176
+ },
177
+ });
178
+ ```
179
+
180
+ The available workflow events are `started`, `completed`, `retried`, `resumed`, `wait_started`, and `wait_resolved`. To observe job-level events, use `workflowJobExecutionStartedTrigger()`, `workflowJobExecutionCompletedTrigger()`, `workflowJobExecutionWaitStartedTrigger()`, `workflowJobExecutionWaitResolvedTrigger()`, or `workflowJobExecutionTrigger()`.
181
+
182
+ `completed` events include `success`; when it is `false`, `error` contains the failure message. A job released from a wait point emits `wait_resolved` instead of `completed`.
183
+
184
+ These triggers require the workflow to publish execution events. `deploy` enables `publishEvents` automatically on each targeted workflow, and on every job of a workflow targeted by a `workflowJobExecution*` trigger, and turns it back off once no such trigger remains; set the value explicitly to pin it. See [Workflow service - Execution Events](./workflow.md#execution-events).
185
+
155
186
  ### Multi-Event Triggers
156
187
 
157
188
  Handle multiple event types in a single executor using multi-event trigger factories. These accept an `events` array of short event names:
@@ -200,7 +231,14 @@ idpUserTrigger({ events: ["created", "deleted"], idp: "my-idp" });
200
231
  authAccessTokenTrigger({ events: ["issued", "revoked"] });
201
232
  ```
202
233
 
203
- The `event` field on args matches the short event name (e.g., `"created"`, `"updated"`, `"deleted"`, `"issued"`, `"refreshed"`, `"revoked"`), enabling type narrowing. The `rawEvent` field contains the full event type string (e.g., `"tailordb.type_record.created"`).
234
+ #### `workflowExecutionTrigger()` and `workflowJobExecutionTrigger()`
235
+
236
+ ```typescript
237
+ workflowExecutionTrigger({ workflow: orderWorkflow, events: ["started", "completed"] });
238
+ workflowJobExecutionTrigger({ workflow: orderWorkflow, events: ["started", "wait_resolved"] });
239
+ ```
240
+
241
+ The `event` field on args matches the short event name, enabling type narrowing. Record triggers use names such as `"created"`, auth token triggers use `"issued"`, and workflow triggers use `"started"`, `"completed"`, and `"wait_resolved"`. The `rawEvent` field contains the full event type string (e.g., `"tailordb.type_record.created"`).
204
242
 
205
243
  ## Operation Types
206
244
 
@@ -554,3 +592,45 @@ interface AuthAccessTokenContext {
554
592
  userId: string; // The user associated with the token
555
593
  }
556
594
  ```
595
+
596
+ ### Workflow Execution Event Payload
597
+
598
+ Workflow execution triggers receive execution context:
599
+
600
+ ```typescript
601
+ interface WorkflowExecutionContext {
602
+ workspaceId: string; // Workspace identifier
603
+ env: TailorEnv; // Environment variables from tailor.config.ts
604
+ actor: TailorActor | null; // Principal that triggered the workflow
605
+ workflowId: string; // Workflow resource ID
606
+ workflowName: string; // Workflow name
607
+ workflowExecutionId: string; // Workflow execution ID
608
+ event: "started" | "completed" | "retried" | "resumed" | "wait_started" | "wait_resolved";
609
+ rawEvent: string; // Full event type
610
+ }
611
+ ```
612
+
613
+ Completed events narrow on `success`. Failed executions include `error`; retried executions include `retryCount` and `retryAfter`.
614
+
615
+ ```typescript
616
+ body: async (args) => {
617
+ if (args.event === "completed" && !args.success) {
618
+ console.error(args.error);
619
+ }
620
+ };
621
+ ```
622
+
623
+ ### Workflow Job Execution Event Payload
624
+
625
+ Workflow job execution triggers include every `WorkflowExecutionContext` field above, plus job-specific fields:
626
+
627
+ ```typescript
628
+ interface WorkflowJobExecutionContext {
629
+ workflowJobExecutionId: string; // Job execution ID
630
+ jobFunctionName: string; // Name passed to createWorkflowJob
631
+ event: "started" | "completed" | "wait_started" | "wait_resolved";
632
+ rawEvent: string; // Full event type
633
+ }
634
+ ```
635
+
636
+ `wait_started` events include `waitKey`, plus JSON-serialized `waitPayload` when the wait point recorded one; `wait_resolved` events include `waitKey`.
@@ -195,7 +195,7 @@ defineIdp("my-idp", {
195
195
 
196
196
  - `enableMfa` - Make TOTP MFA available for users in this namespace. Default `false`. When enabled, users can register an authenticator app (Google Authenticator, 1Password, etc.) from the IdP self-service page.
197
197
  - `requireMfa` - Force password-authenticated users to enroll and pass an MFA challenge on each sign-in. Default `false`. Social sign-in (`allowGoogleOauth` / `allowMicrosoftOauth`) is not affected; the upstream provider's MFA covers those sessions.
198
- - `allowedReturnOrigins` - Origins the IdP self-service pages (such as `/mfa/settings`) are allowed to redirect back to. Each entry is either a literal origin (`https://app.example.com`, scheme + host + optional port, no path/query/fragment) or a static-website placeholder `<name>:url` (e.g. `website.url`) that the CLI resolves to the deployed website's URL at apply time. Required when `enableMfa` is `true`.
198
+ - `allowedReturnOrigins` - Origins the IdP self-service pages (such as `/mfa/settings`) are allowed to redirect back to. Each entry is either a literal origin (`https://app.example.com`, scheme + host + optional port, no path/query/fragment) or a static-website placeholder `<name>:url` (e.g. `website.url`) that the CLI resolves to the deployed website's URL at deployment time. Required when `enableMfa` is `true`.
199
199
  - `mfaIssuer` - Label shown next to the user account in authenticator apps when TOTP is enrolled. Up to 64 characters. Falls back to `"Tailor Platform IdP"` when empty.
200
200
 
201
201
  **Constraints:** the following combinations are rejected at parse time.
@@ -319,21 +319,23 @@ defineIdp("my-idp", {
319
319
 
320
320
  **Values:** `"en"` or `"ja"`.
321
321
 
322
- ### publishUserEvents
322
+ ### publishEvents
323
323
 
324
324
  Publish IdP user lifecycle events (`idp.user.created`, `idp.user.updated`, `idp.user.deleted`). These events are consumed by executors that use `idpUserCreatedTrigger`, `idpUserUpdatedTrigger`, `idpUserDeletedTrigger`, or `idpUserTrigger`.
325
325
 
326
326
  ```typescript
327
327
  defineIdp("my-idp", {
328
328
  clients: ["my-client"],
329
- publishUserEvents: true,
329
+ publishEvents: true,
330
330
  });
331
331
  ```
332
332
 
333
- **Auto-configuration:** When `publishUserEvents` is omitted, the SDK enables it automatically during `apply` for each IdP that is targeted by an executor's `idpUser` trigger. Targeting is per-IdP: an executor specifies which IdP it subscribes to via the trigger's `idp` option (required in multi-IdP projects). Set the value explicitly to override:
333
+ **Auto-configuration:** When `publishEvents` is omitted, `deploy` sets it from the executors taking part in the same run: `true` while one of their `idpUser` triggers targets this IdP, and `false` once none does. Removing the last such trigger turns publishing back off on the next `deploy`. Targeting is per-IdP: an executor specifies which IdP it subscribes to via the trigger's `idp` option (required in multi-IdP projects). Set the value explicitly to override:
334
334
 
335
- - `publishUserEvents: true`: always publish events.
336
- - `publishUserEvents: false`: never publish events. `apply` rejects this with an error if any executor's `idpUser` trigger targets this IdP — either remove `publishUserEvents: false` or remove the matching trigger.
335
+ - `publishEvents: true`: always publish events.
336
+ - `publishEvents: false`: never publish events. `deploy` rejects this with an error if an `idpUser` trigger taking part in the same run targets this IdP — either remove `publishEvents: false` or remove the matching trigger.
337
+
338
+ **Sharing an IdP across configs:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). `deploy` records that dependency, so deploying the owning config alone later asks for confirmation instead of silently turning publishing off — it fails outright in a non-interactive environment. Set `publishEvents: true` on the IdP to keep it on regardless of which configs take part.
337
339
 
338
340
  ## Using idp.provider()
339
341
 
@@ -305,12 +305,12 @@ createResolver({
305
305
  **Behavior:**
306
306
 
307
307
  - When `publishEvents: true`, resolver execution events are published
308
- - When not specified, it is **automatically set to `true`** if an executor uses this resolver with `resolverExecutedTrigger`
309
- - When explicitly set to `false` while an executor uses this resolver, an error is thrown during `tailor deploy`
308
+ - When not specified, `deploy` sets it from the executors taking part in the same run: `true` while one of them uses this resolver with `resolverExecutedTrigger`, and `false` once none does. Removing the last such trigger turns publishing back off on the next `deploy`
309
+ - When explicitly set to `false` while an executor taking part in the same run uses this resolver, `deploy` fails
310
310
 
311
311
  **Use cases:**
312
312
 
313
- 1. **Auto-detection (recommended)**: Don't set `publishEvents` - the SDK automatically enables it when needed by executors
313
+ 1. **Auto-detection (recommended)**: Don't set `publishEvents` - `deploy` enables it while an executor taking part in the same run needs it
314
314
 
315
315
  ```typescript
316
316
  // publishEvents is automatically enabled because an executor uses this resolver
@@ -339,7 +339,7 @@ createResolver({
339
339
  });
340
340
  ```
341
341
 
342
- 3. **Explicit disable**: Disable event publishing for a resolver that doesn't need it (error if executor uses it)
342
+ 3. **Explicit disable**: Disable event publishing for a resolver that doesn't need it (error if an executor taking part in the same run uses it)
343
343
 
344
344
  ```typescript
345
345
  createResolver({
@@ -350,6 +350,8 @@ createResolver({
350
350
  });
351
351
  ```
352
352
 
353
+ **Sharing a resolver across configs:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). `deploy` records that dependency, so deploying the owning config alone later asks for confirmation instead of silently turning publishing off — it fails outright in a non-interactive environment. Set `publishEvents: true` on the resolver to keep it on regardless of which configs take part.
354
+
353
355
  ## Permissions
354
356
 
355
357
  ### Access Requirement (`permission`)
@@ -133,13 +133,13 @@ This writes `migrations/0002/migrate.ts` and `migrations/0002/db.ts` next to the
133
133
 
134
134
  ### Breaking changes without a script
135
135
 
136
- Breaking changes require `migrate.ts`. If it is missing at deploy time (for example, the generated script was deleted), `tailor-sdk deploy` fails before applying the migration or anything after it. When there is genuinely nothing to migrate — say, the affected type holds no data yet — record an explicit acknowledgment instead of keeping an empty script:
136
+ Breaking changes require `migrate.ts`. If it is missing at deploy time (for example, the generated script was deleted), `tailor deploy` fails before applying the migration or anything after it. When there is genuinely nothing to migrate — say, the affected type holds no data yet — record an explicit acknowledgment instead of keeping an empty script:
137
137
 
138
138
  ```bash
139
- tailor-sdk tailordb migration script 0002 --no-script --reason "no data yet, safe to skip"
139
+ tailor tailordb migration script 0002 --no-script --reason "no data yet, safe to skip"
140
140
  ```
141
141
 
142
- This stores the reason in `migrations/0002/diff.json` (commit the change). The next `tailor-sdk deploy` applies the schema change as usual, skips only the script step, and logs the recorded reason. The command refuses to record a skip while `migrate.ts` exists — delete the script first. If `migrate.ts` is added back later, the script takes precedence over the acknowledgment and runs.
142
+ This stores the reason in `migrations/0002/diff.json` (commit the change). The next `tailor deploy` applies the schema change as usual, skips only the script step, and logs the recorded reason. The command refuses to record a skip while `migrate.ts` exists — delete the script first. If `migrate.ts` is added back later, the script takes precedence over the acknowledgment and runs.
143
143
 
144
144
  ## Configuration
145
145
 
@@ -290,7 +290,15 @@ Namespace: tailordb
290
290
 
291
291
  The error also points you at `migration status`, `migration generate`, `migration sync`, and `migration set` — see [Remote schema drift detected](#remote-schema-drift-detected) for which one applies.
292
292
 
293
- To bypass both checks (not recommended outside of recovery scenarios):
293
+ To run the same checks without deploying — plus migration file integrity (numbering, parseable contents, and a `migrate.ts` or a recorded `--no-script` acknowledgment for every migration that requires a script):
294
+
295
+ ```bash
296
+ tailor tailordb migration validate
297
+ ```
298
+
299
+ It reports issues per namespace, exits with a non-zero code when any check fails, and supports `--json` for machine-readable output.
300
+
301
+ To bypass both checks during deploy (not recommended outside of recovery scenarios):
294
302
 
295
303
  ```bash
296
304
  tailor deploy --no-schema-check
@@ -314,6 +322,8 @@ tailor deploy --no-schema-check
314
322
 
315
323
  `tailor tailordb migration set <N>` updates the `sdk-migration` label on the deployed namespace's metadata. **It does not modify any data or schema.** It only changes which migrations the next `apply` will consider pending.
316
324
 
325
+ The migration number is validated before anything is sent to the remote: it must be a 4-digit value (e.g. `0001`) or a bare integer (e.g. `1`) within 0–9999, and must exist in the working tree's migration history, which is itself validated (a gapped history is rejected). `0` is always accepted as the baseline (even when no migrations directory exists yet), provided the history passes validation.
326
+
317
327
  | Movement | Effect on next `apply` | Effect on data |
318
328
  | -------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------- |
319
329
  | Forward (e.g., `0001` → `0003`) | Migrations `0002` and `0003` are skipped — they will not run. | None. |
@@ -355,7 +365,8 @@ Migration numbers are assigned sequentially, so two developers branching off the
355
365
  ### CI / CD
356
366
 
357
367
  - For non-interactive environments, pass `--yes` to `migration generate` and `--yes` to `apply`. `apply` runs migrations automatically when the `migrations/` directory is configured.
358
- - Run `tailor tailordb migration status` in CI to detect "developer forgot to commit a migration" situations early. The exit code is non-zero only on errors, so check the output.
368
+ - Run `tailor tailordb migration validate` in CI to catch uncommitted migrations, broken migration files, and remote schema drift before deploying. It exits with a non-zero code when validation fails and supports `--json`.
369
+ - `tailor tailordb migration status` shows applied and pending migrations for a human-readable comparison. Its exit code is non-zero only on errors, so check the output.
359
370
  - Avoid running migrations in parallel against the same workspace — there is no locking. Serialize deploys per environment.
360
371
 
361
372
  ### Resetting a deployed project
@@ -492,4 +503,4 @@ For genuinely different schemas across environments, prefer separate workspaces
492
503
 
493
504
  **Cause:** `diff.requiresMigrationScript` is true but `migrate.ts` is missing from the migration directory.
494
505
 
495
- **Resolution:** Restore the file from version control, or create it with `tailor-sdk tailordb migration script <N> --namespace <namespace>`. If the migration intentionally needs no data transformation, record that decision with `tailor-sdk tailordb migration script <N> --namespace <namespace> --no-script --reason "<why no data migration is needed>"` instead.
506
+ **Resolution:** Restore the file from version control, or create it with `tailor tailordb migration script <N> --namespace <namespace>`. If the migration intentionally needs no data transformation, record that decision with `tailor tailordb migration script <N> --namespace <namespace> --no-script --reason "<why no data migration is needed>"` instead.
@@ -515,12 +515,12 @@ db.table("User", {
515
515
  **Behavior:**
516
516
 
517
517
  - When `publishEvents: true`, record creation/update/deletion events are published
518
- - When not specified, it is **automatically set to `true`** if an executor uses this type with `recordCreatedTrigger`, `recordUpdatedTrigger`, or `recordDeletedTrigger`
519
- - When explicitly set to `false` while an executor uses this type, an error is thrown during `tailor deploy`
518
+ - When not specified, `deploy` sets it from the executors taking part in the same run: `true` while one of them uses this type with `recordCreatedTrigger`, `recordUpdatedTrigger`, or `recordDeletedTrigger`, and `false` once none does. Removing the last such trigger turns publishing back off on the next `deploy`
519
+ - When explicitly set to `false` while an executor taking part in the same run uses this type, `deploy` fails
520
520
 
521
521
  **Use cases:**
522
522
 
523
- 1. **Auto-detection (recommended)**: Don't set `publishEvents` - the SDK automatically enables it when needed by executors
523
+ 1. **Auto-detection (recommended)**: Don't set `publishEvents` - `deploy` enables it while an executor taking part in the same run needs it
524
524
 
525
525
  ```typescript
526
526
  // publishEvents is automatically enabled because an executor uses this type
@@ -545,7 +545,7 @@ db.table("User", {
545
545
  });
546
546
  ```
547
547
 
548
- 3. **Explicit disable**: Disable event publishing for a type that doesn't need it (error if executor uses it)
548
+ 3. **Explicit disable**: Disable event publishing for a type that doesn't need it (error if an executor taking part in the same run uses it)
549
549
 
550
550
  ```typescript
551
551
  db.table("TempData", {
@@ -555,6 +555,8 @@ db.table("User", {
555
555
  });
556
556
  ```
557
557
 
558
+ **Sharing a type across configs:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). `deploy` records that dependency, so deploying the owning config alone later asks for confirmation instead of silently turning publishing off — it fails outright in a non-interactive environment. Set `publishEvents: true` on the type to keep it on regardless of which configs take part.
559
+
558
560
  #### GraphQL Operations
559
561
 
560
562
  Control which GraphQL operations (`create`, `update`, `delete`, `read`) are exposed for a type. All operations are enabled by default.
@@ -201,6 +201,36 @@ export default createWorkflow({
201
201
  });
202
202
  ```
203
203
 
204
+ ## Execution Events
205
+
206
+ Workflows can publish execution lifecycle events for executors. When an executor subscribes to a workflow's events, `deploy` enables publishing automatically. A `workflowExecution*` trigger enables it on the workflow, and a `workflowJobExecution*` trigger enables it on every job that workflow runs. See [Workflow Execution Triggers](./executor.md#workflow-execution-triggers).
207
+
208
+ Publishing follows the subscription in both directions: removing the last subscribing trigger turns it back off on the next `deploy`.
209
+
210
+ Set `publishEvents` explicitly to pin the value instead. Use `true` to publish workflow-level events with no subscribing executor:
211
+
212
+ ```typescript
213
+ export default createWorkflow({
214
+ name: "order-processing",
215
+ mainJob: processOrder,
216
+ publishEvents: true,
217
+ });
218
+ ```
219
+
220
+ A job takes the same field for its own execution events:
221
+
222
+ ```typescript
223
+ export const processOrder = createWorkflowJob({
224
+ name: "process-order",
225
+ publishEvents: true,
226
+ body: async () => ({ processed: true }),
227
+ });
228
+ ```
229
+
230
+ Use `false` to keep publishing off. `deploy` fails if an executor subscribes to events the value opts out of, so the subscription cannot silently go unfulfilled.
231
+
232
+ **Subscribing from another config:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). The workflow a `workflowExecution*` or `workflowJobExecution*` trigger names must be declared by a config in the run; `deploy` fails otherwise rather than creating an executor whose events never arrive. `deploy` records the dependency on the workflow itself, so deploying that config alone later asks for confirmation instead of silently turning publishing off. Declaring `publishEvents` clears the record: a declared value no longer depends on which configs are deployed together, so there is nothing left to warn about.
233
+
204
234
  ## Wait Points
205
235
 
206
236
  Wait points allow a workflow job to suspend execution and wait for an external signal before resuming. This enables human-in-the-loop patterns such as approvals, reviews, and manual confirmations.
@@ -357,7 +387,7 @@ Execution policies apply a per-key concurrency cap to workflow job function disp
357
387
 
358
388
  ### Declaring Policies
359
389
 
360
- Use `defineWorkflowExecutionPolicies` with a builder callback. Property names supply the workspace-unique name and default key prefix verbatim, matching the mental model of `defineWaitPoints`. Override `name` or `key` in the body when the property identifier is not valid execution policy grammar or the key prefix needs to differ. Set `matchType: "prefix"` to register the prefix as a wildcard that matches every dispatch key starting with it (the default, `"exact"`, matches only a dispatch key equal to it).
390
+ Use `defineWorkflowExecutionPolicies` with a builder callback. Property names supply the workspace-unique name and default key prefix verbatim, matching the mental model of `createWaitPoints`. Override `name` or `key` in the body when the property identifier is not valid execution policy grammar or the key prefix needs to differ. Set `matchType: "prefix"` to register the prefix as a wildcard that matches every dispatch key starting with it (the default, `"exact"`, matches only a dispatch key equal to it).
361
391
 
362
392
  ```typescript
363
393
  import { defineWorkflowExecutionPolicies } from "@tailor-platform/sdk";
@@ -401,7 +431,7 @@ An exact-key policy applies to dispatches whose runtime key equals the policy ke
401
431
 
402
432
  ### Referencing a Policy from a Workflow
403
433
 
404
- Pass the runtime key through the `executionPolicyKey` option on `job.start()` or `tailor.workflow.execJobFunction()` (or its alias `startJobFunction`). For exact-key policies, use `<policy>.key` directly — it's typed so only a value that came from a declared policy can be passed. For wildcard policies (`matchType: "prefix"`), there is no `<policy>.key` — call `<policy>.keyFor(suffix)` to build the concrete key. `keyFor` joins the prefix and suffix with `.` by default; override it with `separator` — the second argument to `defineWorkflowExecutionPolicies` (applies to every policy in the group), or a `def` field on a single `defineWorkflowExecutionPolicy`.
434
+ Pass the runtime key through the `executionPolicyKey` option on `job.start()` or `tailor.workflow.execJobFunction()`. For exact-key policies, use `<policy>.key` directly — it's typed so only a value that came from a declared policy can be passed. For wildcard policies (`matchType: "prefix"`), there is no `<policy>.key` — call `<policy>.keyFor(suffix)` to build the concrete key. `keyFor` joins the prefix and suffix with `.` by default; override it with `separator` — the second argument to `defineWorkflowExecutionPolicies` (applies to every policy in the group), or a `def` field on a single `defineWorkflowExecutionPolicy`.
405
435
 
406
436
  ```typescript
407
437
  import { createWorkflowJob } from "@tailor-platform/sdk";
@@ -427,7 +457,7 @@ export const mainJob = createWorkflowJob({
427
457
  });
428
458
  ```
429
459
 
430
- The same `executionPolicyKey` option is available on `tailor.workflow.execJobFunction(name, args, options)` (or its alias `tailor.workflow.startJobFunction`) for jobs invoked by name.
460
+ The same `executionPolicyKey` option is available on `tailor.workflow.execJobFunction(name, args, options)` for jobs invoked by name.
431
461
 
432
462
  ## Starting a Workflow from a Resolver
433
463
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "2.0.0-next.10",
3
+ "version": "2.0.0-next.11",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -148,9 +148,9 @@
148
148
  }
149
149
  },
150
150
  "dependencies": {
151
- "@0no-co/graphql.web": "1.3.2",
151
+ "@0no-co/graphql.web": "1.3.3",
152
152
  "@badgateway/oauth2-client": "3.3.1",
153
- "@bufbuild/protobuf": "2.12.1",
153
+ "@bufbuild/protobuf": "2.13.0",
154
154
  "@bufbuild/protovalidate": "1.2.0",
155
155
  "@connectrpc/connect": "2.1.2",
156
156
  "@connectrpc/connect-node": "2.1.2",
@@ -159,11 +159,13 @@
159
159
  "@jridgewell/trace-mapping": "0.3.31",
160
160
  "@napi-rs/keyring": "1.3.0",
161
161
  "@opentelemetry/api": "1.9.1",
162
- "@opentelemetry/exporter-trace-otlp-proto": "0.220.0",
163
- "@opentelemetry/resources": "2.9.0",
164
- "@opentelemetry/sdk-trace-node": "2.9.0",
162
+ "@opentelemetry/exporter-trace-otlp-proto": "0.221.0",
163
+ "@opentelemetry/resources": "2.10.0",
164
+ "@opentelemetry/sdk-trace-node": "2.10.0",
165
165
  "@opentelemetry/semantic-conventions": "1.43.0",
166
- "@oxc-project/types": "0.140.0",
166
+ "@oxc-project/types": "0.142.0",
167
+ "@secretlint/core": "13.0.4",
168
+ "@secretlint/secretlint-rule-preset-recommend": "13.0.4",
167
169
  "@standard-schema/spec": "1.1.0",
168
170
  "@tailor-platform/function-kysely-tailordb": "0.1.3",
169
171
  "@toiroakr/lines-db": "0.10.1",
@@ -173,44 +175,44 @@
173
175
  "chalk": "5.6.2",
174
176
  "confbox": "0.2.4",
175
177
  "date-fns": "4.4.0",
176
- "es-toolkit": "1.49.0",
178
+ "es-toolkit": "1.50.0",
177
179
  "find-up-simple": "1.0.1",
178
180
  "get-east-asian-width": "1.6.0",
179
- "globals": "17.7.0",
181
+ "get-tsconfig": "4.14.0",
182
+ "globals": "17.8.0",
180
183
  "graphql": "17.0.2",
181
184
  "inflection": "3.0.2",
182
185
  "kysely": "0.29.4",
183
186
  "mime-types": "3.0.2",
184
187
  "open": "11.0.0",
185
- "oxc-parser": "0.140.0",
188
+ "oxc-parser": "0.142.0",
186
189
  "p-limit": "7.3.1",
187
190
  "pathe": "2.0.3",
188
191
  "pgsql-ast-parser": "12.0.2",
189
192
  "pkg-types": "2.3.1",
190
- "politty": "0.11.5",
193
+ "politty": "0.11.6",
191
194
  "rolldown": "1.2.0",
192
195
  "semver": "7.8.5",
193
196
  "sql-highlight": "6.1.0",
194
197
  "std-env": "4.2.0",
195
198
  "ts-cron-validator": "1.1.5",
196
199
  "type-fest": "5.8.0",
197
- "undici": "8.8.0",
198
200
  "xdg-basedir": "5.1.0",
199
201
  "zod": "4.4.3"
200
202
  },
201
203
  "devDependencies": {
202
- "@opentelemetry/sdk-trace-base": "2.9.0",
204
+ "@opentelemetry/sdk-trace-base": "2.10.0",
203
205
  "@types/mime-types": "3.0.1",
204
206
  "@types/node": "24.13.3",
205
207
  "@types/semver": "7.7.1",
206
208
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
207
209
  "@vitest/coverage-v8": "4.1.10",
208
210
  "eslint-plugin-zod": "4.7.0",
209
- "oxfmt": "0.59.0",
210
- "oxlint": "1.74.0",
211
- "oxlint-tsgolint": "0.25.0",
211
+ "oxfmt": "0.61.0",
212
+ "oxlint": "1.76.0",
213
+ "oxlint-tsgolint": "7.0.2001",
212
214
  "sonda": "0.14.0",
213
- "tsdown": "0.22.12",
215
+ "tsdown": "0.22.14",
214
216
  "typescript": "6.0.3",
215
217
  "vitest": "4.1.10",
216
218
  "zinfer": "0.2.7",
@@ -1,3 +0,0 @@
1
- import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-miwiXtB4.mjs";
2
-
3
- export { defineApplication, generatePluginFilesIfNeeded };