@tailor-platform/sdk 2.0.0-next.1 → 2.0.0-next.2

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 (119) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/application-Dtqap5jM.mjs +3 -0
  3. package/dist/{client-z_oHGVNy.mjs → application-XuMWK4eq.mjs} +5861 -20
  4. package/dist/application-XuMWK4eq.mjs.map +1 -0
  5. package/dist/cli/index.mjs +179 -122
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/lib.d.mts +75 -16
  8. package/dist/cli/lib.mjs +5 -6
  9. package/dist/cli/lib.mjs.map +1 -1
  10. package/dist/completion/zsh-worker.zsh +105 -26
  11. package/dist/configure/index.d.mts +9 -8
  12. package/dist/configure/index.mjs +56 -19
  13. package/dist/configure/index.mjs.map +1 -1
  14. package/dist/context-Bd266-ru.mjs.map +1 -1
  15. package/dist/{context-BuuIb8CC.d.mts → context-C2lEi9uw.d.mts} +7 -28
  16. package/dist/{crashreport-pr6Rhvza.mjs → crashreport-BMWcxeSE.mjs} +1 -1
  17. package/dist/{crashreport-BsjAkFWw.mjs → crashreport-DFq-vsU0.mjs} +5 -7
  18. package/dist/{crashreport-BsjAkFWw.mjs.map → crashreport-DFq-vsU0.mjs.map} +1 -1
  19. package/dist/{file-_oUZo76X.mjs → file-BbdFGdMV.mjs} +2 -10
  20. package/dist/file-BbdFGdMV.mjs.map +1 -0
  21. package/dist/{file-BB8Vs9O_.d.mts → file-Dq3NIt_F.d.mts} +3 -42
  22. package/dist/{file-utils-DcyIPFQh.mjs → file-utils-CYZnO1pX.mjs} +5 -5
  23. package/dist/file-utils-CYZnO1pX.mjs.map +1 -0
  24. package/dist/{globals-Crz8o65k.mjs → globals-Cf0sxIt8.mjs} +2 -2
  25. package/dist/{globals-Crz8o65k.mjs.map → globals-Cf0sxIt8.mjs.map} +1 -1
  26. package/dist/{http-adapter.generated-WgMnb7Sb.d.mts → http-adapter.generated-DFsXDdm5.d.mts} +11 -10
  27. package/dist/{index-BlpzXncY.d.mts → index-BI-_j9Z3.d.mts} +29 -32
  28. package/dist/{index-DjUdWlzf.d.mts → index-C4JirJH8.d.mts} +2 -2
  29. package/dist/{index-5vPyRu1y.d.mts → index-CZfWhr0a.d.mts} +2 -2
  30. package/dist/{index-CK7u9isy.d.mts → index-Cg8VKAdN.d.mts} +4 -4
  31. package/dist/{index-B7AKc18V.d.mts → index-DYRjoLXD.d.mts} +2 -2
  32. package/dist/{index-ZePLwxw7.d.mts → index-lFpcjHPU.d.mts} +8 -15
  33. package/dist/{index-CNYe5lnW.d.mts → index-nW7hE6oE.d.mts} +2 -2
  34. package/dist/{mock-BjFj5o1I.mjs → mock-FPxmnt-y.mjs} +4 -49
  35. package/dist/{mock-BjFj5o1I.mjs.map → mock-FPxmnt-y.mjs.map} +1 -1
  36. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  37. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  38. package/dist/plugin/builtin/file-utils/index.mjs +1 -1
  39. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  40. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  41. package/dist/plugin/builtin/seed/index.mjs +1 -1
  42. package/dist/plugin/index.d.mts +4 -3
  43. package/dist/plugin/index.mjs.map +1 -1
  44. package/dist/{registry-DdsYlL_P.mjs → registry-DH4m7eYo.mjs} +4 -2
  45. package/dist/registry-DH4m7eYo.mjs.map +1 -0
  46. package/dist/runtime/context.d.mts +1 -1
  47. package/dist/runtime/file.d.mts +2 -2
  48. package/dist/runtime/file.mjs +2 -2
  49. package/dist/runtime/globals.d.mts +6 -6
  50. package/dist/runtime/index.d.mts +4 -4
  51. package/dist/runtime/index.mjs +2 -2
  52. package/dist/runtime/workflow.d.mts +2 -2
  53. package/dist/runtime/workflow.mjs +1 -1
  54. package/dist/{runtime-n9NCkjee.mjs → runtime-CY4JvrDj.mjs} +777 -234
  55. package/dist/runtime-CY4JvrDj.mjs.map +1 -0
  56. package/dist/{schema-BhkpP5Hw.mjs → schema-Dtw9Orye.mjs} +16 -13
  57. package/dist/schema-Dtw9Orye.mjs.map +1 -0
  58. package/dist/{secret-file-DBqZhjFQ.mjs → secret-file-VSVGy1V0.mjs} +27 -2
  59. package/dist/{secret-file-DBqZhjFQ.mjs.map → secret-file-VSVGy1V0.mjs.map} +1 -1
  60. package/dist/{seed-jf3008-h.mjs → seed-izIEyP3z.mjs} +3 -4
  61. package/dist/seed-izIEyP3z.mjs.map +1 -0
  62. package/dist/service-DCqIWibD.mjs +3 -0
  63. package/dist/{service-DU1mVzri.mjs → service-DU1mVzri2.mjs} +1 -1
  64. package/dist/service-DU1mVzri2.mjs.map +1 -0
  65. package/dist/{service-CCL8ruDf.mjs → service-DjyqbCaJ.mjs} +7 -7
  66. package/dist/{service-CCL8ruDf.mjs.map → service-DjyqbCaJ.mjs.map} +1 -1
  67. package/dist/test-env-key-D7UkZp99.mjs +75 -0
  68. package/dist/test-env-key-D7UkZp99.mjs.map +1 -0
  69. package/dist/{types-ClhIrW_C.mjs → types-74etvaxy.mjs} +1 -1
  70. package/dist/{types-DhO_VEZd.d.mts → types-BDRml5C3.d.mts} +12 -12
  71. package/dist/{types-B2RpYyA_.mjs → types-BQijbo4m.mjs} +9 -9
  72. package/dist/types-BQijbo4m.mjs.map +1 -0
  73. package/dist/{types-DwDgacni.d.mts → types-BX4q6Mo6.d.mts} +3 -2
  74. package/dist/types-BZ7QKVE8.d.mts +21 -0
  75. package/dist/{types-DCUhgpyI.d.mts → types-CdcQh4Z2.d.mts} +5 -76
  76. package/dist/utils/test/index.d.mts +6 -15
  77. package/dist/utils/test/index.mjs +4 -13
  78. package/dist/utils/test/index.mjs.map +1 -1
  79. package/dist/vitest/environment.mjs +1 -1
  80. package/dist/vitest/index.d.mts +2 -2
  81. package/dist/vitest/index.mjs +4 -4
  82. package/dist/vitest/setup.mjs +2 -2
  83. package/dist/{workflow-DgemCAz3.mjs → workflow-BOmaZwwG.mjs} +8 -3
  84. package/dist/workflow-BOmaZwwG.mjs.map +1 -0
  85. package/dist/{workflow-BbKvGLQg.d.mts → workflow-BVy4XWjS.d.mts} +15 -10
  86. package/dist/{workflow.generated-DtQwEo-x.d.mts → workflow.generated-ClEjBYhm.d.mts} +3 -3
  87. package/docs/cli/executor.md +53 -0
  88. package/docs/cli/setup.md +35 -33
  89. package/docs/cli/workflow.md +157 -20
  90. package/docs/cli-reference.md +26 -20
  91. package/docs/github-actions.md +29 -16
  92. package/docs/migration/v2.md +475 -0
  93. package/docs/runtime.md +1 -1
  94. package/docs/services/auth.md +12 -12
  95. package/docs/services/executor.md +3 -3
  96. package/docs/services/resolver.md +6 -6
  97. package/docs/services/tailordb.md +14 -12
  98. package/docs/services/workflow.md +4 -4
  99. package/docs/testing.md +59 -47
  100. package/package.json +7 -7
  101. package/dist/application-DB2r36Et.mjs +0 -3
  102. package/dist/application-DqS1yBg3.mjs +0 -5680
  103. package/dist/application-DqS1yBg3.mjs.map +0 -1
  104. package/dist/client-Dbohmtkv.mjs +0 -3
  105. package/dist/client-z_oHGVNy.mjs.map +0 -1
  106. package/dist/file-_oUZo76X.mjs.map +0 -1
  107. package/dist/file-utils-DcyIPFQh.mjs.map +0 -1
  108. package/dist/job-fuc3j1Ma.mjs +0 -53
  109. package/dist/job-fuc3j1Ma.mjs.map +0 -1
  110. package/dist/registry-DdsYlL_P.mjs.map +0 -1
  111. package/dist/runtime-n9NCkjee.mjs.map +0 -1
  112. package/dist/schema-BhkpP5Hw.mjs.map +0 -1
  113. package/dist/seed-jf3008-h.mjs.map +0 -1
  114. package/dist/service-D6yonf2I.mjs +0 -3
  115. package/dist/service-DU1mVzri.mjs.map +0 -1
  116. package/dist/test-env-key-D9kM6ETE.mjs +0 -49
  117. package/dist/test-env-key-D9kM6ETE.mjs.map +0 -1
  118. package/dist/types-B2RpYyA_.mjs.map +0 -1
  119. package/dist/workflow-DgemCAz3.mjs.map +0 -1
