Commit Graph

62 Commits

Author SHA1 Message Date
Will Binns-Smith a51910b29a fix(next): always apply turbopack content condition regardless of builder mode (#2253)
* fix(next): always apply turbopack content condition regardless of builder mode

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

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

* add changeset

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-06-05 14:31:18 -07:00
JJ Kasper 0b8b077345 Fix Next lazy step route imports (#2263) 2026-06-05 09:05:19 -07:00
Peter Wielander 1e6b1fdea2 Attributes MVP (experimental and write-only) and CI hardening (#2134)
* fix(core): scan inline sourcemaps during error remapping

* Attributes MVP (experimental and write-only) (#2088)
2026-05-28 18:06:46 +00:00
Nathan Rajlich 070bd0cea9 [next] make lazyDiscovery the default in withWorkflow (#1805)
* [next] make lazyDiscovery the default in withWorkflow

Flips the default for `workflows.lazyDiscovery` from `false` to `true`
so new projects get deferred workflow discovery automatically on Next.js
versions that support deferred entries (>= 16.2.0-canary.48). Older
versions continue to fall back to eager discovery.

Users can still opt back into eager discovery explicitly by passing
`workflows: { lazyDiscovery: false }`.

Also:
- Remove the now-redundant `lazyDiscovery: true` from the Next.js
  workbench apps.
- Reword the fallback warning for clarity when lazy is the default.
- Update the local-build e2e assertion to match the new warning text.
- Update the withWorkflow docs with the new default.

* [workbench] remove commented 'export default nextConfig' lines
2026-05-22 14:11:34 +00:00
Pranay Prakash 0d0bb013d7 Generate local gitignore when using public workflow manifests (#1683)
Co-authored-by: Peter Wielander <peter.wielander@vercel.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-05-22 15:22:25 +02:00
Luke Sandberg 4cde3b962b fix bad socket file location (#2021)
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-05-19 12:11:00 -07:00
Nathan Rajlich 0c997ce571 Auto-remove workflow packages from serverExternalPackages (#1481)
* Warn when serverExternalPackages hides workflow-enabled packages

Add a build-time warning when packages in serverExternalPackages contain
workflow code ('use step', 'use workflow', or serialization classes).
These packages are completely invisible to the workflow compiler when
externalized, causing silent runtime failures.

The warning detects workflow patterns via two methods:
- Fast path: check package.json dependencies for @workflow/serde
- Thorough path: read the package entry file and run pattern detection

Also adds documentation in the serialization guide about the
externalization footgun for 3rd-party packages.

* Auto-remove workflow packages from serverExternalPackages

When workflow-enabled dependencies are externalized in Next.js, compiler transforms are skipped and runtime failures follow. Detect those packages in withWorkflow, remove them from serverExternalPackages for the current build, and keep a generalized externalPackages warning fallback for non-Next builders.

* Address review feedback: add entry-point limitation comment and missing test case
2026-05-05 09:10:30 +00:00
JJ Kasper 00a011dee4 Add stable Next.js eager and lazy test coverage (#1747)
* Add stable Next.js eager and lazy test coverage

* Address PR review feedback

* Fix eager Next step route builds

* Fix eager Next manifest refreshes

* Fix eager Next e2e stack assertions

* Externalize native step bundle bindings

* Lazy load Vercel world runtime

* Fix Next dev step sourcemap assertions

* Consolidate eager build changesets

* Fix Vercel world tracing in Next deployments

* Externalize Vercel world in Next builds

* Fix webpack tracing for Vercel world deps

* Fix eager workflow route bundling

* Rely on Next server externals
2026-05-04 21:09:20 +00:00
Peter Wielander 6dd5c72d8a Allow disabling step sourcemap with new sourcemap option in builders (#1842) 2026-05-04 11:00:15 +00:00
Peter Wielander 8ea1532e48 [core] Combine flow+step bundle and process steps eagerly (#1338) 2026-05-04 09:53:02 +00:00
Nathan Rajlich 906f7c1213 refactor(next): remove step file copy mechanism from deferred builder (#1796)
* refactor(next): remove step file copy mechanism from deferred builder

Step sources are now imported directly into the generated `step/route.js`
using the same `getImportPath`-based logic already used for serde files.
This is possible because the SWC plugin's client mode was merged into
step mode (#1686), so the workflow loader always runs in step mode and
transforms every file it sees, including those from packages.

Removed:
- `__workflow_step_files__/` per-file copies with hashed names, metadata
  comments, inline source maps, and bare-specifier rewriting via
  `enhanced-resolve`
- `createResponseBuiltinsStepFile`; builtins are now imported via
  `require.resolve('workflow/internal/builtins')` at build time
- `step-copy-utils.ts` and all copy-specific branches in `loader.ts`
- `enhanced-resolve` dependency

The deferred builder still removes the legacy `__workflow_step_files__/`
directory on boot so upgrades leave no stale artifacts behind.

Dev tests that inspected copied step file contents now inspect the
manifest.json entries (which list every discovered step keyed by source
path).

* refactor(next): scrub historical phrasing from code comments

* test: update next step stack expectations

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-04-29 21:23:08 +00:00
JJ Kasper baba580794 Write Next diagnostics to dist dir (#1857)
* Write Next diagnostics to dist dir

* Simplify Next dist dir config access
2026-04-28 22:02:03 +00:00
Nathan Rajlich 417c4930be refactor(swc-plugin): remove client transform mode, merge into step mode (#1686)
* refactor(swc-plugin): remove client transform mode, merge into step mode

Remove the `client` transform mode from the SWC compiler plugin. The
`client` and `step` modes were nearly identical — both preserved step
function bodies, replaced workflow bodies with throw stubs, and emitted
the same JSON manifest. Step mode now absorbs all client-mode behaviors:

- Dead code elimination (previously only workflow + client)
- Hoisted variable references for object property steps
- All integrations use mode: 'step' instead of 'client'

BREAKING CHANGE: The `client` value for the SWC plugin `mode` option is
no longer accepted. Use `step` instead.

* fix(nitro): force-inline workflow packages in dev mode for serde classId registration

In dev mode, Nitro's Rollup externalizes npm packages like @workflow/core,
so the SWC transform plugin never processes files like run.js. This means
serde classes (e.g. Run) never get the classId registration IIFE, causing
serialization failures when step functions return Run instances.

Uses a Rollup resolveId hook to force workflow SDK packages to be bundled
(non-external) while leaving all other dependencies external. This is more
targeted than noExternals=true which bundles everything and causes TDZ
errors from circular imports in packages like vue-bundle-renderer/h3.

The Nitro module now also ignores .nitro/workflow/** in watchOptions so
writing generated workflow bundles does not retrigger Nitro's own dev
bundle rebuild loop.

Also wraps dev:reload workflow rebuilds and makes LocalBuilder.build()
atomic (writes to temp files, renames on success) to avoid partial output
state during HMR.

For Nuxt, also configures Vite's ssr.noExternal to bundle workflow
packages in the SSR context.

* fix(nitro,nuxt): address review feedback on dev-mode classId fix

- nitro builders: use crypto.randomUUID() for temp file suffix instead of
  Date.now() to avoid collisions under rapid/concurrent build() calls,
  and serialize concurrent build() calls through an internal queue so
  two overlapping dev rebuilds cannot clobber each other's temp outputs.

- nitro index: use fileURLToPath() to convert file:// URLs to filesystem
  paths, which correctly handles Windows paths (file:///C:/... -> C:\...)
  and percent-decoding, instead of relying on new URL(...).pathname.

- nuxt module: normalize vite.ssr.noExternal to an array (preserving any
  existing string/RegExp/array entry) before appending workflow package
  matchers, so the force-bundle behavior is not a no-op when noExternal
  is already set to a non-array value.
2026-04-16 22:50:46 +00:00
Nathan Rajlich fe131105f2 fix(next): resolve next/package.json from working directory first (#1701)
* fix(next): resolve next/package.json from working directory first

In npm workspaces monorepos, `@workflow/next` can be hoisted to the root
`node_modules/` while `next` stays in a workspace's local `node_modules/`.
The eager `require('next/package.json')` on the fallback path resolved
relative to `@workflow/next`'s own location, failing before the correct
working-directory-relative resolution could run.

Restructure `resolveNextVersion()` to try the working directory path first,
fall back to the package-relative path second, and wrap both in separate
try/catch blocks so neither can crash the process.

Closes #1680

* fix(next): capture resolution errors and include workingDir in error message

Address review feedback: capture caught errors from both resolution
attempts and attach them via `cause` on the final thrown error. Include
the working directory in the error message to aid debugging in monorepo
and CI environments.
2026-04-13 17:35:00 +00:00
JJ Kasper 644d6b8ada fix(next): skip eager discovery in deferred build mode (#1646)
* fix(next): skip eager discovery in deferred build mode

* fix(next): register deferred package steps on stable builds

* fix(next): include manifest package steps in deferred dev builds

* perf(next): reduce deferred manifest step discovery overhead

* fix(next): remove deferred debug logs in deferred builder/loader

* fix(next): restore socket env precedence and robust stub detection

* fix(next): check project-root socket fallback path

* fix(next): make manifest step path resolution windows-safe
2026-04-09 21:07:10 +00:00
Nathan Rajlich 32a17b4033 fix(next): resolve bare specifiers in copied step files for lazy discovery (#1670)
* fix(next): resolve bare specifiers in copied step files for lazy discovery

When the deferred builder copies step files to __workflow_step_files__/,
bare specifiers that are transitive SDK deps can't resolve from the app
directory. Use enhanced-resolve with ESM conditions (preferring 'import'
over 'require') to resolve from the original source location, only when
the specifier can't be resolved from the app directory.

Also add enhanced-resolve to the pnpm catalog and use catalog: in both
@workflow/builders and @workflow/next.

* fix(next): address review feedback on lazy discovery resolver

- Cache ESM/CJS resolvers as class fields instead of re-creating per call
- Remove redundant try/catch (resolveBareCopiedStepSpecifier already
  returns undefined on failure)
- Use shared NODE_RESOLVE_OPTIONS / NODE_ESM_RESOLVE_OPTIONS matching
  the configuration in swc-esbuild-plugin.ts for consistent resolution
2026-04-09 19:20:07 +00:00
Nathan Rajlich 89d242fae2 Remove isWorkflowSdkFile serde exclusion (#1662)
* Remove isWorkflowSdkFile serde exclusion

The SWC detect mode's AST-level manifest (hasManifestEntries) already
correctly filters files without serde class definitions. The broad
isWorkflowSdkFile path exclusion is redundant and was preventing
class definitions in SDK packages from being discovered.

Removed from: builders, next, rollup

* Address review feedback: major semver bump, fix doc comment, add tests

- Bump changeset to major (removing exported APIs is breaking)
- Fix misleading doc comment referencing 'detect mode' in shouldTransformFile
- Add unit tests for shouldTransformFile covering all code paths

* Add AST-level serde filtering to Next.js deferred builder

The isWorkflowSdkFile path-based exclusion was removed from all paths,
but the Next.js deferred builder (collectTransitiveSerdeFiles) was still
using regexp-only detection, causing SDK internal files to be bundled
into the workflow sandbox and triggering stack overflows.

Fix: add applySwcTransform('detect', ...) verification at the end of
collectTransitiveSerdeFiles(). Regex-matched serde candidates are now
verified via the SWC plugin's AST-level manifest to confirm they
actually define serde classes before inclusion in the bundle.
2026-04-08 18:07:39 -07:00
Nathan Rajlich 35b539b146 Add detect mode to SWC plugin for false positive directive filtering (#1641)
* Add detect mode to SWC plugin for false positive directive filtering

Add a new 'detect' mode to the SWC workflow plugin that walks the AST
to find directives and serde patterns and emits the manifest, but does
not transform any code. The discover-entries plugin now uses a two-phase
approach: fast regexp pre-scan to filter out most files, then SWC detect
mode on candidates to validate at the AST level. This eliminates false
positives where directive-like strings appear inside template literals
or other non-code contexts. The mode:false syntax-only transform is also
removed since esbuild handles TypeScript natively.

* Keep SWC syntax transform in discover phase for decorator support

esbuild does not support legacy decorators or emitDecoratorMetadata,
so all files still need the SWC syntax transform (TS→JS) during
discovery. For regexp-matched files the 'detect' mode handles both
the syntax transform and manifest in a single pass; for all other
files the existing mode:false call is used.

* Use Set for discoveredWorkflows/Steps/SerdeFiles

Eliminates the manual .includes() dedup check and prevents duplicate
entries structurally.

* Update DeferredDiscoveredEntries to use Set<string>

* Add @workflow/next to changeset
2026-04-07 16:53:55 -07:00
John Lindquist 5aab85b81b fix(next): remove unused dataDir option from withWorkflow() (#1619)
The `dataDir` option was accepted in the type definition but never
read — `WORKFLOW_LOCAL_DATA_DIR` was unconditionally set to
`.next/workflow-data`. Remove the dead option to avoid confusion.
2026-04-07 10:51:47 -07:00
Nathan Rajlich 44290785e1 fix(next): stop force-setting WORKFLOW_PUBLIC_MANIFEST=1 during next dev (#1597) 2026-04-02 22:49:14 +00:00
Peter Wielander 6dc1b78582 [core] Extend flow route duration to "max" and fail runs where replay takes too long (#1567) 2026-04-01 21:33:39 +00:00
Pranay Prakash ef4ca00b77 chore: bump next to 16.2.1 and fix deferred build (#1496)
* chore: bump next to 16.2.1

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

* test: run deferred Next dev e2e assertions on stable

Bump Next.js to 16.2.1 in docs and swc-playground and update lockfile.

* fix(next): copy all deferred step sources for step-mode transforms

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-03-23 21:25:28 -07:00
JJ Kasper 5010ebe7c5 fix(next): stabilize deferred canary e2e in nextjs workbenches (#1468)
* Revert "[ci] Fix nextjs lazy disocvery impacting e2e tests, disable experimental DurableAgent tests (#1400)"

This reverts commit a2c0c7e6d9.

* fix(next): stabilize deferred discovery on canary builders

* revert canary bump

* fix(next): stabilize local e2e discovery for webpack and turbopack

* fix(next): avoid copying sdk builtins in deferred step routes

* fix(next): restore deferred sdk step registration on canary

* fix(next): stabilize deferred discovery under canary watch
2026-03-23 10:56:30 -07:00
Andrew Barba 30aba2411b fix(builders) - support explicit project roots in swc transforms (#1399)
* fix(builders) - support explicit project roots in swc transforms

* fix(builders) - normalize windows expectations in discovery test

* fix(builders) - use normalized paths in discovery plugin applySwcTransform calls

* fix(next) - reuse outputFileTracingRoot for builder projectRoot

---------

Co-authored-by: Nathan Rajlich <n@n8.io>
2026-03-20 01:07:44 +00:00
Nathan Rajlich 3cc29431b2 Set maxDuration: "max" in vc-config for workflow functions (#1420)
* Set maxDuration: "max" in vc-config for workflow functions

* Use maxDuration: 60 for flow route, "max" for step/webhook

* Remove explicit maxDuration from webhook route, rely on plan default
2026-03-17 14:08:46 -07:00
Peter Wielander a2c0c7e6d9 [ci] Fix nextjs lazy disocvery impacting e2e tests, disable experimental DurableAgent tests (#1400) 2026-03-16 12:30:48 -07:00
JJ Kasper a9fea9132e Update workbench tests to build and run outside of monorepo (#1230)
* Setup fixes

* ci: run local e2e against staged tarball workbenches

* ci: update staged workbench tarball setup script

* chore: set nextjs workbenches back to next 16.1.6

* update lock

* test(e2e): resolve workbench path from WORKBENCH_APP_PATH

* fix: address deferred builder issues outside monorepo

* ci: stage tarball workbenches only for nextjs local e2e

* fix(next): discover deferred steps imported via workflows

* test(core): gate deferred step-discovery dev test to canary

* test(e2e): cover cross-file imported step in build/start lanes

* fix(e2e): use local manifest in local runs and relax dev rebuild timeout

* fix(workbench): add imported-step workflow symlink for sveltekit/astro

* test(e2e): scope imported-step workflow test to nextjs lanes

* fix(next): rebuild deferred entries on discovered file updates

* fix(next): watch transitive deferred step deps for dev rebuilds

* fix(next): restore socket-driven deferred step rebuilds

* add changeset

* chore: address review feedback on deferred e2e updates

* fix(cli): guard stream flush against closed write streams
2026-03-03 11:17:39 -08:00
Nathan Colosimo 339c343922 [next] Avoid package.json resolver failures in loader dep tracking (#1192)
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
2026-02-26 13:01:12 -08:00
JJ Kasper b733e2a173 Unlock canary Next.js version in tests and bump min deferred version (#1088)
* Unlock canary Next.js version

* bump min version
2026-02-16 17:27:16 -08:00
JJ Kasper f4a1994c4b Fix condition for lazy discovery with canary (#1038)
* Fix condition for lazy discovery with canary

* revert test change
2026-02-13 10:13:36 -08:00
JJ Kasper 01e8e80462 Make lazy discovery in Next.js opt-in (#1036) 2026-02-13 16:36:24 +00:00
JJ Kasper 94760b4640 Track loader transform deps instead of clearing Next cache (#1029)
* Track loader transform dependencies and remove SWC cache invalidation

* changeset
2026-02-12 17:41:47 -08: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
JJ Kasper a5935abec7 Add lazy workflow/step discovery via deferredEntries in next (#976)
* Add lazy workflow/step discovery via deferredEntries in next

* discover serde in loader

* fix implicit steps discovery

* update serde

* fix symlink case

* pre-warm non-next

* add resolution cache

* Fix deferred build error propagation and restore start-arg workflow

* revert

* Fix step function alias lookup and dev prewarm stability

* Fix step function alias tests for updated reviver context

* next: address deferred discovery review feedback

* update lockfile

* builders: extract shared workflow alias resolver

* chore: pin next deps to latest canary

* unlock from canary version from testing
2026-02-10 12:03:59 -08:00
Nathan Rajlich 661724c01e Expose workflow manifest via HTTP when WORKFLOW_PUBLIC_MANIFEST=1 (#963)
## Summary

When `WORKFLOW_PUBLIC_MANIFEST=1` is set, each framework builder exposes the workflow manifest at `/.well-known/workflow/v1/manifest.json` via the most appropriate mechanism for the framework:

- **Next.js**: Copies manifest to `public/.well-known/workflow/v1/manifest.json` (served as a static file)
- **SvelteKit**: Copies manifest to `static/.well-known/workflow/v1/manifest.json` (served as a static file)
- **Vercel Build Output API** (example workbench): Copies manifest to `.vercel/output/static/.well-known/workflow/v1/manifest.json` (served as a static file)
- **Nitro** (vite, hono, express, fastify, nuxt, nitro-v2, nitro-v3): Registers a virtual handler that reads and serves the manifest JSON
- **Astro**: Generates a `manifest.json.js` page route that returns the manifest JSON
- **NestJS**: Adds a `@Get('manifest.json')` endpoint on the `WorkflowController` (gated by the env var at runtime)

### Other changes

- `BaseBuilder.createManifest()` now returns the manifest JSON string so framework builders can use it
- Added `shouldExposePublicManifest` getter to `BaseBuilder`
- Fixed Astro `LocalBuilder` which was missing the `createManifest()` call that all other framework builders have
- Removed unused `public/` directory and static file copy from the example workbench build script
- Added `WORKFLOW_PUBLIC_MANIFEST` to `turbo.json` build task env so Vercel builds can access it
- Added generated manifest paths to `.gitignore`
2026-02-06 12:22:37 -08:00
Karthik Kalyan fc077108ef Remove dirs option (#961) 2026-02-05 22:56:03 -08:00
Nathan Rajlich 35a9f0cb03 Add subpath export resolution for package IDs (#901)
Fixed a bug in module specifier resolution and added support for package subpath exports in workflow IDs.

### What changed?

- Fixed a caching bug in the module specifier resolution system that could cause incorrect IDs
- Added support for subpath exports in package IDs (e.g., `workflow/internal/builtins@4.0.0`)
- Improved module resolution by passing absolute file paths to the SWC transform
- Enhanced manifest merging to properly combine results from both workflow and step bundles
- Updated builders to return and merge manifests from both workflow and step bundles

### How to test?

1. Build a project that uses subpath exports in packages
2. Verify that workflow IDs correctly include the subpath (e.g., `workflow/internal/builtins@4.0.0`)
3. Test with a project that has multiple builds to ensure module specifier caching works correctly

### Why make this change?

This change addresses an issue where the module specifier cache could return incorrect results, leading to inconsistent workflow IDs. It also adds support for packages with multiple entry points through subpath exports, ensuring that steps with the same name in different subpaths don't collide. This improves the reliability of cross-bundle references and makes the system more robust when working with complex package structures.
2026-02-04 16:49:16 -08:00
Nathan Rajlich 73bf7be925 Change compiler ID generation logic to use Node.js import specifier (#899)
## Summary

This PR changes how the SWC compiler generates IDs for workflows, steps, and classes. Instead of using raw file paths, IDs are now based on **Node.js module specifiers** when the file belongs to a package (either in `node_modules` or a workspace package).

## Motivation

Previously, IDs were generated using file paths like `step//src/jobs/order.ts//fetchData`. This caused several issues:

1. **Package exports conditions**: When a package uses conditional exports (e.g., `"workflow"` vs `"default"` conditions in `package.json`), the same import specifier can resolve to different files. Using file paths meant IDs could differ based on which export condition was used.
2. **Cross-bundle consistency**: Classes serialized in one bundle couldn't be deserialized in another if the file paths differed.
3. **Version tracking**: No way to include package versions in IDs for cache invalidation.

## Changes

### New ID Format

IDs now use the format `{type}//{modulePath}//{identifier}` where `modulePath` is either:

- A **module specifier** like `point@0.0.1` or `@myorg/shared@1.2.3` for package files
- A **relative path** prefixed with `./` like `./src/jobs/order` for local app files

Examples:

- `step//workflow@4.0.1-beta.50//fetch` (SDK step)
- `step//./workflows/order//processOrder` (local step)
- `class//point@0.0.1//Point` (package class)
- `class//./src/models/User//User` (local class)

### New Module Specifier Resolution

Added `packages/builders/src/module-specifier.ts` which:

- Detects if a file is in `node_modules` or a workspace package
- Finds the nearest `package.json` and extracts name/version
- Returns the module specifier for the SWC plugin to use

### SWC Plugin Changes

- Added `moduleSpecifier` option to plugin config
- Updated `naming.rs` to support both module specifiers and relative paths
- Added `get_module_path()` helper that uses specifier when available, falls back to `./filename` format

### Special Cases

- **Builtin functions** (`__builtin_*`): Continue to use just the function name as the ID for stable, version-independent lookup from the workflow VM runtime.

## Testing

- Updated all 125+ SWC plugin test fixtures to use new ID format
- Added tests for module specifier resolution
- Added tests for Windows path normalization in naming

## Breaking Changes

This is technically a breaking change for any persisted workflow runs that reference the old ID format. However, since IDs are internal implementation details and not user-facing, this should not affect end users.

## Files Changed

- `packages/builders/src/module-specifier.ts` - **NEW**: Module specifier resolution logic
- `packages/builders/src/apply-swc-transform.ts` - Pass module specifier to SWC plugin
- `packages/builders/src/base-builder.ts` - Use `getImportPath` for virtual entry imports
- `packages/swc-plugin-workflow/transform/src/lib.rs` - Accept and use module specifier
- `packages/swc-plugin-workflow/transform/src/naming.rs` - New ID formatting with module paths
- `packages/swc-plugin-workflow/spec.md` - Updated documentation
- `packages/core/e2e/e2e.test.ts` - Updated test assertions for new ID format
2026-02-04 14:23:02 -08:00
JJ Kasper 8ab1ba24d6 Add Next.js cache invalidation on swc transform change (#926)
* Add Next.js cache invalidation on swc transform change

* fix exports

* update distDir

* Use build-hash instead of package version

* refactor to util
2026-02-04 09:56:37 -08:00
Nathan Rajlich 8114792600 Add discovery for custom classes with workflow serialization (#859)
Added automatic discovery for custom classes with workflow serialization, allowing serialization classes to be defined in separate files without requiring explicit directives.

### What changed?

- Added detection for files containing custom class serialization patterns:
    - Files importing from `@workflow/serde`
    - Files using `Symbol.for('workflow-serialize')` or `Symbol.for('workflow-deserialize')`
- Created shared utilities in `transform-utils.ts` for consistent pattern detection across all build tools
- Updated Next.js, Nitro, Rollup, and Vite plugins to use the new detection patterns
- Added exclusion logic to prevent re-processing of generated workflow files
- Added tests to verify the pattern detection works correctly
- Updated documentation in the SWC plugin spec to explain the new discovery mechanism

### How to test?

1. Create a class with custom serialization in a separate file:

```js
// models/point.js
export class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  static [Symbol.for('workflow-serialize')](instance) {
    return { x: instance.x, y: instance.y };
  }

  static [Symbol.for('workflow-deserialize')](data) {
    return new Point(data.x, data.y);
  }
}
```

1. Import and use this class in a workflow or step file:

```js
'use workflow';
import { Point } from '../models/point';

export function myWorkflow() {
  const point = new Point(10, 20);
  return point;
}
```

1. Verify the class is properly serialized when passed between client and server

### Why make this change?

Previously, files containing custom serialization classes needed to include a `'use step'` directive to be discovered and transformed, even if they weren't actual step functions. This was unintuitive and could lead to confusion.

This change allows for a more natural code organization pattern where model classes with serialization can be defined in their own files without requiring directives. The build system will automatically discover and transform these files to ensure the serialization works correctly when the classes are used in workflows or steps.
2026-02-02 23:19:00 -08: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
Pranay Prakash c45bc3fd15 Add SDK version to workflow run executionContext for observability (#868)
* Add SDK version to workflow run executionContext for observability

Wire `@workflow/core` package version through the `executionContext` field
when creating workflow runs. Display the version in the observability UI
attribute panel. Uses genversion for build-time version injection.

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

* Fix workflowCoreVersion extraction and add turbo.json for caching

- Extract workflowCoreVersion from executionContext in hydrateResourceIO
  before stripping the context (addresses Copilot review comment)
- Add turbo.json to include src/version.ts in build outputs for caching

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

* Update workflowCoreVersion display name to @workflow/core version

Use a display name mapping to render the attribute as "@workflow/core version"
in the observability UI for better readability.

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 13:15:06 -08:00
JJ Kasper 344c90ff9f Add Next.js pages router entries handling (#792)
* Add Next.js pages router entries handling

* update trigger-pages

* Apply suggestions from code review

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Signed-off-by: JJ Kasper <jj@jjsweb.site>

---------

Signed-off-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-01-15 19:02:47 -08:00
Rishabh 97c78755da fix: add TypeScript decorator support to SWC transform (#757)
* fix: add TypeScript decorator support to SWC transform

  Enable decorator parsing in SWC configuration to support codebases using
  TypeScript decorators (TypeORM, NestJS, class-validator, custom decorators).

  Without this fix, projects importing files with decorators fail with:
  "Unexpected token `@`. Expected identifier..." syntax errors.

  Changes:
  - Add `decorators: true` to parser options for TypeScript and ECMAScript
  - Add `legacyDecorator: true` for TypeScript's experimentalDecorators
  - Add `decoratorMetadata: true` for emitDecoratorMetadata support

* fix: conditionally enable decorators based on tsconfig compilerOptions

  Read experimentalDecorators and emitDecoratorMetadata from tsconfig.json
  to match Next.js behavior. Decorators are now only enabled when explicitly
  configured in the project's tsconfig.

  - Add getDecoratorOptionsForDirectory() to read tsconfig settings
  - Update applySwcTransform and Next.js loader to use tsconfig options
  - Handle JSONC format (comments, trailing commas) in tsconfig parsing

* fix: use json5 for parsing tsconfig in decorator options

  Replace manual regex-based JSONC parsing with json5 library for more
  robust handling of comments and trailing commas in tsconfig.json files.

* bump

* apply fix

* DCO Remediation Commit for JJ Kasper <jj@jjsweb.site>

I, JJ Kasper <jj@jjsweb.site>, hereby add my Signed-off-by to this commit: aa1dc36db7
I, JJ Kasper <jj@jjsweb.site>, hereby add my Signed-off-by to this commit: e25f1748c6

Signed-off-by: JJ Kasper <jj@jjsweb.site>

* DCO Remediation Commit for Rishabh <rishabh.pugalia@gmail.com>

I, Rishabh <rishabh.pugalia@gmail.com>, hereby add my Signed-off-by to this commit: e2f93048aa
I, Rishabh <rishabh.pugalia@gmail.com>, hereby add my Signed-off-by to this commit: 3faee5d3c2
I, Rishabh <rishabh.pugalia@gmail.com>, hereby add my Signed-off-by to this commit: 9dbbda6362

Signed-off-by: Rishabh <rishabh.pugalia@gmail.com>

---------

Signed-off-by: JJ Kasper <jj@jjsweb.site>
Signed-off-by: Rishabh <rishabh.pugalia@gmail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-01-13 00:09:47 -08:00
Nathan Rajlich 505063cbb9 Special-case "server-only" and "client-only" packages as external (#731) 2026-01-06 18:00:14 -08:00
JJ Kasper 307f4b0e41 Revert "Add lazy workflow and step discovery in Next.js (#640)" (#712) 2025-12-31 09:37:56 -08:00
Nathan Rajlich 7ff68d1753 Pass tsconfig to esbuild for support of "paths" aliases (#705) 2025-12-31 01:00:24 -08:00
JJ Kasper 851c0203fe Validate cached workflows/steps and reduce build debounce (#700) 2025-12-30 10:36:35 +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
JJ Kasper ea3afce222 Add lazy workflow and step discovery in Next.js (#640) 2025-12-22 23:16:17 -06:00