eve 0.26.2 → 0.27.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 (185) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/src/channel/resolve-active-session.d.ts +4 -0
  3. package/dist/src/channel/resolve-active-session.js +1 -0
  4. package/dist/src/channel/routes.d.ts +11 -0
  5. package/dist/src/cli/dev/tui/vercel-trusted-sources-policy.d.ts +1 -1
  6. package/dist/src/cli/dev/tui/vercel-trusted-sources.js +1 -1
  7. package/dist/src/compiled/.vendor-stamp.json +16 -16
  8. package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
  9. package/dist/src/compiled/@ai-sdk/google/index.d.ts +9 -2
  10. package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
  11. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +18 -3
  12. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  13. package/dist/src/compiled/@ai-sdk/openai/index.d.ts +285 -24
  14. package/dist/src/compiled/@ai-sdk/openai/index.js +2 -2
  15. package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
  16. package/dist/src/compiled/@ai-sdk/provider-utils/index.d.ts +7 -3
  17. package/dist/src/compiled/@vercel/oidc/index.js +28 -2
  18. package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +11 -0
  19. package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +7 -0
  20. package/dist/src/compiled/@vercel/sandbox/command.d.ts +8 -0
  21. package/dist/src/compiled/@vercel/sandbox/execution-context.d.ts +116 -0
  22. package/dist/src/compiled/@vercel/sandbox/index.d.ts +3 -1
  23. package/dist/src/compiled/@vercel/sandbox/index.js +20 -19
  24. package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +13 -5
  25. package/dist/src/compiled/@vercel/sandbox/sandbox-user.d.ts +212 -0
  26. package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +133 -2
  27. package/dist/src/compiled/@vercel/sandbox/session.d.ts +2 -1
  28. package/dist/src/compiled/@vercel/sandbox/snapshot.d.ts +1 -1
  29. package/dist/src/compiled/@workflow/core/create-hook.d.ts +41 -22
  30. package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +29 -0
  31. package/dist/src/compiled/@workflow/core/global.d.ts +2 -0
  32. package/dist/src/compiled/@workflow/core/index.js +2 -2
  33. package/dist/src/compiled/@workflow/core/private.d.ts +6 -17
  34. package/dist/src/compiled/@workflow/core/private.js +1 -1
  35. package/dist/src/compiled/@workflow/core/replay-payload-cache.d.ts +56 -0
  36. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +11 -0
  37. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +6 -4
  38. package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +4 -1
  39. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +39 -0
  40. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  41. package/dist/src/compiled/@workflow/core/serialization.d.ts +44 -4
  42. package/dist/src/compiled/@workflow/core/symbols.d.ts +13 -0
  43. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  44. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  45. package/dist/src/compiled/@workflow/errors/error-codes.d.ts +2 -0
  46. package/dist/src/compiled/@workflow/errors/index.d.ts +14 -0
  47. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  48. package/dist/src/compiled/@workflow/world/events.d.ts +15 -0
  49. package/dist/src/compiled/@workflow/world/hooks.d.ts +2 -1
  50. package/dist/src/compiled/@workflow/world/interfaces.d.ts +77 -4
  51. package/dist/src/compiled/@workflow/world-local/index.js +4 -4
  52. package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
  53. package/dist/src/compiled/_chunks/node/{auth-BuQkq4Gr.js → auth-l7F2PF2b.js} +2 -2
  54. package/dist/src/compiled/_chunks/node/{version-DD-FX9rK.js → version-CjHTLx2a.js} +1 -1
  55. package/dist/src/compiled/_chunks/node/virtual-loader-Cwgujv7l.js +1 -0
  56. package/dist/src/compiled/_chunks/workflow/attribute-changes-Dk1fP6vt.js +20 -0
  57. package/dist/src/compiled/_chunks/workflow/{chunk-BHKSVoKr.js → chunk-BTyA9uPd.js} +1 -1
  58. package/dist/src/compiled/_chunks/workflow/dist-B3qkUnLJ.js +3 -0
  59. package/dist/src/compiled/_chunks/workflow/{dist-CSfKNxQW.js → dist-BX517Nmz.js} +2 -2
  60. package/dist/src/compiled/_chunks/workflow/{dist-zLevmMyU.js → dist-C_VDTghO.js} +10 -10
  61. package/dist/src/compiled/_chunks/workflow/{dist-CttsoN4D.js → dist-CrxV2rsR.js} +1 -1
  62. package/dist/src/compiled/_chunks/workflow/{functions-PT9ri9Hu.js → functions-Dv8dc_-I.js} +1 -1
  63. package/dist/src/compiled/_chunks/workflow/resume-hook-czpG5xnP.js +1 -0
  64. package/dist/src/compiled/_chunks/workflow/run-6zaMjFY6.js +1 -0
  65. package/dist/src/compiled/_chunks/workflow/sleep-B2u06FWc.js +1 -0
  66. package/dist/src/compiled/_chunks/workflow/{src-CQuMexnO.js → src-D1EltLDA.js} +1 -1
  67. package/dist/src/compiled/_chunks/workflow/{token-CaY0nA5J.js → token-Cz223z3C.js} +1 -1
  68. package/dist/src/compiled/_chunks/workflow/token-DWqA5-DA.js +1 -0
  69. package/dist/src/compiled/_chunks/workflow/token-util-B6qBs3-0.js +27 -0
  70. package/dist/src/compiled/_chunks/workflow/{undici-fb54XL8i.js → undici-C2ZhYnV9.js} +1 -1
  71. package/dist/src/compiled/_chunks/workflow/wrapper-Cc2otuUR.js +6 -0
  72. package/dist/src/compiled/env-runner/index.js +1 -1
  73. package/dist/src/compiled/env-runner/node-worker.js +1 -1
  74. package/dist/src/compiled/eventsource-parser/stream/index.d.ts +16 -3
  75. package/dist/src/compiled/jose/index.js +1 -1
  76. package/dist/src/compiler/compile-from-memory.d.ts +5 -0
  77. package/dist/src/compiler/compile-from-memory.js +1 -1
  78. package/dist/src/compiler/extension-compatibility.d.ts +10 -10
  79. package/dist/src/compiler/extension-compatibility.js +1 -1
  80. package/dist/src/execution/deliver-payloads.d.ts +1 -1
  81. package/dist/src/execution/deliver-payloads.js +1 -1
  82. package/dist/src/execution/workflow-entry.js +1 -1
  83. package/dist/src/execution/workflow-steps.js +1 -1
  84. package/dist/src/harness/compaction-prompt.d.ts +19 -1
  85. package/dist/src/harness/compaction-prompt.js +7 -5
  86. package/dist/src/harness/compaction.d.ts +4 -11
  87. package/dist/src/harness/compaction.js +1 -1
  88. package/dist/src/harness/prompt-cache.d.ts +16 -5
  89. package/dist/src/harness/prompt-cache.js +1 -1
  90. package/dist/src/harness/session-limit-continuation.d.ts +8 -0
  91. package/dist/src/harness/session-limit-continuation.js +1 -1
  92. package/dist/src/harness/session-limit-enforcement.d.ts +9 -6
  93. package/dist/src/harness/session-limit-enforcement.js +1 -1
  94. package/dist/src/harness/stale-input-responses.d.ts +21 -3
  95. package/dist/src/harness/stale-input-responses.js +2 -2
  96. package/dist/src/harness/token-estimate.d.ts +9 -0
  97. package/dist/src/harness/token-estimate.js +1 -0
  98. package/dist/src/harness/tool-loop.js +2 -2
  99. package/dist/src/harness/turn-cancellation.d.ts +13 -0
  100. package/dist/src/harness/turn-cancellation.js +1 -1
  101. package/dist/src/internal/application/package.js +1 -1
  102. package/dist/src/internal/nitro/host/copy-host-middleware.js +1 -1
  103. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  104. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  105. package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.8/node_modules/@vercel/sdk/esm/models/updateprojectblock.js +1 -0
  106. package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.8/node_modules/@vercel/sdk/esm/models/updateprojectprojectsbranchmatcher.js +1 -0
  107. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  108. package/dist/src/public/channels/auth.d.ts +59 -9
  109. package/dist/src/public/channels/auth.js +1 -1
  110. package/dist/src/public/channels/discord/defaults.js +1 -1
  111. package/dist/src/public/channels/linear/api.d.ts +2 -0
  112. package/dist/src/public/channels/linear/api.js +3 -1
  113. package/dist/src/public/channels/linear/defaults.js +2 -2
  114. package/dist/src/public/channels/linear/hitl.d.ts +8 -13
  115. package/dist/src/public/channels/linear/hitl.js +3 -3
  116. package/dist/src/public/channels/linear/index.d.ts +1 -1
  117. package/dist/src/public/channels/linear/index.js +1 -1
  118. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  119. package/dist/src/public/channels/slack/api.d.ts +20 -0
  120. package/dist/src/public/channels/slack/api.js +1 -1
  121. package/dist/src/public/channels/slack/defaults.js +1 -1
  122. package/dist/src/public/channels/slack/inbound.d.ts +31 -0
  123. package/dist/src/public/channels/slack/inbound.js +1 -1
  124. package/dist/src/public/channels/slack/index.d.ts +2 -2
  125. package/dist/src/public/channels/slack/slackChannel.d.ts +72 -4
  126. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  127. package/dist/src/public/channels/teams/defaults.js +2 -2
  128. package/dist/src/public/channels/teams/index.d.ts +1 -1
  129. package/dist/src/public/channels/teams/teamsChannel.d.ts +7 -2
  130. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  131. package/dist/src/public/channels/telegram/defaults.js +1 -1
  132. package/dist/src/public/definitions/channel.d.ts +1 -1
  133. package/dist/src/public/next/index.js +1 -1
  134. package/dist/src/public/nuxt/index.d.ts +1 -1
  135. package/dist/src/public/nuxt/index.js +1 -1
  136. package/dist/src/public/nuxt/module.d.ts +10 -24
  137. package/dist/src/public/nuxt/module.js +1 -1
  138. package/dist/src/public/nuxt/routing.d.ts +5 -39
  139. package/dist/src/public/nuxt/routing.js +1 -1
  140. package/dist/src/public/nuxt/vercel-services.d.ts +117 -0
  141. package/dist/src/public/nuxt/vercel-services.js +1 -0
  142. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -1
  143. package/dist/src/runtime/framework-tools/todo.js +1 -1
  144. package/dist/src/runtime/governance/auth/http-basic.js +1 -1
  145. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  146. package/dist/src/setup/scaffold/create/project.js +2 -2
  147. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  148. package/dist/src/setup/scaffold/create/web-template.js +90 -5
  149. package/dist/src/setup/scaffold/update/channels.js +2 -2
  150. package/dist/src/setup/scaffold/update/connections.js +1 -1
  151. package/dist/src/{public/next → shared}/resolve-eve-binary.d.ts +1 -1
  152. package/docs/agent-config.md +10 -5
  153. package/docs/channels/slack.mdx +76 -10
  154. package/docs/channels/teams.mdx +10 -3
  155. package/docs/extensions.md +115 -77
  156. package/docs/guides/auth-and-route-protection.md +14 -1
  157. package/docs/guides/deployment/vercel.mdx +1 -1
  158. package/docs/guides/frontend/nuxt.mdx +22 -1
  159. package/docs/guides/frontend/overview.mdx +2 -0
  160. package/docs/meta.json +1 -0
  161. package/package.json +22 -22
  162. package/dist/src/compiled/@workflow/core/step-hydration-cache.d.ts +0 -148
  163. package/dist/src/compiled/_chunks/node/virtual-loader-B8K8w9cr.js +0 -1
  164. package/dist/src/compiled/_chunks/workflow/attribute-changes-CXiYB8h9.js +0 -20
  165. package/dist/src/compiled/_chunks/workflow/dist-BYo8Gno2.js +0 -3
  166. package/dist/src/compiled/_chunks/workflow/resume-hook-CHXbXuRZ.js +0 -1
  167. package/dist/src/compiled/_chunks/workflow/run-BjtAGa3_.js +0 -1
  168. package/dist/src/compiled/_chunks/workflow/sleep-BJAv0MFP.js +0 -1
  169. package/dist/src/compiled/_chunks/workflow/token-D4VIwGlD.js +0 -1
  170. package/dist/src/compiled/_chunks/workflow/wrapper-ulTvoTdW.js +0 -6
  171. package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.1/node_modules/@vercel/sdk/esm/models/updateprojectprojectsaction.js +0 -1
  172. package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.1/node_modules/@vercel/sdk/esm/models/updateprojectprojectsoptionsallowlist.js +0 -1
  173. package/dist/src/public/nuxt/vercel-json.d.ts +0 -17
  174. package/dist/src/public/nuxt/vercel-json.js +0 -1
  175. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/lib/primitives.js +0 -0
  176. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/lib/schemas.js +0 -0
  177. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/models/aclaction.js +0 -0
  178. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/models/sdkvalidationerror.js +0 -0
  179. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/defaultToZeroValue.js +0 -0
  180. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/fp.js +0 -0
  181. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/primitives.js +0 -0
  182. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/rfcdate.js +0 -0
  183. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/smartUnion.js +0 -0
  184. /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/unrecognized.js +0 -0
  185. /package/dist/src/{public/next → shared}/resolve-eve-binary.js +0 -0