@@ -0,0 +1,475 @@
1
+ # Migrating to v2
2
+
3
+ <!-- Generated from the sdk-codemod registry. Run `pnpm codemod:docs:update` and edit `packages/sdk-codemod/src/registry.ts` instead of this file. -->
4
+
5
+ Run the codemods, then finish anything reported as not migrated automatically:
6
+
7
+ ```sh
8
+ npx @tailor-platform/sdk-codemod --from <current-version> --to <target-version>
9
+ ```
10
+
11
+ ## defineGenerators → definePlugins
12
+
13
+ **Migration:** Partially automatic
14
+
15
+ Migrate defineGenerators() tuple syntax to definePlugins() with explicit plugin imports
16
+
17
+ Before:
18
+
19
+ ```ts
20
+ import { defineGenerators } from "@tailor-platform/sdk";
21
+
22
+ export const generators = defineGenerators(
23
+ ["@tailor-platform/kysely-type", { distPath: "db.ts" }],
24
+ );
25
+ ```
26
+
27
+ After:
28
+
29
+ ```ts
30
+ import { definePlugins } from "@tailor-platform/sdk";
31
+ import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
32
+
33
+ export const generators = definePlugins(kyselyTypePlugin({ distPath: "db.ts" }));
34
+ ```
35
+
36
+ <details>
37
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
38
+
39
+ ```text
40
+ defineGenerators() is replaced by definePlugins() in v2. The codemod rewrites the
41
+ known plugin tuples (kysely-type, enum-constants, file-utils, seed). For any
42
+ remaining defineGenerators([...]) the codemod left in place — a plugin it does not
43
+ know, or a non-tuple/spread form — convert it to definePlugins(pluginFn(config)),
44
+ importing the matching plugin from its @tailor-platform/sdk/plugin/<name> subpath.
45
+ ```
46
+
47
+ </details>
48
+
49
+ ## @tailor-platform/sdk/cli plugin imports → dedicated subpaths
50
+
51
+ **Migration:** Automatic
52
+
53
+ Rewrite deprecated plugin re-export imports (kyselyTypePlugin, enumConstantsPlugin, fileUtilsPlugin, seedPlugin) from `@tailor-platform/sdk/cli` to their dedicated plugin subpaths
54
+
55
+ Before:
56
+
57
+ ```ts
58
+ import { kyselyTypePlugin } from "@tailor-platform/sdk/cli";
59
+ ```
60
+
61
+ After:
62
+
63
+ ```ts
64
+ import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
65
+ ```
66
+
67
+ ## function test-run --arg input unwrap
68
+
69
+ **Migration:** Automatic
70
+
71
+ Strip the deprecated {input: ...} wrapper from `tailor-sdk function test-run --arg` JSON in scripts and docs
72
+
73
+ Before:
74
+
75
+ ```sh
76
+ tailor-sdk function test-run resolvers/add.ts --arg '{"input":{"a":1}}'
77
+ ```
78
+
79
+ After:
80
+
81
+ ```sh
82
+ tailor-sdk function test-run resolvers/add.ts --arg '{"a":1}'
83
+ ```
84
+
85
+ ## tailor-sdk-skills → tailor-sdk skills install
86
+
87
+ **Migration:** Partially automatic
88
+
89
+ Replace deprecated `tailor-sdk-skills` invocations with `tailor-sdk skills install`
90
+
91
+ Before:
92
+
93
+ ```sh
94
+ npx tailor-sdk-skills
95
+ ```
96
+
97
+ After:
98
+
99
+ ```sh
100
+ tailor-sdk skills install
101
+ ```
102
+
103
+ <details>
104
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
105
+
106
+ ```text
107
+ The standalone tailor-sdk-skills binary is removed in v2; call the skills install
108
+ subcommand on the main tailor-sdk CLI instead. Replace any remaining
109
+ tailor-sdk-skills invocations the codemod did not rewrite with
110
+ `tailor-sdk skills install`.
111
+ ```
112
+
113
+ </details>
114
+
115
+ ## Unify TailorUser/TailorActor/TailorActorType/TailorInvoker → TailorPrincipal
116
+
117
+ **Migration:** Partially automatic
118
+
119
+ Rename TailorUser/TailorActor/TailorActorType/TailorInvoker to TailorPrincipal, drop unauthenticatedTailorUser, rename resolver body `user` to `caller`, and rename TailorDB callback `user` to `invoker`
120
+
121
+ Type references unify under `TailorPrincipal`:
122
+
123
+ Before:
124
+
125
+ ```ts
126
+ import type { TailorUser } from "@tailor-platform/sdk";
127
+ ```
128
+
129
+ After:
130
+
131
+ ```ts
132
+ import type { TailorPrincipal } from "@tailor-platform/sdk";
133
+ ```
134
+
135
+ The resolver body `user` becomes `caller`:
136
+
137
+ Before:
138
+
139
+ ```ts
140
+ body: ({ input, user }) => user.id,
141
+ ```
142
+
143
+ After:
144
+
145
+ ```ts
146
+ body: ({ input, caller }) => caller.id,
147
+ ```
148
+
149
+ <details>
150
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
151
+
152
+ ```text
153
+ Finish the cases the codemod left for manual migration:
154
+ - Rename user -> caller in resolver bodies the codemod skipped because a `caller`
155
+ binding already exists or renaming would shadow/collide with another value.
156
+ - Replace member-access on the removed unauthenticatedTailorUser (e.g.
157
+ unauthenticatedTailorUser.id); the codemod only replaced standalone references
158
+ with null and left member access to surface a type error.
159
+ - Review helper adapters that still accept or read `context.user`; v2 resolver
160
+ context uses nullable `caller` and `invoker`, so project-specific helper
161
+ semantics for anonymous callers and command invokers must be chosen explicitly.
162
+ - Review `caller?.` values passed to APIs that require non-null values. If the
163
+ resolver requires authentication, throw or otherwise narrow before the call;
164
+ if anonymous callers are allowed, keep the nullable flow explicit.
165
+ Use TailorPrincipal for the unified user/actor/invoker type.
166
+ ```
167
+
168
+ </details>
169
+
170
+ ## tailor-sdk apply → tailor-sdk deploy
171
+
172
+ **Migration:** Automatic
173
+
174
+ Rewrite `tailor-sdk apply` invocations in package.json scripts, shell scripts, CI configs, and docs to the canonical v2 `tailor-sdk deploy` command
175
+
176
+ Before:
177
+
178
+ ```sh
179
+ tailor-sdk apply --profile prod
180
+ ```
181
+
182
+ After:
183
+
184
+ ```sh
185
+ tailor-sdk deploy --profile prod
186
+ ```
187
+
188
+ ## v2 CLI rename
189
+
190
+ **Migration:** Partially automatic
191
+
192
+ Rewrite `tailor-sdk crash-report` to `tailor-sdk crashreport` and `--machineuser` to `--machine-user` across package.json scripts, shell scripts, CI configs, and docs
193
+
194
+ Before:
195
+
196
+ ```sh
197
+ tailor-sdk crash-report list
198
+ tailor-sdk login --machineuser
199
+ ```
200
+
201
+ After:
202
+
203
+ ```sh
204
+ tailor-sdk crashreport list
205
+ tailor-sdk login --machine-user
206
+ ```
207
+
208
+ <details>
209
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
210
+
211
+ ```text
212
+ Apply the v2 CLI renames the codemod did not reach (only `tailor-sdk`-prefixed
213
+ invocations are rewritten): `tailor-sdk crash-report` -> `tailor-sdk crashreport`
214
+ and the `--machineuser` option -> `--machine-user`. Leave unrelated commands that
215
+ happen to use `--machineuser` alone.
216
+ ```
217
+
218
+ </details>
219
+
220
+ ## auth.invoker("name") → "name"
221
+
222
+ **Migration:** Partially automatic
223
+
224
+ Replace `auth.invoker("name")` calls with the bare `"name"` string and drop the `auth` import when no other reference remains. The `auth.invoker()` helper is deprecated in v2 because importing `auth` from `tailor.config.ts` into runtime files pulls Node-only modules into the bundle.
225
+
226
+ Before:
227
+
228
+ ```ts
229
+ createResolver({ invoker: auth.invoker("manager") });
230
+ ```
231
+
232
+ After:
233
+
234
+ ```ts
235
+ createResolver({ invoker: "manager" });
236
+ ```
237
+
238
+ <details>
239
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
240
+
241
+ ```text
242
+ In Tailor SDK v2 the auth.invoker() helper is removed; an invoker is now the
243
+ machine user name passed directly as a string. The codemod already rewrote the
244
+ string-literal form auth.invoker("name") to "name". These files still contain
245
+ auth.invoker(...) because the argument is not a plain string literal (a variable,
246
+ template literal, function call, or property access).
247
+
248
+ For each remaining auth.invoker(<expr>) call:
249
+ 1. Replace the whole call with <expr> as-is (e.g. auth.invoker(name) becomes name).
250
+ 2. Make sure <expr> evaluates to the machine user name (a string); adjust it if it
251
+ resolves to an object or an auth config value instead.
252
+ 3. After removing every auth.invoker usage in a file, delete the now-unused auth
253
+ import (keeping it pulls Node-only config modules into runtime bundles); leave
254
+ the import if auth is still referenced elsewhere.
255
+
256
+ Do not change behavior beyond removing the auth.invoker() indirection.
257
+ ```
258
+
259
+ </details>
260
+
261
+ ## Tailordb → tailordb (lowercase ambient namespace)
262
+
263
+ **Migration:** Partially automatic
264
+
265
+ Rewrite references to the removed capital-cased `Tailordb` ambient namespace (`Tailordb.QueryResult`, `Tailordb.CommandType`, `Tailordb.Client`, `typeof Tailordb.Client`) to the lowercase `tailordb.*` namespace exposed by `@tailor-platform/sdk/runtime/globals`. Because v2 no longer activates ambient declarations automatically, each file that contains `tailordb.*` references after the rewrite must also add `import "@tailor-platform/sdk/runtime/globals"`.
266
+
267
+ Before:
268
+
269
+ ```ts
270
+ const command: Tailordb.CommandType = "SELECT";
271
+ ```
272
+
273
+ After:
274
+
275
+ ```ts
276
+ import "@tailor-platform/sdk/runtime/globals";
277
+ const command: tailordb.CommandType = "SELECT";
278
+ ```
279
+
280
+ <details>
281
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
282
+
283
+ ```text
284
+ The capital-cased Tailordb ambient namespace is removed in v2; use the lowercase
285
+ tailordb.* namespace from @tailor-platform/sdk/runtime/globals. The codemod rewrites
286
+ the known members (QueryResult, CommandType, Client). Rewrite any other remaining
287
+ Tailordb.* reference to its tailordb.* equivalent (and confirm the member still
288
+ exists on the lowercase namespace).
289
+ Also add `import "@tailor-platform/sdk/runtime/globals"` at the top of each file
290
+ that contains any tailordb.* type reference — v2 no longer activates ambient
291
+ declarations automatically on SDK import.
292
+ ```
293
+
294
+ </details>
295
+
296
+ ## executeScript arg JSON.stringify → value
297
+
298
+ **Migration:** Partially automatic
299
+
300
+ Unwrap `JSON.stringify(...)` passed as the `executeScript` `arg` option. In v2 `arg` takes a JSON-serializable value and is serialized internally, so a pre-stringified argument double-encodes.
301
+
302
+ Before:
303
+
304
+ ```ts
305
+ await executeScript({ ...opts, arg: JSON.stringify({ a: 1 }) });
306
+ ```
307
+
308
+ After:
309
+
310
+ ```ts
311
+ await executeScript({ ...opts, arg: { a: 1 } });
312
+ ```
313
+
314
+ <details>
315
+ <summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
316
+
317
+ ```text
318
+ In Tailor SDK v2 the executeScript() arg option takes a JSON-serializable value
319
+ and is serialized internally, so a pre-stringified argument double-encodes. The
320
+ codemod already rewrote the direct form arg: JSON.stringify(X) to arg: X. Review
321
+ the executeScript calls in these files for cases it could not rewrite — where the
322
+ arg value is reached indirectly, for example:
323
+ - a variable holding a JSON.stringify(...) result (const s = JSON.stringify(x); ... arg: s)
324
+ - JSON.stringify(x, null, 2) or another multi-argument form
325
+ - an options object built or spread dynamically
326
+
327
+ For each such call, pass the underlying value directly as arg (drop the
328
+ JSON.stringify wrapper) so executeScript serializes it once. Leave calls that
329
+ already pass a plain value unchanged.
330
+ ```
331
+
332
+ </details>
333
+
334
+ ## openDownloadStream → downloadStream
335
+
336
+ **Migration:** Manual
337
+
338
+ The deprecated `openDownloadStream` file-streaming API is removed in v2. Use `downloadStream` for streamed file downloads. The generated file utilities now emit `downloadFileStream` (which calls `downloadStream` and returns `FileDownloadStreamResponse`) instead of the removed `openFileDownloadStream` helper.
339
+
340
+ Before:
341
+
342
+ ```ts
343
+ const res = await openDownloadStream(namespace, typeName, fieldName, recordId);
344
+ ```
345
+
346
+ After:
347
+
348
+ ```ts
349
+ const res = await downloadStream(namespace, typeName, fieldName, recordId);
350
+ ```
351
+
352
+ <details>
353
+ <summary>Prompt for an AI agent (to perform this migration)</summary>
354
+
355
+ ```text
356
+ The openDownloadStream file-streaming API is removed in v2. Replace every call to
357
+ openDownloadStream with downloadStream (same arguments). If you used the generated
358
+ openFileDownloadStream helper, switch to downloadFileStream, which calls
359
+ downloadStream and returns FileDownloadStreamResponse.
360
+ ```
361
+
362
+ </details>
363
+
364
+ ## Ambient runtime globals are opt-in
365
+
366
+ **Migration:** Manual
367
+
368
+ Importing `@tailor-platform/sdk` no longer activates the ambient `tailor.*` / `tailordb.*` global declarations. Normal SDK development does not need them — use the SDK APIs and the typed wrappers from `@tailor-platform/sdk/runtime`. Only if you relied on the ambient globals directly, add `import "@tailor-platform/sdk/runtime/globals"`. (The capital-cased `Tailordb.*` namespace is removed separately — see the `Tailordb → tailordb` codemod.)
369
+
370
+ Preferred: switch to the typed wrappers from `@tailor-platform/sdk/runtime` and drop the ambient globals:
371
+
372
+ Before:
373
+
374
+ ```ts
375
+ const client = new tailor.idp.Client();
376
+ ```
377
+
378
+ After:
379
+
380
+ ```ts
381
+ import { idp } from "@tailor-platform/sdk/runtime";
382
+ const client = new idp.Client({ namespace: "my-namespace" });
383
+ ```
384
+
385
+ Fallback: only if you must keep referencing the bare `tailor.*` names, opt into the global declarations:
386
+
387
+ Before:
388
+
389
+ ```ts
390
+ const client = new tailor.idp.Client();
391
+ ```
392
+
393
+ After:
394
+
395
+ ```ts
396
+ import "@tailor-platform/sdk/runtime/globals";
397
+ const client = new tailor.idp.Client();
398
+ ```
399
+
400
+ <details>
401
+ <summary>Prompt for an AI agent (to perform this migration)</summary>
402
+
403
+ ```text
404
+ The v2 SDK no longer enables ambient Tailor runtime globals from
405
+ `@tailor-platform/sdk`. For each flagged file that uses `tailor.*`,
406
+ `tailordb.*`, or Tailor runtime error globals, prefer migrating to the
407
+ typed wrappers from `@tailor-platform/sdk/runtime` (e.g. replace
408
+ `new tailor.idp.Client()` with `import { idp } from "@tailor-platform/sdk/runtime"`
409
+ and `new idp.Client({ namespace })`). The wrappers are self-contained, so the
410
+ ambient globals are no longer needed.
411
+
412
+ Only when the file must keep referencing the bare `tailor.*` names directly,
413
+ opt into the global declarations instead by adding one of these:
414
+ - per-file: `import "@tailor-platform/sdk/runtime/globals";`
415
+ - project-wide: `"types": ["@tailor-platform/sdk/runtime/globals"]` in
416
+ the relevant tsconfig compilerOptions
417
+
418
+ Leave files unchanged when the matching name is local, imported from another
419
+ module, or appears only in comments or strings.
420
+ ```
421
+
422
+ </details>
423
+
424
+ ## Workflow .trigger() and trigger tests
425
+
426
+ **Migration:** Manual
427
+
428
+ Workflow job `.trigger()` now aligns with the platform runtime: it returns the job result directly instead of a Promise wrapper, and tests no longer run job bodies locally. Mock trigger responses with `mockWorkflow()` (`setJobHandler` / `enqueueResult`, assert via `triggeredJobs`), or use `runWorkflowLocally()` for a full-chain local run.
429
+
430
+ Tests must mock the workflow runtime instead of running bodies locally:
431
+
432
+ Before:
433
+
434
+ ```ts
435
+ const result = await orderJob.trigger({ id });
436
+ expect(result.status).toBe("done");
437
+ ```
438
+
439
+ After:
440
+
441
+ ```ts
442
+ using wf = mockWorkflow();
443
+ wf.setJobHandler((jobName) => (jobName === "order-job" ? { status: "done" } : null));
444
+ const result = await orderJob.trigger({ id });
445
+ expect(result.status).toBe("done");
446
+ ```
447
+
448
+ <details>
449
+ <summary>Prompt for an AI agent (to perform this migration)</summary>
450
+
451
+ ```text
452
+ Workflow job .trigger() now uses the platform workflow runtime instead of running
453
+ the job body locally. In tests, acquire `using wf = mockWorkflow()` and provide
454
+ trigger responses (setJobHandler / enqueueResult), or use runWorkflowLocally() for a
455
+ full-chain local run; an unmocked trigger now throws. Outside tests, treat the
456
+ trigger result as the job output directly (no Promise wrapper to unwrap).
457
+ ```
458
+
459
+ </details>
460
+
461
+ ## Behavioral changes (no migration required)
462
+
463
+ These v2 changes alter runtime or CLI behavior; no source change is needed.
464
+
465
+ ### CLI tokens stored in the OS keyring
466
+
467
+ CLI login tokens are stored in the OS keyring by default when available, falling back to the platform config file when it is not. No source change is required; re-login if you need tokens moved into the keyring.
468
+
469
+ ### CLI users keyed by subject ID
470
+
471
+ The CLI stores human users by their stable subject ID instead of email (email is kept for display). Legacy email-keyed entries are migrated automatically on the next login or token refresh. No source change is required.
472
+
473
+ ### function logs require a content hash for source mapping
474
+
475
+ `tailor-sdk function logs` maps stack traces against the function bundle only when the execution recorded a `contentHash`. Executions without one now show raw stack traces instead of mapped frames. No source change is required.
package/docs/runtime.md CHANGED
@@ -78,7 +78,7 @@ The runtime entry re-exports the following namespaces. Detailed signatures, para
78
78
  - `idp` — IdP user management (`new Client({ namespace })`)
