eve 0.6.0-beta.1 → 0.6.0-beta.4

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 (64) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/NOTICE +5 -0
  3. package/README.md +2 -2
  4. package/dist/docs/public/advanced/auth-and-route-protection.md +1 -1
  5. package/dist/docs/public/channels/eve.mdx +1 -1
  6. package/dist/docs/public/getting-started.mdx +5 -5
  7. package/dist/docs/public/tutorial/first-agent.mdx +1 -1
  8. package/dist/src/cli/commands/channels.js +1 -1
  9. package/dist/src/cli/dev/tui/test/index.d.ts +4 -3
  10. package/dist/src/compiled/.vendor-stamp.json +1 -1
  11. package/dist/src/compiled/@workflow/core/index.js +1 -1
  12. package/dist/src/compiled/@workflow/core/private.d.ts +72 -0
  13. package/dist/src/compiled/@workflow/core/private.js +1 -1
  14. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +8 -0
  15. package/dist/src/compiled/@workflow/core/runtime.js +27 -27
  16. package/dist/src/compiled/@workflow/core/serialization/encryption.d.ts +3 -2
  17. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  18. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  19. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  20. package/dist/src/compiled/_chunks/workflow/dist-6a3viBXZ.js +3 -0
  21. package/dist/src/compiled/_chunks/workflow/dist-D0jyrm7a.js +1 -0
  22. package/dist/src/compiled/_chunks/workflow/resume-hook-0Zk0zSvq.js +12 -0
  23. package/dist/src/compiled/_chunks/workflow/{sleep-CeJckNg2.js → sleep-DXZr2BgM.js} +1 -1
  24. package/dist/src/compiler/normalize-agent-config.js +1 -1
  25. package/dist/src/compiler/normalize-helpers.d.ts +1 -0
  26. package/dist/src/compiler/normalize-helpers.js +1 -1
  27. package/dist/src/compiler/normalize-subagent.js +1 -1
  28. package/dist/src/execution/eve-workflow-attributes.d.ts +7 -6
  29. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  30. package/dist/src/harness/step-hooks.js +1 -1
  31. package/dist/src/internal/application/package.js +1 -1
  32. package/dist/src/internal/application/tsconfig-dependencies.d.ts +23 -0
  33. package/dist/src/internal/application/tsconfig-dependencies.js +1 -0
  34. package/dist/src/internal/nitro/dev-runtime-artifacts.d.ts +8 -3
  35. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  36. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.d.ts +2 -0
  37. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -0
  38. package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +31 -0
  39. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -0
  40. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  41. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  42. package/dist/src/internal/nitro/routes/index.js +1 -1
  43. package/dist/src/node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js +1 -1
  44. package/dist/src/packages/eve-scaffold/src/channels.js +1 -1
  45. package/dist/src/packages/eve-scaffold/src/cli/channel-add-prompter.js +1 -1
  46. package/dist/src/packages/eve-scaffold/src/cli/connection-add-prompter.js +1 -1
  47. package/dist/src/packages/eve-scaffold/src/cli/index.js +1 -1
  48. package/dist/src/packages/eve-scaffold/src/cli/prompt-ui.js +4 -2
  49. package/dist/src/packages/eve-scaffold/src/cli/rail-log.js +2 -2
  50. package/dist/src/packages/eve-scaffold/src/cli/select-component.js +1 -0
  51. package/dist/src/packages/eve-scaffold/src/cli/select-state.js +1 -0
  52. package/dist/src/packages/eve-scaffold/src/index.js +1 -1
  53. package/dist/src/packages/eve-scaffold/src/primitives/detect-deployment.js +1 -1
  54. package/dist/src/packages/eve-scaffold/src/primitives/run-pnpm.js +1 -1
  55. package/dist/src/packages/eve-scaffold/src/primitives/run-vercel.js +1 -1
  56. package/dist/src/packages/eve-scaffold/src/steps/deploy-to-vercel.js +1 -1
  57. package/dist/src/packages/eve-scaffold/src/steps/run-add-to-agent.js +1 -1
  58. package/dist/src/packages/eve-scaffold/src/steps/setup-connection.js +1 -1
  59. package/dist/src/packages/eve-scaffold/src/steps/setup-slackbot.js +1 -1
  60. package/dist/src/runtime/connections/types.d.ts +5 -8
  61. package/dist/src/runtime/connections/validate-authorization.js +1 -1
  62. package/package.json +12 -7
  63. package/dist/src/compiled/_chunks/workflow/dist-zpK2YVVA.js +0 -3
  64. package/dist/src/compiled/_chunks/workflow/resume-hook-BFK9mgsb.js +0 -12
