Commit Graph

97 Commits

Author SHA1 Message Date
Nathan Rajlich c56dc3848e Extract browser-safe serialization format and move hydration client-side (#1015)
## Summary

Split the serialization/deserialization logic into environment-specific layers so data hydration can happen client-side in the browser. This is a prerequisite for e2e encryption where decryption keys are only available in the browser.

## Architecture

### Layer 1: `@workflow/core/serialization-format` (new, browser-safe)
- Format prefix encoding/decoding (`devl`, future `encr`, etc.)
- Generic `hydrateData()` dispatch — handles Uint8Array (v2 binary), legacy arrays (v1), and plain values
- `hydrateResourceIO(resource, revivers)` resource-type dispatcher (step/hook/event/workflow field mapping)
- `ClassInstanceRef` (plain data class, no `node:util` dependency)
- `StreamRef`, type guards (`isStreamRef`, `isStreamId`, `isClassInstanceRef`), utility functions (`extractStreamIds`, `truncateId`)
- Shared `observabilityRevivers` for stream/class/step display overrides
- 36 unit tests covering all of the above

### Layer 2: Environment-specific revivers
- **`@workflow/web-shared`** (`lib/hydration.ts`) — browser-safe revivers using `atob()` for base64, real `URLSearchParams`/`Headers`/`URL` instances, `ClassInstanceRef` for UI rendering
- **`@workflow/cli`** (`lib/inspect/hydration.ts`) — Node.js revivers using `Buffer.from()` for base64, `CLIClassInstanceRef` with `util.inspect.custom` for CLI output

Each module exports a pre-bound `hydrateResourceIO(resource)` that uses its environment's revivers.

### Removed: `@workflow/core/observability`
- Deleted `observability.ts` and `observability.test.ts` entirely (no remaining consumers)
- Removed `"./observability"` export from `@workflow/core/package.json`
- Removed the `workflow` package's `internal/observability.ts` re-export
- All functionality has been split between `serialization-format.ts` (shared types/utilities) and the environment-specific hydration modules

## Web package changes
- Server passes raw world data through without hydration (CBOR preserves `Uint8Array`)
- Client calls `hydrateResourceIO` from `@workflow/web-shared` after receiving CBOR-decoded data
- No Vite `node:*` stubs needed since `@workflow/core/serialization-format` is browser-safe
- Optimized: event hydration finds the matching event before hydrating (instead of hydrating all)
- Reduced server log noise from handled API errors (4xx errors no longer logged)

## Packages affected
- `@workflow/core` — new `serialization-format` export (with tests), removed `observability` export
- `@workflow/web-shared` — new `lib/hydration.ts` with browser-safe revivers
- `@workflow/cli` — new `lib/inspect/hydration.ts` with Node.js revivers, updated `output.ts` import
- `@workflow/web` — client-side hydration, removed server-side hydration
- `workflow` — removed `internal/observability.ts` re-export
2026-02-12 16:58:19 -08:00
Nathan Rajlich 7653e6bfdb Migrate @workflow/web from Next.js to React Router v7 (#1005)
## Summary

- Replace Next.js App Router with React Router v7.13.0 framework mode (Vite-based), eliminating the large `next` dependency from the web, CLI, and workflow metapackages
- Serve the web UI in-process from the CLI via Express instead of spawning `next start` as a child process
- Switch RPC transport from JSON to CBOR to preserve binary data types across the wire
- Replace `nuqs` URL state management with React Router's `useSearchParams`
- Replace Next.js server actions with an RPC resource route (`/api/rpc`) and a thin CBOR-based client

## Motivation

The `next` package is ~300MB installed and was the single largest dependency in the monorepo. It also required spawning a separate child process from the CLI to run the o11y web server, adding complexity around process lifecycle management, port readiness polling, and environment variable forwarding.

With React Router framework mode, the web package builds to a standard Express-compatible server bundle that the CLI can import and serve directly in its own process.

## What changed

**Framework swap (`@workflow/web`):**
- `next.config.ts` / `postcss.config.mjs` → `react-router.config.ts` / `vite.config.ts`
- `src/` directory → `app/` directory (React Router convention)
- `src/app/layout.tsx` + `layout-client.tsx` → `app/root.tsx`
- `src/app/page.tsx` → `app/routes/home.tsx`
- `src/app/run/[runId]/page.tsx` → `app/routes/run-detail.tsx`
- Path alias `@/` → `~/`
- Removed all `'use client'` / `'use server'` directives

**Data transport:**
- Server actions → RPC resource route at `/api/rpc` with CBOR encoding
- CBOR preserves `Uint8Array` and other binary types natively (no base64 overhead)
- Stream reading → dedicated `/api/stream/:streamId` resource route

**URL state:**
- `nuqs` (`useQueryState`) → `useSearchParams` from `react-router`

**Fonts:**
- `next/font/google` → Geist `.woff2` files referenced directly from `node_modules/geist` via `@font-face` in CSS

**CLI integration (`@workflow/cli`):**
- `import('@workflow/web/server').then(m => m.startServer(port))`
- No child process, no readiness polling, no cleanup handlers

**Radix UI compatibility:**
- `onSubmit` preventDefault on `AlertDialogContent` and `SheetContent` to prevent Radix's internal `<form method="dialog">` from triggering React Router route actions
- Catch-all action on root route for any stray POSTs

## Dependencies removed
- `next`, `swr`, `nuqs`, `@tailwindcss/postcss`

## Dependencies added
- `react-router` / `@react-router/dev` / `@react-router/node` / `@react-router/express` (all `7.13.0`)
- `express`, `vite`, `@tailwindcss/vite`, `cbor-x`, `isbot`, `cross-env`
- `geist` (devDep)
2026-02-12 16:30:51 -08:00
Peter Wielander f7fd88ea96 [core] Tidy health check latency calculation (#951) 2026-02-06 15:54:53 -08:00
Peter Wielander a2b688d062 [core] Add runtime and world backwards compatibility for specVersion v1 (#894) 2026-01-30 13:23:08 -08:00
Nathan Rajlich 1060f9d04a Change user input/output to be binary data at the World interface (#853) 2026-01-28 10:36:28 -08:00
Peter Wielander 57f637653d [world-local] Fix package info stored in data dir showing the wrong version (#718) 2026-01-23 13:46:44 -08:00
Nathan Rajlich bd8116d40b Add WORKFLOW_SERVER_URL_OVERRIDE var to "world-vercel" for testing (#833)
Added `WORKFLOW_SERVER_URL_OVERRIDE` configuration to the Vercel world adapter and removed the deprecated `WORKFLOW_VERCEL_SKIP_PROXY` and `WORKFLOW_VERCEL_BACKEND_URL` environment variables.

### What changed?

- Added a changeset for a patch release across multiple packages
- Removed `WORKFLOW_VERCEL_SKIP_PROXY` environment variable from GitHub workflow tests
- Removed `WORKFLOW_VERCEL_BACKEND_URL` from environment variables in CLI and core packages
- Simplified the URL resolution logic in the Vercel world adapter
- Added support for a `WORKFLOW_SERVER_URL_OVERRIDE` constant for testing against different workflow-server versions
- Added the `x-vercel-workflow-api-url` header when the URL override is set

### How to test?

1. Verify that Vercel deployments continue to work without the removed environment variables
2. Test with a custom workflow server URL by setting the `WORKFLOW_SERVER_URL_OVERRIDE` constant in the world-vercel package

### Why make this change?

This change simplifies the configuration for the Vercel world adapter by removing deprecated environment variables and standardizing on a cleaner approach for specifying the workflow API URL. The new implementation automatically determines whether to use the proxy based on project configuration, making it more intuitive and reducing the need for explicit configuration.
2026-01-23 11:01:45 -08:00
Nathan Rajlich b16a6828af Move "parse-name" into the utils package (#814) 2026-01-23 10:57:52 -08:00
Pranay Prakash 4966b728a8 implement event-sourced architecture (#621)
* perf: implement event-sourced architecture

* Apply suggestions from code review

* Improve invalid event log handling in step/hook/wait

* Handle serialized workflow run errors correctly

* log error in failing test

* Handle queue idempotency in vercel world

* hotfix for error propogation

* Fix: Incorrect HTTP status code 409 should be 410 for terminal run state rejections in postgres storage

* Fix: The code attempts to pass an unsupported `fatal` property when creating a `step_failed` event. The TypeScript schema for `step_failed` events only allows `error` and `stack` properties, so the `fatal` property causes a compilation error.

This commit fixes the issue reported at packages/core/src/runtime/step-handler.ts:133-139

## TypeScript error: Invalid property 'fatal' in step_failed event

**What fails:** TypeScript compilation fails in `packages/core` due to an invalid property in the `step_failed` event creation.

**How to reproduce:**
```bash
cd /vercel/sandbox/primary
pnpm run -F @workflow/core build
```

**Result:**
```
src/runtime/step-handler.ts(133,32): error TS2769: No overload matches this call.
  Overload 1 of 2, '(runId: null, data: { eventType: "run_created"; ... }, gave the following error.
    Argument of type 'string' is not assignable to parameter of type 'null'.
  Overload 2 of 2, '(runId: string, data: CreateEventRequest, params?: CreateEventParams | undefined): Promise<EventResult>', gave the following error.
    Object literal may only specify known properties, and 'fatal' does not exist in type '{ error: any; stack?: string | undefined; }'.
```

**Issue:** The code attempted to pass a `fatal: true` property in the `eventData` object when creating a `step_failed` event. However, the event schema defined in `packages/world/src/events.ts` for `StepFailedEventSchema` only allows `error` and `stack` properties - the `fatal` property is not part of the schema.

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

* Fix: Code silently skips updating workflowRun if result.run is undefined, causing workflows to be incorrectly skipped instead of throwing an error

* Add hook_conflict event type for duplicate token detection

Implements hook_conflict events across all world implementations to handle
cases where a workflow attempts to use a hook token already claimed by another
workflow. Instead of throwing errors, the system now records hook_conflict
events in the event log, enabling deterministic replay.

- Add HookConflictEvent schema to @workflow/world
- Implement hook_conflict in world-local, world-postgres, and suspension-handler
- Update hook consumer to reject promises with WorkflowRuntimeError on conflict
- Add HOOK_CONFLICT error slug with documentation
- Add e2e and unit tests for conflict scenarios

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add changeset for hook_conflict events

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add unit tests for hook_conflict handling

- Add tests for hook_conflict event in workflow.test.ts
- Fix world-postgres test to not expect removed message field

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Improve hook-conflict.mdx error guide

- Remove redundant third point in 'Why This Happens' section
- Add example showing how to handle WorkflowRuntimeError for hook conflicts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Fix docs validation: add hook-conflict to errors index

- Fix broken link in hook-conflict.mdx (/docs/foundations/webhooks -> /docs/api-reference/workflow/create-webhook)
- Add hook-conflict to errors index page so it's discoverable by the docs link validator

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Fix world-local tests for hook_conflict event behavior

Update tests to expect hook_conflict events instead of thrown errors when
duplicate hook tokens are used. This aligns with the new event-sourced
approach where conflicts are recorded as events rather than thrown.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add specVersion property to World interface for backwards compatibility

- Add specVersion property to World interface to track world package version
- Add specVersion to WorkflowRun schema and run_created event data
- World implementations (vercel, local, postgres) set specVersion from npm version
- Server can use specVersion to route operations based on world version
- Add specVersion display to observability UI attribute panel
- Add spec_version column to postgres runs schema

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add migration for spec_version column in postgres schema

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add drizzle migration journal and snapshot for spec_version column

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Regenerate postgres migration using drizzle-kit

- Properly generates migration with drizzle-kit CLI
- Removes deprecated 'paused' status from enum
- Adds spec_version column

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* Add backwards compatibility for event-sourced runs

- Add RunNotSupportedError for runs requiring newer world versions
- Add semver-based version utilities (isLegacyVersion) to @workflow/world
- World implementations check specVersion and route to legacy handlers
- Legacy runs (< 4.1.0): run_cancelled skips event storage, wait_completed stores event only
- New runs always get current world version (4.1.0-beta.0)
- Make EventResult.event optional for legacy compatibility

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

* Refactor spec version from semver strings to integers

Replace semver-based version compatibility with explicit integer spec versions:
- SPEC_VERSION_LEGACY (1): pre-event-sourcing runs
- SPEC_VERSION_CURRENT (2): event-sourced architecture

Use branded SpecVersion type to enforce importing from @workflow/world.
Remove semver dependency from world, world-local, and world-postgres.

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

* Store error as CBOR in postgres world for consistency with input/output

- Add error_cbor bytea columns to workflow_runs and workflow_steps tables
- Deprecate text error column, rename to errorJson with fallback parsing
- Remove JSON.stringify from error writes (run_failed, step_failed, step_retrying)
- Add parseErrorJson helper for backwards compatibility with legacy data

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

* Use WorkflowRuntimeError and improve run entity handling in core runtime

- Replace generic Error with WorkflowRuntimeError for runtime assertions
- Add explicit check for run entity in run_created response
- Use run.runId instead of event.runId for consistency
- Use actual run status instead of hardcoded 'pending' in attributes

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

* Add specVersion to Step, Hook, and Event entities

- Add specVersion field to Step, Hook, and Event interfaces in @workflow/world
- Add spec_version column to steps, hooks, events tables in postgres schema
- Set specVersion to SPEC_VERSION_CURRENT when creating entities in all worlds
- Update migration to include spec_version columns for all entity tables

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

* Refactor world-local storage into modular files

Split storage.ts (1041 lines) into smaller, focused modules:
- storage/filters.ts: Data filtering helpers
- storage/helpers.ts: ULID and date utilities
- storage/hooks-storage.ts: Hook CRUD operations
- storage/legacy.ts: Legacy event handling
- storage/runs-storage.ts: Run get/list operations
- storage/steps-storage.ts: Step get/list operations
- storage/events-storage.ts: Event create/list operations
- storage/index.ts: Main composition

Also extracted test helpers to test-helpers.ts for reusability.

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

* Remove genversion and World.specVersion property

The World.specVersion string property was never actually read - only
the numeric SPEC_VERSION_CURRENT is used for backwards compatibility.

- Remove genversion dependency and generated version.ts from @workflow/world
- Remove specVersion property from World interface and all implementations
- Minor fix: correct error message to reference 'workflow' package
- Minor fix: correct error source priority in world-vercel events.ts
- Minor fix: update comment in runtime.ts

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

* Remove genversion from world-local, world-postgres, and world-vercel

These packages no longer need genversion since we removed the
World.specVersion property in the previous commit.

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

* Remove version.ts from .gitignore files

No longer needed after removing genversion.

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

* Add legacy/backwards compatibility tests

Tests for world-local and world-postgres covering:
- Legacy runs (specVersion < 2 or null/undefined)
  - run_cancelled handling (updates run, no event stored)
  - wait_completed handling (stores event only)
  - Rejection of unsupported events
  - Hook cleanup on cancellation
- Future runs (specVersion > current)
  - Rejection with RunNotSupportedError
- Current version runs (normal processing)
- Legacy error parsing (errorJson field parsing)

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

* Add hook_received support for legacy runs

When resumeHook() is called on a legacy run (specVersion < 2), the
hook_received event was previously rejected. This adds support for
storing hook_received events on legacy runs without entity mutation,
matching the behavior of wait_completed.

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

* Fix missing genversion in world-vercel

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

* Remove deprecated workflow_completed, workflow_failed, and workflow_started events

Replace with run_completed, run_failed, and run_started equivalents.

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

* Add specVersion to EventWithRefsSchema in world-vercel

The manually-created EventWithRefsSchema was missing the specVersion field,
which caused specVersion to be stripped when using lazy (refs) mode for events.

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

* Wire specVersion from client through world backends

- Core runtime now sends specVersion in run_created eventData
- world-local accepts specVersion from eventData (defaults to current)
- world-postgres accepts specVersion from eventData (defaults to current)

This matches workflow-server behavior where v2 endpoints accept
specVersion from the client, while v1 endpoints default to legacy.

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

* Move specVersion to event object level, propagate to entities

- Add specVersion to BaseEventSchema (event level, not eventData)
- Remove specVersion from RunCreatedEventSchema.eventData
- Core runtime sends specVersion on event object
- world-local reads specVersion from event, propagates to run/step/hook entities
- world-postgres reads specVersion from event, propagates to run/step/hook entities

This ensures specVersion flows from client through event to all created entities.

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

* Update specVersion to be optional in types for backwards compatibility

- specVersion is optional in all entity schemas (runs, steps, hooks, events)
  for backwards compatibility with legacy data in storage
- Runtime always sends specVersion on event requests
- world-local and world-postgres provide fallback to SPEC_VERSION_CURRENT
- Test helpers include specVersion in all event creation calls
- EventWithRefsSchema in world-vercel defaults specVersion to 1 for legacy

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

* Fix world-vercel queue tests missing VERCEL_DEPLOYMENT_ID setup

Two tests were calling queue.queue() without setting up
VERCEL_DEPLOYMENT_ID, causing them to fail with "No deploymentId
provided" error before reaching the code they were testing.

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

* Add specVersion to all event creation calls in core package

The server's CreateEventSchemaV2 requires specVersion on all events,
but only run_created was sending it. This caused 400 Bad Request errors
for all other event types (run_started, run_completed, run_failed,
run_cancelled, step_created, step_started, step_completed, step_failed,
step_retrying, hook_created, hook_received, wait_created, wait_completed).

Now all event creation calls include specVersion: SPEC_VERSION_CURRENT.

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

---------

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-01-22 17:24:52 -08:00
Nathan Rajlich 5ba82ec4b1 Add workflow health CLI command and web functionality (#816) 2026-01-21 12:48:03 -08:00
Peter Wielander 714b233005 [world-local] Update log message when PORT not set, and make less prominent (#811) 2026-01-20 11:05:20 +01:00
Peter Wielander abdca8fd52 [web] Observability config overhaul (#774) 2026-01-14 23:22:30 +01:00
Pranay Prakash 3fb57e14c8 feat(web): add self-hosted mode for world configuration (#747)
* feat(web): add self-hosted mode for world configuration

When WORKFLOW_TARGET_WORLD env var is set, the web UI operates in
self-hosted mode where the world configuration is locked to server-side
environment variables and cannot be changed via query params or UI.

- Add getHardcodedConfig server action to detect self-hosted mode
- Modify getWorldFromEnv to use server env vars in hardcoded mode
- Create WorldConfigContext to provide config state app-wide
- Update settings sidebar to show locked state with disabled inputs
- Update connection status to show PostgreSQL backend info
- Mask sensitive values (postgres URL) in hardcoded mode UI

* fix: address PR review feedback

- Remove unused ConfigMode type export
- Fix postgres substring to undefined (tooltip has details)
- Extract buildEnvMapFromProcessEnv helper to reduce duplication
- Remove unused EnvMap import from layout-client
- Import HardcodedConfig from web-shared/server instead of re-defining

* Fix: PostgreSQL URL parameter missing from configParsers, causing loss of postgres URL configuration on page reload in dynamic mode

* fix(cli): clear WORKFLOW_TARGET_WORLD when spawning web server

The CLI sets WORKFLOW_TARGET_WORLD as an env var, which the spawned
Next.js server inherits. This caused the web UI to enter self-hosted
mode even when launched via CLI.

Now we explicitly clear WORKFLOW_TARGET_WORLD from the server's
environment so it starts in dynamic mode where config comes from
query params as intended.

* refactor(web): use server-side env vars for world config

BREAKING CHANGE: The web UI no longer supports configuring the world
backend via URL query parameters. Configuration is now read exclusively
from server-side environment variables.

Changes:
- Remove query param parsing from @workflow/web config.ts
- Add ServerConfig interface with non-sensitive display info
- Update all components to use useServerConfig() hook
- Settings sidebar is now read-only
- CLI passes env vars to spawned web server instead of query params
- Server actions use process.env directly (envMap param reserved for future use)

This simplifies the architecture and improves security by never sending
sensitive data (connection strings, auth tokens) to the client.

* fix(web): fix settings sidebar overflow and shorten data dir path

- Add truncate/overflow handling to settings sidebar config values
- Add shortenPath() helper to abbreviate long file paths:
  - Replaces home directory with ~
  - Shows .../last-two-segments if still too long
- Add title attributes for full path on hover

* Update changeest

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-01-08 18:38:56 -08:00
Peter Wielander dd3db13d54 [world] Remove pause and resume events, actions and states (#751) 2026-01-08 19:29:17 +01:00
Peter Wielander e7de61f8b8 Local ui cli flag (#744) 2026-01-08 11:01:03 +01:00
Peter Wielander 05ecfbcc11 [cli] Ensure npm pre-release versioning works for post-GA release pre-releases (#722)
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
2026-01-07 13:13:09 +01:00
Peter Wielander 1a305bf918 [cli] Print notice on CLI startup when detecting an outdated version (#701) 2026-01-02 17:45:20 +01:00
Peter Wielander 80955e7212 [cli] [web] Allow opening web UI without config validation, show better UI when runs can't be found (#684) 2025-12-28 17:55:24 +01:00
Karthik Kalyanaraman e3f0390469 Workflows graph extractor (#455)
---------

Signed-off-by: Karthik Kalyanaraman <karthik@scale3labs.com>
2025-12-27 16:52:19 +01:00
Peter Wielander 0cf0ac3211 [util] Extract helper function to find local world dataDir across CLI/UI (#682) 2025-12-23 20:42:42 +01:00
Peter Wielander c059cf6fcd [cli] Only do interactive pagination when using the -i flag (#669) 2025-12-23 14:05:06 +01:00
Peter Wielander 4bdd3e5086 Move auth error messages into @workflow/errors package (#638) 2025-12-17 16:54:29 +01:00
Peter Wielander deaf0193e9 [world-vercel] Allow skipping vercel backend proxy for e2e tests where CLI runs in runtime env (#627) 2025-12-16 20:44:05 +01:00
Peter Wielander 161c54ca13 [web] [cli] Add Web and CLI UI for listing and viewing streams (#575) 2025-12-08 18:10:02 -08:00
Peter Wielander c82b46720c [world] Add Streamer.listByRunId method to list all streams for a run (#574) 2025-12-08 16:05:44 -08:00
Peter Wielander 57a2c328ca [world] Add expiredAt attribute to Run (#515) 2025-12-04 12:05:58 -08:00
Peter Wielander 8d4562e856 [world-local] Finish renaming embedded world to local world (#441) 2025-12-02 09:12:40 -08:00
Peter Wielander 11469d8fd2 CLI/Web: Update fallback directory for embedded world (#291) 2025-11-10 11:54:00 -08:00
Peter Wielander 00efdfb063 Web: Improve trace viewer load times and loading animation (#270) 2025-11-08 10:21:57 -08:00
Peter Wielander d71da4acb5 Web-shared: update packaging to support projects with node16 style module resolution (#214) 2025-11-04 18:16:11 -08:00
Nathan Rajlich 03faac19db Fix CLI --web flag on Windows (#207)
---------

Signed-off-by: Nathan Rajlich <n@n8.io>
2025-11-04 13:09:40 -08:00
Pranay Prakash a09a3ea091 remove old builder code (#202)
* remove old builder code

* changeset
2025-11-04 10:43:25 -08:00
Pranay Prakash 10bfd4aea8 refactor: extract path resolution and directory creation helpers (#81)
* feat: add type safety for builder configurations with discriminated unions

Improves type safety by creating discriminated union types for builder-specific
configurations, making it clear which configuration options are required for
each builder type.

Changes:
- Created BaseWorkflowConfig interface with common options
- Created StandaloneConfig, VercelBuildOutputConfig, and NextConfig types
- Made WorkflowConfig a discriminated union based on buildTarget
- Added documentation for each configuration type
- Exported new types from @workflow/builders

This enables better IntelliSense and type checking when constructing builder
configurations, preventing invalid configuration combinations at compile time.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor: extract path resolution and directory creation helpers

Adds reusable helper methods to BaseBuilder for common path operations,
reducing code duplication and improving readability in builder subclasses.

Changes:
- Added resolvePath() helper in BaseBuilder
- Added ensureDirectory() helper in BaseBuilder
- Updated StandaloneBuilder (both in @workflow/builders and @workflow/cli)
  to use the new helpers
- Removed unnecessary imports from StandaloneBuilder

This simplifies path handling code from:
  const path = resolve(this.config.workingDir, this.config.somePath);
  await mkdir(dirname(path), { recursive: true });

To:
  const path = this.resolvePath(this.config.somePath);
  await this.ensureDirectory(path);

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Nathan Rajlich <n@n8.io>

---------

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-03 23:30:05 -08:00
Pranay Prakash bf54a7b061 refactor: standardize method naming and clarify log messages (#79)
Improves code consistency by standardizing method naming conventions and
clarifying log messages across builders.

Changes:
- Renamed buildClientLibrary() to createClientLibrary() in BaseBuilder to match
  the convention where "create" is used for protected/shared methods
- Updated all callers in StandaloneBuilder and VercelBuildOutputAPIBuilder
- Clarified log messages in StandaloneBuilder by removing "Vercel API" prefix
  since this builder is framework-agnostic

This establishes a clear pattern:
- Public/template methods in subclasses: build* (buildStepsFunction, etc.)
- Protected/shared methods in BaseBuilder: create* (createStepsBundle, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-03 23:03:56 -08:00
Pranay Prakash 4585222c75 refactor: deduplicate package.json and .vc-config.json generation (#77)
Extracts repeated package.json and .vc-config.json generation logic into
reusable helper methods in BaseBuilder, eliminating code duplication across
VercelBuildOutputAPIBuilder.

Changes:
- Added createPackageJson() helper method to BaseBuilder
- Added createVcConfig() helper method with sensible defaults
- Updated VercelBuildOutputAPIBuilder (both in @workflow/builders and @workflow/cli)
  to use the new helper methods
- Reduced configuration code from ~20 lines per function to ~3 lines

This makes the build code more maintainable and ensures consistent configuration
across all Vercel Build Output API functions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-03 22:55:01 -08:00
Pranay Prakash 5dfa4eb9f1 refactor: extract queue trigger configuration constants (#76)
Consolidates duplicated queue trigger configurations into shared constants
in @workflow/builders package, eliminating repetition across multiple builders.

Changes:
- Created STEP_QUEUE_TRIGGER and WORKFLOW_QUEUE_TRIGGER constants
- Updated VercelBuildOutputAPIBuilder to use shared constants
- Updated NextBuilder (both in @workflow/next and @workflow/cli) to use constants
- Exported constants from @workflow/builders index

This ensures consistent queue configuration across all builders and makes
future updates to these settings easier to manage from a single location.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-03 22:35:01 -08:00
Adrian 05714f7924 feat: add sveltekit support (#131)
* add workbench sveltekit

* add sveltekit package

* fix: use js for generated server routes in svelte

* add test routes for sveltekit workbench

* updates from debugging

* feat: add sveltekit build target

* update user sign up workflow workbench sveltekit

* fix: base builder missing GET route handler for sveltekit

* feat: add vercel builder and check for vercel env

* refactor: workflowPlugin for sveltekit

* ci: add tests to workbench sveltekit

* fix: no start command and vercel builder outputs

* fix: base builder conditions

* .

* add auto adapter sveltekit

* fix: disable checking origin for cross site ci stuff

* allow all trusted origins in svelte config

* fix: add catch for error thrown when waiting for ops

* fix: sveltekit workbench adapter

* test

* test

* refactor: move vercel builder on config resolved

* update package json

* add demo workflow trigger

* test letting sveltekit handle route generation

* fix: exclude git ignore for local builder outputs

* update config

* add debug logs

* update debug

* update turbo.json

* fix env check

* another output

* use top-level await

* ensure vercel functions are patched

* change hook

* update

* fix spread

* debug

* update

* chore: remove vercel builder

* chore: update comments in sveltekit workflow package

* chore: remove console comment

* refactor: workflow svelte plugin

* refactor: simplify local builder config

* chore: remove unused deps

* chore: add comment for workbench svelte app

* chore: add sveltekit export to workflow

* export sveltekit from workflow

* lockfile

* chore: remove unused deps svelte workbench

* update styling

* add sveltekit getting started docs

* update sveltekit docs getting started

* changeset

* Apply suggestion from @vercel[bot]

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* use proper env var

* Update packages/sveltekit/src/index.ts

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* Update docs/content/docs/getting-started/sveltekit.mdx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Document CSRF protection bypass in SvelteKit workbench config (#157)

* Initial plan

* docs: add CSRF security warning to svelte.config.js

Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com>

* refactor: deduplicate SvelteKit request conversion logic (#156)

* Initial plan

* refactor: extract duplicated SvelteKit request conversion to helper

Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com>

* docs: fix getting staretd sveltekit missing folder

* chore: cleanup sveltekit builder after rebase

* lockfile

* fix: sveltekit building logic in base builder

* refactor: move sveltekit builder logic to its own package

* fix: console log base builder

* changeset

* test

* feat: create hmr plugin

* fix: add initial build on load

* fix: check all files for workflows and steps

* add comments for plugin todo

* remove catching error

* fix: missing context for nodejs envs causing waitUntil to fail

* fix: setting global request conext in vercel environments

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2025-11-03 21:15:33 -08:00
Pranay Prakash 2363e472ca feat: move NextBuilder to @workflow/next package (#74)
Moves NextBuilder from @workflow/cli to @workflow/next package, establishing
proper package boundaries where framework-specific builders live in their
respective framework integration packages.

Changes:
- Moved NextBuilder from @workflow/cli to @workflow/next
- Added @workflow/builders and watchpack dependencies to @workflow/next
- Updated runtime re-export to use @workflow/core/dist/runtime directly
- Removed direct dependency on @workflow/cli from @workflow/next

This aligns the Next.js builder with the Nitro builder pattern (which already
lives in @workflow/nitro), creating consistent package organization.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 14:25:14 -08:00
Pranay Prakash 652485aa30 feat: create @workflow/builders package with shared builder infrastructure (#73)
This commit extracts builder infrastructure from @workflow/cli into a new
shared @workflow/builders package. This improves code organization by:

- Creating a dedicated package for builder functionality
- Allowing @workflow/next and @workflow/nitro to depend on builders directly
- Reducing coupling between framework integrations and the CLI
- Preparing for moving NextBuilder to @workflow/next in the next PR

Changes:
- Created new @workflow/builders package
- Moved BaseBuilder, BasicBuilder, and VercelBuildOutputAPIBuilder
- Moved esbuild plugins (swc, discover-entries, node-module)
- Moved WorkflowConfig and BuildTarget types
- Updated @workflow/cli to import from @workflow/builders
- Updated @workflow/nitro to import from @workflow/builders
- Re-exported types from CLI for backwards compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 13:37:39 -08:00
Peter Wielander a3326a257c Add workflow inspect sleep command to list active sleep/wait events (#170) 2025-10-31 15:24:49 -07:00
Peter Wielander e367046105 World-vercel: allow proxying queue endpoint (#130) 2025-10-29 17:24:13 -07:00
Peter Wielander 0f845afb2a Alias workflow web to workflow inspect runs --web, update o11y doc image, hide trace viewer search for small runs (#124) 2025-10-28 17:19:39 -07:00
Peter Wielander eadf588573 Web: Add button to re-run workflows (#94) 2025-10-27 13:10:34 -07:00
Peter Wielander dbf2207b7c Web: refactor active/hover styles from trace viewer to avoid color conflicts (#45) 2025-10-26 13:45:14 -07:00
Pranay Prakash 66332f2897 Rename "vercel-static" build mode to "standalone" (#71) 2025-10-26 00:37:35 -07:00
Pranay Prakash dfdb280f59 Generate the webhook route in the static builder (#67) 2025-10-25 16:20:13 -07:00
Gal Schlezinger 4ca9a3edbd Introducing Workflow DevKit
build durable, resilient, and observable workflows.

Co-authored-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: Adrian <me@adriandlam.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
Co-authored-by: Gal Schlezinger <gal@spitfire.co.il>
Co-authored-by: Manuel Muñoz Solera <mamuso@mamuso.net>
Co-authored-by: Garrett <garrett.tolbert@vercel.com>
Co-authored-by: Lars Grammel <lars.grammel@gmail.com>
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
Co-authored-by: Tom Dale <tom@tomdale.net>
Co-authored-by: Vishal Yathish <135551666+visyat@users.noreply.github.com>
Co-authored-by: josh <144584931+dancer@users.noreply.github.com>
2025-10-23 12:07:52 +03:00