79
79
  - `workflow` — workflow & job control (`triggerWorkflow`, `triggerJobFunction`, `wait`, `resolve`)
80
80
  - `context` — execution context (`getInvoker`)
81
- - `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream`, `openDownloadStream` _(deprecated)_)
81
+ - `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream`)
82
82
 
83
83
  ## Testing
84
84
 
@@ -139,18 +139,18 @@ export const user = db.type("User", {
139
139
  });
140
140
  ```
141
141
 
142
- The `attributeList` values are accessible via `user.attributeList` as a tuple:
142
+ The `attributeList` values are accessible via the runtime principal's `attributeList` as a tuple:
143
143
 
144
144
  ```typescript
145
145
  // In a resolver
146
146
  body: (context) => {
147
- const [organizationId, teamId] = context.user.attributeList;
147
+ const [organizationId, teamId] = context.caller?.attributeList ?? [];
148
148
  },
149
149
 
150
150
  // In TailorDB hooks
151
151
  .hooks({
152
152
  field: {
153
- create: ({ user }) => user.attributeList[0], // First UUID from list
153
+ create: ({ invoker }) => invoker?.attributeList[0] ?? null, // First UUID from list
154
154
  },
155
155
  })
156
156
  ```
@@ -160,7 +160,7 @@ body: (context) => {
160
160
  When you want to use machine users without defining a `userProfile`, define `machineUserAttributes` instead. These attributes are used for:
161
161
 
162
162
  - type-safe `machineUsers[*].attributes`
163
- - `context.user.attributes` typing (via `tailor.d.ts`)
163
+ - runtime principal `attributes` typing (via `tailor.d.ts`)
164
164
 
165
165
  ```typescript
