Commit Graph

1208 Commits

Author SHA1 Message Date
Pranay Prakash b2fb3b0708 Merge main and address cache review feedback
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
2026-06-08 17:04:28 -07:00
Pranay Prakash bb6ff9ac99 Patch vulnerable package dependencies (#2301)
* chore: patch package dependency vulnerabilities

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>

* Prefer direct dependency upgrades for security fixes

---------

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
2026-06-08 16:29:26 -07:00
Karthik Kalyan 3ae0ae2917 Deprecate DurableAgent and update it with WorkflowAgent in v5 docs (#2285)
* docs: deprecate DurableAgent in v5

* docs: fix workflow docs CI failures

* docs: trim deprecated DurableAgent guidance

* docs: point v5 cookbook to WorkflowAgent

* docs: fix v5 cookbook navigation

* docs: align WorkflowAgent guide

* docs: add WorkflowAgent cookbook heading

* docs: expand WorkflowAgent cookbook handoff
2026-06-08 16:02:18 -07:00
Pranay Prakash 867e33903d [codex] Fix partial world-local exclusive writes (#2296)
* fix(world-local): publish exclusive files atomically

* fix(world-local): guard temp cleanup
2026-06-08 13:04:56 -07:00
Nathan Rajlich c19f38d907 [world-vercel] Validate ref resolve responses before use (#2035)
* [world-vercel] Validate ref resolve responses before use

When workflow-server returns a ref body to the SDK, the bytes are
fed into the workflow runtime's event log and deserialized via
`decodeFormatPrefix`. The SDK always writes ref payloads with at
least a 4-byte format prefix (see `encodeWithFormatPrefix` in
`@workflow/core`), so a zero-byte response — or one whose length
disagrees with `Content-Length` — is never a valid stored value.

Before this change, `resolveRefDescriptor` had no validation: a
200 with an empty body would be passed downstream as a zero-length
Uint8Array, which then failed deep inside replay with:

    Data too short to contain format prefix: expected at least 4 bytes, got 0

By that point the workflow's in-memory event snapshot is already
poisoned with the empty payload, so every subsequent replay
deterministically reproduces the same failure, downstream
`resumeHook()` calls surface as `Hook not found`, and the run
only unsticks when stale-run cleanup terminates the sandbox.

This catches the failure at the transport boundary instead, where
it can be retried as a `WorkflowWorldError`. Both an empty body
and a length mismatch (truncated streaming response) are rejected.

This is the SDK-side companion to vercel/workflow-server#432, which
adds the same validation on the server side.

* Address review: reject <4-byte bodies, handle malformed Content-Length

Three review changes:

1. Reject any body shorter than the 4-byte format-prefix length, not
   just zero-byte bodies. The SDK guarantees every stored ref payload
   starts with a 4-byte format prefix (FORMAT_PREFIX_LENGTH in
   @workflow/core), so a 1-3 byte body would also fail downstream
   replay with the same 'Data too short to contain format prefix'
   error this PR exists to prevent.

2. Parse Content-Length safely with parseInt + Number.isFinite +
   non-negative checks instead of bare Number(). A non-numeric value
   like 'abc' would otherwise produce NaN and silently surface as a
   'truncated' error, masking the real cause. Malformed values are
   treated as absent; the minimum-length check still defends against
   actual truncation in that case.

3. Add tests for the truncated-body-without-Content-Length case
   (chunked transfer where Content-Length validation can't see the
   truncation), and for a malformed Content-Length header that should
   be ignored rather than misreported as truncation.

The validation logic also moves into a small assertValidRefBody
helper to keep the inner trace function under the noExcessiveCognitiveComplexity limit.

* Address review: scope 4-byte minimum to binary refs, strict Content-Length parsing

- Only apply the 4-byte format-prefix minimum to application/octet-stream
  payloads; CBOR refs can legitimately be 1-byte primitives (true/0/null).
- Require Content-Length to be a plain run of digits before comparing;
  parseInt would otherwise accept numeric-prefixed garbage ('12junk' -> 12).
- Make the changeset succinct.

* Address review: skip Content-Length check for compressed responses

fetch/undici transparently decompresses gzip/br bodies but leaves
Content-Length describing the encoded (compressed) size, so comparing it
against the decompressed byteLength would reject valid compressed refs as
a phantom 'ref-body-length-mismatch'. Skip the comparison when a
non-identity Content-Encoding is present; an absent or 'identity' encoding
is still validated. Adds regression tests for both cases.
2026-06-08 12:34:28 -07:00
Pranay Prakash aa628b7a8f fix: bump devalue to 5.8.1 (#2292) 2026-06-08 12:04:38 -07:00
Pranay Prakash ccd37e9a59 Handle lazy stream key request failures (#2257)
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
2026-06-08 12:01:39 -07:00
Nathan Rajlich 0e39f3b657 fix(docs): declare Nitro auto-import globals for code samples (#2290)
The nitro-native-build changelog sample calls useStorage() (a Nitro
server-side auto-import) from a step, which the docs type-checker
couldn't resolve and failed with TS2552. Add liberal global
declarations for useStorage/useDatabase/useRuntimeConfig so Nitro
auto-imports type-check in docs samples.
2026-06-08 11:29:05 -07:00
Peter Wielander 0fd0891cc4 [core] Preserve event-log order in hook-vs-sleep replay races (#2171) (#2185)
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-06-08 10:39:32 -07:00
Rihan Arfan 5b448ceb03 docs: add nitro changelog (#2232) 2026-06-08 16:06:55 +01:00
Will Binns-Smith a51910b29a fix(next): always apply turbopack content condition regardless of builder mode (#2253)
* fix(next): always apply turbopack content condition regardless of builder mode

When lazy discovery is enabled (deferred builder), shouldApplyTurboCondition
was false, so turbopack.rules were added with no content filter — causing the
workflow loader to run on every JS/TS file. Apply the content condition
unconditionally so the loader only fires on files with workflow directives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* add changeset

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-06-05 14:31:18 -07:00
Casey Gowrie 81bda490ef Update @vercel/queue from 0.2.1 to 0.3.0 (#2255)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-05 11:39:53 -07:00
Peter Wielander d674d6fccd [nest] Use AST-based CommonJS import rewriting (#2080)
Signed-off-by: yao <zhangyaoruo@outlook.com>
Co-authored-by: yao <zhangyaoruo@outlook.com>
2026-06-05 18:09:03 +02:00
Nathan Rajlich 8d75491a07 [core] Surface workflowCoreVersion from healthCheck() result (#1854)
Co-authored-by: Peter Wielander <peter.wielander@vercel.com>
2026-06-05 18:07:41 +02:00
JJ Kasper 0b8b077345 Fix Next lazy step route imports (#2263) 2026-06-05 09:05:19 -07:00
Karthik Kalyan 63f1a9906d [web-shared] Fix message-only error rendering (#2251)
* Fix message-only error rendering

* Handle non-string error stacks
2026-06-04 15:39:47 -07:00
Pranay Prakash cd6a045623 Cache workflow event prefixes and remote refs
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
2026-06-04 13:44:36 -07:00
Mitul Shah 9398065812 Cleaning up trace viewer code (#2252)
* cleanup

* remove dead code

* Delete .changeset/postgres-pin-event-now.md

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>

* Update icons.tsx

* Update event-list.tsx

* Update timeline.tsx

* Create trace-viewer-cleanup.md

---------

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>
2026-06-04 16:25:03 -04:00
github-actions[bot] ff66ee9f2b Version Packages (beta) (#2216)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
workflow@5.0.0-beta.12
2026-06-04 13:06:39 -07:00
Karthik Kalyan 5bf2c167a5 Add serializable reviver compatibility check (#2250) 2026-06-04 12:50:32 -07:00
Karthik Kalyan 24a96d8301 Fix HookConflictError web hydration (#2249) 2026-06-04 11:47:07 -07:00
Casey Gowrie ddc8a79741 Update @vercel/queue from 0.1.7 to 0.2.1 (#2246)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 16:17:53 +00:00
Andrew Barba 3a16272bd3 feat(world-vercel): allow a custom dispatcher (#2235)
* feat(world-vercel): allow a custom dispatcher

Add a `dispatcher` option to `APIConfig`/`createVercelWorld` so callers can
supply a custom undici dispatcher. It is threaded through every request path
(HTTP and the queue) and defaults to the shared undici RetryAgent.

* docs(world-vercel): explain why dispatcher is typed unknown
2026-06-04 02:15:30 +00:00
Mitul Shah fe41b3be3c Reduce width on trace viewer detail pane (#2209)
* Update trace-viewer.tsx

* Create narrow-trace-detail-pane.md
2026-06-03 21:40:22 +00:00
Peter Wielander b8a337c945 [world-local] [world-vercel] Update undici from 7.22.0 to 7.26.0 (#2231) 2026-06-03 18:07:38 +02:00
Pranay Prakash 12c35b54eb fix(core): skip terminal event replay on main (#2215) 2026-06-02 13:04:22 -07:00
Rihan Arfan a65105235c feat(nitro): add /_workflow web ui during dev (#2110) 2026-06-02 14:43:56 +01:00
Peter Wielander 249196935a [docs] Reduce noise in changelog files (#2075) 2026-06-02 12:17:59 +02:00
Pranay Prakash 52d63d1b61 fix(core): advance workflow clock only for consumed events (#2206) (#2211)
* fix(core): advance workflow clock only for consumed events

* test(core): hammer replay branch clock determinism

* fix(core): address consumed event replay review feedback

* test(core): bound replay regression concurrency

(cherry picked from commit 1e32d05758)
2026-06-01 23:49:39 -07:00
Pranay Prakash 2a3b11bcb4 Retry replay divergence before failing event logs (#2212)
(cherry picked from commit 813cd9a9de)
2026-06-02 08:48:00 +02:00
github-actions[bot] 275316fac4 Version Packages (beta) (#2183)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
workflow@5.0.0-beta.11
2026-06-01 20:49:30 -07:00
Pranay Prakash 3867270be8 Reduce unnecessary CI runtime (#2151)
* Reduce unnecessary CI runtime

* Fix shared E2E artifact extraction path

* Stabilize getWorkflowPort timeout test on Windows

* Preserve UI unit coverage on CI fast path
2026-06-02 02:49:20 +00:00
Peter Wielander 7994629b8b [world-vercel] Retry transient response-body parse failures in the HTTP client (#2204)
* fix(world-vercel): retry transient response-body parse failures in the HTTP client

A sporadic failure reading/decoding a 2xx response body (truncated or
terminated stream, connection reset mid-body, or a gateway returning a
non-CBOR/JSON body) was surfaced immediately as a PARSE_ERROR. The
shared RetryAgent only retries connection/5xx failures — body
consumption happens after it returns the response, so these escape its
retry logic.

Retry such failures inside `makeRequest` with bounded exponential
backoff, scoped to idempotent methods (GET/HEAD) so writes are never
replayed. This fixes the reported `events.list` parse failure at the
adapter layer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(core): propagate exhausted transient world errors to the queue

Pairs with the world-vercel in-adapter retry: when a response-body parse
failure survives the adapter's retries (or comes from a non-idempotent
write that is never retried in-process), it must not fail the run.
Re-throw such transient world errors from the replay loop so they
propagate to the queue handler, which replays the whole run — safe
because replay is idempotent. Schema-validation contract errors stay
fatal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Revert "fix(core): propagate exhausted transient world errors to the queue"

This reverts commit 7bb62e9f81.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:49:49 -07:00
Mitul Shah 445ec8c7e6 Add virtualization to the trace viewer (#2205)
* loading state

* Update trace-viewer.tsx

* Update use-trace-viewer.test.ts

* virtualization

* Create swift-parks-move.md

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>

---------

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>
2026-06-01 20:22:30 +00:00
Mitul Shah f0f002ae05 Trace viewer: scroll-load events past an auto-load cap (#2200)
* loading state

* Update trace-viewer.tsx

* Update use-trace-viewer.test.ts
2026-06-01 15:42:47 -04:00
Pranay Prakash 8f68d3525c fix(core): resolve forwarded stream keys across deployments (#2191) 2026-06-01 18:38:38 +00:00
Peter Wielander ae3c833acd [e2e] Improve error labeling in event-log-race-repro CI job (#2190) 2026-06-01 11:07:50 +02:00
Pranay Prakash 1ee63b870a [core] Harden event pagination response parsing (#2180) (#2179)
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-05-31 10:48:21 +02:00
Mitul Shah 0606949e4a Add loading skeleton to the new trace viewer (#2164)
* Update run-detail-view.tsx

* trace viewer skellyl

* Add changeset for trace viewer loading skeleton

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Export TraceViewerSkeleton from web-shared

Lets consumers render the trace viewer loading skeleton standalone
(e.g. front's run-detail page during the initial run fetch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Update trace-viewer-skeleton.tsx

* Update trace-viewer-skeleton.tsx

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 23:52:24 +00:00
Mitul Shah ab7e5ab7ba Add tooltip components + apply on up/down detail pane (#2163)
* tooltips

* Apply suggestions from code review

Co-authored-by: Mitul Shah <mitulxshah@gmail.com>
Signed-off-by: Mitul Shah <mitulxshah@gmail.com>

---------

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>
2026-05-30 23:37:23 +00:00
Peter Wielander 5dabbeecab fix(swc-plugin): allow wasm host imports during link (#2174) 2026-05-30 14:57:18 -07:00
Peter Wielander b659ef7cb3 [test] Forward-port reused-sleep replay divergence test (#2172) 2026-05-30 21:28:30 +02:00
Peter Wielander 625fab46c8 [e2e] Add event-log-race-repro label for triggering CI stress-test (#2159) 2026-05-30 00:45:43 -07:00
github-actions[bot] 3d615fb78d Version Packages (beta) (#2162)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
workflow@5.0.0-beta.10
2026-05-29 15:01:15 -07:00
Allen Zhou 3128dfce80 fix(world-local): skip Nov 2025 ghost versions on npm (#2168)
* fix(world-local): skip Nov 2025 ghost versions on npm

`@workflow/world-local` versions 5.0.0-beta.8, beta.9, and beta.10 are
published on npm from an abandoned November 2025 release train (see "About
this version" timestamps on npmjs.com). They use the old `createEmbeddedWorld`
export and 4.x dependencies, while current code uses `createLocalWorld` and
5.x deps.

The last "Version Packages (beta)" PR (#2147) bumped world-local's
package.json from beta.7 → beta.8. The actual publish to npm was either
silently skipped or 409'd, so the npm slot still holds the November
content while `@workflow/core@5.0.0-beta.9` was published with a hard
dependency pin on `@workflow/world-local@5.0.0-beta.8` — pointing
downstream consumers (e.g. Ash) at incompatible code:

  npm ERR! MISSING_EXPORT: "createLocalWorld" is not exported by
  ".../@workflow/world-local@5.0.0-beta.8/.../dist/index.js"

Bump packages/world-local/package.json to 5.0.0-beta.10 (the highest
contaminated slot) so the next Version Packages PR computes
5.0.0-beta.11, which is a free slot on npm. That cascades a patch bump
to core (workspace:*) → core@5.0.0-beta.10 with a clean pin to
world-local@5.0.0-beta.11.

No functional code changes.

* Tighten changeset to one sentence

Signed-off-by: Nathan Rajlich <n@n8.io>

---------

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-29 14:51:50 -07:00
Nathan Rajlich 8d0928b2a2 fix(core,errors): classify SDK encryption failures as RUNTIME_ERROR (#2145)
* fix(core,errors): classify SDK encryption failures as RUNTIME_ERROR

SDK-level AES-GCM encrypt/decrypt failures are never the user's fault,
but the run-failure classifier was tagging them as USER_ERROR because
the native Web Crypto OperationError (most commonly raised by
AESCipherJob.onDone on GCM auth-tag mismatch) does not match any
RUNTIME_ERROR_CHECKS entry.

Introduce a new RuntimeDecryptionError (subclass of WorkflowRuntimeError)
that the encryption module throws when subtle.encrypt/subtle.decrypt
fails, with the original DOMException as cause plus diagnostic context
(operation, byteLength, printable/hex format prefix of the input
header). classifyRunError now picks it up via RUNTIME_ERROR_CHECKS, so
these failures surface as RUNTIME_ERROR with a proper named class for
dashboards and triage.

* Trim changeset description to one sentence

* Trim historical-context comments

* docs: add runtime-decryption-failed troubleshooting page (v4 + v5)

* fix(core): round-trip RuntimeDecryptionError context, fix formatPrefix, propagate through serialization wrappers

Addresses review feedback on #2145:

- Add a RuntimeDecryptionError reducer/reviver (+ SerializableSpecial
  entry + globalThis registration) so its `context` (operation,
  byteLength, formatPrefix) survives the dehydrate/hydrate run-error
  round trip instead of being dropped by the generic Error reducer.

- Stop capturing `formatPrefix` in the low-level encryption layer, which
  only sees the stripped AES payload (nonce bytes), not the outer `encr`
  marker. The serialization layer now attaches the real envelope prefix.

- Rethrow RuntimeDecryptionError unchanged from the serialize/dehydrate
  catch blocks instead of reframing it as a SerializationError, so an
  encryption failure during dehydration stays a RUNTIME_ERROR rather than
  being misclassified as USER_ERROR.

* fix(core): enrich stream decrypt errors with envelope prefix + fix lint

- Mirror the catch/enrich/rethrow block from serialization/encryption.ts
  around the stream-path aesGcmDecrypt() call so auth-tag failures on
  encrypted stream frames also carry context.formatPrefix = 'encr'
  (addresses review feedback). Add a tampered-frame test.
- Fix all auto-fixable Biome lint findings in the touched files
  (template literals, useless try/catch wrappers, optional chaining,
  non-null assertions).
2026-05-29 18:53:17 +00:00
Karthik Kalyan ad5c068d7f [web-shared][web] Fix events tab search (#2107)
* Add server-backed exact ID search to the Events tab.

Replace client-side substring filtering with API lookups for full correlation and event IDs so searches work beyond the first loaded page.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix exact ID search dimming and support wrun_ correlation IDs.

Disable group dimming for server search results and accept run IDs in the exact ID parser so run-level correlation search works.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix dimmed row when searching by event ID for run-level events.

Map selectedGroupKey to __run__ for run-level search results so the matched row is treated as related instead of dimmed.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove run ID search from Events tab exact ID lookup.

Workflow-server only accepts step, wait, and hook correlation IDs — not wrun_. Update the search placeholder and validation toast accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Harden exact ID search UX and correlation fetch limits.

Normalize lowercase ULIDs, scope Enter toasts to ID-like input, abort stale searches, disable search when unavailable, expand parser tests, and cap correlation pagination in workflow web.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix search clear race and surface truncated correlation results.

Guard successful exact-ID search against aborted requests, invalidate in-flight work when the input clears, and return truncation metadata from correlation pagination.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Differentiate exact ID search errors from not-found results.

Return a discriminated union from onExactIdSearch and show search errors in the Events tab instead of mislabeling them as missing IDs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Apply suggestion from @VaguelySerious

Signed-off-by: Peter Wielander <mittgfu@gmail.com>

---------

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-05-29 11:00:53 -07:00
github-actions[bot] 7e7d7e61d2 Version Packages (beta) (#2147) workflow@5.0.0-beta.9 2026-05-29 19:59:27 +02:00
Peter Wielander 409b1033d9 Allow setting workflow attributes from steps (#2157) 2026-05-29 19:38:10 +02:00
Mitul Shah b33c5ef120 Better search handling on the trace viewer (#2144)
* Update copyable-data-block.tsx

* Update event-list.tsx

* Create clever-spans-search.md

* Update index.ts

* Update detail-panel.tsx

* Create icon-button.tsx

* nice

* nice

* cleanup
2026-05-29 16:20:23 +00:00