@@ -54,24 +54,32 @@ type NetworkPolicyMatch = {
54
54
  */
55
55
  type NetworkPolicyRule = {
56
56
  /**
57
- * Optional request matcher. When provided, transforms only apply to requests
58
- * that match every specified dimension.
57
+ * Optional request matcher. When provided, transforms and forwarding rules
58
+ * only apply to requests that match every specified dimension.
59
59
  */
60
60
  match?: NetworkPolicyMatch;
61
+ } & ({
61
62
  /**
62
63
  * Transforms to apply to matching requests.
64
+ *
65
+ * `transform` cannot be used together with `forwardURL`.
63
66
  */
64
- transform?: NetworkTransformer[];
67
+ transform: NetworkTransformer[];
68
+ forwardURL?: never;
69
+ } | {
70
+ transform?: never;
65
71
  /**
66
72
  * HTTPS proxy URL to forward matching requests to. Must not include query string or fragment.
67
73
  *
68
74
  * You can use the `defineSandboxProxy` helper from `@vercel/sandbox/proxy` to implement the proxy handler
69
75
  * automatically, which handles authorization and extracts metadata about the request and sandbox.
70
76
  *
77
+ * `forwardURL` cannot be used together with `transform`.
78
+ *
71
79
  * @see https://vercel.com/docs/vercel-sandbox/concepts/firewall#requests-proxying
72
80
  */
73
- forwardURL?: string;
74
- };
81
+ forwardURL: string;
82
+ });
75
83
  /**
76
84
  * Network policy to define network restrictions for the sandbox.
77
85
  *
@@ -0,0 +1,212 @@
1
+ import { Command, CommandFinished } from "./command.js";
2
+ import { ExecutionContext } from "./execution-context.js";
3
+ import { RunCommandParams } from "./session.js";
4
+ import { Sandbox } from "./sandbox.js";
5
+
6
+ //#region src/sandbox-user.d.ts
7
+
8
+ /**
9
+ * Thrown when {@link Sandbox.createUser} is called for an existing username.
10
+ */
11
+ declare class SandboxUserAlreadyExistsError extends Error {
12
+ readonly username: string;
13
+ constructor(username: string);
14
+ }
15
+ /**
16
+ * A user context within a sandbox.
17
+ *
18
+ * All file and command operations default to running as this user.
19
+ * Created via {@link Sandbox.createUser} or {@link Sandbox.asUser}.
20
+ *
21
+ * @hideconstructor
22
+ */
23
+ declare class SandboxUser implements ExecutionContext {
24
+ /**
25
+ * The Linux username.
26
+ */
27
+ readonly username: string;
28
+ /**
29
+ * The user's home directory (e.g., `/home/alice`).
30
+ */
31
+ readonly homeDir: string;
32
+ private readonly sandbox;
33
+ /**
34
+ * Memoized lookup of this user's primary group.
35
+ * See {@link SandboxUser.primaryGroup}.
36
+ */
37
+ private primaryGroupPromise?;
38
+ constructor({
39
+ sandbox,
40
+ username
41
+ }: {
42
+ sandbox: Sandbox;
43
+ username: string;
44
+ });
45
+ /**
46
+ * Build the wrapped command args to run as this user via `sudo -u`.
47
+ *
48
+ * When `env` is provided, injects `env KEY=VAL ...` so that environment
49
+ * variables survive the `sudo -u` transition.
50
+ */
51
+ private buildUserCommand;
52
+ /**
53
+ * Resolve a path relative to this user's home directory.
54
+ * Absolute paths are returned as-is.
55
+ */
56
+ private resolvePath;
57
+ /**
58
+ * Start executing a command as this user.
59
+ *
60
+ * @param command - The command to execute.
61
+ * @param args - Arguments to pass to the command.
62
+ * @param opts - Optional parameters.
63
+ * @returns A {@link CommandFinished} result once execution is done.
64
+ */
65
+ runCommand(command: string, args?: string[], opts?: {
66
+ signal?: AbortSignal;
67
+ timeoutMs?: number;
68
+ }): Promise<CommandFinished>;
69
+ /**
70
+ * Start executing a command as this user in detached mode.
71
+ *
72
+ * @param params - The command parameters.
73
+ * @returns A {@link Command} instance for the running command.
74
+ */
75
+ runCommand(params: RunCommandParams & {
76
+ detached: true;
77
+ }): Promise<Command>;
78
+ /**
79
+ * Start executing a command as this user.
80
+ *
81
+ * @param params - The command parameters.
82
+ * @returns A {@link CommandFinished} result once execution is done.
83
+ */
84
+ runCommand(params: RunCommandParams): Promise<CommandFinished>;
85
+ /**
86
+ * Write files to this user's home directory (or absolute paths).
87
+ * Files are written via the sandbox HTTP API then chowned to this user.
88
+ *
89
+ * The HTTP API can write to user home dirs because they are group-owned
90
+ * by the sandbox's default user group with `770` permissions.
91
+ *
92
+ * @param files - Array of files with path, content, and optional mode
93
+ * @param opts - Optional parameters.
94
+ */
95
+ writeFiles(files: {
96
+ path: string;
97
+ content: string | Uint8Array;
98
+ mode?: number;
99
+ }[], opts?: {
100
+ signal?: AbortSignal;
101
+ }): Promise<void>;
102
+ /**
103
+ * Read a file from this user's context as a stream.
104
+ *
105
+ * @param file - File to read, with path and optional cwd
106
+ * @param opts - Optional parameters.
107
+ * @returns A ReadableStream of the file contents, or null if not found
108
+ */
109
+ readFile(file: {
110
+ path: string;
111
+ cwd?: string;
112
+ }, opts?: {
113
+ signal?: AbortSignal;
114
+ }): Promise<NodeJS.ReadableStream | null>;
115
+ /**
116
+ * Read a file from this user's context as a Buffer.
117
+ *
118
+ * @param file - File to read, with path and optional cwd
119
+ * @param opts - Optional parameters.
120
+ * @returns The file contents as a Buffer, or null if not found
121
+ */
122
+ readFileToBuffer(file: {
123
+ path: string;
124
+ cwd?: string;
125
+ }, opts?: {
126
+ signal?: AbortSignal;
127
+ }): Promise<Buffer | null>;
128
+ /**
129
+ * Download a file from this user's context to the local filesystem.
130
+ *
131
+ * @param src - Source file in the sandbox
132
+ * @param dst - Destination on the local machine
133
+ * @param opts - Optional parameters.
134
+ * @returns The absolute path to the written file, or null if not found
135
+ */
136
+ downloadFile(src: {
137
+ path: string;
138
+ cwd?: string;
139
+ }, dst: {
140
+ path: string;
141
+ cwd?: string;
142
+ }, opts?: {
143
+ mkdirRecursive?: boolean;
144
+ signal?: AbortSignal;
145
+ }): Promise<string | null>;
146
+ /**
147
+ * Read a file as this user and return its bytes, or null if it does not
148
+ * exist.
149
+ *
150
+ * Reads via `sudo -u <user> base64` rather than the HTTP file API: on stock
151
+ * runtimes the API runs as `vercel-sandbox` and cannot read files this user
152
+ * has kept private (e.g. mode `600`), whereas reading as the user always
153
+ * honours the user's own permissions. The payload is base64-encoded because
154
+ * the command output channel is UTF-8 only and would otherwise corrupt
155
+ * binary files.
156
+ */
157
+ private catAsUser;
158
+ /**
159
+ * Create a directory owned by this user.
160
+ *
161
+ * @param path - Path of the directory to create
162
+ * @param opts - Optional parameters.
163
+ */
164
+ mkDir(path: string, opts?: {
165
+ signal?: AbortSignal;
166
+ }): Promise<void>;
167
+ /**
168
+ * This user's primary group. Users created via {@link Sandbox.createUser}
169
+ * get a group named after them, but {@link Sandbox.asUser} accepts
170
+ * pre-existing users whose primary group can differ (e.g. system users), so
171
+ * we resolve it from the sandbox rather than assuming `<username>`.
172
+ *
173
+ * The result is memoized for the lifetime of this instance.
174
+ */
175
+ private primaryGroup;
176
+ private resolvePrimaryGroup;
177
+ /**
178
+ * Run `chown <ownership> <paths...>` as root, throwing on failure.
179
+ */
180
+ private chownOrThrow;
181
+ /**
182
+ * Run `chmod <mode> <paths...>` as root, throwing on failure.
183
+ */
184
+ private chmodOrThrow;
185
+ /**
186
+ * Given absolute leaf paths, return the directories strictly between this
187
+ * user's home directory and each leaf. The home dir itself is excluded, as
188
+ * are any paths that fall outside the home dir.
189
+ */
190
+ private ancestorDirsUnderHome;
191
+ /**
192
+ * Add this user to a group.
193
+ *
194
+ * @param groupname - Name of the group to join
195
+ * @param opts - Optional parameters.
196
+ */
197
+ addToGroup(groupname: string, opts?: {
198
+ signal?: AbortSignal;
199
+ }): Promise<void>;
200
+ /**
201
+ * Remove this user from a group.
202
+ *
203
+ * @param groupname - Name of the group to leave
204
+ * @param opts - Optional parameters.
205
+ */
206
+ removeFromGroup(groupname: string, opts?: {
207
+ signal?: AbortSignal;
208
+ }): Promise<void>;
209
+ }
210
+ //#endregion
211
+ export { SandboxUser, SandboxUserAlreadyExistsError };
212
+ //# sourceMappingURL=sandbox-user.d.ts.map
@@ -9,8 +9,10 @@ import { Credentials } from "./utils/get-credentials.js";
9
9
  import { Command, CommandFinished } from "./command.js";