166
166
  import { defineAuth, t } from "@tailor-platform/sdk";
@@ -200,12 +200,12 @@ machineUsers: {
200
200
  },
201
201
  ```
202
202
 
203
- **attributes**: Values for attributes enabled in `userProfile.attributes` (or all fields defined in `machineUserAttributes` when `userProfile` is omitted). All enabled fields must be set here. These values are accessible via `user.attributes`:
203
+ **attributes**: Values for attributes enabled in `userProfile.attributes` (or all fields defined in `machineUserAttributes` when `userProfile` is omitted). All enabled fields must be set here. These values are accessible via the runtime principal's `attributes`:
204
204
 
205
205
  ```typescript
206
206
  // In a resolver
207
207
  body: (context) => {
208
- const role = context.user.attributes?.role;
208
+ const role = context.caller?.attributes.role;
209
209
  },
210
210
  ```
211
211
 
@@ -230,25 +230,25 @@ machineUsers: {
230
230
  },
231
231
  ```
232
232
 
233
- These values are accessible via `user.attributeList`:
233
+ These values are accessible via the runtime principal's `attributeList`:
234
234
 
235
235
  ```typescript
236
236
  // In a resolver
237
237
  body: (context) => {
238
- const [organizationId, teamId] = context.user.attributeList;
238
+ const [organizationId, teamId] = context.caller?.attributeList ?? [];
239
239
  },
240
240
 
241
241
  // In TailorDB hooks
242
242
  .hooks({
243
243
  field: {
244
- create: ({ user }) => user.attributes?.role === "ADMIN" ? "default" : null,
244
+ create: ({ invoker }) => invoker?.attributes.role === "ADMIN" ? "default" : null,
245
245
  },
246
246
  })
247
247
 
248
248
  // In TailorDB validate
249
249
  .validate({
250
250
  field: [
251
- ({ user }) => user.attributes?.role === "ADMIN",
251
+ ({ invoker }) => invoker?.attributes.role === "ADMIN",
252
252
  "Only admins can set this field",
253
253
  ],
254
254
  })
@@ -269,7 +269,7 @@ tailor-sdk machineuser token <name>
269
269
 
270
270
  ### Specifying a machine user invoker
271
271
 
272
- Resolvers, executors, and `workflow.trigger()` accept an `authInvoker` option that chooses which machine user runs the operation. Pass the machine user name as a plain string — it is type-narrowed to the names you registered in `machineUsers`.
272
+ Resolvers, executors, and `workflow.trigger()` accept an `invoker` option that chooses which machine user runs the operation. Pass the machine user name as a plain string — it is type-narrowed to the names you registered in `machineUsers`.
273
273
 
274
274
  ```typescript
