Commit Graph

999 Commits

Author SHA1 Message Date
github-actions[bot] b93e7c3b59 Version Packages (#1921)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
workflow@4.2.5
2026-05-22 13:34:26 -07:00
Nathan Rajlich 5f50bbcee6 Backport #1829: fix(world-local): prevent path traversal via request-supplied IDs (#1920)
* fix(world-local): prevent path traversal via request-supplied IDs (#1829)

* fix(world-local): prevent path traversal via request-supplied IDs

Request-supplied identifiers (runId, eventId, stepId, hookId, correlationId,
stream names, and tags) flowed directly into path.join() calls, allowing a
client to send values like '../../../package' and cause the backend to read
or write files outside the workflow data directory.

Add a centralized validator (assertSafeEntityId) that rejects IDs which are
empty, start with '.', or contain path separators or NUL bytes. Apply it at
each storage-layer entry point that composes IDs into filesystem paths:
fs.taggedPath / readJSONWithFallback / paginatedFileSystemQuery, the runs /
steps / events / hooks storage methods, and the streamer.

* address review feedback

- UnsafeEntityIdError now extends WorkflowWorldError for consistency with
  other storage-layer errors and the platform error-to-HTTP mapping.
- Add resolveWithinBase(basedir, ...segments) containment helper and
  apply it at every taggedPath / readJSONWithFallback / .locks path
  construction site in events-storage and legacy, so a forgotten
  assertSafeEntityId at a future call site can't silently regress.
- Truncate attacker-controlled values in the error message.
- Drop unused assertSafeEntityIds helper and the unreachable typeof
  check under the TS signature.
- Fix docstrings on assertSafeEntityId / taggedPath JSDoc example /
  filePrefix validation comment to match what the code actually does.
- handleLegacyEvent now re-asserts runId locally so the invariant is
  documented at the call site instead of implicitly inherited from
  events.create.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>

* fix(world-local): tighten ID validation and add streamer regression tests

Addresses code review feedback on the path-traversal backport:

- Reject dots inside entity IDs in `assertSafeEntityId`. Internal IDs
  (ULIDs, step_N, etc.) never contain dots, but `stripTag()` /
  `getObjectCreatedAt()` strip a trailing `.[tag]` suffix from filenames,
  so a request-supplied runId like `wrun_123.foo` would be silently
  mangled during listing/pagination.

- Reject empty `correlationId` on events that include one. The event
  schemas only require `z.string()`, so without this check a
  step_created / hook_created / wait_created request with
  `correlationId: ''` would silently be written under a malformed
  composite key like `${runId}-`.

- Add streamer regression tests covering writeToStream, closeStream,
  listStreamsByRunId, and getStreamChunks (the v4-shape surface that
  this backport touches independently of main).

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-05-22 13:28:49 -07:00
github-actions[bot] ac83cd4bd5 fix(workbench): cache .vercel/output for Next workbench builds (#2095) (#2096)
Turborepo replays nextjs-turbopack:build from cache without restoring the
Vercel diagnostics manifest (.vercel/output/diagnostics/workflows-manifest.json),
which causes the Vercel deployment to fail post-build. Add .vercel/output/**
to the workbench's Turbo outputs so it is persisted and replayed. Applies to
both nextjs-turbopack and nextjs-webpack (whose turbo.json is a symlink).

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 12:54:44 -07:00
github-actions[bot] 74874309cb [core] Fix "event cursor missing after initial load" performance degradation due to clobbered cursor (#2056) (#2076)
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 12:19:42 -07:00
github-actions[bot] 066c157a2b Backport #1965: Fix Nitro dev loading of local step dependencies (#1968)
* Fix Nitro dev loading of local step dependencies (#1965)

* Fix local step dependency bundling

* Limit local dependency bundling to Nitro dev

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

* Fix stable backport build failures

* Revert runtime workaround changes

* Revert DOMException reducer change

* Revert serialization test mock

---------

Signed-off-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nathan Rajlich <n@n8.io>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-05-22 12:19:13 -07:00
Nathan Rajlich cab9a5334f docs(stable): update docs/README and docs-checks comment for tarballs move (#2094)
Per-deployment SDK tarballs are now built by the tarballs/ app, not by
docs/. Remove the outdated reference to docs/scripts/pack.ts (which no
longer exists) and point readers at tarballs/README.md.
2026-05-22 11:58:29 -07:00
Nathan Rajlich 8b31a5c124 [swc-plugin] Fix nested-step-arguments fixture stepId on stable (#2093)
The fixture was introduced by the backport of #1935 (#1945) with the
pre-namespacing step ID "step//./input//step" in the __internal_workflows
manifest comment. The subsequent backport of #1944 (#1946) shipped the
namespacing fix in lib.rs but did not update this fixture, since on main
the two PRs landed in the reverse order and #1944's diff already covered
the fixture there.

Update the expected output to match what the plugin now emits:
"step//./input//outer/step" — same value already present in main.
2026-05-22 11:39:30 -07:00
github-actions[bot] 05c7d07e41 [ci] Attribute backport changelog entries to original PR author (#2091) (#2092)
* [ci] Attribute backport changelog entries to original PR author

`@changesets/changelog-github` resolves a changeset commit to its
associated PR via the GitHub GraphQL `associatedPullRequests` field. For
commits landed on `stable` via our backport workflow, that resolves to
the backport PR authored by `github-actions[bot]` (since the backport
workflow uses `createCommitOnBranch` to produce signed commits), so the
generated changelog ends up with "Thanks @github-actions!" instead of
the original contributor.

This adds a small `.changeset/changelog.mjs` wrapper around
`@changesets/changelog-github` that detects backport PRs by matching the
title (`Backport #N: ...`) or body (`Automated backport of #N to
` + '`stable`' + `...`) produced by `.github/workflows/backport.yml`, resolves the
original PR number, and injects `pr:`/`commit:` directives into the
changeset summary before delegating to the upstream generator. The
result is that the rendered changelog entry attributes the change to the
original PR and author, while the commit link still points at the
backport commit on the release branch.

* Address review feedback

- Use `Bearer` instead of `Token` for the GitHub GraphQL auth header
  for consistency with the rest of the repo (Copilot review on PR #2091).
- Add a defensive `formatError` helper so `console.warn` in the catch
  blocks doesn't itself throw when a non-Error value is thrown (Copilot
  review on PR #2091).

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 11:04:28 -07:00
github-actions[bot] 73e0c4dc0e Show hook name on trace viewer + no toast on decrypt (#1955) (#1960)
* remove toast on succesful decrypt

* show hook name

* fix hook on detail view

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 10:45:43 -07:00
github-actions[bot] a9cc1d5ac1 [swc-plugin] Preserve imports referenced by hoisted nested steps (#1944) (#1946)
* [swc-plugin] Preserve imports referenced by hoisted nested steps

Dead-code elimination ran before nested step functions were hoisted out of workflow bodies, so imports referenced only by hoisted step bodies were incorrectly stripped from the step bundle, causing a ReferenceError at runtime. Move DCE to run after hoisting in visit_mut_program.

* [swc-plugin] Namespace nested step IDs under non-exported workflow functions

Anonymous steps nested inside callback properties of a non-exported workflow function were registered with an unnamespaced step ID in step mode while the workflow-mode proxy looked them up under the workflow function name, causing a runtime 'step not found' failure. Set current_workflow_function_name in visit_mut_fn_decl for non-exported workflow functions to match the behavior in visit_mut_export_decl. Also clarify the fixture comment to distinguish step-mode and workflow-mode behavior per reviewer feedback.

* [swc-plugin] Namespace nested step IDs across all workflow declaration shapes

Extends the previous fix to cover all three non-exported workflow declaration forms (async function decl, const arrow, const fn-expr) by visiting the workflow body with workflow context before replacing it, and corrects the __internal_workflows manifest comment to report the same prefixed step IDs that are registered at runtime and looked up by the workflow-mode WORKFLOW_USE_STEP proxy. Adds a dedicated regression fixture covering all three shapes.

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-22 10:38:56 -07:00
github-actions[bot] 6aabd6fd2e [swc-plugin] Capture lexical this for nested arrow step functions (#1935) (#1945)
* [swc-plugin] Capture lexical `this` for nested arrow step functions

When a nested arrow `"use step"` references the enclosing function/method's
`this`, plumb that `this` through the workflow runtime so the step body
sees the correct receiver.

- Workflow mode wraps the step proxy with `.bind(this)`, so invoking the
  proxy captures the caller's `this` as `thisVal` on the queue item.
- Step mode hoists the body as a regular `function` (not an arrow) so the
  runtime's `stepFn.apply(thisVal, args)` rebinds `this` inside the
  hoisted body.

Detection only fires for arrows, since arrows inherit `this` lexically.
Nested non-arrow functions/methods/getters/setters introduce their own
`this`, so the detector stops at those boundaries.

The runtime already supported `thisVal` for instance-method steps; this
PR is purely a compiler change to feed the existing pipeline.

Caveat: capture works at runtime only when the captured value is
serializable across the workflow->step boundary (i.e. the enclosing
class implements `WORKFLOW_SERIALIZE`/`WORKFLOW_DESERIALIZE`).

Refs vercel/workflow#1865

* Address PR review: preserve step proxy metadata + tighter `this` detection

- core: Override `.bind` on step proxies so the bound function retains
  `stepId` and `__closureVarsFn`. Without this, a bound proxy that flows
  through workflow serialization (e.g. as a step argument) would be
  treated as a non-serializable plain function by `getStepFunctionReducer`.
- swc-plugin: Detector now also walks `arrow.params` so `this` references
  in default values / destructuring initializers (e.g. `(x = this.foo) =>
  ...`) trigger the `.bind(this)` path.
- swc-plugin: Class bodies inside the arrow body are now treated as
  `this`-binding boundaries — `this` inside class field initializers,
  methods, etc. is bound to the class instance, not the outer arrow. The
  detector still walks `extends` clauses and computed property keys
  because those are evaluated in the surrounding scope.
- spec.md: Sharpen the note about `this` in step bodies — it's
  syntactically allowed but only meaningful for instance-method steps and
  lexical-`this` arrow steps; other shapes compile but `this` will be
  whatever the caller of the step proxy passes.
- Add `lexical-this-detector-edge-cases` fixture covering both the
  default-param positive case and the inner-class false-positive guard.
- Strengthen the runtime test to assert `stepId` / `__closureVarsFn`
  survive `.bind(...)`.

* [swc-plugin] Fix `arguments` closure-var capture; drop dead `this`/`arguments` checks

- Add `arguments` to `is_global_identifier` so it's not captured as a
  closure variable. Previously a nested `function`-form step like

      function step() { 'use step'; return arguments[0]; }

  was hoisted with `const { arguments } = ...` (a strict-mode syntax
  error) and the body's `arguments[0]` resolved against the destructured
  binding instead of the function's intrinsic `arguments` object.
- Remove dead `ForbiddenExpression` checks for `this` and `arguments` in
  `visit_mut_this_expr` / `visit_mut_ident`. The `'use step'` /
  `'use workflow'` directives are stripped during the module-level
  traversal before children are visited, so `in_step_function` /
  `in_workflow_function` are never observed as true here in practice.
  The existing `step-with-this-arguments-super` fixture explicitly
  documents that all three identifiers are allowed in step bodies.
- Tighten the spec note about `arguments` accordingly: it works in
  `function`-form steps (reflecting positional args) but is not captured
  for arrow-form steps; use `...args` for that case.
- Add `nested-step-arguments` fixture pinning down the new behavior.

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-22 10:16:25 -07:00
github-actions[bot] 01cfe1906f Fix old trace viewer layout (#1952) (#1954)
* Update workflow-trace-view.tsx

* Update trace viewer layout to be in a row



---------

Signed-off-by: Mitul Shah <mitulxshah@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 09:59:11 -07:00
github-actions[bot] 88070cfb52 [web-shared] Fix "Queued for" duration for retried steps (#2087) (#2089)
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-author-by: Peter Wielander <mittgfu@gmail.com>
2026-05-22 18:55:03 +02:00
github-actions[bot] 478a9c7618 Generate local gitignore when using public workflow manifests (#1683) (#2085)
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: Peter Wielander <peter.wielander@vercel.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
2026-05-22 15:37:33 +02:00
github-actions[bot] 05bf938983 Fix Next workbench cached outputs (#2071) (#2072)
Signed-off-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-21 17:14:42 -07:00
Pranay Prakash 096adbfd8e Enforce per-(run, correlation) uniqueness for entity-creating events in world-postgres (#1878) (#2069)
Adds a unique partial index on workflow_events(run_id, correlation_id, type)
filtered to step_created/hook_created/wait_created, and translates the
resulting unique-violation (pg code 23505, surfaced via DrizzleQueryError.cause)
into EntityConflictError. The steps table already deduped via
onConflictDoNothing, but the event row still inserted, leaving duplicate
events in the log. Now both rows are kept consistent and the runtime's
existing dedup catch path handles concurrent writers cleanly.

(cherry picked from commit 7c45e9e213)

Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-21 16:47:25 -07:00
github-actions[bot] ca5f355999 Capture world contract failures as fatal (#2060) (#2064)
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-21 15:07:58 -07:00
github-actions[bot] 6d3186e102 [codex] Fix preview tarball generated versions (#2044) (#2052)
* Fix preview tarball generated versions

* Skip docs smoke for skipped preview deployments

* Address tarball review comments

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-20 17:03:58 -07:00
github-actions[bot] 8407c1e9a4 Report corrupted event logs distinctly (#2046) (#2049)
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-20 16:14:50 -07:00
Pranay Prakash c3475096e9 [codex] Guard event consumers during replay (#2030) (#2042)
* Guard event consumers during replay

* Address event guard review feedback

* Update event guard test fixtures
2026-05-20 15:12:09 -07:00
github-actions[bot] cb1bd8d716 Add minimum release age configuration and exclusions (#2037) (#2040)
Sets pnpm's `minimumReleaseAge` to 2 days (company-wide standard) and
excludes internal scopes from the gate.

Signed-off-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:01:30 -07:00
github-actions[bot] cab6c14bef Fix observability getWorld import docstring (#2032) (#2033)
Signed-off-by: yikZero <i@yikzero.com>
2026-05-20 18:43:33 +07:00
github-actions[bot] be506ccbd0 [world-postgres] Bootstrap graphile-worker schema in setup CLI (#2019) (#2027)
* fix(world-postgres): bootstrap graphile-worker schema in setup CLI

`workflow-postgres-setup` now installs the `graphile_worker` schema in
addition to the drizzle migrations so that by the time any consumer
calls `world.start()`, both schemas already exist. This eliminates the
inter-process race on graphile-worker's `installSchema` where
concurrent `CREATE SCHEMA IF NOT EXISTS` calls could both pass the
MVCC-snapshotted existence check and one would fail with
`duplicate key value violates unique constraint "pg_namespace_nspname_index"`.

Reproduced locally against a fresh postgres:18-alpine with 8 parallel
`makeWorkerUtils().migrate()` calls — 7/8 fail without the pre-bootstrap,
0/8 fail after running `workflow-postgres-setup` first.



* Apply suggestions from code review




---------

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-19 22:34:06 -07:00
Pranay Prakash a434184858 [codex] Fix stale wait replay race (#2029)
* Add sleep race replay repro tests

* Trigger CI for sleep race repro tests

* Fix stale wait replay race

* Fetch event deltas after wait completion

* Address wait replay review comments

* Address wait replay review nits
2026-05-19 22:17:07 -07:00
github-actions[bot] 39368e96e9 Ignore the "tarballs" app in changesets config (#2024) (#2025)
No need to version this app, it doesn't get published to npm.

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-19 14:28:25 -07:00
github-actions[bot] 9ebe5e47ca fix bad socket file location (#2021) (#2023)
Signed-off-by: Luke Sandberg <lukesandberg@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-05-19 12:25:45 -07:00
Pranay Prakash 16f2c236d3 Fix stable CI test harness failures (#1986)
* Fix stable CI test harness failures

* Fix dev e2e cleanup races

* Restore non-Next dev cleanup

* Keep Next dev temp workflow files intact

* Keep dev test placeholders on disk

* Speed up workflow port detection

* Probe workflow health with POST

* Support HEAD workflow health checks

* Stabilize local CI health checks

* Retry flaky Vercel agent e2e

* Wrap generated framework route exports

* Relax remote addTen e2e timeout

* Materialize manual webhook responses

* Give remote CLI inspect more time

* Stabilize remote sleep and hook e2e checks

* Wait for step return streams before completion

* Stabilize hook and stream e2e waits

* Bound queue health check timeouts

* Address stable CI review feedback

* Fix route export replacement with embedded source maps
2026-05-18 17:46:24 -07:00
github-actions[bot] c3f3a756f9 Add workflow versioning docs (#2010) (#2014)
* Add workflow versioning docs

* Link cookbook patterns to versioning docs

* Align v5 start docs with native workflow support

* Address versioning docs review feedback

* Address versioning preview comment

* Address versioning toolbar feedback

* Cross-link versioning docs

* Address latest versioning toolbar feedback

* Rename versioning self-upgrade section

* Address versioning PR review comments

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-18 16:53:15 -07:00
github-actions[bot] a5e82e5661 docs(ai): update durable agents guide to use ToolLoopAgent (#1975) (#1990)
The AI SDK renamed `Experimental_Agent` to `ToolLoopAgent`. Update the
"Building Durable AI Agents" page's API route snippet (v4 and v5) so it
matches the current AI SDK API.

Signed-off-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 15:31:46 -07:00
github-actions[bot] 4bc53fc7a9 Remove instrumentation from workbench (#1959) (#1963)
* Remove instrumentation from workbench

* bump

Signed-off-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-18 15:01:42 -07:00
github-actions[bot] a350e8ddf2 Retry failed VQS handlers immediately (#1999) (#2007)
* Retry failed VQS handlers immediately

* Address VQS retry review feedback

* Tune VQS handler retry backoff

* Add jitter to VQS handler retry backoff

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-18 15:00:53 -07:00
github-actions[bot] ecfccc37c0 Update to latest queue client version (#1987) (#1996)
Signed-off-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-14 16:07:51 -07:00
github-actions[bot] 76352f0b66 [codex] Fix detached ArrayBuffer proxy DX (#1985) (#1998)
* fix(world-local): explain detached ArrayBuffer proxy failures

* fix(docs): make proxy handler anchor navigable

* fix(docs): open accordions for hash links

Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-14 16:06:42 -07:00
Pranay Prakash 5b6a581235 Fix stale SvelteKit workflow queue triggers (#1984)
* Fix stale SvelteKit workflow queue triggers

* Address SvelteKit queue trigger review
2026-05-14 16:04:55 -07:00
github-actions[bot] 14326adcf9 Auto-remove workflow packages from serverExternalPackages (#1481) (#1940)
* 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

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-06 07:59:43 +00:00
github-actions[bot] 15e44b3605 Backport #1902: Fix compatibility with Zod 4.4.x (#1938)
* Fix compatibility with Zod 4.4.x (#1902)

* Fix compatibility with Zod 4.4.x

* DCO Remediation Commit for Ziyak <ziyak97@gmail.com>

I, Ziyak <ziyak97@gmail.com>, hereby add my Signed-off-by to this commit: 2bf58718e6

Signed-off-by: Ziyak <ziyak97@gmail.com>

---------

Signed-off-by: Ziyak <ziyak97@gmail.com>
Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Nathan Rajlich <n@n8.io>
Signed-off-by: Ziyak Jehangir <53836911+ziyak97@users.noreply.github.com>

* Add missing changeset for Zod 4.4.x compatibility fix

PR #1902 landed without a changeset; this adds the missing patch-level changeset for @workflow/world to the backport branch.

---------

Signed-off-by: Ziyak <ziyak97@gmail.com>
Signed-off-by: Nathan Rajlich <n@n8.io>
Signed-off-by: Ziyak Jehangir <53836911+ziyak97@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nathan Rajlich <n@n8.io>
2026-05-05 22:49:57 +00:00
Pranay Prakash 18fa7f485a tarballs: redesign preview tarballs index page (#1911) (#1926)
* tarballs: redesign preview tarballs index page

Rebuild the static index page produced by `tarballs/scripts/pack.ts`:

- Featured `workflow` package up top with prominent install command,
  copy button, and direct tarball download
- Top-of-page metadata chips: short SHA (linked to commit), branch,
  PR number, build timestamp, package count + total size
- Collapsible "What is this?" explainer
- Package-manager tab toggle (pnpm / npm / yarn / bun) that swaps the
  install command for every row in place
- Live filter input over the rest of the package list (with `/` shortcut)
- Per-row install command, copy button, and direct download
- Modern dark/light theme with system preference, Geist-inspired styling

Also captures tarball size during pack and renders human-readable byte counts.



* tarballs: fix client-side interactivity broken by HTML-encoded JSON

`escapeHtml(JSON.stringify(catalog))` was HTML-encoding every quote in
the embedded catalog JSON to `&quot;`, so `JSON.parse(textContent)` threw
on the first character and the IIFE bailed before attaching any event
listeners — package-manager toggle, search filter, copy buttons, and the
`/` shortcut were all dead UI on the deployed page.

`<script type="application/json">` content is treated as text by the HTML
parser; the only sequence that can break out is `</script>` (or `</`
in legacy parsers). Replace `<` with the JSON `<` escape, which is
legal per the JSON spec and prevents the breakout without needing entity
encoding.

Also switch `formatBytes` from `KB`/`MB` to `KiB`/`MiB` since the
divisor is 1024.



* tarballs: rewrite as Vite + Preact SPA with file breakdown, fix bundling

Address TooTallNate's review feedback by replacing the hand-rolled HTML-
in-template-literal approach with a small Vite + Preact SPA. The old
~600 lines of inlined HTML/CSS/JS in `pack.ts` is now `~80 lines of TSX`,
fully type-checked.

Layout:
- `tarballs/index.html`, `vite.config.ts`, `tsconfig.json` at the root
- `src/main.tsx` mounts the Preact app and fetches `/catalog.json`
- `src/app.tsx` is the page (Header, FeaturedCard, PackageRow, etc.)
- `src/catalog.ts` is the shared types + helpers (`buildInstallCommand`,
  `formatBytes`)
- `src/icons.tsx`, `src/styles.css`
- `scripts/pack.ts` is now data-only — it scans packages, packs
  tarballs, and writes `public/catalog.json`

The eliminates several smells the reviewer called out:
- The interactive script is now TypeScript with strict mode and JSX
  type checking instead of an inline `<script>` block
- The `escapeHtml`-around-JSON-blob hack that broke client-side JS in
  the prior commit is gone; the SPA fetches `catalog.json` and parses
  it natively
- Pack-time logic and presentation logic no longer share a file

While verifying real tarball sizes I noticed `workflow-serde.tgz` was
only 828 bytes — it had `package.json`, `LICENSE.md`, `README.md` and
*nothing* else, because each package's `files: ["dist"]` excludes
sources but `dist/` hadn't been built. The Vercel build was running
`pnpm --filter tarballs build`, which only builds the `tarballs`
package itself — its workspace dependencies were never built.

Switch `vercel.json#buildCommand` to `pnpm turbo run build
--filter=tarballs`, which transitively builds dependencies first via
the `dependsOn: ["^build"]` rule already in the root `turbo.json`. With
the fix:

  workflow:        241 KiB  →  252 KiB tarball, 916 KiB unpacked, 205 files
  @workflow/core:   59 KiB  →  493 KiB tarball, 1.70 MiB unpacked, 236 files
  @workflow/serde: 828 B    →  1.4 KiB tarball, 4.6 KiB unpacked, 7 files

Add a smoke check that the `workflow` package has at least 5 files in
its tarball — catches the regression directly.

`pack.ts` now also runs `tar -tvzf` on each tarball and records the
file list with sizes. The SPA renders this as an expandable
"What's inside?" disclosure per package, grouped by top-level
directory (e.g. `dist/`, `docs/`) with proportional bars showing
each group's share of the unpacked size, and the largest files
listed below.



* tarballs: replace tar shell-out with in-process tar reader

The smoke check broke in CI: `'workflow' tarball only has 0 files`.
Root cause is that `tar -tvzf` emits a different verbose layout on GNU
tar (Linux, what CI runs) vs BSD tar (macOS, where I tested locally) —
the parser only matched the BSD column ordering, so on Linux every line
was rejected and `fileCount` came out as 0.

Replace the shell-out with a small in-process tar reader using
`zlib.gunzipSync` + manual 512-byte block walk. ustar headers are
trivially structured (name at offset 0, octal size at 124, typeflag at
156, ustar prefix at 345). We emit regular files only (`typeflag` `0`
or NUL) and consume but skip pax extended headers (`x`/`g`) and GNU
long-name entries (`L`). Result is identical on every platform.

Verified locally: 206 files / 998413 bytes for `workflow.tgz` matches
`tar -tvzf` exactly.



* tarballs: redesign per-package details with packagephobia-style stats

The previous "What's inside?" view crammed nested directory groups,
proportional bars, and per-group file lists into a `<details>` inside
an already-narrow row. It was hard to read and harder to compare.

Replace it with the layout packagephobia uses on its result page:

- Two large headline metric tiles (Publish size / Unpacked size)
  with a big bold value, smaller unit, and small uppercase label.
  Modeled directly on packagephobia's `Stats` component but using
  our existing CSS variables so it tracks light/dark theme.
- A single sortable file table beneath. Default is size-descending so
  the contributors to package size are immediately visible. Click a
  header to flip direction or switch sort key. Sticky header keeps
  the columns visible inside the scrollable region.

Drop the `groupByTopLevel`, `ContentsGroup`, and bar-chart styles —
they were the source of the "hard to use" feedback and don't add
information that the flat sortable table doesn't already convey.



* tarballs: address Copilot review feedback (a11y, dev script, caching)

- main.tsx: drop `cache: 'no-store'` from the catalog fetch. Each
  tarballs deployment is immutable per commit, so HTTP caching is
  appropriate; forcing no-store made every visit re-download the full
  catalog (which now includes per-package file lists).
- app.tsx (search input): add `aria-label="Filter packages"`. The
  visible label only contained an icon and placeholder, so screen
  readers had no name for the control.
- app.tsx (PmTabs): replace `role="tablist"` / `role="tab"` /
  `aria-selected` with plain buttons that use `aria-pressed`. The
  ARIA tab pattern requires arrow-key roving focus we never wired
  up; toggle buttons are the honest representation. Each button
  also gets an explicit `aria-label`.
- app.tsx (row buttons): include the package name in the accessible
  label of every per-row copy/download button (and on the featured
  card too), so the screen reader buttons/links list distinguishes
  them. Added an `accessibleName` prop to `CopyButton`.
- app.tsx (CopyButton): only flip to the "Copied" state when the
  write actually succeeded. Both the modern `navigator.clipboard`
  path and the `execCommand` fallback can fail; the new
  `writeToClipboard` helper returns success and the button shows a
  short "Failed" state if both paths fail.

The previous `dev: vite` couldn't actually serve the page because
`/catalog.json` 404s and the SPA boots into the error fallback.

Restructure the build layout to vite's conventional shape:
- `public/` is now a true vite public dir — pack writes tarballs and
  catalog.json there. In dev, vite serves these at the root.
- `dist/` is the production build output (vite copies public/ into it
  and adds index.html + assets/).
- `vercel.json#outputDirectory` switches from `public` → `dist`.
- `turbo.json` outputs updated to match.
- `dev` chains pack before vite so the catalog exists when the dev
  server starts.



---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 03:03:17 +00:00
Nathan Rajlich 3621f8d058 [backport] [ci] Stop using Release App token + bump pnpm/action-setup (#1918)
* ci: upgrade pnpm/action-setup to v5 and read version from package.json (#1785)

* ci: upgrade pnpm/action-setup to v6 and read version from package.json

Removes hardcoded pnpm version (10.14.0) from all workflows and instead
reads the version from the packageManager field in package.json, so CI
stays in sync with the version used locally.

* ci: update setup-workflow-dev composite action to use pnpm/action-setup@v6

Also removes the pnpm-version input since the action now reads the
version from package.json#packageManager.

* ci: downgrade pnpm/action-setup to v5

v6 installs pnpm 11 RC/beta, which has a regression
(pnpm/pnpm#11264, pnpm/action-setup#225/#227/#228) that causes
'ERR_PNPM_BROKEN_LOCKFILE: expected a single document in the stream'
when the project's packageManager pins a 10.x pnpm version. v5 is the
latest stable release before v6 and supports reading the version from
package.json#packageManager.

* ci: stop using Release App token in release workflows (#1866)

The Release App has been temporarily removed. Switch the Release and
Backport workflows to use the default GITHUB_TOKEN, and disable the
cross-repo Front dispatch workflow until the App is restored.

Also add a workflow_dispatch trigger to release.yml so the Version
Packages PR can be created/updated manually (since pushes made by
GITHUB_TOKEN do not trigger downstream workflow runs).

* ci: use GitHub API commit mode for changesets action (#1867)

The repo enforces "Commits must have verified signatures" via an
org/enterprise-level ruleset, which blocks unsigned commits pushed via
the Git CLI by GITHUB_TOKEN. Switching the changesets action to
commitMode: github-api makes commits GPG-signed by GitHub.

* Add changeset for backport

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Rajlich <n@n8.io>

---------

Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-04 14:26:23 -07:00
Peter Wielander bb910f2571 [backport] [workbench] Add TanStack Start workbench (#1875, #1907) (#1914)
* [workbench] Add TanStack Start workbench and tests (#1875)

(cherry picked from commit 8202663857)

* Fix pnpm type issue after tanstack PR (#1907)

(cherry picked from commit a7071bf3d4)
2026-05-04 19:30:39 +00:00
Nathan Rajlich 077eb2a0ad [backport] Bump vite + enable step source-map assertions for vite local dev (#1919)
* Bump vite (#1827)

* test: enable step source-map assertions for vite local dev (#1862)

* test: enable step source-map assertions for vite local dev

Vite ^7.3.2 (bumped in #1827) preserves step bundle source maps in
dev mode, so stack traces now contain original file paths. Update
hasStepSourceMaps() so vite returns true in local dev and stays false
only in local prod, fixing the consistently failing 'basic step error'
and 'cross-file step error' e2e tests.

* chore: drop body from empty changeset

* address review: drop redundant vite local-prod guard

The default `!DEV_TEST_CONFIG` fall-through already returns false for
vite local prod, so the vite-specific guard is dead code. Just remove
the vite block entirely now that vite local dev matches the default
'has source maps' behavior.

---------

Co-authored-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com>
2026-05-04 11:30:22 -07:00
Peter Wielander e428cdb1d5 [vitest] [world-local] Backport: Fix local-world data recovery isolation (#1895) (#1898) 2026-05-04 09:38:34 +00:00
Peter Wielander d7eef0c1fd [backport] [tarballs] Use turbo to build workspace deps before packing (#1908) (#1909) 2026-05-04 05:44:49 +00:00
Peter Wielander eb54dd8544 [backport] Split tarball hosting out of docs into its own project (#1893) (#1899) 2026-05-04 12:33:00 +09:00
Peter Wielander f073c680c7 [world-vercel] Revert stream control framing (#1892)
This reverts commit 5ef9ac2073
2026-05-03 03:07:03 +00:00
Peter Wielander 677867bd19 [backport] ci: switch Vercel deployment-protection bypass to OIDC Trusted Sources (#1897)
Backport of #1882
2026-05-03 02:45:01 +00:00
Nathan Rajlich f852b5eb78 Remove skills/ directory from stable branch (#1797)
The skills/ directory is not maintained on stable — it is only kept
current on main. Removing these files prevents stale skills from
being packaged with stable releases and matches how docs/ is handled.
2026-04-17 10:41:37 -07:00
Peter Wielander 8389bce6c3 [docs] Build packages before packing preview tarballs on stable (#1793) 2026-04-16 17:54:23 -07:00
Peter Wielander 5ef9ac2073 [world-vercel] Use stream control frame for transparent reconnection (#1790) 2026-04-16 17:47:59 -07:00
workflow-devkit-release-bot[bot] dd139dfe76 Version Packages (#1789) workflow@4.2.4 2026-04-16 17:10:05 -07:00
Peter Wielander 7be05b9253 Revert #1766 (Use stream control frame for transparent reconnection) (#1788) 2026-04-16 17:05:11 -07:00