package/CHANGELOG.md CHANGED
@@ -1 +1,22 @@
1
1
  # eve
2
+
3
+ ## 0.6.0-beta.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 2aec0cf: Raise the derived `$eve.title` cap (`EVE_SESSION_TITLE_MAX_CHARS`) from 80 to 125 code points so Agent Runs titles keep more of the original prompt.
8
+ - 5b69978: Fix `eve dev` source snapshots so monorepo-relative config paths and local workspace package links keep resolving from immutable dev-runtime snapshots.
9
+
10
+ ## 0.6.0-beta.3
11
+
12
+ ### Patch Changes
13
+
14
+ - 3f71a5c: Add `repository`, `homepage`, and `bugs` metadata to published packages, ship the Apache-2.0 NOTICE file in npm tarballs, and add an `exports` map and `sideEffects: false` to `create-eve`.
15
+
16
+ ## 0.6.0-beta.2
17
+
18
+ ### Patch Changes
19
+
20
+ - 3af511f: Bump `@workflow/core` to `5.0.0-beta.13`.
21
+ - 5923ebc: fix(eve): prevent provider-executed tool calls from being emitted as client actions
22
+ - beddb37: Prepare packages for open source: remove the internal `eve/dev-tui-test` subpath export, point the deployed home page and headless onboarding hints at the public docs site, add a README and packed CHANGELOG for `create-eve`, and remove internal doc references from runtime error messages.
package/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ eve
2
+ Copyright 2026 Vercel, Inc. and contributors
3
+
4
+ This product includes software developed at Vercel, Inc.
5
+ (https://vercel.com/).
package/README.md CHANGED
@@ -105,12 +105,12 @@ export default defineAgent({
105
105
  ## Quick Start
106
106
 
107
107
  ```bash
108
- pnpm create eve
108
+ pnpm create eve@beta
109
109
  cd my-agent
110
110
  pnpm dev
111
111
  ```
112
112
 
113
- The wizard scaffolds the project, picks a model, and (for the REPL channel) installs dependencies and starts the dev server for you. To scaffold into the current empty directory, run `pnpm create eve .`.
113
+ The wizard scaffolds the project, picks a model, and (for the REPL channel) installs dependencies and starts the dev server for you. To scaffold into the current empty directory, run `pnpm create eve@beta .`.
114
114
 
115
115
  CLI commands:
116
116
 
@@ -184,7 +184,7 @@ export default defineChannel({
184
184
 
185
185
  ## Replace `placeholderAuth` before production
186
186
 
187
- `pnpm create eve` sometimes scaffolds `agent/channels/eve.ts` with a `placeholderAuth()` guardrail:
187
+ `pnpm create eve@beta` sometimes scaffolds `agent/channels/eve.ts` with a `placeholderAuth()` guardrail:
188
188
 
189
189
  ```ts
190
190
  import { eveChannel } from "eve/channels/eve";
@@ -36,7 +36,7 @@ The `auth` option decides who can call these routes. The built-in helpers are me
36
36
 
37
37
  Neither admits browser users or external clients in production. For a public app, wire the channel to your own auth (Clerk, Auth.js, or your own OIDC/JWT verification).
38
38
 
39
- `pnpm create eve` scaffolds an `agent/channels/eve.ts` with a production placeholder so you replace it before going live. The generated channel allows Vercel OIDC and localhost, and includes `placeholderAuth()`, which returns a setup-focused 401 in production until you swap it for real auth. Delete the file and Eve falls back to `[localDev(), vercelOidc()]`, which still does not admit browser users in production.
39
+ `pnpm create eve@beta` scaffolds an `agent/channels/eve.ts` with a production placeholder so you replace it before going live. The generated channel allows Vercel OIDC and localhost, and includes `placeholderAuth()`, which returns a setup-focused 401 in production until you swap it for real auth. Delete the file and Eve falls back to `[localDev(), vercelOidc()]`, which still does not admit browser users in production.
40
40
 
41
41
  For the full auth model and helper list, see [Auth & route protection](../advanced/auth-and-route-protection).
42
42
 
@@ -17,7 +17,7 @@ You also need a model credential. Set the provider or gateway key your model str
17
17
  The fastest path is the `create` CLI. It scaffolds the project, prompts for a model, and wires up an optional channel:
18
18
 
19
19
  ```bash
20
- pnpm create eve@latest
20
+ pnpm create eve@beta
21
21
  ```
22
22
 
23
23
  The wizard asks for a model and which channel you want (Web Chat or Slack). You can skip both: every app ships the built-in HTTP channel (`agent/channels/eve.ts`) regardless. For a local chat it installs dependencies and starts the dev server for you.
@@ -25,7 +25,7 @@ The wizard asks for a model and which channel you want (Web Chat or Slack). You
25
25
  To add Eve to an existing app instead:
26
26
 
27
27
  ```bash
28
- pnpm add -D eve
28
+ pnpm add eve@beta
29
29
  ```
30
30
 
31
31
  ## What's In Your Project
@@ -153,9 +153,9 @@ See [Sessions, runs & streaming](./advanced/sessions-runs-and-streaming) for the
153
153
 
154
154
  If a coding agent (Claude Code, Cursor, and the like) is doing the setup, hand it this prompt:
155
155
 
156
- <CopyPrompt text="Set up an Eve agent for the user. Eve is a filesystem-first TypeScript framework for durable agents, published as the npm package eve. Read its docs: once eve is installed they are bundled in the package at node_modules/eve/dist/docs/public; before eve is installed, read the published Introduction and Getting Started pages. If the project has no Eve app, scaffold one with `pnpm create eve`; to add Eve to an existing app, run `pnpm add eve`. Make sure agent/agent.ts (which sets the model) and agent/instructions.md exist, then add a first typed tool at agent/tools/get_weather.ts using defineTool from eve/tools with a Zod inputSchema and an inline execute. Run it locally with `pnpm dev` (or `eve dev`), then exercise the HTTP API: create a session with POST /eve/v1/session, attach to GET /eve/v1/session/:id/stream, and send a follow-up with the returned continuationToken. Verify with the project's typecheck, adapt model and provider choices to the project, and do not commit unless the user asks.">
156
+ <CopyPrompt text="Set up an Eve agent for the user. Eve is a filesystem-first TypeScript framework for durable agents, published as the npm package eve. Read its docs: once eve is installed they are bundled in the package at node_modules/eve/dist/docs/public; before eve is installed, read the published Introduction and Getting Started pages. If the project has no Eve app, scaffold one with `pnpm create eve@beta`; to add Eve to an existing app, run `pnpm add eve@beta`. Make sure agent/agent.ts (which sets the model) and agent/instructions.md exist, then add a first typed tool at agent/tools/get_weather.ts using defineTool from eve/tools with a Zod inputSchema and an inline execute. Run it locally with `pnpm dev` (or `eve dev`), then exercise the HTTP API: create a session with POST /eve/v1/session, attach to GET /eve/v1/session/:id/stream, and send a follow-up with the returned continuationToken. Verify with the project's typecheck, adapt model and provider choices to the project, and do not commit unless the user asks.">
157
157
  Set up an Eve agent: read the Eve docs (bundled at node_modules/eve/dist/docs/public once eve is
158
- installed), scaffold with `pnpm create eve` (or `pnpm add eve` in an existing app), add a typed
158
+ installed), scaffold with `pnpm create eve@beta` (or `pnpm add eve@beta` in an existing app), add a typed
159
159
  tool at agent/tools/get_weather.ts, run it with `pnpm dev`, then create a session, stream it, and
160
160
  send a follow-up.
161
161
  </CopyPrompt>
@@ -164,7 +164,7 @@ Once `eve` is a dependency, the full docs are bundled in the package, so the age
164
164
 
165
165
  - Docs: `node_modules/eve/dist/docs/public/`
166
166
 
167
- To scaffold a project end to end, `pnpm create eve` collects the decisions (name, model, channels), runs setup, adds Slack interactively with `eve channels add slack`, and verifies the result with `eve info --json`.
167
+ To scaffold a project end to end, `pnpm create eve@beta` collects the decisions (name, model, channels), runs setup, adds Slack interactively with `eve channels add slack`, and verifies the result with `eve info --json`.
168
168
 
169
169
  ## What to read next
170
170
 
@@ -10,7 +10,7 @@ Step 1 gets it talking. The scaffold bundles a small sample dataset, so your fir
10
10
  ## Scaffold
11
11
 
12
12
  ```bash
13
- pnpm create eve@latest
13
+ pnpm create eve@beta
14
14
  ```
15
15
 
16
16
  The wizard prompts for a model and which channels to add (Web Chat or Slack). Skip both for this tutorial: every app ships the built-in HTTP API channel (`agent/channels/eve.ts`). The wizard then installs dependencies and writes a starter `agent/`.
@@ -1 +1 @@
1
- import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{isEveProject}from"../../packages/eve-scaffold/src/project.js";import{listAuthoredChannels}from"../../packages/eve-scaffold/src/channels.js";import"../../packages/eve-scaffold/src/index.js";import{detectDeployment}from"../../packages/eve-scaffold/src/primitives/detect-deployment.js";import{createAddToAgentState,deployProject,runAddToAgent}from"../../packages/eve-scaffold/src/steps/run-add-to-agent.js";import"../../packages/eve-scaffold/src/steps/index.js";import{ChannelAddCancelledError,createChannelAddPrompter}from"../../packages/eve-scaffold/src/cli/channel-add-prompter.js";import"../../packages/eve-scaffold/src/cli/index.js";import"../../packages/eve-scaffold/src/primitives/index.js";const NOT_AN_AGENT_MESSAGE="No Eve agent in this directory. Run `pnpm create eve`, then run this command from inside the new project.",KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment,deployProject,runAddToAgent};async function runAddChannelsFlow(n,r,i,o){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let s=o.createPrompter?.()??createChannelAddPrompter();s.intro(`Add channels to your Eve agent`),s.log.message(`Checking the current Vercel project...`);let c=createAddToAgentState(await o.detectDeployment(n)),l;function inspectRegistrations(){return l===void 0&&(s.log.message(`Inspecting existing channel registrations...`),l=inspectExistingChannelRegistrations(n)),l}let u=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0;c=await o.runAddToAgent({prompter:s,projectPath:n,state:c,presetChannels:r===void 0?void 0:[r],presetCreateSlackbot:i.yes?!0:void 0,disabledChannelReasons:u,force:i.force,validateSelectedChannels:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),c=await o.deployProject({prompter:s,projectPath:n,state:c}),s.outro(c.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,r,i=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,r.kind===void 0?void 0:parseChannelKind(r.kind),r.options,i)}catch(t){if(t instanceof ChannelAddCancelledError)return;e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,i){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let a=await listAuthoredChannels(t);if(i.json){e.log(JSON.stringify({channels:a},null,2));return}if(a.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of a)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
1
+ import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{isEveProject}from"../../packages/eve-scaffold/src/project.js";import{listAuthoredChannels}from"../../packages/eve-scaffold/src/channels.js";import"../../packages/eve-scaffold/src/index.js";import{detectDeployment}from"../../packages/eve-scaffold/src/primitives/detect-deployment.js";import{createAddToAgentState,deployProject,runAddToAgent}from"../../packages/eve-scaffold/src/steps/run-add-to-agent.js";import"../../packages/eve-scaffold/src/steps/index.js";import{ChannelAddCancelledError,createChannelAddPrompter}from"../../packages/eve-scaffold/src/cli/channel-add-prompter.js";import"../../packages/eve-scaffold/src/cli/index.js";import"../../packages/eve-scaffold/src/primitives/index.js";const NOT_AN_AGENT_MESSAGE="No Eve agent in this directory. Run `pnpm create eve@beta`, then run this command from inside the new project.",KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment,deployProject,runAddToAgent};async function runAddChannelsFlow(n,r,i,o){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let s=o.createPrompter?.()??createChannelAddPrompter();s.intro(`Add channels to your Eve agent`),s.log.message(`Checking the current Vercel project...`);let c=createAddToAgentState(await o.detectDeployment(n)),l;function inspectRegistrations(){return l===void 0&&(s.log.message(`Inspecting existing channel registrations...`),l=inspectExistingChannelRegistrations(n)),l}let u=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0;c=await o.runAddToAgent({prompter:s,projectPath:n,state:c,presetChannels:r===void 0?void 0:[r],presetCreateSlackbot:i.yes?!0:void 0,disabledChannelReasons:u,force:i.force,validateSelectedChannels:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),c=await o.deployProject({prompter:s,projectPath:n,state:c}),s.outro(c.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,r,i=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,r.kind===void 0?void 0:parseChannelKind(r.kind),r.options,i)}catch(t){if(t instanceof ChannelAddCancelledError)return;e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,i){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let a=await listAuthoredChannels(t);if(i.json){e.log(JSON.stringify({channels:a},null,2));return}if(a.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of a)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Test-only entrypoint for driving the `eve dev` terminal UI from
3
- * end-to-end smoke tests. Exposed via the `eve/dev-tui-test`
4
- * subpath export. Not part of the supported public API — production code
5
- * reaches the TUI through the internal `#cli/dev/tui/*` modules instead.
3
+ * end-to-end smoke tests. Consumed via `smoke-tests/lib/tui.ts`, which
4
+ * imports the built output directly by path. Not part of the supported
5
+ * public API — production code reaches the TUI through the internal
6
+ * `#cli/dev/tui/*` modules instead.
6
7
  */
7
8
  export { EveTUIRunner } from "../runner.js";
8
9
  export type { EveTUIRunnerOptions } from "../runner.js";
@@ -22,7 +22,7 @@
22
22
  "turndown": "7.2.4",
23
23
  "@vercel/oidc": "3.5.0",
24
24
  "@vercel/sandbox": "2.1.0",
25
- "@workflow/core": "5.0.0-beta.12",
25
+ "@workflow/core": "5.0.0-beta.13",
26
26
  "@workflow/errors": "5.0.0-beta.7",
27
27
  "@workflow/world": "5.0.0-beta.7",
28
28
  "zod": "4.4.3",
@@ -1,2 +1,2 @@
1
- import{c as e,i as t}from"../../_chunks/workflow/dist-zpK2YVVA.js";import{c as n,l as r,nt as i,rt as a,s as o,tt as s}from"../../_chunks/workflow/symbols-BWCAoPHE.js";import{Bt as c,C as l,I as u,R as d,Rt as f,Vt as p,m,n as h,x as g,zt as _}from"../../_chunks/workflow/resume-hook-BFK9mgsb.js";import{n as v,t as y}from"../../_chunks/workflow/sleep-CeJckNg2.js";function b(e){i(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){i(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){i(`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 h(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(`
1
+ import{c as e,i as t}from"../../_chunks/workflow/dist-6a3viBXZ.js";import{c as n,l as r,nt as i,rt as a,s as o,tt as s}from"../../_chunks/workflow/symbols-BWCAoPHE.js";import{Bt as c,C as l,I as u,R as d,Rt as f,Vt as p,m,n as h,x as g,zt as _}from"../../_chunks/workflow/resume-hook-0Zk0zSvq.js";import{n as v,t as y}from"../../_chunks/workflow/sleep-DXZr2BgM.js";function b(e){i(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){i(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){i(`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 h(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
2
  `)}`)}return await h(t,r.value)}}}const C=Symbol.for(`@workflow/setAttributes//unsupportedWorldWarned`);async function w(e,n={}){let r=d.getStore()?.workflowMetadata?.workflowRunId;if(!r)throw new t(`experimental_setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let i=v(e,n);if(i.length===0)return;let a=await f();if(typeof a.runs.experimentalSetAttributes!=`function`){let e=globalThis;if(!e[C]){e[C]=!0;let t=`name`in a&&typeof a.name==`string`?a.name:``,n=t?` (${t})`:``;console.warn(`[workflow] setAttributes: the current world implementation${n} does not implement experimentalSetAttributes; this call (and any subsequent setAttributes calls in this process) is a no-op. Attributes will become available once the world adapter adds support.`)}return}await a.runs.experimentalSetAttributes(r,i,n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{})}function T(){let e=d.getStore();return e||s(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,T),e.stepMetadata}function E(){let e=d.getStore();return e||a(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,E),e.workflowMetadata}function D(e={}){let t=d.getStore();t||a(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,D);let{namespace:i}=e,s=t.workflowMetadata.workflowRunId,f=u(s,i),h=t.writables??=new Map,v=h.get(f);if(v)return v.writable;let y=l(g(globalThis,t.ops,s,t.encryptionKey),t.encryptionKey),b=new m(s,f),x=_();return t.ops.push(x.promise),c(y.readable,b,x).catch(()=>{}),p(y.writable,x),Object.defineProperty(y.writable,o,{value:f,writable:!1}),Object.defineProperty(y.writable,r,{value:s,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,n,{value:t.workflowDeploymentId,writable:!1}),h.set(f,{writable:y.writable,state:x}),y.writable}export{t as FatalError,e as RetryableError,b as createHook,x as createWebhook,S as defineHook,w as experimental_setAttributes,T as getStepMetadata,E as getWorkflowMetadata,D as getWritable,y as sleep};
@@ -50,7 +50,78 @@ export interface WorkflowOrchestratorContext {
50
50
  * to reach 0 before firing, to avoid preempting data delivery.
51
51
  */
52
52
  pendingDeliveries: number;
53
+ /**
54
+ * Ordered registry of in-flight "branch-deciding" deliveries — the
55
+ * resolutions a workflow typically `Promise.race`s on: buffered hook
56
+ * payloads (`hook_received`) and wait completions (`wait_completed`).
57
+ * Keyed by the delivery's position (index) in the consumed event log.
58
+ *
59
+ * The problem: a buffered hook payload is observed via the async hook
60
+ * iterator (`yield await this`), costing extra microtask hops, while a
61
+ * `wait_completed` resolves with fewer hops — and a reused sleep can
62
+ * resolve in an entirely earlier loop iteration. Either way, the
63
+ * resolution that the committed event log ordered first can lose a
64
+ * `Promise.race` to a faster- or already-resolved competitor, diverging
65
+ * from the log and surfacing as `CorruptedEventLogError`.
66
+ *
67
+ * The fix is a strict, deterministic delivery order anchored on
68
+ * event-log position: a delivery does not resolve to the workflow until
69
+ * every earlier-in-log delivery of the OPPOSITE kind has been delivered.
70
+ * (Opposite kind only: sequential same-kind hook payloads must not block
71
+ * one another, and a wait need not wait behind a later wait.) Because the
72
+ * gate is "the earlier delivery resolved", not "won a timing race", the
73
+ * outcome is independent of microtask hops, hydration/decryption time,
74
+ * and `Promise.race` argument order.
75
+ *
76
+ * Index is used rather than the `eventId` string because `eventId` is an
77
+ * opaque, world-assigned value not guaranteed to sort in creation order
78
+ * (only the bundled ULID worlds happen to).
79
+ *
80
+ * Optional so older/out-of-tree contexts (and lightweight test harnesses)
81
+ * that do not initialize it degrade gracefully to the previous behavior.
82
+ */
83
+ pendingDeliveryBarriers?: Map<number, DeliveryBarrierEntry>;
84
+ }
85
+ /** The kind of branch-deciding delivery a barrier represents. */
86
+ export type DeliveryKind = 'hook' | 'wait';
87
+ interface DeliveryBarrierEntry {
88
+ kind: DeliveryKind;
89
+ /** Resolves once this delivery has resolved to the workflow. */
90
+ delivered: Promise<void>;
91
+ }
92
+ /**
93
+ * Awaits, in strict event-log order, every still-registered delivery whose
94
+ * index is earlier than `eventIndex` AND whose kind is in `deferBehindKinds`,
95
+ * so that this resolution is handed to the workflow only after all relevant
96
+ * earlier-in-log deliveries have been. This is what keeps a `Promise.race`
97
+ * deterministic and aligned with the committed event log, independent of
98
+ * microtask-hop counts, hydration time, or race-argument order.
99
+ *
100
+ * `deferBehindKinds` is the opposite kind(s): a hook defers behind earlier
101
+ * WAITS (not earlier hooks — those are sequential same-entity payloads), a
102
+ * wait defers behind earlier HOOKS.
103
+ */
104
+ export declare function awaitEarlierDeliveries(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, deferBehindKinds: readonly DeliveryKind[]): Promise<void>;
105
+ /** Handle for a registered branch-deciding delivery barrier. */
106
+ export interface DeliveryBarrier {
107
+ /**
108
+ * Mark this delivery as delivered to the workflow. Resolves its
109
+ * `delivered` promise so any later-in-log opposite-kind delivery gated on
110
+ * it (via {@link awaitEarlierDeliveries}) may proceed, and removes it from
111
+ * the registry. Idempotent.
112
+ */
113
+ markDelivered: () => void;
53
114
  }
115
+ /**
116
+ * Register a branch-deciding delivery at its event-log index so that later
117
+ * opposite-kind deliveries can be ordered strictly after it. Returns an inert
118
+ * handle when `pendingDeliveryBarriers` is not initialized.
119
+ *
120
+ * To guarantee a later delivery gated on this one can never hang when this
121
+ * delivery is abandoned (the workflow took a different branch or is
122
+ * suspending and never observes it), the barrier auto-resolves at idle.
123
+ */
124
+ export declare function registerDeliveryBarrier(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, kind: DeliveryKind): DeliveryBarrier;
54
125
  /**
55
126
  * Schedule a callback to fire only after all pending data deliveries
56
127
  * (step results, hook payloads) and async deserialization have completed.
@@ -60,4 +131,5 @@ export interface WorkflowOrchestratorContext {
60
131
  * async work to the promiseQueue.
61
132
  */
62
133
  export declare function scheduleWhenIdle(ctx: WorkflowOrchestratorContext, fn: () => void): void;
134
+ export {};
63
135
  //# sourceMappingURL=private.d.ts.map
@@ -1 +1 @@
1
- const e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e]??=new Map,r=new Set([`__builtin_response_array_buffer`,`__builtin_response_json`,`__builtin_response_text`]);function i(e){let t=e.split(`//`);if(t.length!==3||t[0]!==`step`)return[];let n=t[1],r=t[2],i=new Set,a=e=>{e!==n&&i.add(e)};if(n.startsWith(`./workflows/`)){let e=n.slice(2);a(`./example/${e}`),a(`./src/${e}`)}else if(n.startsWith(`./example/workflows/`)){let e=n.slice(10);a(`./${e}`),a(`./src/${e}`)}else if(n.startsWith(`./src/workflows/`)){let e=n.slice(6);a(`./${e}`),a(`./example/${e}`)}return Array.from(i,e=>`step//${e}//${r}`)}function a(e){if(r.has(e)){for(let[t,r]of n.entries())if(t.endsWith(`//${e}`))return r}}function o(e,t){n.set(e,t),t.stepId=e}function s(e){let t=n.get(e);if(t)return t;for(let t of i(e)){let e=n.get(t);if(e)return e}let r=a(e);if(r)return r}function c(e,t){let n=()=>{e.pendingDeliveries>0?e.promiseQueue.then(()=>{setTimeout(n,0)}):t()};setTimeout(n,0)}export{s as getStepFunction,o as registerStepFunction,c as scheduleWhenIdle};
1
+ import{a as e}from"../../_chunks/workflow/dist-D0jyrm7a.js";const t=Symbol.for(`@workflow/core//registeredSteps`),n=globalThis,r=n[t]??=new Map,i=new Set([`__builtin_response_array_buffer`,`__builtin_response_json`,`__builtin_response_text`]);function a(e){let t=e.split(`//`);if(t.length!==3||t[0]!==`step`)return[];let n=t[1],r=t[2],i=new Set,a=e=>{e!==n&&i.add(e)};if(n.startsWith(`./workflows/`)){let e=n.slice(2);a(`./example/${e}`),a(`./src/${e}`)}else if(n.startsWith(`./example/workflows/`)){let e=n.slice(10);a(`./${e}`),a(`./src/${e}`)}else if(n.startsWith(`./src/workflows/`)){let e=n.slice(6);a(`./${e}`),a(`./example/${e}`)}return Array.from(i,e=>`step//${e}//${r}`)}function o(e){if(i.has(e)){for(let[t,n]of r.entries())if(t.endsWith(`//${e}`))return n}}function s(e,t){r.set(e,t),t.stepId=e}function c(e){let t=r.get(e);if(t)return t;for(let t of a(e)){let e=r.get(t);if(e)return e}let n=o(e);if(n)return n}async function l(e,t,n){if(t===void 0||!e.pendingDeliveryBarriers||e.pendingDeliveryBarriers.size===0)return;let r=[];for(let[i,a]of e.pendingDeliveryBarriers)i<t&&n.includes(a.kind)&&r.push(a.delivered);r.length>0&&await Promise.all(r)}function u(t,n,r){let i=t.pendingDeliveryBarriers;if(!i||n===void 0)return{markDelivered:()=>{}};let a=!1,{promise:o,resolve:s}=e(),c={kind:r,delivered:o};i.set(n,c);let l=()=>{a||(a=!0,i.get(n)===c&&i.delete(n),s())};return d(t,l),{markDelivered:l}}function d(e,t){let n=()=>{e.pendingDeliveries>0?e.promiseQueue.then(()=>{setTimeout(n,0)}):t()};setTimeout(n,0)}export{l as awaitEarlierDeliveries,c as getStepFunction,u as registerDeliveryBarrier,s as registerStepFunction,d as scheduleWhenIdle};
@@ -17,6 +17,14 @@ export interface HealthCheckResult {
17
17
  latencyMs?: number;
18
18
  /** Spec version of the responding deployment */
19
19
  specVersion?: number;
20
+ /**
21
+ * `@workflow/core` version of the responding deployment, used for
22
+ * capability detection (see `getRunCapabilities`). Omitted when the
23
+ * responding deployment did not provide the field as a string —
24
+ * for example, an older `@workflow/core` that predates this field,
25
+ * or a non-JSON plain-text health response.
26
+ */
27
+ workflowCoreVersion?: string;
20
28
  }
21
29
  /**
22
30
  * Checks if the given message is a health check payload.