275
275
  // tailor.config.ts
@@ -298,7 +298,7 @@ export default createResolver({
298
298
  // Trigger workflow with machine user permissions
299
299
  const workflowRunId = await myWorkflow.trigger(
300
300
  { id: input.id },
301
- { authInvoker: "admin-machine-user" },
301
+ { invoker: "admin-machine-user" },
302
302
  );
303
303
  return { workflowRunId };
304
304
  },
@@ -219,7 +219,7 @@ createExecutor({
219
219
  });
220
220
  ```
221
221
 
222
- Executor callbacks receive the trigger args, including `env` from `defineConfig({ env })`. `function` and `jobFunction` `body` args also include an `invoker` field: the principal running this function, overridden by `authInvoker` when set; `null` for anonymous calls. Other operation kinds (`graphql`, `webhook`, `workflow`) receive `env` through their callback args but do not pass `invoker` into those callbacks.
222
+ Executor callbacks receive the trigger args, including `env` from `defineConfig({ env })`. `function` and `jobFunction` `body` args also include an `invoker` field: the principal running this function, or the machine user configured through the operation `invoker` option; `null` for anonymous calls. Other operation kinds (`graphql`, `webhook`, `workflow`) receive `env` through their callback args but do not pass `invoker` into those callbacks.
223
223
 
224
224
  ### Job Function Operation
225
225
 
@@ -331,7 +331,7 @@ createExecutor({
331
331
 
332
332
  ### Authentication for Operations
333
333
 
334
- GraphQL and Workflow operations can specify an `authInvoker` to execute with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names defined in your auth config:
334
+ GraphQL and Workflow operations can specify an `invoker` to execute with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names defined in your auth config:
335
335
 
336
336
  ```typescript
337
337
  import { createExecutor, scheduleTrigger } from "@tailor-platform/sdk";
@@ -342,7 +342,7 @@ export default createExecutor({
342
342
  operation: {
343
343
  kind: "graphql",
344
344
  query: `mutation { cleanupOldRecords { count } }`,
345
- authInvoker: "batch-processor",
345
+ invoker: "batch-processor",
346
346
  },
347
347
  });
348
348
  ```
@@ -208,7 +208,7 @@ Validation functions receive:
208
208
 
209
209
  - `value` - The field value being validated
210
210
  - `data` - The entire input object
211
- - `user` - The user performing the operation
211
+ - `invoker` - The principal performing the operation
212
212
 
213
213
  You can specify validation as:
214
214
 
@@ -234,8 +234,8 @@ Validation runs automatically before the `body` function executes. When validati
234
234
  Define actual resolver logic in the `body` function. Function arguments include:
235
235
 
236
236
  - `input` - Input data from GraphQL request
237
- - `user` - The user who called this resolver; unaffected by `authInvoker`
238
- - `invoker` - The principal running this function; equals `user` by default, or the machine user set by `authInvoker`. `null` for anonymous calls.
237
+ - `caller` - The user or machine user who called this resolver; unaffected by `invoker`. `null` for anonymous calls.
238
+ - `invoker` - The principal running this function; equals `caller` by default, or the machine user configured through the resolver `invoker` option. `null` for anonymous calls.
239
239
  - `env` - Environment variables declared in `tailor.config.ts`
240
240
 
241
241
  ### Using Kysely for Database Access
@@ -352,7 +352,7 @@ createResolver({
352
352
 
353
353
  ## Authentication
354
354
 
355
- Specify an `authInvoker` to execute the resolver with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names you defined in your auth config:
355
+ Specify an `invoker` to execute the resolver with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names you defined in your auth config:
356
356
 
357
357
  ```typescript
358
358
  import { createResolver, t } from "@tailor-platform/sdk";
@@ -365,10 +365,10 @@ export default createResolver({
365
365
  // Executes as "batch-processor" machine user
366
366
  return { result: "ok" };
367
367
  },
368
- authInvoker: "batch-processor",
368
+ invoker: "batch-processor",
369
369
  });
370
370
  ```
371
371
 
372
372
  The machine user name is looked up in the auth service configured on your app (`machineUsers` in `defineAuth`). The namespace is resolved automatically — no need to import `auth` from `tailor.config.ts` in resolver files.
373
373
 
374
- **Note:** `authInvoker` controls the permissions for database operations and other platform actions. The `user` object passed to `body` still reflects the original caller, while `invoker` reflects the principal actually running the body.
374
+ **Note:** The `invoker` option controls the permissions for database operations and other platform actions. The `caller` object passed to `body` still reflects the original caller, while the `invoker` body field reflects the principal actually running the body.