Commit Graph

424 Commits

Author SHA1 Message Date
Peter Wielander 01bbe66d5a [world] Add stream pagination and metadata endpoints (#1470) 2026-03-23 17:39:39 -07:00
Peter Wielander c1389ddf3f Remove NestJS Vercel integration while in experimental phase (#1485) 2026-03-23 17:04:31 -07:00
Pranay Prakash 2ef33d2828 feat: export semantic error types and add API reference docs (#1447)
* feat: export semantic error types and add API reference documentation

Add missing error exports (HookNotFoundError, EntityConflictError,
RunExpiredError, TooEarlyError, ThrottleError, RunNotSupportedError,
WorkflowWorldError) to workflow/internal/errors. Create new error
classes for world-level semantics. Tighten TSDoc comments on all
error classes. Add API reference docs for all error types.

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

* fix: use @setup declarations, workflow/errors import, and errors/ doc section

- Replace @skip-typecheck with proper `declare` + `// @setup` lines
  so code samples are typechecked but setup lines hidden from readers
- Add `workflow/errors` export to package.json (public API, replaces
  `workflow/internal/errors` in docs)
- Add `workflow/errors` path mapping in docs-typecheck type-checker
- Add HookConflictError to re-export list
- Move all error docs under api-reference/workflow/errors/ subdirectory
- Update all internal cross-references and links

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

* refactor: move error docs to top-level workflow-errors section

- Move semantic error docs to api-reference/workflow-errors/ (matching
  the workflow/errors import path, like workflow-api for workflow/api)
- Keep FatalError and RetryableError in api-reference/workflow/ since
  they're imported from workflow, not workflow/errors
- Fix all cross-reference links

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

* chore: update HTTP debug logger JSDoc to clarify scope

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

* fix: make TooEarlyError.retryAfter a number (seconds) matching WorkflowWorldError

TooEarlyError.retryAfter is now seconds (number) instead of a Date,
consistent with ThrottleError and WorkflowWorldError. The conversion
from seconds to Date is done at the consumer site (step-handler) rather
than at construction time.

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

* fix: address review feedback on docs accuracy

- WorkflowWorldError docs: add status, code, url, retryAfter properties
  to TSDoc; clarify that .is() only matches direct instances (not
  subclasses); use instanceof in catch-all example
- TooEarlyError/ThrottleError docs: mark retryAfter as optional (?)
  to match actual type definitions

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:01:36 +00:00
Peter Wielander 823f58e5c6 Revert "Add support for calling start() inside workflow functions (#1133)" (#1475)
This reverts commit e889860984.
2026-03-20 17:04:28 -07:00
Peter Wielander 78f1b0e19f [core] Support negative startIndex for streaming (#1460) 2026-03-20 13:29:42 -07:00
Peter Wielander 2b07294313 [core] Ensure open stream flush is await-able in pendingOps (#1446) 2026-03-20 13:28:05 -07:00
Pranay Prakash e889860984 Add support for calling start() inside workflow functions (#1133)
* Add support for calling `start()` directly inside workflow functions

Enable `start()` to work in workflow context by routing through an
internal step (`__workflow_start`), reusing existing step infrastructure
with no new event types or server changes needed.

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

* Address PR review feedback

- Use typeof check instead of truthiness for WORKFLOW_START symbol
- Validate start() options in workflow context (reject unsupported options like world)
- Set maxRetries=0 on __workflow_start step to prevent orphaned child runs
- Add unit tests for createStart factory (6 tests)

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

* Make Run serializable in workflow context with step-backed methods

- Add Run serialization via __serializable marker + custom Run reducer/reviver
  in the serialization module (avoids SWC plugin injecting class-serialization imports)
- Create WorkflowRun class factory (packages/core/src/workflow/run.ts) with
  step-backed methods: cancel(), status, returnValue, workflowName, createdAt,
  startedAt, completedAt, exists
- Register 8 built-in steps (__run_cancel, __run_status, etc.) in step-handler
- Update __workflow_start to return full Run object (serialized → WorkflowRun in VM)
- Update createStart to pass through step result directly
- Update docs to reflect full Run support in workflow context

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

* Fix start() in workflow VM by delegating from api-workflow stub

The workflow VM loads api-workflow.ts (via the "workflow" export condition)
which stubs all runtime functions. The start stub needs to check for the
injected WORKFLOW_START symbol and delegate to it, otherwise start() throws
"doesn't allow this runtime usage" in the workflow context.

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

* Address PR review: fix stale WORKFLOW_SERIALIZE comments and register Run in host registry

- Update comments in step-handler.ts and start.ts to reference the actual
  serialization mechanism (Run reducer with __serializable marker) instead
  of the stale WORKFLOW_SERIALIZE reference
- Register Run class in the host's class registry from step-handler.ts so
  the Run reviver can deserialize Run/WorkflowRun instances in step context

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

* Add docs for recursive/repeating workflows and deploymentId: "latest"

- Document using start() for self-chaining workflows to avoid large event logs
- Add examples for batch processing and cron-like repeating patterns
- Document deploymentId: "latest" option with type safety warning
- Update skill file with same patterns

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

* Return full Run object from startFromWorkflow e2e workflow

Update the e2e workflow to return the childRun object directly instead of
just childRun.runId, exercising Run serialization across the workflow boundary.
Update e2e test assertions to match.

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

* Add recursive fibonacci e2e test for start() in workflow

Demonstrates recursive workflow composition: fibonacciWorkflow starts
new instances of itself via start() + Promise.all to compute fib(6)=8,
fanning out across independent workflow runs.

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

* Move Run method steps to builtins with "use step" directives

Refactor: instead of manually registering Run method steps via
registerStepFunction in step-handler.ts, define them as proper "use step"
functions in builtins.ts with __builtin_ prefix. This leverages the
existing SWC plugin infrastructure — functions starting with "__builtin"
get stable bare-name step IDs.

- Add __builtin_run_{cancel,status,return_value,...} to both builtins files
- Use dynamic import() for getRun inside step bodies to avoid pulling
  Node.js modules into the workflow bundle
- Remove manual registerStepFunction calls from step-handler.ts
- Update WorkflowRun step references to __builtin_run_* names
- Fix step name display in web observability: fall back to raw name
  instead of "?" for built-in steps that don't follow step//module//fn format
- Add fibonacciWorkflow default args for nextjs-turbopack workbench UI

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

* Render Run objects as clickable links in web observability UI

- Add RunRef type and Run reviver to observabilityRevivers so serialized
  Run objects are hydrated as RunRef instead of showing raw Uint8Array
- Add RunRefInline component (purple badge with run ID) that navigates
  to the target run on click, matching the StreamRef pattern
- Thread onRunClick callback through the component chain:
  WorkflowTraceViewer → EntityDetailPanel → AttributePanel → DataInspector
- Wire up navigation in the web app's run-detail-view
- Add startFromWorkflow default args for workbench UI

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

* Throw error instead of silent fallback when Run class not in registry

Address PR review: the Run reviver now throws if the class isn't found
in the registry, instead of silently returning a plain { runId } object
that would break the assumption of getting a valid Run instance.

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

* Fix e2e failures: allow retries on Run getter steps, fix docs code samples

- Remove maxRetries=0 from read-only Run getter steps (status, returnValue,
  workflowName, etc.) — these are safe to retry and need retries when the
  child workflow hasn't completed within the step timeout. Only cancel
  keeps maxRetries=0.
- Fix docs code samples: use correct import path (workflow/api not workflow),
  add declare statements for helper functions used in examples.

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

* Use standard step//module//function naming for built-in steps

Update the SWC plugin's __builtin_ special case to generate proper
step//@workflow/core//{name} IDs instead of bare function names. This
makes parseStepName work correctly for built-in steps, showing:
- StepName: "Run#returnValue" (not "__builtin_run_return_value")
- ModuleSpecifier: "@workflow/core" (not the raw function name)

Convention: __builtin_Run_cancel → step//@workflow/core//Run#cancel
(uppercase prefix + underscore → instance method # notation)

- Move __workflow_start to builtins.ts as __builtin_start
- Rename __builtin_run_* to __builtin_Run_* for proper # notation
- Update WorkflowRun step refs to use full step// IDs
- Remove manual registerStepFunction from step-handler.ts
- Update SWC spec.md with new naming examples

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

* Remove SWC __builtin special case, use standard step naming for builtins

Remove the SWC plugin's __builtin_ special case so built-in steps get
standard step//{module}@{version}//{fn} IDs like any other step. This
makes parseStepName work correctly, showing proper StepName and
ModuleSpecifier in observability.

The VM reconstructs the same IDs via builtinStepId() which uses the
@workflow/core version to build: step//workflow/internal/builtins@{v}//{fn}

- Remove __builtin special case from SWC plugin (revert to original)
- Add builtinStepId() helper shared by workflow.ts, start.ts, run.ts
- Rename Run steps: __builtin_Run_cancel → Run_cancel, etc.
- Rename start step: __builtin_start → start
- Move start step from manual registerStepFunction to builtins.ts
- Keep __builtin_response_* names unchanged (pre-existing)

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

* Use static class methods for Run steps to get Run.method naming

Refactor Run method steps from standalone functions (Run_cancel) to
static methods on a Run class, so the SWC plugin generates step IDs
with the standard static method convention: Run.cancel, Run.returnValue,
Run.status, etc.

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

* Address PR review: tests, docs warnings, skill fix

- Add TODO on Run.returnValue about polling blocking (replace with system
  hooks once AbortSignal/AbortController PR lands)
- Add docs callout warning about returnValue holding workers alive
- Fix SKILL.md contradiction that said start() can't be used in workflows
- Enhance suspension test to assert step arguments are forwarded
- Add WorkflowRun unit tests: serializable marker, runId, registry, delegation

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

* Fix response builtins: adopt this-serialization from PR #1413

The rebase onto main didn't fully adopt PR #1413's refactor of response
builtins to use `this` instead of explicit parameters. The old pattern
(resJson(this) wrappers) passed `this` as an argument, but the step
functions now expect `this` to be set via method call context.

Switch to Object.defineProperties on Request/Response prototypes,
matching main's approach. Also document WORKFLOW_PUBLIC_MANIFEST=1
for local e2e testing.

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

* Address docs review: returnValue polling is temporary, link to start() API ref

- Update returnValue warning to note this is a temporary implementation
  that will be replaced with internal hooks
- Replace inline deploymentId: "latest" docs with link to the existing
  start() API reference which already covers it comprehensively

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

* Fix e2e tests: replace collectedRunIds with trackRun API

PR #1426 replaced the manual collectedRunIds array with a trackRun()
helper. The start() wrapper already auto-tracks, so just remove the
manual push calls and add trackRun for the child run.

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

---------

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:00:17 -07:00
Pranay Prakash 32cc0755bd docs: document error codes and remove docs typecheck import inference (#1445)
* docs: document error codes in errors and retries guide

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

* changes

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

* docs: address PR review comments on error codes guide

- Add missing `start` import from `workflow/api`
- Note that `cause.code` may be undefined for older runs
- Remove invalid `--withData` flag and use `npx workflow` CLI style
- Remove empty changeset (docs-only change needs no changeset)

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

* fix: correct WorkflowRunFailedError import and docs typecheck

- Import from `@workflow/errors` instead of `workflow` (not re-exported)
- Add WorkflowRunFailedError to import inference map
- Add myWorkflow placeholder to docs globals

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

* fix: remove import inference from docs typecheck, add explicit imports

Remove the import-inference system that auto-added imports to doc
snippets before typechecking. This was masking real issues — if a
snippet imported from the wrong module or was missing an import, the
typechecker silently fixed it instead of catching the bug.

All 24 affected doc snippets now have explicit, correct imports that
match what users would actually write.

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

* fix: remove unused sleep import from rate limiting example

Co-Authored-By: Claude Opus 4.6 (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>
2026-03-19 13:41:23 -07:00
Pranay Prakash 73a851ada6 feat: add HookConflictError for hook token conflicts (#1448)
* feat: add HookConflictError for hook token conflicts

Replace WorkflowRuntimeError with a dedicated HookConflictError class
for hook token conflicts. This correctly classifies the error as a
USER_ERROR (duplicate token is a user mistake) rather than a
RUNTIME_ERROR.

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

* fix: use HookConflictError.is() instead of instanceof in docs

The .is() static method handles cross-VM/realm boundaries where
instanceof can be unreliable.

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 11:18:09 -07:00
Pranay Prakash f7bbe71e39 Add TSDoc for stepName field and document world.steps API (#1451)
* feat: add stepName field for human-readable step names

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1773936163539109?thread_ts=1773936163.539109&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* docs: add step examples with resolveData and hydration, document parseStepName/parseWorkflowName utilities

- Split step examples into two: one with resolveData: 'none' for efficient listing without data, and one showing how to hydrate input/output with observabilityRevivers
- Add TSDoc to stepName and workflowName fields explaining the machine-readable format and how to use parse utilities
- Document parseStepName() and parseWorkflowName() from @workflow/utils/parse-name for extracting shortName and moduleSpecifier for UI display
- Add Callout explaining the naming format

---------

Co-authored-by: v0 <v0[bot]@users.noreply.github.com>
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>
2026-03-19 10:56:01 -07:00
Nathan Rajlich 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
2026-03-18 07:22:42 +00:00
Nathan Rajlich c31afa8099 Add documentation for custom class serialization (#810)
* Add documentation for custom class serialization

* Enhance serialization docs: custom class examples with 'use step' instance methods

- Add custom classes to Supported Serializable Types with anchor link
- Replace verbose parenthetical in Requirements with back-link
- Add [!code highlight] to Basic Example serde methods
- Simplify geometry.ts to import Point instead of redefining it
- Rewrite Complex Example to demonstrate 'use step' on instance methods
  with realistic APIs (database, HTTP) and contrast with workflow-context methods
- Add pass-by-value note for 'this' context with return-and-reassign pattern

* Fix docs typecheck: use correct @expect-error codes for Order examples

* Fix pre-existing docs typecheck failures in workflow-serde API reference

Add @skip-typecheck to bare static method signatures that aren't valid
standalone TypeScript.

* Revert extractor changes, use HTML comments for @expect-error markers

The docs typecheck extractor only supports HTML comment syntax for
@expect-error on main. Use <!-- @expect-error:XXXX --> instead of
{/* @expect-error:XXXX */} to match the existing convention.

* Use MDX comment syntax for @expect-error markers, add MDX support to extractor

MDX files don't support HTML comments (<!-- -->). The extractor's
@expect-error regex only supported HTML syntax, but @skip-typecheck
already supported both. This aligns @expect-error to also support
the MDX comment syntax ({/* @expect-error:XXXX */}).
2026-03-18 00:18:43 +00:00
Nathan Rajlich 97e43846f0 docs: add documentation for deploymentId: "latest" in start() (#1409)
* docs: add documentation for `deploymentId: "latest"` in `start()`

* docs: clarify deploymentId as Vercel-specific, add return value compat note
2026-03-16 22:58:27 +00:00
Pranay Prakash 74aea7b0af Add DurableAgent compat tests, e2e tests, and migrate to AI SDK v6 (#1362)
* Add DurableAgent compat tests, e2e agent tests, and migrate to AI SDK v6

- Port ToolLoopAgent test suite as DurableAgent compatibility spec (34 tests,
  all expected to fail — each maps to a feature gap to implement)
- Add e2e workflow definitions using mock LLM providers (no API keys needed)
- Add e2e test file for DurableAgent workflows
- Migrate all AI SDK types from V2 to V3 (LanguageModelV2 → V3, etc.)
- Drop AI SDK v5 support: ai peer dep ^5||^6 → ^6, @ai-sdk/provider ^2||^3 → ^3
- Update ai catalog version from 5.0.104 to 6.0.116
- Simplify CompatibleLanguageModel to just LanguageModelV3

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

* Address PR review feedback

- Remove providerExecuted guard on tool-result stream parts (V3: all
  tool-results are provider-executed by definition)
- Remove providerExecuted spread from tool-output-available UI chunks
- Replace inline MockLanguageModelV3 with import from ai/test (works
  without msw in AI SDK v6)

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

* Remove streamTextIterator mock from compat tests, use it.fails for gaps

Tests now exercise the real DurableAgent code path instead of mocking
the core iterator. 5 tests pass (features DurableAgent already has),
29 are marked it.fails() for known API gaps that will alert when fixed.

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

* Implement Tier 1+2 gaps, add @workflow/ai/test mock provider, wire e2e in CI

DurableAgent API additions:
- Add `instructions` (string | SystemModelMessage | SystemModelMessage[])
  as alias for deprecated `system` on constructor
- Add `onStepFinish` and `onFinish` on constructor, merged with stream
  options (constructor first, then stream — matching ToolLoopAgent)
- Add `timeout` on stream options (converted to AbortSignal)
- Add `text`, `finishReason`, `totalUsage` to onFinish event

Test infrastructure:
- Add @workflow/ai/test export with `mockModel()` wrapper that wraps
  MockLanguageModelV3 from ai/test as an async step function
- E2e workflows now use mockModel() + convertArrayToReadableStream
  from @workflow/ai/test instead of inline V2 mock models
- Add e2e-agent.test.ts to test:e2e script so it runs in CI
- Flip 6 compat tests from it.fails → it (now passing)

Score: 11 passing / 23 it.fails (was 5/29)

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

* Remove e2e agent tests — mock models can't serialize across step boundary

The workflow runtime serializes step arguments, and function closures
(like mock model doStream callbacks) aren't serializable. Mock models
only work in unit tests where 'use step' is a no-op. Real e2e agent
tests would need either a mock HTTP server or real provider credentials.

Also removes 'use step' from mockModel wrapper (closures aren't
serializable) and reverts test:e2e script and example workbench dep.

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

* Add working e2e agent tests with mock model step factories

Mock model factories use the same 'use step' pattern as real providers
(anthropic, openai). Closure variables are bound to locals at the step
body level so the SWC plugin detects them via __private_getClosureVars.

All 4 e2e tests pass against local dev server:
- agentBasicE2e: text response (11s)
- agentToolCallE2e: single tool call + text (11s)
- agentMultiStepE2e: 3 sequential tool calls (12s)
- agentErrorToolE2e: FatalError recovery (11s)

Also adds e2e-agent.test.ts to test:e2e script for CI.

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

* Use @workflow/ai/test package imports for e2e mock models

Split mock provider into two files to work around SWC constructor
closure bug: mock-create.ts has the model creation logic,
mock.ts has the 'use step' wrappers that capture only serializable
args (strings, plain object arrays).

Exports mockTextModel(text) and mockSequenceModel(responses) —
same 'use step' pattern as real providers (anthropic, openai, etc.).
E2e workflows now import directly from @workflow/ai/test.

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

* Simplify mock provider, add comprehensive e2e tests for all features + gaps

Mock provider:
- Replace mock-create.ts with mock-function-wrapper.ts that simply wraps
  MockLanguageModelV3 constructor in a function (SWC class closure bug)
- mockTextModel/mockSequenceModel use mockProvider() from wrapper file
- Bind closure vars at step body level (_text = text) for SWC detection
- Fix AbortController not available in workflow VM sandbox

E2e tests (13 total, all passing):
- Core: basic text, tool call, multi-step, error recovery (4)
- Callbacks: onStepFinish constructor+stream, onFinish constructor+stream (2)
- Features: instructions, timeout (2)
- GAPs documented: onStart, onStepStart, onToolCallStart,
  onToolCallFinish, prepareCall (5 — complete but callbacks not called)

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

* Add tool approval (needsApproval) gap tests, fix SWC closure var binding

Unit tests: 2 new it.fails() tests for tool approval
- needsApproval: true should pause agent (pending tool call, no result)
- needsApproval as function should receive tool input

E2e tests: 1 new test for tool approval gap
- Documents that needsApproval is currently ignored (tool executes anyway)

Also fixes:
- Bind closure vars at step body level in mock provider (_text = text,
  _responses = responses) so SWC plugin detects them
- Guard AbortController usage in workflow VM (not available in sandbox)

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

* Add default args for agent e2e workflows in UI definitions

The nextjs-turbopack UI calls workflows with hardcoded default args.
Without these entries, agent workflows were called with no args,
causing prompt=undefined → ModelMessage validation failure.

Also removes debug logging.

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

* Add DurableAgent chat UI with tools, update docs for AI SDK v6

Chat UI:
- Tab-based layout with Workflows (existing) and DurableAgent Chat tabs
- Chat powered by DurableAgent + WorkflowChatTransport + ai-elements
- Tools: getWeather (fake data), calculate (math expressions)
- Uses createUIMessageStreamResponse for proper stream serialization
- Reconnect route at /api/chat/[runId]/stream
- ai-elements components: conversation, message, prompt-input, tool
- onStepFinish + onFinish callbacks with console logging

Docs (AI SDK v6 migration):
- system → instructions in DurableAgent constructor examples (10 places)
- LanguageModelV2Prompt → LanguageModelV3Prompt in type references (3 places)

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

* Fix tool rendering, add reasoning support, model picker, observability links

- Fix tool part rendering: use `input`/`output` props (not `args`/`result`)
  and `tool-{name}` part type (AI SDK v6 format)
- Add reasoning support for Opus 4.5 via providerOptions
- Model picker: Haiku 4.5, Sonnet 4, Opus 4.5 (reasoning), GPT-5.2, GPT-5.3
- Fix observability links: localhost:3456 for local, Vercel dashboard for prod
- Add suggestions above prompt input
- Add MessageParts component handling text, tool, reasoning, step-start
- Add loading spinner for submitted state
- Update docs: system → instructions, LanguageModelV2Prompt → V3

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

* Fix tool output rendering: use input/output props on ToolInput/ToolOutput

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

* Fix: Documentation for `PrepareStepInfo` and `PrepareStepResult` interfaces references the obsolete `LanguageModelV2` type while the codebase has fully migrated to `LanguageModelV3`.

This commit fixes the issue reported at docs/content/docs/ai/message-queueing.mdx:36

**Bug explanation:**

The codebase migrated from AI SDK V2 to V3. In `packages/ai/src/agent/types.ts`, `CompatibleLanguageModel` is defined as `LanguageModelV3` (from `@ai-sdk/provider`). The actual TypeScript interfaces in `packages/ai/src/agent/durable-agent.ts` use `string | (() => Promise<CompatibleLanguageModel>)` which resolves to `LanguageModelV3`.

However, the documentation in `docs/content/docs/ai/message-queueing.mdx` at lines 36 and 43 still referenced `LanguageModelV2` for the `model` field in both `PrepareStepInfo` and `PrepareStepResult`. This is inconsistent because:
1. The `messages` fields in the same interfaces were correctly updated to `LanguageModelV3Prompt`
2. The actual source code uses `LanguageModelV3` via `CompatibleLanguageModel`
3. There is no `LanguageModelV2` type anywhere in the codebase

This would mislead developers reading the documentation into using the wrong type.

**Fix explanation:**

Changed both `LanguageModelV2` references to `LanguageModelV3` on lines 36 and 43 of the documentation file, matching the actual codebase types. Verified no other stale `LanguageModelV2` references remain in the docs directory.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: pranaygp <pranay.gp@gmail.com>

* Fix instructions tests: flip from it.fails to it, update snapshots

The 3 instructions tests (string, SystemModelMessage, array) now pass.
The snapshots include the assistant reply message from the agent loop,
which is a behavioral difference from ToolLoopAgent (DurableAgent
captures the prompt after the full loop iteration).

Score: 14 passing / 22 it.fails (was 11/25)

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

* Fix getReadable call: pass startIndex as options object

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

* Fix docs type errors and turbopack build

Docs:
- Add await to convertToModelMessages() calls (now async in AI SDK v6)
- Change LanguageModelV3Prompt → ModelMessage[] in type references
- Change LanguageModelV3 → LanguageModel in PrepareStepInfo
- Update docs-globals.d.ts convertToModelMessages return type
- Add LanguageModel to import inference map

DurableAgent:
- Update OutputSpecification to match AI SDK v6 Output interface
  (type→name, parsePartial→parsePartialOutput, parseOutput→parseCompleteOutput,
  responseFormat now PromiseLike)

Turbopack build:
- Remove streamdown plugins from MessageResponse (plugins prop API
  changed in streamdown 2.4.0, causing type mismatch in CI)

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

* Fix pnpm-workspace.yaml: use double quotes for catalog entries

The stage-workbench-with-tarballs.mjs script only strips double quotes
when parsing catalog keys. Single-quoted @-scoped entries (e.g.,
'@types/node') weren't matched, causing "unresolved catalog dependencies"
errors in CI.

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

* Fix CI build failures, add changeset

- Remove streamdown plugins from reasoning.tsx (same CI type mismatch)
- Cast ToolHeader type prop and WorkflowChatTransport to fix type errors
- Fix pnpm-workspace.yaml single→double quotes for staging script
- Add minor changeset for @workflow/ai (breaking: AI SDK v6 migration)

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

* Sync webpack workbench with turbopack: add chat UI deps and symlinks

- Symlink app-shell.tsx, chat-client.tsx, agent_chat workflow,
  chat API routes into nextjs-webpack
- Add matching deps: streamdown, @streamdown/*, shiki, cmdk, nanoid,
  motion, @radix-ui/react-use-controllable-state

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

* Fix circular symlink: restore chat-client.tsx as real file in turbopack

The previous commit accidentally converted turbopack's chat-client.tsx
into a circular symlink pointing to itself. Webpack's symlink to it
then couldn't resolve, breaking both builds on Vercel.

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

* Add missing deps to webpack: use-stick-to-bottom, radix-ui, @vercel/blob

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

* Fix model picker: merge body params via prepareSendMessagesRequest

WorkflowChatTransport sends { messages } by default, ignoring the
body option from ChatRequestOptions. Use prepareSendMessagesRequest
to merge { messages, ...body } so the model selection reaches the API.

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

* Fix WorkflowChatTransport: forward body/headers from ChatRequestOptions

The transport hardcoded body: undefined when calling
prepareSendMessagesRequest, so extra body params (like model selection)
from sendMessage({ body: { model } }) were silently dropped.

Now forwards options.body and options.headers to both
prepareSendMessagesRequest and the default request body.

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

* Fix model IDs: use real AI Gateway model names

gpt-5.2 and gpt-5.3 don't exist in the AI Gateway.
Replace with gpt-4o and gpt-4o-mini.

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

* Use correct AI Gateway model IDs: Opus 4.5, GPT-5.2, GPT-5.3

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

* Enable reasoning for all model providers

- Anthropic: thinking.type='enabled' with 10k token budget
- OpenAI: reasoningEffort='high'
- Instructions kept for all models (no longer conditionally removed)

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

* Fix OpenAI reasoning: use 'medium' effort (GPT-5.3 doesn't support 'high')

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

* Address all PR review comments

- Change changeset from minor to patch (repo convention)
- Use ?? instead of || for system/instructions fallback
- Clean up timeout: store ID, clearTimeout in finally, { once: true } listeners
- Update class docstring example to use instructions
- Map unrecognized finish reasons to 'other' with validation
- Fix duplicate test, align assertion for unrecognized type
- Support ^ exponentiation in calculate tool
- Remove debug console.log from chat client
- Fix ReactNode/ComponentProps type imports in UI components
- Remove unused MockLanguageModelV3 re-exports from mock.ts

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

* Remove accidentally created empty mock2.ts

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

* Change changeset back to minor for breaking AI SDK v6 migration

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

* Fix agent e2e tests: add Vercel world setup for CI

The agent e2e tests only configured the local filesystem world but not
the Vercel world backend. On CI (Vercel prod tests), this caused
VercelOidcTokenError because the world wasn't initialized.

Now matches the setup pattern from e2e.test.ts: configures Vercel world
with OIDC token and project config from CI environment variables.

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

* Deduplicate e2e test utilities: extract shared code to utils.ts

Extract manifest fetching, workflow lookup, world setup, and types
into shared utils.ts. Both e2e.test.ts and e2e-agent.test.ts now
import from the same source, eliminating ~200 lines of duplication.

Shared utilities:
- WorkflowManifest interface
- fetchManifest() with caching
- getWorkflowMetadata() with retry and fallback
- setupWorld() handling local/Vercel/Postgres backends

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

* Fix missing deploymentUrl args in e2e.test.ts after utils refactor

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

* Add @workflow/ai dep to all workbenches for agent e2e tests

All workbenches now have @workflow/ai as a dependency and the
100_durable_agent_e2e.ts symlink, so agent e2e tests run everywhere.

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

* Fix missing imports in e2e.test.ts: add fetchManifest and sleep

The utils refactor removed these imports but they're still used:
- fetchManifest: used in stepFunctionAsStartArgWorkflow test
- sleep (setTimeout): used in webhookWorkflow test

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-03-13 15:20:06 -07:00
Nathan Rajlich b8865edaea swc-playground: resizable panels, collapsible outputs, vim mode, and dep cleanup (#1370)
* swc-playground: add resizable panels, collapsible outputs, vim mode toggle, and clean up deps

- Add resizable split between input editor and output panels using react-resizable-panels
- Add collapsible accordion-style output views (workflow/step/client) with chevron toggles
- Add vim keybindings toggle (persisted to localStorage) using monaco-vim
- Add shadcn Switch and Resizable UI components
- Remove unused individual @radix-ui/react-* packages in favor of unified radix-ui package
- Remove unused bulk shadcn init dependencies (recharts, sonner, vaul, zod, cmdk, etc.)

* Address PR review: fix vim mode race condition, mount timing, and add aria attributes

- Add cancellation flag to async monaco-vim import to prevent stale callbacks
- Add .catch() for import failure handling
- Track editor mount state so vim mode initializes when persisted as enabled
- Add aria-expanded and aria-controls to collapsible output panel toggle buttons
2026-03-13 08:34:22 +00:00
Pranay Prakash fb5a500ead feat: add exists getter to Run class (#1336)
* feat: add `exists` getter to `Run` class

Allow checking if a workflow run exists without catching errors.
Returns `true` if the run is found, `false` for WorkflowRunNotFoundError,
and re-throws any other errors.

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

* address PR feedback: use resolveData: 'none' in exists getter, fix docs wording

Pass { resolveData: 'none' } to world.runs.get() in the exists getter
to skip fetching input/output payloads. Update docs to say "without
throwing when the run is not found" instead of "without throwing an error".

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-11 16:19:33 -07:00
Pranay Prakash 15e6bc008c Fix docs typechecker to resolve workflow module types (#1271)
* Fix docs typechecker to actually resolve workflow module types

The docs typechecker was silently failing to resolve `workflow` imports
because:
1. repoRoot was computed 4 levels up instead of 3
2. No path mappings for workspace packages
3. Missing TS lib files for disposable and DOM iterables

This meant all imported symbols became `any` and type errors in docs
code samples went undetected.

Fixes:
- Fix repoRoot: '../../../..' -> '../../..'
- Add path mappings for workflow, @workflow/core, @workflow/ai, etc.
- Add lib.dom.iterable.d.ts and lib.esnext.disposable.d.ts
- Fix regex that ate first line of some code blocks
- Auto-skip error demonstration code blocks
- Add respondWith to global Request for webhook doc patterns

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

* Fix docs typecheck failures against updated base branch

- Skip incomplete code samples (with `...`/`/* ... */`) from type checking
- Fix sleep("1 month") → sleep("30d") (valid ms duration)
- Fix run.result() → run.returnValue (correct Run API)
- Add skip-typecheck for docs with intentionally simplified types

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

* Fix doc code samples to typecheck instead of skipping them

- hook-conflict.mdx: use error.message.includes() instead of non-existent error.slug
- get-hook-by-token.mdx: cast hook.metadata to expected shape
- ai/index.mdx: fix tool inputSchema to match execute function params
- get-writable.mdx: use ModelMessage[], spread result.messages, use model placeholder
- Add myModel global placeholder for docs examples

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

* Narrow TS2307 ignore to only non-mapped modules

Instead of blanket-ignoring all "Cannot find module" errors (TS2307),
only ignore them for modules not in our explicit paths mappings.
This ensures workspace package imports (workflow, @workflow/core, etc.)
are validated while still allowing relative imports and framework deps.

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 11:45:40 -08:00
Peter Wielander 456c1aa455 Add vitest plugin for testing full workflows without setting up a server (#1237) 2026-03-05 16:08:48 -08:00
Pranay Prakash 30e24d441e Merge commit from fork
* Prevent deterministic tokens in createWebhook

Remove the `token` option from `WebhookOptions` to prevent unauthorized
access to the public webhook endpoint. Webhook tokens are now always
randomly generated. Deterministic tokens remain available for
`createHook()` with server-side `resumeHook()`.

**BREAKING CHANGE**: `createWebhook()` no longer accepts a `token` option.

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

* Address PR feedback: throw on token, revert unnecessary doc changes, replace examples

- createWebhook() now throws an error if token is passed at runtime
  instead of silently stripping it
- Revert unnecessary changes to create-hook.mdx (only keep
  slack_webhook -> slack_messages prefix change)
- Replace Slack webhook examples in create-webhook.mdx and hooks.mdx
  with generic event collector examples that make sense without
  deterministic tokens

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

* Address andresriancho's feedback: stricter token check, add unit test

- Use `token !== undefined` instead of `if (token)` for correctness
  (empty string should also be rejected)
- Add unit test verifying createWebhook({ token: "anything" }) throws
  the expected error message

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

* change changeset to minor

* Fix docs typechecker to actually resolve workflow module types

The docs typechecker was silently failing to resolve `workflow` imports
because:
1. repoRoot was computed 4 levels up instead of 3
2. No path mappings for workspace packages
3. Missing TS lib files for disposable and DOM iterables

This meant all imported symbols became `any` and type errors in docs
code samples went undetected.

Fixes:
- Fix repoRoot: '../../../..' -> '../../..'
- Add path mappings for workflow, @workflow/core, @workflow/ai, etc.
- Add lib.dom.iterable.d.ts and lib.esnext.disposable.d.ts
- Fix regex that ate first line of some code blocks
- Auto-skip error demonstration code blocks
- Add respondWith to global Request for webhook doc patterns

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

* Revert "Fix docs typechecker to actually resolve workflow module types"

This reverts commit 02d42ac866e6db1b6d016339739344cdd9538e90.

* chore: trigger CI

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 10:33:53 -08:00
John Lindquist 4ac75f4806 Add Fluid compute callout to Vercel World docs (#1242)
* Add Fluid compute warning callout to Vercel World docs

Follow-up from #1216 review feedback to include the
FluidComputeCallout on the Vercel World page.

* Register FluidComputeCallout in worlds/[id] page

The /worlds/vercel route uses a separate page component from
/docs/... and was missing the FluidComputeCallout in its MDX
component map, causing a 500 error.
2026-03-02 19:43:23 -08:00
Peter Wielander ece45a0d7c Lint after biome update (whitespace changes only) (#1243) 2026-03-02 17:21:23 -08:00
Pranay Prakash 4ab4412ae6 Add Run.wakeUp() method to interrupt pending sleeps (#1232)
* feat: add testing section and navigation link

Create new 'testing/' section and update Foundations index page.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* docs: fix testing page API references and examples

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* fix: update testing.mdx and meta.json for docs-writer guidelines

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: clarify unit testing focus on steps, remove workflow example

Update documentation to emphasize unit testing for steps only.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: reorganize testing page and fix unit test section

Move testing to top-level, fix content and update meta files.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: add Nitro server setup and observability section to tests

Add 'globalSetup' script and vitest config, and update docs for test debugging.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* [ci] Disable claude code CI (#1231)

* feat: add `Run.wakeUp()` method to programmatically interrupt pending sleeps

Exposes the existing `wakeUpRun` logic as an instance method on the `Run`
class, allowing users to skip sleep() calls in tests or custom UIs.

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

* fix: address PR review comments

- Fix JSDoc @returns to describe StopSleepResult object instead of number
- Clean up global world state in afterEach to prevent test leakage
- Add delay before wakeUp() in docs example to allow workflow replay

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

* chore: restore claude.yml to match base branch

The file was removed on main but still exists on the base branch.
Restoring it so this PR's diff only contains relevant changes.

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

* fix: add imports to standalone code snippet in get-run docs

The docs test type-checks each code block independently, so the
standalone wakeUp snippet needs its own imports and run variable.

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

* fix: use @setup preamble for standalone wakeUp snippet

Use the // @setup comment pattern to provide type context without
rendering the setup line, keeping the snippet lean.

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

* docs: document // @setup preamble pattern in docs-writer agent

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

---------

Co-authored-by: v0 <v0[bot]@users.noreply.github.com>
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 16:43:01 -08:00
John Lindquist 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>
2026-03-02 14:31:02 -08:00
Pranay Prakash 329ad19806 Add Testing documentation as top-level page (#1229)
* feat: add testing section and navigation link

Create new 'testing/' section and update Foundations index page.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* docs: fix testing page API references and examples

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* fix: update testing.mdx and meta.json for docs-writer guidelines

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: clarify unit testing focus on steps, remove workflow example

Update documentation to emphasize unit testing for steps only.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: reorganize testing page and fix unit test section

Move testing to top-level, fix content and update meta files.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: add Nitro server setup and observability section to tests

Add 'globalSetup' script and vitest config, and update docs for test debugging.

Slack-Thread: https://vercel.slack.com/archives/C09125LC4AX/p1772375177894629?thread_ts=1772375177.894629&cid=C09125LC4AX
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>
2026-03-02 10:17:25 -08:00
Pranay Prakash 02681dce4a feat(core): add hook.dispose() method to release hook tokens early (#1181)
* feat(core): add hook.dispose() method to release hook tokens early

Add a `dispose()` method to the Hook interface that allows workflows to
explicitly release hook tokens for reuse by other workflows while the
current workflow is still running. This enables handoff patterns where
one workflow can transfer a hook token to another workflow.

- Add `dispose()` method to Hook interface in create-hook.ts
- Implement dispose functionality in workflow/hook.ts
- Add HookDisposedInvocationQueueItem to global.ts
- Handle hook_disposed events in suspension-handler.ts
- Update documentation in hooks.mdx and create-hook.mdx
- Add e2e test for hook token reuse after explicit disposal

https://claude.ai/code/session_01AkvrXduyFTbtV2joTPHrDH

* feat(core): implement TypeScript Disposable spec for hooks

Add Symbol.dispose to Hook interface to support the TC39 Explicit Resource
Management proposal. This allows hooks to be used with the `using` keyword
for automatic disposal when exiting scope.

https://claude.ai/code/session_01AkvrXduyFTbtV2joTPHrDH

* docs: prefer `using` keyword for hooks and webhooks

Update all documentation and e2e tests to use the `using` keyword as the
recommended approach for creating hooks and webhooks. This leverages the
TC39 Explicit Resource Management proposal for automatic disposal.

- Update e2e tests to use `using` syntax
- Update foundational hooks guide to recommend `using`
- Update create-hook API reference with `using` examples
- Update create-webhook API reference with `using` examples
- Update example workflow to use `using`

https://claude.ai/code/session_01AkvrXduyFTbtV2joTPHrDH

* chore: simplify `using` examples in docs and e2e tests

Remove unnecessary block scopes and excessive comments about automatic
disposal. Block scopes are only used when early disposal is relevant
(like in the handoff test).

https://claude.ai/code/session_01AkvrXduyFTbtV2joTPHrDH

* docs: add brief explanation of `using` in first examples

Add a one-liner explaining the `using` keyword in the intro examples
of the API reference docs, so new users understand the syntax.

https://claude.ai/code/session_01AkvrXduyFTbtV2joTPHrDH

* fix: address PR review comments

- Restore code highlights (`[!code highlight]`) that were unintentionally
  removed from pre-existing doc examples
- Move `using` explanation from prose to inline code comment in intro
  examples
- Add `{/* @skip-typecheck */}` to incomplete manual dispose() snippet
- Add 409 (conflict/duplicate) error handling for hook_disposed events
  in suspension handler to handle workflow re-invocation

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

* fix: polyfill Symbol.dispose in workflow VM context

The workflow VM sandbox doesn't have Symbol.dispose/Symbol.asyncDispose
available, causing `using` keyword to fail with "Symbol.dispose is not
defined" at runtime. Add polyfill in the VM context creation.

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

* fix: use VM's Symbol.dispose for hook disposable support

The workflow VM sandbox has its own Symbol object with a polyfilled
Symbol.dispose. The hook object was using the host's Symbol.dispose,
which is a different symbol instance. The SWC-compiled `using` keyword
looks up the VM's Symbol.dispose on the object, causing "Object not
disposable" errors.

Fix by setting Symbol.dispose on the hook object dynamically using the
VM's globalThis.Symbol.dispose from the orchestrator context.

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

* fix: revert webhookWorkflow to create all webhooks upfront

The webhookWorkflow e2e test creates 3 webhooks that must all exist
before the test sends HTTP requests. Using `using` with sequential
creation meant only the first webhook existed at the first suspension
point. Revert to `const` since all webhooks need to be created upfront.

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

* fix: eliminate hook_disposed queue item, use flag pattern for disposal

Instead of adding a separate HookDisposedInvocationQueueItem to the
queue on dispose, keep the HookInvocationQueueItem throughout the
hook lifecycle and track state with flags (hasCreatedEvent, disposed).
A closure variable (hasDisposedEvent) makes disposeHook() a pure no-op
on replay, avoiding redundant server calls and 409 errors.

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

* fix: delete hook from invocations queue on hook_disposed terminal event

Match the pattern used by steps (step_completed/step_failed) and waits
(wait_completed) where the queue item is removed on the terminal event.

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

* test: verify dispose() is safe when called twice after replay

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

* test: add comprehensive edge case tests for hook disposal

- WorkflowSuspension counts disposed hooks separately from active hooks
- Dispose after hook_created replay produces correct suspension
- Dispose before first suspension (needs both create + dispose)
- Multiple hooks where only one is disposed
- Dispose on a conflicted hook is safe (no crash)
- Symbol.dispose calls disposeHook correctly (using keyword pattern)
- Iterator break without dispose keeps hook alive in queue
- Await after dispose on first invocation triggers suspension

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

* fix: remove unsafe cast by adding Symbol.dispose to hook object literal

Add [Symbol.dispose] directly to the hook object so it satisfies the
Hook<T> type without `as unknown as`. The VM's Symbol.dispose is still
added separately when it differs from the host's.

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

* fix: address remaining Copilot review comments

- Rename test to match new behavior (hooks stay in queue, not removed)
- Use neutral "processed" verb in WorkflowSuspension message when
  mixed item types are present
- Remove extends Disposable from Hook interface to avoid requiring
  lib.esnext.disposable in downstream consumers (explicit
  [Symbol.dispose]() method is still declared on the interface)

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

* fix: drain pending promises in disposeHook to prevent orphaned awaits

When dispose() is called while a promise is pending (e.g., iterator
suspended on yield await this, or direct await hook after dispose),
the promise would hang forever since the event consumer will never
deliver another hook_received. Now disposeHook() clears the promises
array and triggers a WorkflowSuspension so the runtime processes the
disposal cleanly.

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

* chore: remove workflow from changeset, keep only @workflow/core

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-27 12:59:54 -08:00
Peter Wielander 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>
2026-02-27 12:16:50 -08:00
Pranay Prakash 40f54cf323 Add preview deployment badge with clipboard safety guard (#1202)
* feat: add PreviewBadge component and integrate into home page

Slack-Thread: https://vercel.slack.com/archives/C09G3EQAL84/p1772085714762119?thread_ts=1772085714.762119&cid=C09G3EQAL84
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>

* feat: enhance clipboard copy error handling in preview-badge component

Slack-Thread: https://vercel.slack.com/archives/C09G3EQAL84/p1772085714762119?thread_ts=1772085714.762119&cid=C09G3EQAL84
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>
2026-02-26 16:14:19 -08:00
Pranay Prakash 45800b474b Fix OG image routing under i18n (#1176)
* Fix og route handling in i18n middleware

* Add docs CI smoke test for OG and sitemap

* Run docs OG checks against Vercel preview

* Refactor docs CI checks and rename smoke test

* Use docs Vercel token for preview checks

* Expand docs OG smoke coverage

* Check docs HTML OG metadata
2026-02-23 23:40:46 -08:00
Kevin 1f9a67c759 [world-postgres] Replace pg-boss with graphile-worker (#1124) 2026-02-20 16:24:21 -08:00
Karthik Kalyan 289fc46a1c Add back sitemap code and add docs unit test (#1136)
* Bring back sitemap

* Bring back sitemap

* Add pre commit hooks for sitemap

* Add pre commit hooks for sitemap

* Fix failing queue test

* Revert queue test failure

* Add unit tests
2026-02-20 12:52:43 -08:00
Pranay Prakash 5e06a7c833 Materialize waits as entities to prevent duplicate wait_completed events (#1057)
* Handle 409 conflict when completing waits that were already completed

When multiple concurrent workflow invocations race to complete the same
wait, the server returns 409 (conflict) for duplicates. This change
handles the 409 gracefully in both runtime.ts (sleep elapsed check) and
runs.ts (wakeUpRun), preventing crashes and treating already-completed
waits as successful.

Also updates event-sourcing docs to reflect that waits are now
materialized as entities in storage with atomic completion guarantees.

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

* Point e2e tests at workflow-server preview for wait materialization branch

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

* Materialize waits as entities in local and postgres worlds to prevent duplicate wait_completed events

Adds Wait type/schema to the shared world package and implements wait entity
materialization in both local (filesystem) and postgres world implementations,
matching the DynamoDB behavior. wait_created creates a wait entity with status
'waiting', and wait_completed transitions it to 'completed' with guards that
reject duplicates (409).

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

* Fix waitId to use composite key for consistency with postgres world

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

* Clean up wait entities on terminal run states and register waits migration

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

* Clear WORKFLOW_SERVER_URL_OVERRIDE for merge

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

* Update changeset for all affected packages and restore server URL override

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

* Clear WORKFLOW_SERVER_URL_OVERRIDE now that server PR is merged

The server-side changes (vercel/workflow-server#265) have been merged to main
and deployed to production, so we no longer need to point at the preview URL.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:46:49 -08:00
Nathan Rajlich 89f96306ea fix(docs): correct retry instructions in corrupted-event-log error page (#1059)
Remove reference to non-existent 'npx workflow runs start' CLI command.
The correct way to retry is via the Re-run button in the Workflow Dashboard.
2026-02-14 01:07:00 -08:00
Pranay Prakash c2b4fe9906 fix(core): detect and fatal error on orphaned/invalid events (#1055)
* fix(core): detect and fatal error on orphaned/invalid events in EventsConsumer

When an event log has duplicate or invalid events (e.g., 2 wait_completed for a single wait_created), the EventsConsumer gets stuck: the orphaned event has no callback to consume it, so eventIndex never advances, blocking all subsequent events and hanging the workflow forever. This adds deferred orphaned event detection that raises a WorkflowRuntimeError instead.

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

* add corrupted-event-log error slug and docs page

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

* add changeset for orphaned event detection

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

* address PR feedback on docs and JSDoc

- Add JSDoc to EventsConsumer constructor's onUnconsumedEvent parameter
- Rewrite docs to clarify this is a SDK/server bug, not user code
- Remove cancel/programmatic retry advice; run is already marked failed
- Emphasize error is uncatchable inside workflow code
- Add steps: upgrade package, retry via dashboard/CLI, report issue on GitHub

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

* address PR review: structured options, required callback, reorder docs

- Change EventsConsumer constructor to use structured EventsConsumerOptions object
- Make onUnconsumedEvent required (all callsites provide it)
- Move corrupted-event-log card to last position in errors index
- Update all callsites in tests

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

* fix docs code sample to pass type-checking

Use correct imports (getRun from workflow/api) and declare variables
to satisfy the docs-typecheck CI job.

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

* add e2e test for parallel sleep (Promise.all with 10x sleep)

Adds parallelSleepWorkflow that does Promise.all with 10 concurrent
sleep('1s') calls, and an e2e test asserting it completes or fails
within a reasonable time (not hanging).

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

* fix parallelSleep e2e test: await returnValue instead of checking status

run.status returns immediately and the workflow is still 'running'.
Use run.returnValue which polls until completion.

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

* fix parallelSleep e2e: assert parallel completion under 10s

The test verifies 10 concurrent sleep('1s') calls complete in parallel
(~1s) rather than serially (10s) or hanging indefinitely. 30s timeout
is sufficient since the workflow should finish in ~1-2s.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:31:39 -08:00
Hayden Bleasel 6da8e2358b Update Docs (#1028)
* Remove math and mermaid

* Add alternates
2026-02-13 05:59:28 +00:00
Pranay Prakash ff9fcc25ad Fix benchmark history continuity and caching (#1034)
* Fix benchmark history continuity across metric name rename

The concurrent step benchmarks were renamed in beta.53 (dropping the
"stress test: " prefix), which broke the history API's exact-name lookup
against older gh-pages data. Add legacy alias fallbacks so charts show
continuous history across the rename boundary.

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

* Paginate GitHub API calls and use generic legacy name fallback

Three fixes:
- Paginate gh-pages commits (was fetching 100 of 216, missing most history)
- Paginate tags (workflow@ tags were cut off beyond page 1)
- Paginate main branch commits for commits mode
- Replace hardcoded LEGACY_METRIC_ALIASES with generic "stress test: "
  prefix fallback

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

* Cache benchmark history with unstable_cache and aggressive CDN TTLs

The snapshot map (200+ GitHub API fetches) is now cached via
unstable_cache for 1 hour, shared across all parameter combinations.
Tags are cached separately. Individual fetch calls use force-cache
with long revalidation periods since historical data is immutable.

CDN cache bumped from 5min to 1h with 24h stale-while-revalidate,
matching how infrequently benchmark data changes.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:57:18 -08:00
Hayden Bleasel 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
2026-02-12 19:27:52 +00:00
JJ Kasper dc2dc6ac79 next: stop esbuild bundling for deferred step route (#992)
* next: remove deferred step esbuild bundle and use copied step files

* chore: bump workspace Next.js deps to canary

* web: avoid type re-exports from use server actions module

* next: resolve copied step import extensions for symlinked TS sources

* next: fix deferred copied step dependency discovery and imports

* next: add deferred step copy source-map plumbing

* add changeset

* next/builders: scope deferred logging and warning suppression

* next: derive deferred transitive entries from tracked deps

* fix(next): include transitive step files in deferred step copy

* fix(next): include transitive serde files in deferred builds

* fix(next): clean deferred artifacts on startup

* reset to stable next

* bump
2026-02-11 16:26:41 -08:00
Nathan Rajlich a4a9b526a8 docs: use markdown image syntax in observability page (#1008) 2026-02-11 14:44:11 -08:00
Pranay Prakash 01732dac93 [docs] Add single-region limitation to Vercel World (#953)
* [docs] Add single-region limitation to Vercel World page

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

* [docs] Use bullet point format for limitations section

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 11:52:26 -08:00
Karthik Kalyan fc077108ef Remove dirs option (#961) 2026-02-05 22:56:03 -08:00
Peter Wielander 4712931c26 [docs] Fix image link in NestJS getting started guide (#941) 2026-02-05 09:44:27 -08:00
Pranay Prakash 41f28d8b80 fix(docs): complete OpenGraph image integration for docs pages (#917)
* changeset

Signed-off-by: voyager14 <21mh124@queensu.ca>

* refactor OG image generation into shared utility

Signed-off-by: voyager14 <21mh124@queensu.ca>

* fix og image height mismatch

Signed-off-by: voyager14 <21mh124@queensu.ca>

* fix: add missing getPageImage and include OG assets in Vercel output

Signed-off-by: voyager14 <21mh124@queensu.ca>

* exclude og in middleware

Signed-off-by: voyager14 <21mh124@queensu.ca>

* fix(docs): wire up OpenGraph images for docs pages

Complete the OG image integration that was started in PR #858:

- Add openGraph.images metadata to docs page generateMetadata using
  the getPageImage helper from source.ts
- Add metadataBase to the root layout so Next.js can resolve OG URLs
- Remove unused generatePageMetadata helper from docs-page.tsx

This ensures docs pages like /docs/how-it-works/event-sourcing have
proper OpenGraph images when shared on social media.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>

* fix(docs): use dynamic OG image for homepage

The static opengraph-image.png at the app root wasn't being served
because all routes are under [lang]/. Next.js OG images need to be
in the same route segment as the page they apply to.

- Create dynamic opengraph-image.tsx in [lang]/(home)/ using the
  shared createOgImage utility
- Remove the unused static opengraph-image.png from app root

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): use dynamic metadataBase for preview deployments

The metadataBase was hardcoded to useworkflow.dev, which caused
preview deployments to generate OG image URLs pointing to production
instead of the preview URL.

Now uses:
- Production: https://useworkflow.dev
- Preview: https://${VERCEL_URL}
- Local dev: http://localhost:3000

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): address PR review comments for OG images

- Fix semibold font weight from 500 to 600 (semibold is weight 600)
- Extract OG_IMAGE_SIZE constant to lib/og/index.tsx for consistency
- Use shared constant in all opengraph-image.tsx files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): match OG image styling to production design

- Fix title styling: "Workflow:" in white, rest in grey (#888888)
- Remove description from homepage OG image
- Adjust positioning and font size to match expected design
- Reduce text width to prevent overflow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): add display flex for Satori multi-child divs

Satori requires explicit display: flex on divs with multiple children.
Added flex flex-wrap to the title div containing the two spans.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): simplify OG image layout with stacked title

Use separate divs for "Workflow:" and title instead of trying to
inline them with flex-wrap, which was causing layout issues in Satori.

- "Workflow:" on first line in white
- Title on second line in grey
- Reduced font size slightly to prevent overflow
- Properly stacked with flex-col layout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): correct OG image positioning below background Workflow: text

The background.png already contains "Workflow:" text, so we only need
to render the dynamic title positioned below it.

- Remove hardcoded "Workflow:" from JSX (it's in the background image)
- Adjust top positioning to 290px to place title below background text
- Restore textWrap: balance for proper text flow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): align OG title with background Workflow: text

Position and size title to match background image's Workflow: text,
using non-breaking spaces for horizontal offset so title flows inline.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): restore debug border on OG image container

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): add homepage OG route and fix positioning

- Add /og route for homepage OG image (avoids i18n middleware conflict)
- Remove broken opengraph-image.tsx that conflicted with middleware
- Add explicit openGraph metadata to homepage
- Restore debug border for positioning

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): add OG routes for worlds pages

- Add /og/worlds route for worlds listing page
- Add /og/worlds/[id] route for individual world pages
- Remove broken opengraph-image.tsx that conflicted with i18n middleware
- Add explicit openGraph metadata to worlds pages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): remove badge from worlds OG images

Badge was causing layout issues with title positioning.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add descriptions to AI, foundations, how-it-works, deploying, and observability pages

Add terse descriptions for OG image rendering to:
- 8 AI docs
- 9 foundations docs
- 4 how-it-works docs
- 5 deploying docs
- 1 observability doc

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add descriptions to API reference, errors, and remaining getting-started pages

Add terse descriptions for OG image rendering to:
- 23 API reference docs (workflow, workflow/api, @workflow/ai, workflow/next)
- 9 errors docs
- 5 getting-started docs (Astro, Express, Fastify, NestJS, Vite)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: voyager14 <21mh124@queensu.ca>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: voyager14 <21mh124@queensu.ca>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:41:48 -08:00
Vercel Release Bot 3dde14d529 Version Packages (beta) (#834) 2026-02-02 10:33:56 -08:00
Peter Wielander 6ae65f0ed0 [core] Follow up fixes for v1 compat (#907) 2026-01-30 17:55:19 -08:00
Pranay Prakash 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>
2026-01-30 14:49:24 -08:00
Peter Wielander 972f3ce6ea fix(docs): restore SVG and ZIP file exclusion in middleware matcher (#904)
The docs template refactor accidentally removed the SVG and ZIP file
exclusions from the middleware matcher, causing public static assets
like workflow-circle-symbol-light.svg and workflow-circle-symbol-dark.svg
to be processed by the i18n middleware instead of being served directly.

This restores the original behavior where static files are served from
the public folder without middleware interference.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-30 14:22:39 -08:00
Peter Wielander 556d86b521 Docs dark mode styling (#885)
* fix(docs): use true black backgrounds in dark mode and improve sidebar highlight visibility

- Change dark mode background from gray (oklch 0.145) to true black (oklch 0 0 0)
- Adjust card/popover backgrounds from oklch 0.205 to oklch 0.1 for better contrast
- Update secondary/muted/accent backgrounds from oklch 0.269 to oklch 0.15
- Set sidebar background to true black (oklch 0 0 0)
- Increase sidebar-accent from oklch 0.269 to oklch 0.2 for better visibility of highlighted items
- Set sidebar-accent-foreground to pure white (oklch 1 0 0) for maximum contrast

* chore: add empty changeset for docs styling change

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

---------

Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-28 16:58:14 -08:00
Nathan Rajlich 600047af72 Fix workflow tarball URLs on "docs" app (#882) 2026-01-28 15:18:00 -08:00
Matan Kushner 8205717921 [docs] bypass proxy for sitemap and .md paths (#879) 2026-01-28 02:17:53 -05:00
Karthik Kalyan 409972e3b4 [perf]: add configurable dirs option to withWorkflow (#843)
* perf(builders): optimize workflow discovery with hybrid SWC approach

Apply SWC transforms only to files containing workflow/step directives
instead of all files. Uses regex for fast filtering, then SWC where needed.

- esbuild follows imports to build dependency graph
- regex detects 'use workflow'/'use step' directives
- SWC applied only to files with directives (<1% typically)
- other files use esbuild's built-in TS handling

* Remove blank line

* feat(next): add configurable `dirs` option to withWorkflow

Allow users to specify which directories to scan for workflow directives,
helping reduce memory usage and build times in large Next.js applications.

- Add `dirs` option that overrides the default directories
- Document all configuration options in API reference
- Add troubleshooting guide for OOM errors during build

* fix(docs): add missing imports in withWorkflow code example

Add missing import statements and nextConfig declaration to the
troubleshooting code example to fix docs typecheck.

* docs: move OOM troubleshooting to getting-started/next

Move the OOM troubleshooting section from the API reference to the
existing troubleshooting section in docs/getting-started/next.mdx
for better discoverability.

* move dirs inside workflow config
2026-01-27 21:51:39 -08:00