mirror of
https://github.com/vercel/workflow.git
synced 2026-09-14 19:59:43 +08:00
pgp/dispatch-skip-queue-owned
56 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b3dbc6d264 | [docs] v5 changes docs: what's new, world upgrade guide, migration skills (#3100) | ||
|
|
3c7875ad73 |
[docs] upgrade @vercel/geistdocs to 1.19.0 (#3170)
* chore: upgrade @vercel/geistdocs to 1.17.1
Picks up the new footer (Footer no longer takes a config prop), the
heading font-weight change to 450, and the tightened navbar OSS-menu
marks. Also switches the site's own navbar logo from the vendored
geistcn LogoWorkflow fallback to the package's LogoWorkflowSdk, using
its new tuned default height instead of a hardcoded 15.
Fixes a resulting regression: navbarOssProducts entries lacked an `id`,
so resolveOssProducts' `product.id !== activeProduct` filter evaluated
to `undefined !== undefined` (false) for every entry and emptied the
OSS flyout. Added stable `id`/`label` values to each entry.
* refactor: use default navbarOssProducts list instead of a custom override
The manual navbarOssProducts array (with local logo imports/heights) is
no longer needed now that the package's DEFAULT_OSS_PRODUCTS list
already includes all these SDKs with proper id/label/section values.
navbarActiveProduct: 'workflow-sdk' now handles self-exclusion instead.
* fix: use bg-background-200 for docs surfaces to match the template
The docs, cookbook, and v5 route layouts plus the shared DocsLayout
container hardcoded bg-background-100 (pure white), so /docs/* pages
rendered on a lighter surface than the rest of the site. Switch them to
bg-background-200, matching the geistdocs template's page background.
* style: adopt package text-heading-* utilities for homepage headings
The marketing homepage headings hardcoded font-semibold (weight 600)
plus manual responsive sizes/tracking, so they rendered heavier than
the docs headings that now use Geist's 450 heading weight. Swap each
display heading to the package's text-heading-* utilities, which bundle
the 450 weight, line-height, and tracking, mapped across breakpoints to
the nearest design-system size. Inline label/emphasis spans keep their
own weight.
* style: adopt package text-heading-* utilities for worlds headings
Extends the homepage heading change to the /worlds section: the world
listing, detail, compare, and building-a-world pages plus their
components hardcoded font-semibold display headings. Swap each to the
package's text-heading-* utilities (450 weight + line-height +
tracking), mapped across breakpoints to the nearest design-system size.
Mono stat numbers, per-benchmark item labels, and the dialog title keep
their own weight.
* style: remove the bordered grid framing from the homepage
The homepage sections were wrapped in a grid divide-y border-y sm:border-x
container, drawing side borders and divider lines between every section.
Drop that framing so the sections flow with whitespace separation.
* style: remove vertical column dividers from homepage sections
Drop the divide-x column dividers still drawn inside the use-cases
(3-col), feature-grid (2-col), and templates sections, so no vertical
lines remain after the section-grid removal. Section padding keeps the
columns visually separated.
* style: make the homepage "Get started" CTA button rounded-full
* style: use text-heading-* for the feature-grid paragraph text
The two 2-col feature blurbs ("Deep integration with AI SDK.",
"Durable agents by default.") hardcoded their size/leading/tracking
plus font-medium/font-semibold weights. Those manual sizes already
equal text-heading-20/24, so swap to text-heading-20 lg:text-heading-24
— same sizes, but the Geist 450 heading weight (lead drops 600 -> 500
via the utility's [&>strong] rule). The lead stays gray-1000 for
emphasis; body stays gray-900.
* style: fade out the run-anywhere provider logos at the left/right edges
Add linear-gradient masks to the flanking cloud-provider logo groups in
the "Run anywhere, no lock-in" viz so they fade to transparent toward
the outer edges, leaving the centered code block untouched.
* style: widen the right-edge fade on the Vercel dashboard viz
The "Workflow SDK on Vercel" dashboard is offset off the right edge, so
the existing to_left black_10% mask fell off-screen and the visible
right edge hard-clipped. Widen it to black_40% so the dashboard fades
out gradually at the visible right edge.
* style: add spacing between the Vercel, use-cases, and templates sections
Wrap the UseCases and Templates sections with a top margin so there's
clear separation between "Workflow SDK on Vercel", "Build anything with
AI Agents", and "Get started" now that the section dividers are gone.
* style: widen the homepage layout from 1080px to 1200px
* style: align use-cases code block and templates cards with the Vercel section
Switch the "Build anything with" and "Get started" sections from
grid-cols-3 / [1fr_2fr] to [1fr_1.5fr], matching the "Workflow SDK on
Vercel" section above so their code block and cards share the same
right-hand column. The wider text column also lets "Build anything with"
sit on one line. Normalize both to outer padding + column gap so the
code block and cards line up exactly.
* style: extend use-cases/templates content to the right layout edge
Drop the right padding at md+ (md:pr-0) so the code block and template
cards reach the same right edge as the "Workflow SDK on Vercel"
dashboard above, which bleeds to the container edge. Mobile keeps its
padding.
* style: remove the divider between the two feature cards
Drop divide-y/lg:divide-y-0 from the feature grid so no border shows
between "Deep integration with AI SDK" and "Durable agents by default".
* refactor: position homepage sections on a shared 12-col grid
Replace the ad-hoc [1fr_1.5fr] + md:pr-0 + lg:pl-* positioning on the
Vercel, use-cases, and templates sections with a shared grid-cols-12
layout (text col-span-5, visual col-span-7), matching the vercel.com
marketing grid convention. The Vercel dashboard becomes a proper grid
cell instead of an absolutely-offset right-bleed, so all three
sections' visuals align by the grid columns with no magic values.
* style: align homepage width with the navbar content
Widen the homepage container from max-w-[1200px] to the site's
max-w-[1448px] (matching the navbar/footer) and reduce the section
gutters from sm:px-12 to sm:px-6, so section content lines up with the
navbar's content edges (right edge flush at the same column as the
navbar and footer). Also convert the "Reliability-as-code" section to
the shared grid-cols-12 layout (col-span-5 text / col-span-7 code
example), replacing its lg:grid-cols-[330px_1fr] magic values.
* refactor: handle homepage horizontal padding at the root container
Move the mobile/desktop gutter (px-4 sm:px-6) onto the homepage root
container and remove the horizontal padding from every section
component. Section content still aligns with the navbar/footer content
edges, but the gutter is now defined once instead of repeated per
section. Inner-element padding (tab buttons, visual internals) is
unchanged.
* style: left-align content sections on mobile + fix run-anywhere/o11y viz
- Left-align the centered content sections on mobile only (FeatureCardWide,
TweetWall heading, Frameworks, Run-anywhere heading/buttons), restoring
their centered layout at sm and up.
- Make the "Inspect every run" timeline span edge-to-edge by shifting its
gantt from a 14-col grid (content in cols 2-13) to a flush 12-col grid.
- Constrain the run-anywhere viz cluster to the code block width so the
provider cards (AWS/Docker/etc.) overlap behind the code block again.
* style: anchor run-anywhere provider cards to overlap the code block
Position the flanking provider-card groups relative to the centered
code block (right/left calc(50%+140px)) instead of the section edges,
so the cards sit behind and overlap the code block regardless of the
section width.
* style: make the reliability-as-code example fill its column to the right edge
Drop max-w-3xl mx-auto from the workflow/non-workflow code examples so
they fill the col-span-7 cell, aligning the code block's right edge with
the layout's right content edge (matching the tabs and other sections).
* style: split feature-card copy into a title + description
Break the AI SDK / durable-agents feature blurbs into a heading and a
separate muted description with a gap (matching the other sections)
instead of one inline paragraph, and drop the trailing periods from the
feature titles so they read as headings.
* update
* update
* style: give the tweet cards a bg-background-100 surface
* fix(swc-playground): pin monaco-editor to 0.55.1
The lockfile refresh resolved the unpinned `monaco-editor: "latest"` from
0.55.1 to 0.56.0, breaking the workflow-swc-playground Turbopack build.
0.56.0 rewrote its exports map to reroot subpaths under `esm/vs/`
("./*": "./esm/vs/*.js"). monaco-vim@0.4.4 deep-imports
`monaco-editor/esm/vs/editor/editor.api` and
`.../common/commands/shiftCommand`, which now map to
`esm/vs/esm/vs/...` — a path that does not exist. Under 0.55.1
("./*": "./*") both specifiers resolve to real files.
monaco-vim 0.4.4 is the latest published release, so pinning
monaco-editor is the only available fix.
* update
---------
Signed-off-by: christopherkindl <53372002+christopherkindl@users.noreply.github.com>
|
||
|
|
32ac8e73fd |
Fix Biome lint violations and add Biome CI check (#3222)
* Fix Biome lint violations and add Biome CI check Biome was not configured to respect .gitignore, so ~92% of the 13,355 reported diagnostics came from gitignored build artifacts. Enable VCS integration (useIgnoreFile), apply safe auto-fixes across the repo, fix the remaining mechanical errors by hand, downgrade judgment-call a11y / dangerouslySetInnerHTML rules to warnings, and add a 'biome ci' job to the Lint workflow so violations block PRs going forward. * Use an empty changeset (no behavior change, no release needed) |
||
|
|
aafc3fd7f4 | docs: fall back to first child page for sidebar folders without an index (#3009) | ||
|
|
21448a8ab3 |
chore(docs): update @vercel/geistdocs to 1.14.0 (#3002)
Co-authored-by: Peter Wielander <mittgfu@gmail.com> |
||
|
|
8a872529fe |
docs: make /worlds the canonical home for World docs (#2934)
* docs: make /worlds the canonical home for World docs The world pages (Local/Postgres/Vercel) and Building a World were duplicated inside the v4 and v5 docs trees while /worlds/[id] rendered the v4 copy — hiding v5-only content like multi-region and leaving two diverging sources of truth. - Move world docs to an unversioned docs/content/worlds/ collection (based on the v5 copies, with inline 4.x callouts for factory naming and 5.x-only env vars), rendered at /worlds/* - Add /worlds/building-a-world; flatten the docs Deploying section to a single intro page and drop its Rocket icon - Point every link, frontmatter ref, and worlds-manifest docs field at /worlds/*; add redirects for the removed v5 and building-a-world URLs - Keep world docs on agent-facing surfaces: search, llms.txt, sitemap.md/.xml, and .md exports now serve the worlds collection - Extend the docs link linter to validate worlds pages (with heading anchors) and their outgoing links Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * docs: version the world docs like the docs trees (v4/v5 switcher) Instead of a single unversioned copy, world docs now follow the same versioning strategy as the docs pages: content/worlds/v4 is served at /worlds/* (current) and content/worlds/v5 at /v5/worlds/*, restoring the original per-version content. Each world detail page (and Building a World) renders the docs version switcher — the worlds listing page has no natural home for it, so it lives on the world pages themselves. - Render-time href rewriting on v5 pages now covers /worlds/... links (shared rewriteHrefForVersion helper, also used by the v5 docs and cookbook routes), and the markdown-export rewrite does the same - v5 world pages are noindexed with a canonical to /worlds/<id>; community worlds stay unversioned (/v5/worlds/<id> redirects) - /v5/docs/deploying/world/* redirects now land on /v5/worlds/*; /v5/worlds and /v5/worlds/compare redirect to the unversioned pages - Link linter models the versioned worlds URL spaces (v5 pages resolve /worlds hrefs against the v5 collection); sitemap.md and the .md export routes cover /v5/worlds/* Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * docs: fix v4 multi-region anchor and tighten version-prefix matching Address PR review: - The v4 Deploying page linked /worlds/vercel#multi-region, but the Multi-region section only exists on the v5 world page; use the explicit cross-version /v5/worlds/vercel#multi-region link (this was the Docs Links CI failure) - rewriteHrefForVersion now uses the boundary-checked hasPathPrefix (shared leaf module lib/geistdocs/path-prefix.ts, also used by source.ts) instead of bare startsWith - buildVersionUrl's shared-route fast path is segment-based rather than substring includes() Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> --------- Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
aa93cc5e69 |
Migrate docs to package-backed geistdocs (#2222)
* Migrate docs to package-backed geistdocs * update agent install cmd on home page * add copy prompt component usage * update docs test for sitemap inclusion * cut unused components * address docs migration review feedback * address stale review feedback: geistdocs 1.8.2, version icons, cookbook prompts * drop Workflow from OSS products dropdown (self-link) * bump @vercel/geistdocs to 1.11.0 * fix: resolve pnpm-lock.yaml conflict marker from main merge --------- Co-authored-by: Peter Wielander <peter.wielander@vercel.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
5b7fa7cf15 |
chore(docs): update eve link (#2738)
eve homepage is now live, change the link from the docs to the homepage now, reflecting how the other OSS sites behave Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
04ee1ce31d |
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Swap the text-based eve placeholder for the real eve wordmark (hard-copied SVG from @vercel/geistcn-assets, themed via currentColor) and drop Streamdown so AI Elements is last. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Pranay Prakash <pranay.gp@gmail.com> |
||
|
|
6fad87b2a4 |
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Section index card grids (e.g. foundations) were hand-written and drifted from the sidebar (meta.json) and the actual pages. Make them derive from the fumadocs page tree (single source of truth) and add CI lint so the card grid and navigation can't fall out of sync again. - resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs routes (correct /docs vs /v5/docs URL spaces) - getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links - manualCards frontmatter opt-out for curated pages (source.config.ts) - checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve (dangling meta entries) in scripts/lint.ts - convert foundations + errors (drift fixes) and v5 observability to AutoCards - mark deploying + ai as manualCards (intentionally curated) - remove dangling meta entries: v4 cancellation (x2), root introduction (x2), v4/internal serializable-abort-controller Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5377e880c7 |
feat(docs): add eve and AI SDK to product switcher (#2543)
Wire the existing AI SDK logo into the OSS product switcher (above Flags SDK) and add a new eve entry (text wordmark + Beta badge, linking to eve.dev/docs) above it at the top of the list. Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
3229d20614 |
fix(docs): repair broken links, fix the link linter, and version-correct v5 Card + edit links (#2391)
* fix(docs): repair broken links and make the docs link linter actually validate The docs link linter (docs/scripts/lint.ts) had been silently passing everything since the app moved under app/[lang]/ (#552): the next-validate-link populate key 'docs/[[...slug]]' no longer matched the real route, and the unpopulated [lang] homepage route produced a fallback regex (^\/(.+)$) that matched every href. It also only scanned v4 content. - Rewrite lint.ts to build explicit v4/v5 URL spaces from both fumadocs sources (including cookbook URL variants, app routes, worlds pages, public/ assets, and next.config.ts redirects) and validate each version's content against version-correct render semantics. Also validate frontmatter related/prerequisites references (version-relative) and heading fragments. - Rewrite Card hrefs on v5 pages: the v5 routes rewrote inline markdown links from /docs/... to /v5/docs/... but Card renders its own Link, so Card hrefs escaped to the v4 routes and 404'd for v5-only pages (e.g. /v5/docs/observability linking to /docs/observability/attributes). - Fix all dead content links surfaced by the working linter (56 across v4+v5): nonexistent use-workflow/use-step/start API pages now point at foundations/workflows-and-steps and workflow-api/start, getStepMetadata path corrected, /docs/worlds/local → /worlds/local, dead changelog/ internal references removed or unlinked, retired common-patterns links point at the cookbook, and a dead #returnvalue anchor now targets #returns. - Add an index page for api-reference/workflow-errors (both versions), which was linked from the API reference landing page but had no page. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(docs): add version prefix to 'Edit this page on GitHub' links All "Edit this page on GitHub" links 404'd since the v4/v5 content split (#1948): page.path is relative to the per-version content dir, but EditSource built URLs against docs/content/docs/ without the v4/ or v5/ segment. Add a required version prop, passed from each page route. Incorporates #2120 by Luke Howard (@gldkhoward), rebased onto the v5 route changes from this branch. Fixes #2119. Co-authored-by: Luke Howard <dev@lukehoward.com.au> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
3cf0e33562 |
fix(docs): right-align sidebar folder carets consistently (#2377)
SidebarFolderTrigger renders a <button>, which shrink-to-fits its content, so the ms-auto chevron sat directly next to the folder name for folders without an index link (e.g. How it works, AI Agents, Testing). SidebarFolderLink renders an <a> that spans the full sidebar width, so its chevron was pushed to the right edge. Add w-full to both so every folder caret is right-aligned. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b9b121e636 | Hide flaky worlds indicators (#2000) | ||
|
|
e213447a64 |
Add Fantastic Four community worlds (#1964)
Register the Fantastic Four community world packages in the worlds manifest and show the Redis variants in the Embedded docs section. Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> Co-authored-by: Pranay Prakash <pranay.gp@gmail.com> |
||
|
|
c145bf56d9 |
[codex] Fix detached ArrayBuffer proxy DX (#1985)
* fix(world-local): explain detached ArrayBuffer proxy failures * fix(docs): make proxy handler anchor navigable * fix(docs): open accordions for hash links |
||
|
|
ea16d04599 |
docs: split v4/v5 content trees and fix version switcher end-to-end (#1948)
* docs: split v4/v5 content, fix version switcher end-to-end ## Content restructuring - Split `docs/content/docs/` into `docs/content/docs/v4/` and `docs/content/docs/v5/` so each version is a fully independent content tree with no shared-file coupling - v4 excludes the four pages that are v5-only (AbortController cancellation docs and the serializable-abort-controller internal page) - v5 retains all pages; `preRelease` frontmatter field removed (no longer needed now that each version is its own folder) - Removed `AbortController` / `AbortSignal` from v4 serialization page (section moved to v5 only) ## Fumadocs source - Added `v4docs` and `v5docs` as separate `defineDocs()` collections in `source.config.ts`; shared `docsSchema` (no more `preRelease` field) - `source.ts` exports both `source` (v4, `baseUrl: /docs`) and `v5Source` (v5, same base URL) ## Version routing - `version-source.ts` simplified: `filterPreReleaseFromNodes` and `isPreReleaseUrl` logic removed; v4 tree uses `source`, v5 tree uses `v5Source` + `rewriteNodeUrls` - v4 `page.tsx`: removed `preRelease` guard (v4Source has no such pages) - v5 `page.tsx`: uses `v5Source` for `getPage` / `generateStaticParams` / `generateMetadata`; `v5Link` wrapper rewrites `/docs/…` hrefs to `/v5/docs/…` so inline MDX links stay in the v5 context ## Versioned cookbook - Added `app/[lang]/v5/cookbook/` layout + page (mirrors v4 but uses `v5Source`, `rewriteCookbookUrlForVersion`, and `V5CookbookLink`) - `getCookbookTree` accepts a `versionPrefix` parameter; sidebar URLs are prefixed accordingly (`/v5/cookbook/…`) - `cookbook-tree.ts`: added `skipVersions?: string[]` per-recipe field for version-specific exclusions; `distributed-abort-controller` is marked `skipVersions: ['v5']` ## Version switcher — state & navigation - New `VersionProvider` context (`hooks/geistdocs/use-version.tsx`) backed by `localStorage`: URL is source of truth on versioned pages, `localStorage` carries the preference across non-versioned pages (cookbook overview, worlds, etc.) - `VersionSwitcher` uses `useVersion()` context instead of URL-only detection; now visible on all pages including cookbook - `DesktopMenu` and `MobileMenu` use `activeVersion` from context so the "Docs" and "Cookbook" navbar links resolve to the correct version prefix on every page - `buildVersionUrl` expanded to handle `/cookbook/…` paths alongside `/docs/…`; non-versioned routes (worlds, api) return unchanged - `switchVersion` does a `HEAD` probe before navigating; falls back to the versioned cookbook or docs home if the target page doesn't exist in that version (handles v4-only → v5 and v5-only → v4 cases) ## Cookbook content (v5) - Rewrote `agent-cancellation` recipe using a single `AbortController` pattern; removed Hard Cancellation vs Stop Signal two-approach comparison - Deleted `distributed-abort-controller` recipe from v5 (native `AbortController` serialization makes it unnecessary) - Removed references to distributed-abort-controller from `cookbook/index.mdx` and `common-patterns/timeouts.mdx` Co-authored-by: Cursor <cursoragent@cursor.com> * fix(docs): use abortSignal (not signal) in DurableAgent.stream() options Co-authored-by: Cursor <cursoragent@cursor.com> * fix(docs): update prepack scripts to use versioned content paths Content moved from docs/content/docs/ to docs/content/docs/v5/ on main (pre-release channel). Stable branch will use v4/ after backport. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
6c9c32e275 |
fix(docs): hide preview-only nav items in production (#1941)
The geistdocs facelift (#1666) dropped the VERCEL_ENV-based filter on nav items, so the "Internal" entry (preview: true) was visible on the production docs deployment. Restore the filter in the server-rendered Navbar and pass the filtered list to MobileMenu so both desktop and mobile honor it. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
aee56993c7 |
feat: serializable AbortController/AbortSignal (#1301)
* feat: add docs and test stubs for serializable AbortController/AbortSignal Adds documentation and test infrastructure for making AbortController and AbortSignal serializable across workflow and step boundaries. The feature uses a dual hook+stream backing: hooks for deterministic replay in the workflow context, streams for real-time propagation to running steps. Docs: - Cancellation guide (foundations) covering AbortSignal and run cancellation - How Cancellation Works (how-it-works) explaining hook+stream internals - AbortSignal.timeout() error page for the workflow VM restriction - Updated serialization docs with AbortController/AbortSignal section Tests (all .todo stubs for TDD): - VM behavior: AbortController API, static methods, hook integration - Step-side: stream reader setup, abort propagation, ops queue - Serialization round-trips: all boundaries, encryption, nested structures - Consistency: race conditions, partial failure, eventual convergence - E2E workflows: timeout, parallel, step-initiated, hook-triggered, replay Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use correct frontmatter type for error page Change type from "error" to "troubleshooting" to match the valid frontmatter schema used by all other error pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: address review feedback on cancellation docs - abort() in workflow does not synchronously update signal.aborted; instead it queues hook resumption and the replay handles state update - stream name and hook token are generated at serialization time (not deterministically in the workflow) and stored in the event log - use throwIfAborted() instead of manual signal.aborted checks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: document runtime change for processing abort queue items on completion The current runtime only processes invocation queue items on suspension. When abort() is called after the last suspension point and the workflow completes, the queue items are dropped with a warning. Document that the runtime needs to flush abort-related items on completion/failure too. Add test stubs for this behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: generalize queue processing on completion to all item types Processing pending invocations queue items on workflow completion/failure should apply to all queue item types (steps, hooks, waits, abort signals), not just abort-related ones. Update docs and tests accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: abort errors in steps are automatically wrapped in FatalError When a step throws due to an abort (AbortError from fetch, throwIfAborted, etc.), the error is wrapped in FatalError so the step skips retries. An abort is intentional cancellation, not a transient failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: remove contrived "aborting from within a step" example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add meaningful step-initiated abort example (quota monitor) Replace the contrived example with a watchdog pattern where a monitoring step polls an external condition and aborts parallel work when triggered. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: remove unnecessary "as const" from hook cancellation example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: implement serializable AbortController/AbortSignal Core serialization layer: - Add AbortController/AbortSignal to SerializableSpecial interface - Add reducers for all 4 contexts (external, workflow, step, common) - Add revivers for all 4 contexts with stream-backed propagation - Add reviveAbortController helper for step/external contexts - Guard instanceof checks for VMs without AbortController global Workflow VM: - New workflow/abort-controller.ts with createCreateAbortController factory - WorkflowAbortSignal class with hook-backed state - AbortSignal static methods (abort, any, timeout blocked) - Hook integration via invocations queue and events consumer Supporting changes: - Add ABORT_STREAM_NAME, ABORT_HOOK_TOKEN symbols - Add getAbortStreamId() for system stream namespace - Add isSystem, abortRequested, abortReason to HookInvocationQueueItem - Add isSystem to world Hook entity and events - Wrap AbortError in FatalError in step handler (skip retries) - Add AbortController/AbortSignal to Serializable type - Add observability revivers for abort types - Add isSystem to postgres schema and web-shared attribute panel All 454 existing tests pass with no regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: wire up AbortController in workflow VM and process queue on completion - Wire up AbortController/AbortSignal in workflow VM (workflow.ts) - Add abort processing to suspension handler (hook resume + stream write) - Process pending queue items on workflow completion (throw WorkflowSuspension instead of warning for actionable items) - Fix instanceof guards for non-function AbortSignal in VM - Update test to expect WorkflowSuspension for unawaited steps All 454 existing tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: implement tests and Request.signal serialization Tests (516 passing, 18 todo for integration tests): - 18 VM behavior tests (abort-controller.test.ts) - 18 step-side behavior tests (abort-controller-step.test.ts) - 4 consistency tests + 14 integration todos (abort-consistency.test.ts) - 14 serialization round-trip tests (serialization.test.ts) - 7 hook integration + 4 integration todos (step.test.ts) Request.signal serialization: - Add signal field to SerializableSpecial Request type - Include signal in Request reducer when present - Pass signal through in external and step Request revivers Fix workflow reviver for AbortController/AbortSignal: - Use plain objects instead of prototype-based stubs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: implement all remaining .todo test stubs Convert all 27 remaining .todo stubs to real implementations: - 14 consistency tests (race conditions, partial failures, queue processing) - 4 hook integration tests (suspension handler, hydration, eventual consistency) - 9 e2e tests (timeout, parallel, step-abort, hook-cancel, replay, external signal) All 558 tests pass, 0 todos remaining. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review comments + add changelog PR review fixes: - Move cancellation after streaming in foundations nav - Fix AbortSignal reducer to detect WorkflowAbortSignal via symbol - Guard AbortController reducer from matching AbortSignal objects - Add e2e tests: throwIfAborted, reason types, uncaught fetch AbortError Changelog: - Add hidden changelog section (not in sidebar, accessible via URL) - Add draft changelog entry for serializable AbortController/AbortSignal Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: show changelog in nav for preview deployments only - Add `preview` flag to nav items in geistdocs.tsx - Filter preview items in Navbar (server component) based on VERCEL_ENV - Show "Preview" badge on preview nav items in DesktopMenu - Changelog link visible in preview deployments and local dev only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: move preview badge from home page to navbar Move the PreviewBadge (with package tarball install modal) from the fixed bottom-right position on the home page to the navbar, so it appears on every page during preview deployments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: consolidate preview tools into single Internal page Replace separate Changelog nav item and PreviewBadge with a single "Internal" page that only appears in preview deployments: - Rename docs/changelog/ to docs/internal/ - Internal page includes preview package install commands and draft changelogs in one place - Nav shows "Internal" with Preview badge in preview/dev only - Remove PreviewBadge from navbar (now on the Internal page) - Add callout that page is preview-only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: use real deployment URLs on internal page + exclude from indexing - Add PreviewInstall component with copy-to-clipboard buttons using the actual VERCEL_URL (not placeholders) - Register PreviewInstallServer as MDX component for docs pages - Exclude /internal/ pages from sitemap.xml, sitemap.md, and llms.mdx - Add robots.txt Disallow for /internal/ paths Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add missing type declarations for docs code sample typechecking Add declare statements and @setup/@skip-typecheck annotations for undeclared functions in code samples (stepA, stepB, fetchData, cancellableStep, splitIntoChunks, processChunk). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add missing type declarations for all docs code samples Fix docs typecheck CI by adding declare statements and @skip-typecheck annotations for all undeclared function references across cancellation docs, error page, how-it-works page, and internal changelog. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: only suspend on completion for abort items, not all pending items The previous logic threw WorkflowSuspension for any pending queue item on completion (steps, waits, hooks). This broke fire-and-forget patterns like `void sleep('1d').then(...)` which intentionally leave a wait in the queue without awaiting it. Now only abort-related items (hooks with abortRequested) trigger suspension on completion. Other pending items get the original warning behavior — they may be intentional fire-and-forget operations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: all pending queue items are fire-and-forget on completion Remove special-case suspension for abort items on workflow completion. ALL pending queue items (steps, hooks, waits, abort signals) are now fire-and-forget when the workflow completes — they get warned about but don't block completion. This matches the existing behavior for fire-and-forget patterns like `void sleep('1d').then(...)`. Abort signals propagate through the normal suspension flow during the workflow (not at completion time). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve docs typecheck errors in code samples Move declare statements before imports to avoid TypeScript overload signature conflicts with auto-inferred imports. Add @skip-typecheck for conceptual snippets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: abort() in workflow updates signal.aborted synchronously abort() must update signal.aborted immediately so that: 1. Subsequent reads in the workflow see the correct state 2. Serialization captures aborted=true when passing signal to steps 3. Event listeners fire synchronously The hook resumption still happens via the suspension handler for durable event log recording. Both local state and durable state are now updated. Fixes e2e failures where steps received aborted=false for signals that were aborted before being passed to the step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update how-it-works to reflect synchronous signal.aborted update abort() now updates signal.aborted synchronously in the workflow. Update lifecycle diagram and remove outdated paragraph about signal not being updated synchronously. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: ensure abort listeners fire at deterministic point across replays On replay, hook_received is processed during event consumer subscription (at AbortController construction time), which is BEFORE the abort() call in the workflow code. If listeners fired during event processing, they'd fire at a different point than on first-run — breaking determinism. Solution: split abort into two phases: 1. _markAbortedFromReplay(): Sets signal.aborted=true (for reads/serialization) but does NOT fire listeners. Called by event consumer during replay. 2. abort(): Detects the replay flag and fires listeners at the call site. On first-run, fires listeners immediately as before. This ensures listeners fire at the abort() call site on BOTH first-run and replay, maintaining consistent ordering of side effects. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add replay ordering tests for interleaved hook scenarios Add 3 tests validating that abort listeners fire at the abort() call site on both first-run and replay, even when other hook events are interleaved in the event log. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: signal.aborted stays false until abort() is called for deterministic replay _markAbortedFromReplay no longer sets signal.aborted = true. Both aborted state and listener firing are fully deferred to abort(). This prevents if-checks on signal.aborted from taking different branches on first-run vs replay. Add deterministic branching test (unit + e2e): const controller = new AbortController(); if (controller.signal.aborted) { return 'was aborted'; // never taken } else { controller.abort(); return 'just aborted'; // always taken, both runs } Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add abort+hook ordering matrix e2e tests (4 combinations) Test all combinations of listener registration order and event trigger order to validate deterministic ordering across first-run and replay: 1. addEventListener first, abort() first 2. addEventListener first, resumeHook first 3. hook.then first, abort() first 4. hook.then first, resumeHook first Each test verifies that abort-listener fires synchronously at the abort() call site (immediately before 'after-abort' in the log), regardless of when the hook is resumed or when listeners are registered. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: simplify abort — event consumer calls _setAborted directly Remove the deferred _markAbortedFromReplay approach. The event consumer now calls _setAborted directly when hook_received is processed, which sets signal.aborted = true AND fires listeners at that point. This is correct because: - Cross-execution aborts (step/external): signal.aborted SHOULD be true on replay since the abort is a fact from a previous run. Listeners must fire so the workflow can react to the abort. - Same-execution aborts: abort() fires _setAborted synchronously. On replay, the event consumer fires it first, and abort() is a no-op. - The promiseQueue ensures listeners fire at the deterministic point matching the hook_received event's position in the event log. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: skip abort+hook ordering e2e tests pending full integration The 4 ordering matrix tests require the abort controller's internal system hook to be fully wired through the suspension handler. The hook creation timing interacts with the user hook lookup in getHookByToken. Skip until the full integration is complete. All 13 other abort e2e tests pass on CI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * handle dangling streams * fix postgres world * fix abort serialization bug * refactors * add drizzle migration file * fix tests * fix tests * replace setTimeout probe and any casts with typed abort internals Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * cover post-serialization abort and nested-in-Request reader cleanup Two leak paths the prior fix left uncovered: - External signal aborted after serialization: verifies the listener attached by reduceAbortWithListener actually fires and writes the abort packet once the caller aborts later. - Signal nested inside a Request: exposed a real leak. The Request constructor copies the signal to an internal AbortSignal, so the ABORT_READER_CANCEL symbol set by reviveAbortSignal never reached request.signal, and cancelAbortReaders' walker had no Request case so Object.values(request) returned []. Fixed both sides: - Request reviver copies abort-internal symbols via copyAbortInternals - Walker descends into Request.signal explicitly Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * add v4/v5 docs switcher and pre-release gating - Mark new abort-controller/cancellation pages with preRelease: true (cancellation, how-it-works/cancellation, abort-signal-timeout-in-workflow, serializable-abort-controller). preRelease is a new optional frontmatter field declared in source.config.ts. - lib/geistdocs/versions.ts: declarative version list (v4 Latest, v5 Pre-release) plus getVersionFromPathname and buildVersionUrl helpers used by the switcher. - lib/geistdocs/version-source.ts: filter preRelease pages out of the v4 sidebar tree; rewrite sidebar URLs to /v5/docs/* on v5 so links stay in the pre-release view. - components/geistdocs/version-switcher.tsx: dropdown at the top of the sidebar, styled after the ai-sdk.dev pattern (label + subtitle). - components/geistdocs/pre-release-banner.tsx: banner rendered above the docs layout on all /v5/docs/* routes, linking back to /docs/* (Latest). - app/[lang]/v5/docs: parallel route (layout + page) that reuses the existing docs rendering but keeps preRelease pages visible. - app/[lang]/docs/[[...slug]]: 404 direct access to preRelease pages on v4 so unreleased content is never reachable without the /v5 prefix. - next.config.ts: /v5/docs -> /v5/docs/getting-started mirror of the existing /docs -> /docs/getting-started redirect. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix version switcher URL when default locale is hidden buildVersionUrl assumed segment 0 was the locale, but next.js i18n middleware hides the default locale from the URL so usePathname() returns '/docs/...' rather than '/en/docs/...'. The old logic treated 'docs' as the locale and produced '/docs/v5/getting-started' (404) instead of '/v5/docs/getting-started'. Detect the locale by checking whether segment 0 is a known structural token ('docs' or 'v5') rather than by position, so the function works for both '/docs/...' and '/<locale>/docs/...' inputs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * match ai-sdk pre-release banner styling Filled sparkles glyph, blue tint on the message text, and a plain underlined "Go to ..." link in the foreground color instead of a bordered pill. Matches the ai-sdk.dev v7 banner reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * match ai-sdk switcher icons and banner link color - Switcher: colored rounded icon tile next to each version (orange tint for pre-release, blue for latest), matching the ai-sdk.dev dropdown. Uses a workflow glyph inside a tinted ring. - Banner link: blue text with a softer underline by default, deeper blue on hover. Replaces the foreground-colored link that didn't match ai-sdk's styling. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * use exact ai-sdk icons and darker banner link - Switcher tile: use the T-mark SVG and the bg-orange-100/border-orange-300 (pre-release) / bg-blue-100/border-blue-300 (latest) palette extracted from the ai-sdk.dev live markup, with matching dark-mode variants. - Pre-release banner sparkle: replaced the placeholder with the exact three-path geist sparkle used by ai-sdk. - Banner "Go to Latest" link: foreground color with a muted underline by default (same weight as ai-sdk's near-black link), underline intensifies on hover. The previous blue-600 was too light. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(docs): correct dark-mode colors for pre-release banner and version switcher The geistcn design-system palette inverts brightness semantics in dark mode (low indices = dim, high indices = bright) and remaps `blue-*` but not `orange-*`, so the previous token choices rendered as dim gray-blue text and a mid-bright blue icon inconsistent with the dropdown list. - Banner: use `dark:text-blue-900` for icon + label and switch the "Go to" link from `text-foreground` to the same blue (with a blue underline) so it reads as a single colored banner. - VersionSwitcher: move the text color onto the SVG itself so the `DropdownMenuItem` SVG-color override no longer hijacks the T color, and invert the dark blue palette (dark bg, light border, bright T) so the selected/trigger icon matches the list icon. - Active-row check icon: use green instead of `fd-primary` (which resolves to near-white in dark mode). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: add signal field to Request serializable type The merge from main moved the Request type into serialization/types.ts without carrying over the signal?: AbortSignal field, causing the abort-related reducers/revivers in serialization.ts to fail typecheck. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: address review feedback on abort serialization - Dedupe abort listener attach in serialization reducers via marker symbol (prevents N-listener leak when one controller is serialized to N steps, which would double-close the backing stream on abort). - Replace token.replace('abrt_', '') string-surgery in suspension-handler by storing streamName directly on HookInvocationQueueItem at the point where it's already known (workflow/abort-controller.ts construction). - Document the deliberate sync-vs-microtask listener divergence in the workflow VM (replay determinism > spec parity inside the VM). - Add changeset noting the AbortError -> FatalError behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: correct cancellation docs against implementation - Remove the contradictory paragraph claiming signal.aborted is not set synchronously when abort() is called in the workflow. The implementation sets it sync via _setAborted; replay re-applies via the events consumer. - Reword the "Stream Succeeds, Hook Fails" recovery — there's no in-process retry loop on the step-side resumeHook call; convergence comes from the next replay re-reading the stream. - Tighten Request.signal handling: plain non-aborted native signals are intentionally dropped to avoid minting stream infra for auto-generated Request signals; only already-aborted or workflow-tagged signals are forwarded. - Replace the wrong "Pending queue items processed on completion" bullet with an accurate fire-and-forget note matching the warn-only behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: DOMException serialization (replace broken isNativeError guard) DOMException is `instanceof Error` in Node but does NOT pass `types.isNativeError()` — the existing reducer's first guard was `isNativeError(value)`, so DOMException never matched. Devalue then fell through to its arbitrary-POJO failure path. This surfaced as a real bug for AbortController/AbortSignal: when abort() is called with no argument, native AbortController synthesizes a default DOMException as signal.reason. Returning that signal's reason from a step (e.g. `{aborted, reason: signal.reason}`) crashed step return-value serialization. Replace the guard with a constructor-name check (cross-VM safe; same pattern used elsewhere for matching Error subclasses across realms). Also fixes 7 pre-existing DOMException tests in serialization.test.ts that were previously failing on main. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: drain pending queue items on workflow completion End-of-run now goes through the same suspension handler that processes a real suspension. Previously, items left in the invocations queue when the workflow function returned (or threw) were dropped with an "uncommitted operation" warning — `controller.abort()` called as the last statement of a workflow never actually propagated. Concretely fixes: - Abort hooks now write hook_received + stream packet so in-flight steps on other compute instances see signal.aborted=true and bail out. - Unawaited hooks are created (so external callers can resume them). - Unawaited steps and sleeps are queued (will execute / fire later). Strengthens abortTimeoutWorkflow's test to inspect the event log for the hook_received event — the original assertion only verified the workflow VM's local signal.aborted, which was set synchronously by the abort() call regardless of whether propagation actually happened. The strengthened test fails on main and passes after this commit. Drops the warnPendingQueueItems warning entirely. Drain failures are swallowed so the workflow's own outcome (return value or thrown error) remains the source of truth for the run's terminal state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: cover the deserialized AbortSignal listener path with an in-flight fetch The existing abort tests exercised either the polled `signal.aborted` read path (longStep busy-wait) or the already-aborted-before-fetch path. Nothing exercised the live listener path: signal starts non-aborted, step kicks off a fetch against a slow endpoint, abort fires while fetch is awaiting the response, and fetch's internal `signal.addEventListener('abort', …)` listener cancels the in-flight HTTP request. The pre-existing `fetchWithSignal` helper step was orphaned — defined but not referenced by any workflow. Wires it into a new `abortFetchInFlightWorkflow` that races a 30s fetch against a 2s sleep, aborts when the sleep wins, and returns the step's catch-path result. The test asserts both `winner=timeout` and `fetchResult.aborted=true`, which together prove fetch saw the cancellation mid-flight (the natural-completion path would set ok=true,aborted=false). Adds a local /api/delay endpoint to the nextjs-turbopack workbench so the test doesn't depend on an external service. Honors the request's own AbortSignal so cancelled connections close immediately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: extend abortFromStepWorkflow to verify in-flight sibling cancellation The original test only asserted that the workflow VM's signal saw aborted=true after a step called controller.abort(). It didn't actually verify that another in-flight step received the cancellation through the backing stream — those two paths are different (workflow VM signal updates via the hook event; sibling-step propagation runs through the live stream packet). Restructure the workflow to run longStep (a 30s polling loop on signal.aborted) in parallel with abortFromStep (now sleeps 1s, then aborts). The new assertion expects longStep.result === 'aborted' — proving it exited via the abort branch within ~1.5s, NOT ran to its 30s natural completion. Returning 'completed' would mean realtime cross-step cancellation is broken. abortFromStep gained an optional delayMs parameter so it can be sequenced against a sibling without an out-of-band sleep. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: dehydrate abort stream packets via the same machinery as hook events The abort stream packet was being encoded with bare `JSON.stringify({reason})` on the writer and decoded with `JSON.parse(text).reason` on the reader. That codec drops `undefined` (so a reason-less abort wrote literally `{}` and the observability UI showed an empty stream), and doesn't handle DOMException or any other type the rest of the codebase serializes via devalue+reducers. Switch all three sites — suspension-handler workflow-side write, patched abort step-side write, and `setupAbortStreamReader` — to use `dehydrateStepArguments`/`hydrateStepArguments`. Now the `reason` round-trips with full type fidelity (DOMException, custom errors, encrypted payloads), matching what the hook event payload already does. The suspension handler literally reuses the same dehydrated bytes for the event and the stream so they're guaranteed identical. Encryption key threading: - Suspension handler: `encryptionKey` was already in scope. - Patched abort: read from `contextStorage.getStore()?.encryptionKey` (set by the step handler before invoking the deserialize chain). - Reader (`setupAbortStreamReader`): read from `contextStorage.getStore()?.encryptionKey` for the same reason; falls back to `undefined` when called outside step context (the hydrate path is key-tolerant). On-disk verification: - Before: chunk for `controller.abort()` (no reason) was `00 7b 7d` — 3 bytes, the literal JSON `{}`, no reason carried at all. - After: chunk is `00 64 65 76 6c [{"aborted":1,"reason":2},true,"test"]` — 43 bytes, devalue-flat-encoded with the reason intact. Updated the existing stream-reader unit test to encode its mock payload through the same dehydrate path so the reader can decode it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: cover addEventListener, mid-flight throwIfAborted, and step-initiated determinism The polled-`signal.aborted` path was the only abort consumption pattern exercised end-to-end. Three new e2e tests fill the gaps: - **abortListenerWorkflow** — `signal.addEventListener('abort', cb)` firing on the deserialized step-side signal. Distinct from abortFetchInFlightWorkflow which only proves it indirectly through fetch's internal listener; this one verifies user-attached listeners directly. Step resolves with via:'listener' if propagation worked, via:'timeout' on a 30s safety timeout if it didn't. - **abortThrowIfAbortedMidFlightWorkflow** — throwIfAborted() in a polling loop, not just at step entry. The existing abortThrowIfAbortedWorkflow only covers the synchronous-throw case on a pre-aborted signal. This one starts the signal non-aborted, polls throwIfAborted every 500ms, and aborts from a sibling step after 1s. Verifies the DOMException propagates as FatalError (no retries) when fired mid-flight. - **abortDeterministicBranchFromStepWorkflow** — counterpart to abortDeterministicBranchWorkflow, but with the abort source being a step (via the patched abort() path / hook event) instead of the workflow body. Both branch-reads MUST take the same path on every replay. Uncovered a real semantic: signal.aborted reflects step-initiated aborts only after the next promise-queue checkpoint (sleep, step await, etc.) since _setAborted is chained on promiseQueue. The test inserts the required sleep('1s') checkpoint and asserts both pre and post values. Helper steps factored: stepWaitingOnAbortListener and stepPollingThrowIfAborted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: drop signal.aborted shortcut in stepWaitingOnAbortListener The shortcut would have masked a regression in the addEventListener-on-an- already-aborted-signal contract. Per the AbortSignal spec, calling addEventListener('abort', cb) on an aborted signal fires the callback (on a microtask), so user code that subscribes via the listener path alone — the common pattern — depends on it. Test the contract directly: rely solely on the listener resolving the promise. If addEventListener-on-aborted ever silently breaks, this test now reports via:'timeout' instead of paving over it with a fast-path that reads signal.aborted directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: add DOMException reviver to observabilityRevivers so the o11y UI hydrates abort reasons The observability UI (and CLI) hydrates step IO via `observabilityRevivers`, which had no `DOMException` entry. When a step returned a value containing a DOMException (typically `{aborted, reason: <DOMException>}` — synthesized by native AbortController when abort() is called with no reason), devalue's `parse` would throw on the `["DOMException", ...]` tag, `hydrateStepIO`'s try/catch would swallow it, and the raw devalue-flat string survived to the UI. The user-visible result was step Output showing literal text like: devl[{"aborted":1,"reason":2},true,["DOMException",3]...] instead of a JSON viewer with a proper DOMException card. Add the reviver. Reconstruct as a real DOMException when the global is available (modern browsers + Node 18+, where the o11y consumers run), falling back to a name-tagged Error otherwise. Preserves message/name/ stack/cause for display. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: cover the external-signal-aborted-in-flight propagation path The existing abortExternalSignalWorkflow only validates a static read of an already-aborted signal — it tells us nothing about whether an abort that fires AFTER serialization actually propagates from the caller process, through the listener attached at workflow-start, into the backing stream, and out into the deserialized signals on the in-flight step compute. Add abortExternalSignalInFlightWorkflow that takes a non-aborted signal and runs two parallel consumption patterns against it: longStep (polling signal.aborted) and stepWaitingOnAbortListener (addEventListener path). The test creates a fresh AbortController, calls start() with its non-aborted signal, and aborts the source controller 1.5s later via setTimeout — well after both steps are mid-flight on their compute instances. Both consumers must see the cancellation: - pollResult === 'aborted' (NOT 'completed' — that would mean longStep ran the full 30s without ever seeing signal.aborted=true) - listenerResult.via === 'listener' (NOT 'timeout' — that would mean the addEventListener callback never fired) This exercises the longest end-to-end abort path in the codebase: caller-process AbortController → serialization-time listener → backing stream → step compute → deserialized signal → (poll OR addEventListener) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(test): use httpbin.org/delay for abortFetchInFlightWorkflow The previous setup added a /api/delay route to workbench/nextjs-turbopack to give the test a slow endpoint to fetch against. That made the workflow fail in CI on every other workbench (nextjs-webpack, astro, sveltekit, …) since the route only existed on one of them — fetch returned 404 and the test failed within 1s instead of taking the expected ~3s. Switch to httpbin.org/delay/30, the same external-service pattern used by other e2e workflows in this file (jsonplaceholder, example.com). Removes the per-workbench dependency. Drops the now-unused deploymentUrl argument from the workflow signature and test call site. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: fix serialization page — drop duplicate header, move AbortController section Two issues on the serialization foundations page: 1. `## Pass-by-Value Semantics` appeared twice. The second occurrence had no body, which rendered as an orphaned heading just above the AbortController section in the docs preview. 2. `## AbortController & AbortSignal` was at the bottom of the page, after `## Custom Class Serialization`. It belongs above the custom-class section so the standard serializable types are grouped together before the advanced topic. Removes the empty duplicate; relocates the AbortController section to sit between Request & Response and Custom Class Serialization. No content changes inside the section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: note that run.cancel() is the same as the observability Cancel button The Run Cancellation section showed the programmatic path but didn't tie it back to the UI. Add a callout: calling run.cancel() is the same action as clicking the Cancel button on a run in the observability UI — both produce identical run_cancelled events. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: cover AbortSignal.any in both workflow VM and step contexts Two distinct paths: the workflow VM ships its own AbortSignal.any impl in workflow/abort-controller.ts (composes WorkflowAbortSignals via listeners, no stream/hook backing on the composite), while steps use the native Node implementation over deserialized signals. Neither was tested. abortAnyInWorkflowWorkflow exercises the VM impl directly: creates two controllers, composes their signals via AbortSignal.any, aborts one, and asserts the composite reflects the abort synchronously without any stream round-trip. Also asserts the other source signal is unaffected so a mass-abort regression would surface here. abortAnyInStepWorkflow exercises the longest end-to-end path that uses AbortSignal.any: source controller is aborted by a sibling step, abort flows through the workflow's VM, then the backing stream, into the step's deserialized signal, into the AbortSignal.any composite, into the user's listener. Returning via:'timeout' instead of via:'listener' would mean a break anywhere on that chain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Update .changeset/fix-dom-exception-serialization.md Co-authored-by: Peter Wielander <mittgfu@gmail.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * Update .changeset/serializable-abort-controller.md Co-authored-by: Peter Wielander <mittgfu@gmail.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * Update .changeset/drain-pending-queue-on-completion.md Co-authored-by: Peter Wielander <mittgfu@gmail.com> Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> * docs(errors): match slug-as-title convention + simplify the timeout example Two toolbar-comment fixes on the abort-signal-timeout-in-workflow error page: 1. The page title was Title Case ("AbortSignal.timeout() in Workflow") while every other page in docs/content/docs/errors/ uses the kebab-case slug as the title (e.g. timeout-in-workflow, fetch-in-workflow, workflow-not-registered). Match the convention. 2. The recommended replacement for AbortSignal.timeout() was a Promise.race that wrapped the abort + null sentinel + custom Error throw. Boil it down to the much simpler: const controller = new AbortController(); void sleep("10s").then(() => controller.abort()); return await fetchData(controller.signal); If fetchData finishes within 10s you get the response; if not, the timer fires controller.abort(), fetch rejects with AbortError, and the step's failure propagates to the workflow as a FatalError (no retries). Same observable behavior, no Promise.race scaffolding. Adds abortVoidSleepTimeoutWorkflow + matching e2e test that exercises this exact pattern end-to-end so the doc example is verified runnable (not just pseudocode). Asserts the fetch is cancelled mid-flight by the timer, returning aborted=true,ok=false from the step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Signed-off-by: Pranay Prakash <pranay.gp@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Karthik Kalyanaraman <karthik.kalyanaraman@vercel.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Peter Wielander <mittgfu@gmail.com> |
||
|
|
03dfab35e7 | Updated Workflow Trace viewer (#1454) | ||
|
|
64c66d211e |
docs(cookbook): rewrite core recipes, dedupe, and reorder sidebar (#1850)
* fix(docs): highlight active top-bar nav item and drop duplicate keys Match the current pathname (accounting for the hidden default locale) and forward an `active` prop to the Radix NavigationMenuLink so the selected top-bar item stays highlighted. Also remove module-level `key` props from the intro Loading/Success/Error indicators — they fired React's duplicate-key warning whenever two lines shared a state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * update saga cookbook docs with adaptation guidance and streaming example Made-with: Cursor * docs(cookbook): rewrite core recipes, dedupe, reorder sidebar Pass over the cookbook focused on correctness, concrete examples, and tighter information architecture. Rewrites: - Saga / Batching / Scheduling: concrete use cases (order fulfillment, CSV import, cancellable drip campaign); added "how it works" + "adapting" sections. - Durable Agent / Human-in-the-Loop / Stop Workflow: fixed broken patterns (tool invocations don't stream before return; prepareStep flag checks never fire); canonical single example per page. - AI SDK integration: refocused from DurableAgent showcase to streamText(); added multi-turn session pattern with durable stream slicing, ai-sdk.dev deep links, and a pitfalls section. - Sandbox integration: rewrote around the real @vercel/sandbox SDK; flagship pattern is one workflow run = one persistent sandbox session that outlives the 5-hour VM cap via snapshot rotation. - Chat SDK integration: full rewrite — previous page documented AI SDK's useChat, not chat-sdk.dev. New page covers durable chat sessions, Mermaid flowchart, and cross-SDK serialization. - Publishing Libraries: swapped ASCII tree for Fumadocs <Files> (font-independent); corrected isomorphic guidance ("use workflow" / "use step" are safe no-ops when SWC plugin doesn't process them); added Mux AI and World ID adopter examples with canonical links. Deletions (redundant or flawed): - Fan-Out, Conditional Routing (covered by Batching / not a pattern). - Tool Streaming, Tool Orchestration (covered by foundations/streaming and ai/defining-tools). - Durable Objects (hook-in-loop bug; framing doesn't hold up). - Custom Serialization, Isomorphic Packages (merged into foundations/serialization and publishing-libraries respectively). Sidebar restructure: - Reordered: Overview -> Agent Patterns -> Common Patterns -> Integrations -> Advanced (Agent Patterns leads since it drives most new-visitor traffic). - Moved Child Workflows + Distributed Abort Controller from Common Patterns to Advanced (composition / coordination concerns, not common reliability recipes); permanent redirects added in next.config.ts. Made-with: Cursor * docs(cookbook): rename Agent Stop Signal → Agent Cancellation, migrate common patterns The agent cancellation page now covers two named patterns — Hard Cancellation via getRun(runId).cancel() and Stop Signal via a hook + Promise.race — so the prior "Agent Stop Signal" title biased toward only one of them. Rename to the broader noun phrase and update the intro, description, and section heading to frame both approaches equally. Also migrate all patterns from foundations/common-patterns into dedicated cookbook recipes (timeouts, sequential-and-parallel, workflow-composition) and remove the foundations page. Permanent redirects added for the prior URLs (stop-workflow, agent-stop-signal, foundations/common-patterns) so no inbound link breaks. Made-with: Cursor * docs(cookbook): fix CI typecheck failures on three snippets - publishing-libraries.mdx: the second processPayment snippet uses getWorkflowRunId() defined in the prior block. Each block is type-checked independently, so add @skip-typecheck (matches the existing pattern in this file). - ai-sdk.mdx: the "snapshot tailIndex first" pitfall is a fragment referencing probe / turnHook / run / text from the surrounding multi-turn pattern. Add @skip-typecheck. - chat-sdk.mdx: the [platform] webhook route used Next.js 15 typegen (RouteContext<"/api/webhooks/[platform]">), which isn't part of the docs-typecheck environment. Switch to the manually-typed { params }: { params: Promise<{ platform: string }> } form — still fully supported by Next.js 15+ and doesn't depend on .next/types. Made-with: Cursor --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f102ed925d |
Add Python SDK beta documentation page (#1775)
* feat: add Python SVG icon and related documentation Slack-Thread: https://vercel.slack.com/archives/C0AG7R4PU22/p1776354109663229?thread_ts=1776354109.663229&cid=C0AG7R4PU22 Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: reintroduce Python SDK card in getting-started guide Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: add beta badge to Python SDK documentation sidebar item Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: enhance sidebar item with badge and layout update Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: refactor sidebar item badges to use array and function for mapping Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: add Python getting started guide card in beta Added a new card for the Python getting started guide with a beta badge. Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: simplify description of Workflow Python SDK Updated the description for clarity and conciseness. Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * feat: enhance Python SDK documentation and examples Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> * fix: update Python SDK documentation link for language parameter Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> --------- Co-authored-by: v0 <v0[bot]@users.noreply.github.com> Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com> |
||
|
|
173756dc4d |
[docs] Rename workflowdevkit to workflowsdk and useworkflow.dev to workflow-sdk.dev (#1759)
* [docs] Rename workflowdevkit references to workflowsdk * [docs] Rename useworkflow.dev to workflow-sdk.dev * [chore] Add changeset for domain rename * [docs] Revert sitemap rewrite to useworkflow.dev (crawled-sitemap not yet available for new domain) |
||
|
|
6fba441999 |
[docs] Remove performance section on worlds pages (#1753)
Co-authored-by: Peter Wielander <mittgfu@gmail.com> |
||
|
|
c1405fbf08 |
Fix "Edit this page on GitHub" link path (#1750)
* feat: add redirect rule to strip.md extension from routes Added a new redirect to remove.md extension from any route. Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1776281595825439?thread_ts=1776281595.825439&cid=C09125LC4AX Co-authored-by: Mitul Shah <19615826+mitul-s@users.noreply.github.com> * feat: update GitHub edit URL path for Geistdocs component Updated GitHub edit URL to correct directory structure for documentation files. Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1776281595825439?thread_ts=1776281595.825439&cid=C09125LC4AX Co-authored-by: Mitul Shah <19615826+mitul-s@users.noreply.github.com> * Update next.config.ts * Fix URL path in EditSource component Signed-off-by: Mitul Shah <mitulxshah@gmail.com> --------- Signed-off-by: Mitul Shah <mitulxshah@gmail.com> Co-authored-by: v0 <v0[bot]@users.noreply.github.com> Co-authored-by: Mitul Shah <19615826+mitul-s@users.noreply.github.com> |
||
|
|
f26db3416f |
Add command-prompt component to docs (#1733)
* [docs] Add command-prompt component Port the command-prompt compound component from vercel-marketing for use on the workflow docs/landing page. Replaces geist icon imports with hard-copied SVG fallbacks and uses the local cn() utility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * [docs] Replace hero CTA with command-prompt component Swap the "Get Started" button and inline `npm i workflow` copy block for the CommandPrompt compound component, matching the vercel.com/workflow hero. Shows "For humans" / "For agents" tabs with animated copy-to-clipboard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * [docs] Fix icon alignment and add missing font utilities - Remove conflicting p-3.5 on copy button (was larger than w-6 h-6 container) - Use size-8 for the copy button hit target with flex centering - Remove geist-specific -mt-0.5 hack on check icon - Add text-label-14-mono and text-label-16-mono utility classes to match geist DS typography tokens used by the command-prompt component Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * [docs] Fix copy button alignment in command-prompt - Use size-8 instead of size-6 + p-3.5 for proper icon centering - Both icon spans use absolute + flex centering - Remove -mt-0.5 geist-specific hack on check icon - Nudge copy button 2px right for optical alignment Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * DCO Remediation Commit for christopherkindl <53372002+christopherkindl@users.noreply.github.com> I, christopherkindl <53372002+christopherkindl@users.noreply.github.com>, hereby add my Signed-off-by to this commit: |
||
|
|
80595e6463 |
[home][docs] migrate to new geistdocs facelift (#1666)
* fix: migrate to new facelift * add: max-w- for footer * update * DCO Remediation Commit for christopherkindl <53372002+christopherkindl@users.noreply.github.com> I, christopherkindl <53372002+christopherkindl@users.noreply.github.com>, hereby add my Signed-off-by to this commit: |
||
|
|
31bc57e513 |
Add encryption documentation and world features manifest (#1432)
* Add encryption documentation and world features manifest - Add encryption.mdx under How it Works explaining end-to-end encryption - Add features array to worlds-manifest.json (encryption for Vercel World) - Display encryption support in WorldDetailHero and WorldCardSimple - Add cross-references from Vercel World and Observability pages * Derive WorldFeature type from const array * Address review feedback: simplify key explanation, show 'No' for missing encryption, fix tooltip |
||
|
|
42361d651b |
Add Fluid compute warning callout across deployment docs (#1216)
Signed-off-by: John Lindquist <johnlindquist@gmail.com> Co-authored-by: Peter Wielander <mittgfu@gmail.com> |
||
|
|
963a5e904e |
[docs] Split the Worlds page into sections (#1156)
* [docs] Split the Worlds page into sections Signed-off-by: Peter Wielander <mittgfu@gmail.com> * Wording Signed-off-by: Peter Wielander <mittgfu@gmail.com> * Update text Signed-off-by: Peter Wielander <mittgfu@gmail.com> * remove benchmark numbers Signed-off-by: Peter Wielander <mittgfu@gmail.com> --------- Signed-off-by: Peter Wielander <mittgfu@gmail.com> |
||
|
|
6da8e2358b |
Update Docs (#1028)
* Remove math and mermaid * Add alternates |
||
|
|
2cc8c3dc9c |
Update docs (#1010)
* Run update script * Update deps * Restore code block modifications * Reapply navbar patch * Restore custom proxy config * Add md-metadata * Add new frontmatter |
||
|
|
6ae65f0ed0 | [core] Follow up fixes for v1 compat (#907) | ||
|
|
4f68877fbe |
fix(docs): align header nav responsive breakpoint with mobile menu (#906)
* fix(docs): align header nav responsive breakpoint with mobile menu The desktop navigation links (Docs, Worlds, Examples) and search button were using `xl:flex` (1280px) while the mobile hamburger menu used `md:hidden` (768px). This created a gap between 768px-1280px where neither the nav links nor the hamburger menu were visible. Changed both to use `md:flex` so the navigation is visible at the same breakpoint where the mobile menu button hides. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): add top-level nav links to mobile sidebar menu The mobile hamburger menu only showed the docs table of contents. Now it also includes the top-level navigation links (Docs, Worlds, Examples) at the top of the sheet with a border separator. This ensures all navigation is accessible at mobile viewports. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
9ec21584d6 | Update docs template (#552) | ||
|
|
4d7badce87 |
docs: URL in docs was missing the docs/ prefix, 404 errors (#852)
Signed-off-by: voyager14 <21mh124@queensu.ca> |
||
|
|
243bf8f50d |
docs: rename Control Flow Patterns to Common Patterns and add new content (#846)
* feat: improve world page metadata and add dynamic OG images
- Update title format to '{Name} World | Workflow DevKit'
- Update worlds index page title to 'Worlds | Workflow DevKit'
- Improve world descriptions in worlds-manifest.json for better SEO
- Add dynamic OG image generation at /worlds/[id]/og
- Add openGraph and twitter metadata to world detail pages
* fix: use opengraph-image.tsx file convention for dynamic OG images
- Replace route-based og/route.tsx with opengraph-image.tsx file convention
- Remove runtime = 'edge' to allow generateStaticParams for static generation
- Simplify page.tsx metadata (Next.js auto-detects opengraph-image.tsx)
* docs: rename Control Flow Patterns to Common Patterns and add new content
- Rename page from control-flow-patterns to common-patterns
- Add redirect for old URL to prevent broken external links
- Add new Timeout Pattern section (Promise.race with sleep)
- Add new Workflow Composition section (direct await vs background execution)
- Implement @setup comment marker to hide type declarations in code examples
- Update navigation and references to new page name
* docs: move Full Example section after Parallel Execution
The Full Example only demonstrates sequential and parallel execution,
so it should come before the new Timeout and Workflow Composition patterns.
* fix: use useLayoutEffect to prevent flash of @setup lines in code blocks
* docs: remove incorrect retry/failure handling guidance from workflow composition
|
||
|
|
8a146a5bb1 |
docs: revamp World documentation pages (#763)
* docs: revamp World documentation pages with new structure and design
- Add dedicated world detail pages at /worlds/[id] with MDX-driven content
- Create WorldDetailHero, WorldDetailToc, WorldTestingPerformance components
- Add benchmark history charts and test summary links
- Rewrite local-world, postgres-world, and vercel-world MDX with cleaner structure
- Use h3 headings for configuration options instead of tables/accordions
- Add WorldDataProvider context for passing world data to MDX components
- Add example field to worlds-manifest for linking to example repos
- Update worlds index page design
* fix: update worlds page meta title and description
* feat(docs): improve globe backdrop responsiveness and positioning
- Globe now scales with container width up to 1200px max
- Increased opacity from 20% to 30% for better visibility
- Positioned globe 30% down to show north pole behind header
- Globe component now auto-sizes based on container width
* fix(docs): add light mode support for globe backdrop
* feat: improve world page metadata and add dynamic OG images
- Update title format to '{Name} World | Workflow DevKit'
- Update worlds index page title to 'Worlds | Workflow DevKit'
- Improve world descriptions in worlds-manifest.json for better SEO
- Add dynamic OG image generation at /worlds/[id]/og
- Add openGraph and twitter metadata to world detail pages
* fix: use opengraph-image.tsx file convention for dynamic OG images
- Replace route-based og/route.tsx with opengraph-image.tsx file convention
- Remove runtime = 'edge' to allow generateStaticParams for static generation
- Simplify page.tsx metadata (Next.js auto-detects opengraph-image.tsx)
* docs: improve worlds page UI and restructure deploying section
- Fix globe visibility in light/dark mode
- Fix tooltip positioning on mobile breakpoints
- Remove redundant Documentation button for community worlds
- Add missing pages to Foundations index (streaming, serialization, idempotency)
- Restructure deploying section with new index and building-a-world guide
- Restore original MDX content for official worlds (local, vercel, postgres)
- Auto-expand sidebar folders when child page is active
* docs: simplify worlds page footer sections
* docs: move last updated section under worlds grid
* fix(docs): fix broken links and skip typecheck for interface definitions
- Fix /docs/deploying/world link to /docs/deploying/building-a-world
- Fix /docs/deploying#what-are-worlds invalid anchor to /docs/deploying
- Add @skip-typecheck markers to interface definition code blocks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): address PR review feedback
- benchmark-history/route.ts: Add error handling for JSON parsing,
distinguish 404s from actual errors
- Globe.tsx: Fix hydration mismatch by deferring theme-dependent
rendering until component is mounted
- sidebar.tsx: Improve path check robustness for active child detection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
|
||
|
|
dc44dab49d | Biome config tweaks and fixes applied (#741) | ||
|
|
3f0a2e76d2 |
Bring back agent sitemap code (#665)
Original PR #108 This was deleted in a bad merge here https://github.com/vercel/workflow/commit/c0991b4ff795687bb477e96f6b4261a2c8a5bc61#diff-4f67490b6b20a5606964421a564836c3033f0ff2b0d90a41fe8822001d217f20 Also introduces proper canonical URLs and alternates for the MD responses. Signed-off-by: Malte Ubl <malte.ubl@gmail.com> |
||
|
|
220a6d40f3 | fix (#521) | ||
|
|
18610cd34a |
fix: docs theming (#520)
* fix: index frameworks comp * fix: active theming * fix background theming docs * rename og folder * remove og |
||
|
|
5c1c31db6f | [docs] Guide on writing durable agents (#443) | ||
|
|
5dd15452cd |
Test and benchmark community worlds against e2e tests (#482)
* Add new github workflow * Enable pull_request trigger for community worlds workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add community worlds manifest and generation scripts - Add community-worlds.json manifest as single source of truth - Add scripts/generate-community-worlds-workflow.mjs to generate CI workflow - Add scripts/generate-community-worlds-docs.mjs to generate docs section - Update aggregate-benchmarks.js to load community worlds dynamically - Add pnpm generate:community-worlds script - Update docs/deploying/world/index.mdx with community worlds The manifest-based approach allows: - E2E tests to be auto-generated from the manifest - Benchmark aggregation to include community worlds - Docs to stay in sync with tested worlds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix YAML syntax error - quote strings starting with @ The @ symbol has special meaning in YAML, so package names like @workflow-worlds/turso need to be quoted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix Redis health-cmd quoting, remove unpublished starter world - Quote health-cmd when it contains spaces (fixes Docker arg parsing) - Remove @workflow-worlds/starter as it's not published to npm 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add benchmarks and summary job for community worlds - Add build job to share artifacts between benchmark jobs - Add benchmark jobs for Turso, MongoDB, and Redis worlds - Update summary job to show both E2E and benchmark status matrix - Add left border/indent to sidebar child items for visual hierarchy - Update workflow generator to support benchmark generation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Reuse build artifacts for E2E tests E2E jobs now depend on the shared build job and download artifacts instead of rebuilding packages from scratch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add Worlds Ecosystem dashboard to docs - Create worlds-manifest.json with official and community worlds - Add aggregate-worlds-data.mjs script for processing E2E and benchmark results - Create WorldsDashboard, WorldCard, and BenchmarkChart components - Add /docs/worlds page showing compatibility status and performance - Include sample data for development The dashboard shows: - E2E test progress per world (pass/fail/skip counts) - Benchmark performance comparison across all worlds - Filter by official vs community worlds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix CI to output JSON test results and add Jazz world - Update workflow generator to output JSON test results from vitest - Upload E2E results as artifacts for parsing in summary job - Summary job now shows actual pass/fail/skip counts per world - Add Jazz world to worlds-manifest.json (requires external credentials) - Add update-worlds-status.yml workflow to auto-update dashboard data - Update TypeScript types to support null lastRun and metrics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Refactor community worlds to use reusable workflows Instead of a generated workflow file, integrate community world testing directly into tests.yml and benchmarks.yml using reusable workflows. - Add reusable workflows for E2E tests: e2e-community-world.yml (no services), e2e-community-world-mongodb.yml, e2e-community-world-redis.yml - Add reusable workflows for benchmarks: benchmark-community-world.yml, benchmark-community-world-mongodb.yml, benchmark-community-world-redis.yml - Update tests.yml to call reusable workflows for Turso, MongoDB, Redis - Update benchmarks.yml to include community world benchmarks in summary - Delete generated community-worlds.yml and generator script This approach: - Inherits proper Rust/SWC setup from the main workflows - Keeps all CI in the established patterns - Makes adding new community worlds straightforward 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix benchmark timing file naming for community worlds Add WORKFLOW_BENCH_BACKEND env var support to bench.bench.ts so community world benchmarks generate timing files with the correct backend suffix (e.g., bench-timings-nextjs-turbopack-turso.json instead of -local.json). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add @workflow-worlds/starter to community worlds test matrix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Unify worlds manifest and add dynamic GitHub API fetching - Merge community-worlds.json into worlds-manifest.json with type field - Add server-side data fetching from GitHub API for worlds dashboard - Remove static worlds-status.json, fetch CI artifacts dynamically - Update all references to use unified manifest format - Remove obsolete community-worlds.yml and update-worlds-status.yml workflows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Skip community worlds for non-nextjs-turbopack in benchmark summary Community worlds only run against nextjs-turbopack, so hide the "missing" rows for Express and Nitro frameworks in the benchmark comparison tables. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix stream benchmark detection to check for actual TTFB data The previous check `!== null` incorrectly returned true for undefined, causing all benchmarks to show TTFB columns. Now explicitly checks for a number type. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Hide Worlds Ecosystem page from sidebar The page is still accessible via direct link at /docs/worlds but won't appear in the navigation until it's been further iterated on. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix review comments: trailing newline and division by zero - Add trailing newline when replacing Community Worlds section in docs - Fix division by zero in WorldCard benchmark calculation when metrics is empty 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Consolidate community world workflows with service-type parameter - Create setup-workflow-dev composite action for common setup steps - Add service-type input to benchmark-community-world.yml and e2e-community-world.yml - Use conditional job execution (if: inputs.service-type == 'mongodb') to handle different services - Update benchmarks.yml and tests.yml to pass service-type parameter - Delete redundant workflow files: - benchmark-community-world-mongodb.yml - benchmark-community-world-redis.yml - e2e-community-world-mongodb.yml - e2e-community-world-redis.yml Reduces workflow files from 11 to 7 and eliminates ~500 lines of duplicated YAML. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Generate community world test matrix from worlds-manifest.json Replace hardcoded community world jobs with dynamic matrix generation using scripts/create-community-worlds-matrix.mjs. This allows adding/removing community worlds by editing the manifest instead of multiple workflow files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Apply suggestion from @vercel[bot] Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> * Add Samples column and separate local/production benchmarks - Add Samples column to all benchmark tables showing iteration count - Separate benchmark results into Local Development and Production sections - Add explanatory context for each section (localhost vs Vercel deployment) - Add GitHub action step summaries to e2e community world tests - Create aggregate-e2e-results.js script for parsing vitest JSON output 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove obsolete generate-community-worlds-docs script The Worlds Ecosystem page now fetches from worlds-manifest.json at runtime, making this script unnecessary. The npm script also referenced a non-existent workflow generator script. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Maximize composite action usage and reorganize benchmark output - Update setup-workflow-dev composite action with optional Rust, install-dependencies, and install-args inputs - Update tests.yml to use composite action in unit, e2e-vercel-prod, getTestMatrix, e2e-local-*, and getCommunityWorldsMatrix jobs - Update benchmarks.yml to use composite action in build, benchmark-local, benchmark-postgres, benchmark-vercel, and getCommunityWorldsMatrix jobs - Reorganize benchmark output to group by benchmark test with local/production tables within each benchmark - Remove invalid $schema reference from worlds-manifest.json 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add beads stealth mode stuff (for personal claude memory - will remove stealth if people want) * Add E2E test results PR comment summary - Add pr-comment-start job to create/update PR comment when tests start - Add artifact uploads to all e2e test jobs (vercel-prod, local-dev, local-prod, local-postgres, windows) - Update e2e-community-world.yml with consistent artifact naming (e2e-community-*) - Add summary job to aggregate all e2e results and update PR comment - Extend aggregate-e2e-results.js with --mode aggregate for multi-job PR summary - Group results by category (Vercel Production, Local Development, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add step summaries to all e2e test jobs Add "Generate E2E summary" step to each individual e2e job: - e2e-vercel-prod - e2e-local-dev - e2e-local-prod - e2e-local-postgres - e2e-windows Each job now outputs pass/fail/skip counts to GITHUB_STEP_SUMMARY. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Consolidate community world workflows to single job Replace 3 mutually exclusive jobs (e2e/e2e-mongodb/e2e-redis) with a single job that starts services via docker run when needed. This eliminates the skipped job entries that appear in the GitHub Actions UI. - Use conditional docker run steps instead of services: block - Add health check loops to wait for service readiness - Add cleanup step to stop containers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix extractWorldId to handle community world artifact naming Add handling for `e2e-results-community-{world}` pattern so community world test results are properly extracted (e.g., `e2e-results-community-turso` now correctly extracts `turso` instead of `community-turso`). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> |
||
|
|
103900c058 | Patch sidebar indentation bug (#486) | ||
|
|
0ecd2da992 | [docs] Add button link to X account (#435) | ||
|
|
c0991b4ff7 |
Update docs (#349)
* Initial migration
* Remove ExperimentalPackageCallout
* Remove Callout imports
* Add missing dep
* Update postgres-world.mdx
* Add missing deps, remove unused files
* Restore homepage css
* Update logo, fix homepage
* Update run-anywhere.tsx
* Remove duplicate h1 tags
* Fix package install commands
* Update global.css
* Update code-block.tsx
* Fix framework descriptions
* Remove unused files
* Fix steps
* Update sidebar.tsx
* Remove excess horizontal rules
* Remove unused components
* Cleanup home code-block component
* Update route.ts
* Add missing feed dep
* Rename middleware to proxy
* Update next config
* Update route.tsx
* Move generateDefinition call into tsx
* Update page.tsx
* Update sidebar.tsx
* Update layout.tsx
* Remove unused files
* Fix nav
* Update route.ts
* Remove deprecated lint:links
* Load fonts locally
* Update layout.tsx
* Update route.ts
* Update Geistdocs
* Update hero.tsx
* Update search.tsx
* Update search.tsx
* docs: update url structure in chat tools example
* chore: replace gpt-5 reasoning with gpt-5.1
* docs: update instructions for llm to be more workflow-centric
* Revert "docs: update instructions for llm to be more workflow-centric"
This reverts commit
|
||
|
|
9e0f7b0e0d |
Add DurableAgent and WorkflowChatTransport doc pages (#44)
Co-authored-by: Adrian <me@adriandlam.com> |
||
|
|
804976d694 |
[docs]: explain how to build your own workflow handler (#50)
* wip * almost good * Update meta.json * use mermaid diagram * sdk -> dev kit * fixes * security explanation * Update runtime-adapters.mdx * move under how it works * update how workflow build works * fix file filtering + remove component 3 * dedup http handler info * merge sections * explain difference between bun framework and runtime * runtime adapter -> framework integration * framework integration * bunfig instructions * Pranay's edits * Refactor to 2 pages * Improve framework integrations doc --------- Co-authored-by: Pranay Prakash <pranay.gp@gmail.com> |
||
|
|
c9b884e82f |
[docs] improve mobile navbar view (#63)
* show workflow logo on mobile * Integrate GitHub link button in navbar Add GitHub button to the navbar and adjust styles. * add github icon * . |