10
10
  import { Snapshot } from "./snapshot.js";
11
11
  import { SandboxSnapshot } from "./utils/sandbox-snapshot.js";
12
+ import { ExecutionContext } from "./execution-context.js";
12
13
  import { RunCommandParams, Session } from "./session.js";
13
14
  import { FileSystem } from "./filesystem.js";
15
+ import { SandboxUser } from "./sandbox-user.js";
14
16
  import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from "./_workflow-serde.js";
15
17
 
16
18
  //#region src/sandbox.d.ts
@@ -236,7 +238,7 @@ interface SerializedSandbox {
236
238
  * Use {@link Sandbox.create} or {@link Sandbox.get} to construct.
237
239
  * @hideconstructor
238
240
  */
239
- declare class Sandbox {
241
+ declare class Sandbox implements ExecutionContext {
240
242
  private _client;
241
243
  private readonly projectId;
242
244
  /**
@@ -255,6 +257,11 @@ declare class Sandbox {
255
257
  * Hook that will be executed when a new session is created during resume.
256
258
  */
257
259
  private readonly onResume?;
260
+ /**
261
+ * Memoized lookup of the sandbox's default user and its primary group.
262
+ * See {@link Sandbox.getDefaultUser}.
263
+ */
264
+ private defaultUserPromise?;
258
265
  /**
259
266
  * A `node:fs/promises`-compatible API for interacting with the sandbox filesystem.
260
267
  *
@@ -295,8 +302,17 @@ declare class Sandbox {
295
302
  * Memory allocated in MB.
296
303
  */
297
304
  get memory(): number | undefined;
298
- /** Runtime identifier (e.g. "node24", "python3.13"). */
305
+ /**
306
+ * Runtime identifier (e.g. "node24", "python3.13").
307
+ * Mutually exclusive with {@link Sandbox.image}.
308
+ */
299
309
  get runtime(): string | undefined;
310
+ /**
311
+ * Digest-pinned reference of the container image the sandbox was created
312
+ * from, when it was created from an image (`"{repository}@{manifestDigest}"`).
313
+ * Mutually exclusive with {@link Sandbox.runtime}.
314
+ */
315
+ get image(): string | undefined;
300
316
  /**
301
317
  * Cumulative egress bytes across all sessions.
302
318
  */
@@ -342,6 +358,10 @@ declare class Sandbox {
342
358
  * The default timeout of this sandbox in milliseconds.
343
359
  */
344
360
  get timeout(): number | undefined;
361
+ /**
362
+ * When the currently running session will time out.
363
+ */
364
+ get expiresAt(): Date | undefined;
345
365
  /**
346
366
  * Key-value tags attached to the sandbox.
347
367
  */
@@ -408,6 +428,7 @@ declare class Sandbox {
408
428
  vcpus?: number | undefined;
409
429
  memory?: number | undefined;
410
430
  runtime?: string | undefined;
431
+ image?: string | undefined;
411
432
  timeout?: number | undefined;
412
433
  networkPolicy?: {
413
434
  [x: string]: unknown;
@@ -499,6 +520,7 @@ declare class Sandbox {
499
520
  totalIngressBytes?: number | undefined;
500
521
  totalActiveCpuDurationMs?: number | undefined;
501
522
  totalDurationMs?: number | undefined;
523
+ expiresAt?: number | undefined;
502
524
  currentSnapshotId?: string | undefined;
503
525
  statusUpdatedAt?: number | undefined;
504
526
  cwd?: string | undefined;
@@ -867,6 +889,112 @@ declare class Sandbox {
867
889
  extendTimeout(duration: number, opts?: {
868
890
  signal?: AbortSignal;
869
891
  }): Promise<void>;
892
+ /**
893
+ * The user that non-`sudo` commands and the HTTP file API run as, together
894
+ * with that user's primary group. This depends on the sandbox image: stock
895
+ * runtimes default to `vercel-sandbox`, while Ubuntu-based images default to
896
+ * `root`. The multi-user helpers group-own home and shared directories by
897
+ * this user's group so the file API can traverse them, so we resolve it from
898
+ * the running sandbox rather than assuming a fixed name.
899
+ *
900
+ * The result is memoized for the lifetime of this instance.
901
+ *
902
+ * @internal
903
+ */
904
+ getDefaultUser(opts?: {
905
+ signal?: AbortSignal;
906
+ }): Promise<{
907
+ username: string;
908
+ group: string;
909
+ }>;
910
+ private resolveDefaultUser;
911
+ /**
912
+ * Create a new Linux user in this sandbox with an isolated home directory.
913
+ *
914
+ * The home directory is group-owned by the sandbox's default user group with
915
+ * `770` permissions, so the SDK's HTTP file API can read/write directly.
916
+ * Other users cannot access this user's home directory since they are not in
917
+ * that group.
918
+ *
919
+ * @param username - Linux username (lowercase letters, digits, hyphens, underscores)
920
+ * @param opts - Optional parameters.
921
+ * @param opts.signal - An AbortSignal to cancel the operation.
922
+ * @returns A {@link SandboxUser} instance for the created user.
923
+ *
924
+ * @example
925
+ * const alice = await sandbox.createUser("alice");
926
+ * await alice.runCommand("whoami"); // "alice"
927
+ * await alice.writeFiles([{ path: "hello.txt", content: Buffer.from("hi") }]);
928
+ */
929
+ createUser(username: string, opts?: {
930
+ signal?: AbortSignal;
931
+ }): Promise<SandboxUser>;
932
+ /**
933
+ * Get a user handle without creating the user.
934
+ * Assumes the user already exists in the sandbox.
935
+ *
936
+ * @param username - Linux username
937
+ * @returns A {@link SandboxUser} instance.
938
+ *
939
+ * @example
940
+ * const root = sandbox.asUser("root");
941
+ * await root.runCommand("whoami"); // "root"
942
+ */
943
+ asUser(username: "root" | (string & {})): SandboxUser;
944
+ /**
945
+ * Create a new Linux group with a shared directory.
946
+ *
947
+ * Creates a shared directory at `/shared/<groupname>` with setgid permissions
948
+ * (`2770`), so files created inside it automatically inherit the group.
949
+ * All group members can read and write files in the shared directory.
950
+ *
951
+ * @param groupname - Group name (lowercase letters, digits, hyphens, underscores)
952
+ * @param opts - Optional parameters.
953
+ * @param opts.signal - An AbortSignal to cancel the operation.
954
+ * @returns An object with the group name and shared directory path.
955
+ *
956
+ * @example
957
+ * const devs = await sandbox.createGroup("devs");
958
+ * console.log(devs.sharedDir); // "/shared/devs"
959
+ * await sandbox.addUserToGroup("alice", "devs");
960
+ */
961
+ createGroup(groupname: string, opts?: {
962
+ signal?: AbortSignal;
963
+ }): Promise<{
964
+ groupname: string;
965
+ sharedDir: string;
966
+ }>;
967
+ /**
968
+ * Add a user to a group.
969
+ *
970
+ * After joining, the user can read and write files in the group's
971
+ * shared directory at `/shared/<groupname>`.
972
+ *
973
+ * @param username - The user to add
974
+ * @param groupname - The group to add the user to
975
+ * @param opts - Optional parameters.
976
+ * @param opts.signal - An AbortSignal to cancel the operation.
977
+ *
978
+ * @example
979
+ * await sandbox.addUserToGroup("alice", "devs");
980
+ */
981
+ addUserToGroup(username: string, groupname: string, opts?: {
982
+ signal?: AbortSignal;
983
+ }): Promise<void>;
984
+ /**
985
+ * Remove a user from a group.
986
+ *
987
+ * @param username - The user to remove
988
+ * @param groupname - The group to remove the user from
989
+ * @param opts - Optional parameters.
990
+ * @param opts.signal - An AbortSignal to cancel the operation.
991
+ *
992
+ * @example
993
+ * await sandbox.removeUserFromGroup("alice", "devs");
994
+ */
995
+ removeUserFromGroup(username: string, groupname: string, opts?: {
996
+ signal?: AbortSignal;
997
+ }): Promise<void>;
870
998
  /**
871
999
  * Create a snapshot from this currently running sandbox. New sandboxes can
872
1000
  * then be created from this snapshot using {@link Sandbox.createFromSnapshot}.
@@ -888,6 +1016,9 @@ declare class Sandbox {
888
1016
  * When `ports` is provided, it is treated as the full desired port list:
889
1017
  * any currently exposed port omitted from the array will be deregistered.
890
1018
  *
1019
+ * When `timeout` is increased and a session is currently running, the running
1020
+ * session's deadline is also extended.
1021
+ *
891
1022
  * @param params - Fields to update.
892
1023
  * @param opts - Optional abort signal.
893
1024
  */
@@ -5,6 +5,7 @@ import "./api-client/index.js";
5
5
  import { Command, CommandFinished } from "./command.js";
6
6
  import { Snapshot } from "./snapshot.js";
7
7
  import { SandboxSnapshot } from "./utils/sandbox-snapshot.js";
8
+ import { ExecutionContext } from "./execution-context.js";
8
9
  import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from "./_workflow-serde.js";
9
10
  import { Writable } from "stream";
10
11
 
@@ -66,7 +67,7 @@ interface RunCommandParams {
66
67
  *
67
68
  * Obtain a session via {@link Sandbox.currentSession}.
68
69
  */
69
- declare class Session {
70
+ declare class Session implements ExecutionContext {
70
71
  private _client;
71
72
  /**
72
73
  * Lazily resolve credentials and construct an API client.
@@ -212,7 +212,7 @@ declare class Snapshot {
212
212
  * @param params - Get parameters and optional credentials.
213
213
  * @returns A promise resolving to the {@link Sandbox}.
214
214
  */
215
- static get(params: GetSnapshotParams | (GetSnapshotParams & Credentials)): Promise<Snapshot>;
215
+ static get(params: (GetSnapshotParams | (GetSnapshotParams & Credentials)) & WithFetchOptions): Promise<Snapshot>;
216
216
  /**
217
217
  * Delete this snapshot.
218
218
  *
@@ -1,3 +1,4 @@
1
+ import type { StringValue } from './_ms.js';
1
2
  import type { Run } from './runtime/run.js';
2
3
  import type { Serializable } from './schemas.js';
3
4
  /**
@@ -26,28 +27,16 @@ export interface Hook<T = any> extends AsyncIterable<T>, Thenable<T> {
26
27
  */
27
28
  token: string;
28
29
  /**
29
- * Returns a promise that resolves with the conflicting {@link Run} if
30
- * another active hook already owns this hook's token, or `null` once
31
- * the hook has been registered and is ready to receive payloads.
30
+ * Returns the {@link Run} already using this token, or `null` when this Hook
31
+ * registers successfully.
32
32
  *
33
33
  * Calling `createHook()` alone does not register the hook — registration
34
34
  * only happens when the workflow suspends. Awaiting `getConflict()`
35
- * suspends the workflow to commit the hook registration, so it can be
36
- * used to claim the token (and detect token conflicts early) without
37
- * waiting for payload data.
38
- *
39
- * When a conflict is detected, the resolved `Run` is the run that
40
- * currently owns the token. The workflow can decide how to handle the
41
- * duplicate in code: return or log `conflict.runId`, inspect
42
- * `await conflict.status`, await `conflict.returnValue`, or cancel the
43
- * owner with `await conflict.cancel()` and continue in the current run.
44
- *
45
- * Note that awaiting the hook's payload (`await hook`) when the token is
46
- * already owned by another active hook still rejects with
47
- * `HookConflictError`. In the rare case where the conflicting run cannot
48
- * be identified (a `hook_conflict` event persisted by an old world that
49
- * did not record the owning run's ID), `getConflict()` also rejects with
50
- * `HookConflictError` rather than resolving with an incomplete value.
35
+ * suspends the workflow to commit the hook registration without waiting for
36
+ * payload data.
37
+ *
38
+ * If it returns a run, this Hook was not created. Awaiting the Hook instead
39
+ * rejects with `HookConflictError`.
51
40
  *
52
41
  * @example
53
42
  * ```ts
@@ -55,9 +44,9 @@ export interface Hook<T = any> extends AsyncIterable<T>, Thenable<T> {
55
44
  * const conflict = await hook.getConflict();
56
45
  * if (conflict) {
57
46
  * // another run already owns this token
58
- * return { dedupedTo: conflict.runId };
47
+ * return { status: 'duplicate', runId: conflict.runId };
59
48
  * }
60
- * // token is now claimed, without waiting for payload data
49
+ * // this Hook registered without waiting for payload data
61
50
  * ```
62
51
  */
63
52
  getConflict(): Promise<Run<unknown> | null>;
@@ -137,6 +126,36 @@ export interface HookOptions {
137
126
  * ```
138
127
  */
139
128
  token?: string;
129
+ /**
130
+ * **Experimental.** Keeps this Hook's token unavailable for at least the
131
+ * configured time after `createHook()` runs.
132
+ *
133
+ * Accepts the same values as `sleep()`: a duration string, a number of
134
+ * milliseconds, or an absolute `Date`. Relative durations start when
135
+ * `createHook()` runs, not when the workflow ends.
136
+ *
137
+ * The Hook remains active until the workflow ends, even if the configured
138
+ * time passes first. Another Hook can use the token only after both the run
139
+ * has ended and the configured time has passed.
140
+ * After the run ends, the Hook can still be found with `getHookByToken()`
141
+ * until retention ends, but it cannot be resumed.
142
+ *
143
+ * Calling `dispose()` (including through `using`) releases the token
144
+ * immediately.
145
+ *
146
+ * `createHook()` throws if the configured World does not support this
147
+ * experimental option.
148
+ *
149
+ * @example
150
+ *
151
+ * ```ts
152
+ * const hook = createHook({
153
+ * token: `order:${orderId}`,
154
+ * experimental_minRetention: '30d',
155
+ * });
156
+ * ```
157
+ */
158
+ experimental_minRetention?: StringValue | Date | number;
140
159
  /**
141
160
  * Additional user-defined data to include with the hook payload.
142
161
  *
@@ -166,7 +185,7 @@ export interface HookOptions {
166
185
  */
167
186
  isWebhook?: boolean;
168
187
  }
169
- export interface WebhookOptions extends Omit<HookOptions, 'token' | 'isWebhook'> {
188
+ export interface WebhookOptions extends Omit<HookOptions, 'token' | 'isWebhook' | 'experimental_minRetention'> {
170
189
  /**
171
190
  * If set to a `Response` object, the webhook will automatically
172
191
  * respond with the specified response.
@@ -1,4 +1,33 @@
1
1
  import { type PromiseWithResolvers } from './_workflow-utils.js';
2
+ /**
3
+ * Flow-control knob: upper bound on chunks read-but-not-yet-durably-written
4
+ * while coalescing. Once this many chunks are outstanding the producer stops
5
+ * reading until the consumer drains a batch, so a fast producer paired with a
6
+ * slow server can't grow the in-memory queue without bound. Override:
7
+ * `WORKFLOW_STREAM_MAX_INFLIGHT_CHUNKS`.
8
+ *
9
+ * This is deliberately distinct from the per-request batch caps below: this
10
+ * bounds how much is *buffered*, those bound how much goes out in one
11
+ * `writeMulti`. Raising this must never let a single request exceed a wire
12
+ * limit — batch sizing enforces that independently.
13
+ */
14
+ export declare const MAX_INFLIGHT_CHUNKS = 1000;
15
+ /**
16
+ * Wire limit: maximum number of chunks in a single coalesced `writeMulti`.
17
+ * The server enforces a per-multi-write chunk cap (1,000 today); a batch is
18
+ * split at this bound so it can never be rejected wholesale, independently of
19
+ * the backpressure knob above. Override: `WORKFLOW_STREAM_MAX_CHUNKS_PER_BATCH`.
20
+ */
21
+ export declare const MAX_CHUNKS_PER_BATCH = 1000;
22
+ /**
23
+ * Wire limit: maximum cumulative bytes in a single coalesced `writeMulti`.
24
+ * Chunk *count* alone is not enough — 1,000 small chunks are ~100KB but 1,000
25
+ * file-sized chunks can be hundreds of MB, which platform request-body limits
26
+ * reject long before the count cap matters. A batch is split once adding the
27
+ * next chunk would exceed this (a single chunk larger than the cap still goes
28
+ * out alone). Default 1 MiB. Override: `WORKFLOW_STREAM_MAX_BYTES_PER_BATCH`.
29
+ */
30
+ export declare const MAX_BYTES_PER_BATCH: number;
2
31
  /**
3
32
  * Polling interval (in ms) for lock release detection.
4
33
  *
@@ -33,6 +33,8 @@ export interface HookInvocationQueueItem {
33
33
  type: 'hook';
34
34
  correlationId: string;
35
35
  token: string;
36
+ /** Earliest time the token can be reused after the run ends. */
37
+ tokenRetentionUntil?: Date;
36
38
  metadata?: Serializable;
37
39
  hasCreatedEvent?: boolean;
38
40
  /** Whether the workflow is awaiting `hook.getConflict()` for this hook */
@@ -1,2 +1,2 @@
1
- import{i as e,l as t}from"../../_chunks/workflow/dist-BYo8Gno2.js";import{An as n,B as r,D as i,Dn as a,Fn as o,In as s,Pn as c,T as l,V as u,_ as d,_n as f,gn as p,jn as m,kn as h,t as g,vn as _}from"../../_chunks/workflow/attribute-changes-CXiYB8h9.js";import"../../_chunks/workflow/dist-CSfKNxQW.js";import{n as v}from"../../_chunks/workflow/resume-hook-CHXbXuRZ.js";import{t as y}from"../../_chunks/workflow/sleep-BJAv0MFP.js";function b(e){o(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){o(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){o(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await v(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
- `)}`)}return await v(t,r.value)}}}async function C(t,n={}){let r=u.getStore(),i=r?.workflowMetadata?.workflowRunId;if(!i)throw new e(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let o=g(t,n);if(o.length!==0){if(r.runReadyBarrier)try{await r.runReadyBarrier}catch{}await(await a()).events.create(i,{eventType:`attr_set`,specVersion:5,eventData:{changes:o,writer:{type:`step`,stepId:r.stepMetadata.stepId,attempt:r.stepMetadata.attempt},...n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}const w=C;function T(){let e=u.getStore();return e||c(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,T),e.stepMetadata}function E(){let e=u.getStore();return e||s(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,E),e.workflowMetadata}function D(e={}){let t=u.getStore();t||s(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,D);let{namespace:a}=e,o=t.workflowMetadata.workflowRunId,c=r(o,a),g=t.writables??=new Map,v=g.get(c);if(v)return v.writable;let y=i(l(globalThis,t.ops,o,t.encryptionKey,!0,t.runReadyBarrier),t.encryptionKey),b=new d(o,c,t.runReadyBarrier),x=h();return t.ops.push(x.promise),n(y.readable,b,x).catch(()=>{}),m(y.writable,x),Object.defineProperty(y.writable,p,{value:c,writable:!1}),Object.defineProperty(y.writable,_,{value:o,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,f,{value:t.workflowDeploymentId,writable:!1}),g.set(c,{writable:y.writable,state:x}),y.writable}export{e as FatalError,t as RetryableError,b as createHook,x as createWebhook,S as defineHook,w as experimental_setAttributes,T as getStepMetadata,E as getWorkflowMetadata,D as getWritable,C as setAttributes,y as sleep};
1
+ import{i as e,u as t}from"../../_chunks/workflow/dist-B3qkUnLJ.js";import{Dn as n,E as r,En as i,H as a,In as o,Ln as s,O as c,Rn as l,Sn as u,Tn as d,U as f,bn as p,t as m,v as h,vn as g,xn as _}from"../../_chunks/workflow/attribute-changes-Dk1fP6vt.js";import"../../_chunks/workflow/dist-BX517Nmz.js";import{n as v}from"../../_chunks/workflow/resume-hook-czpG5xnP.js";import{t as y}from"../../_chunks/workflow/sleep-B2u06FWc.js";function b(e){s(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){s(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){s(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await v(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
+ `)}`)}return await v(t,r.value)}}}async function C(t,n={}){let r=f.getStore(),i=r?.workflowMetadata?.workflowRunId;if(!i)throw new e(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let a=m(t,n);if(a.length!==0){if(r.runReadyBarrier)try{await r.runReadyBarrier}catch{}await(await g()).events.create(i,{eventType:`attr_set`,specVersion:5,eventData:{changes:a,writer:{type:`step`,stepId:r.stepMetadata.stepId,attempt:r.stepMetadata.attempt},...n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}const w=C;function T(){let e=f.getStore();return e||o(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,T),e.stepMetadata}function E(){let e=f.getStore();return e||l(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,E),e.workflowMetadata}function D(e={}){let t=f.getStore();t||l(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,D);let{namespace:o}=e,s=t.workflowMetadata.workflowRunId,m=a(s,o),g=t.writables??=new Map,v=g.get(m);if(v)return v.writable;let y=c(r(globalThis,t.ops,s,t.encryptionKey,!0,t.runReadyBarrier),t.encryptionKey),b=new h(s,m,t.runReadyBarrier),x=p();return t.ops.push(x.promise),_(y.readable,b,x).catch(()=>{}),u(y.writable,x),Object.defineProperty(y.writable,d,{value:m,writable:!1}),Object.defineProperty(y.writable,n,{value:s,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,i,{value:t.workflowDeploymentId,writable:!1}),g.set(m,{writable:y.writable,state:x}),y.writable}export{e as FatalError,t as RetryableError,b as createHook,x as createWebhook,S as defineHook,w as experimental_setAttributes,T as getStepMetadata,E as getWorkflowMetadata,D as getWritable,C as setAttributes,y as sleep};