Skip to content

[core] V2: skip inline step execution when suspension also has a wait#1924

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/fix-step-vs-wait-race
May 5, 2026
Merged

[core] V2: skip inline step execution when suspension also has a wait#1924
VaguelySerious merged 2 commits into
mainfrom
peter/fix-step-vs-wait-race

Conversation

@VaguelySerious
Copy link
Copy Markdown
Member

Summary

Fix Promise.race(step, sleep) semantics in V2 mixed suspensions: when a workflow suspension contains both pending steps and at least one wait (sleep), the runtime now queues every step instead of executing one inline.

Inline `await executeStep(...)` blocks the V2 handler for the full step duration, but `wait_completed` events are only created on the next loop iteration's "complete elapsed waits" pass. So if the sleep is shorter than the step, the wait timer never fires on time — replay just sees `step_completed` first and `Promise.race` resolves with the step. A 1s sleep racing a 10s step would silently resolve to the step.

This restores V1's behavior, where each step ran in a separate function invocation and the wait timer drove a parallel queue continuation.

Reproducer (failing test from #1916)

`sleepWinsRaceWorkflow`: a 1s sleep raced against a 10s step. Expected `'sleep'` to win.

Event log on the failing run, before the fix:

t (s) Event
0.000 `run_created`
1.738 `step_created` + `wait_created` resumeAt = t+1s
1.742 `step_started` inline execution begins
11.825 `step_completed` step body finishes after ~10s
11.861 `wait_completed` created right after step_completed, not on time
11.959 `run_completed` replay picked `'step'`

After the fix, `wait_completed` lands at t≈1s after `wait_created` and the run completes with `'sleep'` in ~1s.

Change

One-liner in `packages/core/src/runtime.ts`:

```ts
const inlineStep =
suspensionResult.timeoutSeconds === undefined
? ownedPendingSteps[0]
: undefined;
```

The existing "queue every pending step except the inline one" loop and the `if (!inlineStep)` early-return already handle the `undefined` case correctly.

What about hooks?

Audited every flavor of suspension. Step + wait is the only fully-broken combination.

Suspension contains Behavior in V2 Race-correct?
steps only one inline, rest queued
wait only returns with timeoutSeconds
hook only returns; external resumeHook drives continuation
wait + hook no steps → returns with timeoutSeconds
step + wait step inline-blocks, wait timer never fires ❌ — fixed here
step + hook step inline-blocks, but hook continuation runs concurrently via queueConcurrency (≥1000 on world-local, 50 on world-postgres, auto on Vercel) ⚠️ correct via concurrency, but step keeps running uselessly until termination

Step + hook works on all first-party worlds today. A consistent follow-up would extend the same carve-out to `hasPendingHooks`, but it would require a new field in `SuspensionHandlerResult` and isn't strictly necessary — happy to do that as a follow-up if desired.

Test plan

  • New e2e tests `sleepWinsRaceWorkflow` and `stepWinsRaceWorkflow` (the failing tests from Add dev-tmux skill for portless+tmux local Workflow SDK dev #1916, plus the symmetric stepWins case).
  • `pnpm vitest run packages/core/e2e/e2e.test.ts -t WinsRaceWorkflow` against the `nextjs-turbopack` workbench locally — both pass.
  • Event log inspection confirms `wait_completed` is now created at t≈1s.
  • All 842 `@workflow/core` unit tests pass.

Docs

`docs/content/docs/changelog/eager-processing.mdx` "Mixed Suspensions" section rewritten to describe the carve-out and explicitly call out the `Promise.race(step, sleep)` race-semantics motivation.

🤖 Generated with Claude Code

Inline `await executeStep(...)` blocks the V2 handler for the full
step duration, but `wait_completed` events are only created on the
*next* loop iteration's "complete elapsed waits" pass. This breaks
`Promise.race(step, sleep)` semantics whenever the sleep is shorter
than the step — replay still picks the step because the sleep's
wait_completed event hasn't been written yet.

Reproducer (`sleepWinsRaceWorkflow`): a 1s sleep raced against a 10s
step. Expected `'sleep'` to win; the runtime returned `'step'`. On
the failing run, `wait_completed` was created at t=11.86s — right
after `step_completed` — instead of at t≈2.74s when its `resumeAt`
elapsed.

Fix: in `runtime.ts`, gate the inline-step pick on the absence of a
wait timeout. When `suspensionResult.timeoutSeconds !== undefined`,
queue every pending step instead and return with the wait timeout.
This lets the wait timer drive a continuation in parallel, matching
V1's behavior where each step ran in a separate function
invocation. Pure step suspensions (without waits) still benefit
from inline execution.

Test plan:
- New e2e tests `sleepWinsRaceWorkflow` and `stepWinsRaceWorkflow`
  exercising `Promise.race` between a step function and `sleep()`,
  in both directions.
- Verified locally against `nextjs-turbopack` workbench: both pass.
  Event log confirms `wait_completed` is now created on time
  (t≈1s after `wait_created`) rather than after the inline step.

Eager-processing changelog updated with a "Mixed Suspensions"
section describing the carve-out and its rationale.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment May 5, 2026 0:26am
example-nextjs-workflow-webpack Ready Ready Preview, Comment May 5, 2026 0:26am
example-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-astro-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-express-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-fastify-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-hono-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-nitro-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-nuxt-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-sveltekit-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-tanstack-start-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workbench-vite-workflow Ready Ready Preview, Comment May 5, 2026 0:26am
workflow-docs Ready Ready Preview, Comment, Open in v0 May 5, 2026 0:26am
workflow-swc-playground Ready Ready Preview, Comment May 5, 2026 0:26am
workflow-tarballs Ready Ready Preview, Comment May 5, 2026 0:26am
workflow-web Ready Ready Preview, Comment May 5, 2026 0:26am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 5, 2026

🦋 Changeset detected

Latest commit: ee02092

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
@workflow/core Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web-shared Patch
@workflow/web Patch
workflow Patch
@workflow/world-testing Patch
tarballs Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch
@workflow/ai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 0.031s (-29.8% 🟢) 1.005s (~) 0.974s 10 1.00x
💻 Local Nitro 0.032s (-24.8% 🟢) 1.005s (~) 0.973s 10 1.04x
🐘 Postgres Nitro 0.041s (-56.5% 🟢) 1.011s (-3.0%) 0.970s 10 1.33x
🐘 Postgres Express 0.046s (-20.0% 🟢) 1.012s (~) 0.965s 10 1.49x
🌐 Redis Next.js (Turbopack) 0.053s 1.005s 0.952s 10 1.70x
🐘 Postgres Next.js (Turbopack) 0.061s 1.013s 0.952s 10 1.95x
🌐 MongoDB Next.js (Turbopack) 0.089s 1.006s 0.918s 10 2.86x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.806s (+220.6% 🔺) 2.783s (+19.3% 🔺) 1.976s 10 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.068s (-5.6% 🟢) 2.006s (~) 0.938s 10 1.00x
💻 Local Express 1.072s (-4.7%) 2.006s (~) 0.934s 10 1.00x
🐘 Postgres Express 1.081s (-5.7% 🟢) 2.009s (~) 0.928s 10 1.01x
🐘 Postgres Nitro 1.084s (-4.9%) 2.010s (~) 0.926s 10 1.01x
🌐 Redis Next.js (Turbopack) 1.111s 2.006s 0.895s 10 1.04x
🐘 Postgres Next.js (Turbopack) 1.131s 2.010s 0.879s 10 1.06x
🌐 MongoDB Next.js (Turbopack) 1.151s 2.007s 0.856s 10 1.08x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.825s (+38.8% 🔺) 4.958s (+29.4% 🔺) 2.134s 10 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 10.402s (-5.0%) 11.021s (~) 0.618s 3 1.00x
💻 Local Express 10.407s (-4.7%) 11.021s (~) 0.614s 3 1.00x
🐘 Postgres Express 10.418s (-5.0%) 11.015s (~) 0.598s 3 1.00x
🐘 Postgres Nitro 10.423s (-4.1%) 11.015s (~) 0.593s 3 1.00x
🌐 Redis Next.js (Turbopack) 10.663s 11.023s 0.360s 3 1.03x
🌐 MongoDB Next.js (Turbopack) 10.670s 11.014s 0.344s 3 1.03x
🐘 Postgres Next.js (Turbopack) 10.715s 11.017s 0.302s 3 1.03x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 15.794s (-8.8% 🟢) 17.951s (-7.5% 🟢) 2.157s 2 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 13.439s (-7.8% 🟢) 14.018s (-6.7% 🟢) 0.578s 5 1.00x
💻 Local Nitro 13.450s (-10.7% 🟢) 14.026s (-12.5% 🟢) 0.577s 5 1.00x
💻 Local Express 13.485s (-9.9% 🟢) 14.026s (-6.7% 🟢) 0.541s 5 1.00x
🐘 Postgres Nitro 13.488s (-7.6% 🟢) 14.019s (-6.7% 🟢) 0.530s 5 1.00x
🌐 MongoDB Next.js (Turbopack) 13.940s 14.219s 0.279s 5 1.04x
🐘 Postgres Next.js (Turbopack) 14.131s 15.022s 0.891s 4 1.05x
🌐 Redis Next.js (Turbopack) 14.169s 15.030s 0.861s 4 1.05x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 23.629s (-55.0% 🟢) 25.826s (-52.7% 🟢) 2.197s 3 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 11.849s (-29.4% 🟢) 12.022s (-29.4% 🟢) 0.173s 8 1.00x
💻 Local Express 11.902s (-28.3% 🟢) 12.022s (-29.4% 🟢) 0.120s 8 1.00x
🐘 Postgres Express 12.005s (-14.3% 🟢) 12.394s (-15.1% 🟢) 0.389s 8 1.01x
🐘 Postgres Nitro 12.046s (-13.8% 🟢) 12.645s (-11.6% 🟢) 0.599s 8 1.02x
🌐 MongoDB Next.js (Turbopack) 12.694s 13.017s 0.323s 7 1.07x
🌐 Redis Next.js (Turbopack) 13.121s 14.028s 0.907s 7 1.11x
🐘 Postgres Next.js (Turbopack) 13.366s 14.018s 0.651s 7 1.13x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 34.490s (-91.2% 🟢) 36.796s (-90.7% 🟢) 2.306s 3 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.145s (-10.2% 🟢) 2.007s (~) 0.862s 15 1.00x
🐘 Postgres Express 1.147s (-9.0% 🟢) 2.008s (~) 0.861s 15 1.00x
💻 Local Nitro 1.174s (-28.0% 🟢) 2.006s (-3.3%) 0.831s 15 1.03x
💻 Local Express 1.211s (-18.6% 🟢) 2.006s (~) 0.794s 15 1.06x
🐘 Postgres Next.js (Turbopack) 1.219s 2.008s 0.788s 15 1.07x
🌐 Redis Next.js (Turbopack) 1.275s 2.007s 0.732s 15 1.11x
🌐 MongoDB Next.js (Turbopack) 2.019s 2.674s 0.655s 12 1.76x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.105s (+20.8% 🔺) 6.180s (+25.3% 🔺) 2.075s 5 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.202s (-48.9% 🟢) 2.006s (-33.3% 🟢) 0.804s 15 1.00x
🐘 Postgres Express 1.226s (-48.1% 🟢) 2.007s (-33.3% 🟢) 0.782s 15 1.02x
🐘 Postgres Next.js (Turbopack) 1.375s 2.007s 0.633s 15 1.14x
💻 Local Nitro 1.677s (-46.7% 🟢) 2.005s (-48.4% 🟢) 0.329s 15 1.39x
💻 Local Express 1.798s (-39.1% 🟢) 2.008s (-41.9% 🟢) 0.209s 15 1.50x
🌐 Redis Next.js (Turbopack) 2.397s 3.009s 0.612s 10 1.99x
🌐 MongoDB Next.js (Turbopack) 3.570s 4.008s 0.438s 8 2.97x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.819s (-32.1% 🟢) 6.927s (-22.2% 🟢) 2.108s 5 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.326s (-61.9% 🟢) 2.008s (-49.9% 🟢) 0.682s 15 1.00x
🐘 Postgres Express 1.365s (-60.8% 🟢) 2.008s (-49.9% 🟢) 0.643s 15 1.03x
🐘 Postgres Next.js (Turbopack) 1.662s 2.007s 0.345s 15 1.25x
🌐 Redis Next.js (Turbopack) 3.651s 4.011s 0.360s 8 2.75x
💻 Local Nitro 4.459s (-46.6% 🟢) 5.013s (-44.4% 🟢) 0.554s 7 3.36x
💻 Local Express 5.277s (-36.7% 🟢) 5.846s (-35.2% 🟢) 0.569s 6 3.98x
🌐 MongoDB Next.js (Turbopack) 6.145s 7.011s 0.866s 5 4.64x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 7.711s (-13.5% 🟢) 10.175s (-7.2% 🟢) 2.464s 4 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.143s (-9.1% 🟢) 2.008s (~) 0.865s 15 1.00x
🐘 Postgres Nitro 1.149s (-8.6% 🟢) 2.008s (~) 0.860s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.210s 2.007s 0.797s 15 1.06x
🌐 Redis Next.js (Turbopack) 1.237s 2.007s 0.770s 15 1.08x
💻 Local Nitro 1.377s (-26.2% 🟢) 2.006s (-14.3% 🟢) 0.629s 15 1.20x
💻 Local Express 1.754s (-7.4% 🟢) 2.391s (+1.2%) 0.638s 13 1.53x
🌐 MongoDB Next.js (Turbopack) 2.025s 2.734s 0.709s 11 1.77x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 3.859s (+31.6% 🔺) 5.663s (+22.0% 🔺) 1.805s 6 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.217s (-48.0% 🟢) 2.075s (-31.1% 🟢) 0.858s 15 1.00x
🐘 Postgres Express 1.234s (-47.3% 🟢) 2.010s (-33.3% 🟢) 0.776s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.370s 2.007s 0.636s 15 1.13x
💻 Local Nitro 1.804s (-41.2% 🟢) 2.222s (-42.8% 🟢) 0.419s 14 1.48x
💻 Local Express 2.119s (-32.4% 🟢) 2.590s (-31.2% 🟢) 0.472s 12 1.74x
🌐 Redis Next.js (Turbopack) 2.366s 3.009s 0.643s 10 1.94x
🌐 MongoDB Next.js (Turbopack) 3.566s 4.008s 0.442s 8 2.93x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.086s (+61.8% 🔺) 7.055s (+56.0% 🔺) 1.969s 5 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.319s (-62.1% 🟢) 2.007s (-49.9% 🟢) 0.688s 15 1.00x
🐘 Postgres Express 1.359s (-61.2% 🟢) 2.008s (-49.9% 🟢) 0.649s 15 1.03x
🐘 Postgres Next.js (Turbopack) 1.654s 2.008s 0.354s 15 1.25x
🌐 Redis Next.js (Turbopack) 3.666s 4.010s 0.344s 8 2.78x
💻 Local Nitro 4.835s (-47.1% 🟢) 5.513s (-45.0% 🟢) 0.677s 6 3.67x
💻 Local Express 5.619s (-36.2% 🟢) 6.217s (-33.0% 🟢) 0.598s 5 4.26x
🌐 MongoDB Next.js (Turbopack) 6.228s 7.010s 0.782s 5 4.72x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.106s (-9.6% 🟢) 7.716s (-9.7% 🟢) 1.609s 4 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.448s (-45.4% 🟢) 1.006s (~) 0.558s 60 1.00x
💻 Local Express 0.463s (-52.9% 🟢) 1.004s (-6.7% 🟢) 0.541s 60 1.03x
🐘 Postgres Express 0.481s (-42.6% 🟢) 1.023s (~) 0.542s 59 1.07x
💻 Local Nitro 0.513s (-47.7% 🟢) 1.021s (-6.7% 🟢) 0.508s 59 1.14x
🌐 MongoDB Next.js (Turbopack) 0.595s 1.005s 0.410s 60 1.33x
🌐 Redis Next.js (Turbopack) 0.658s 1.005s 0.346s 60 1.47x
🐘 Postgres Next.js (Turbopack) 0.698s 1.006s 0.308s 60 1.56x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.179s (-57.4% 🟢) 8.102s (-49.6% 🟢) 1.923s 8 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.065s (-44.8% 🟢) 1.772s (-15.6% 🟢) 0.707s 51 1.00x
🐘 Postgres Express 1.152s (-41.7% 🟢) 1.844s (-18.3% 🟢) 0.692s 49 1.08x
💻 Local Nitro 1.168s (-61.5% 🟢) 2.005s (-46.6% 🟢) 0.837s 45 1.10x
💻 Local Express 1.301s (-56.9% 🟢) 2.122s (-40.8% 🟢) 0.821s 43 1.22x
🌐 MongoDB Next.js (Turbopack) 1.484s 2.006s 0.522s 45 1.39x
🌐 Redis Next.js (Turbopack) 1.561s 2.006s 0.445s 45 1.47x
🐘 Postgres Next.js (Turbopack) 1.604s 2.007s 0.403s 45 1.51x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 14.969s (-69.9% 🟢) 17.357s (-66.4% 🟢) 2.388s 6 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 2.021s (-49.4% 🟢) 2.456s (-43.8% 🟢) 0.435s 49 1.00x
🐘 Postgres Nitro 2.028s (-50.6% 🟢) 2.528s (-45.1% 🟢) 0.501s 48 1.00x
💻 Local Nitro 2.651s (-71.5% 🟢) 3.007s (-70.0% 🟢) 0.356s 40 1.31x
💻 Local Express 2.654s (-71.2% 🟢) 3.007s (-70.0% 🟢) 0.354s 40 1.31x
🌐 Redis Next.js (Turbopack) 3.018s 3.396s 0.378s 36 1.49x
🐘 Postgres Next.js (Turbopack) 3.183s 4.009s 0.825s 30 1.58x
🌐 MongoDB Next.js (Turbopack) 3.422s 4.010s 0.588s 30 1.69x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 43.502s (-59.4% 🟢) 46.024s (-57.7% 🟢) 2.522s 3 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.179s (-36.6% 🟢) 1.006s (~) 0.827s 60 1.00x
🐘 Postgres Nitro 0.181s (-36.2% 🟢) 1.006s (~) 0.825s 60 1.01x
🐘 Postgres Next.js (Turbopack) 0.236s 1.005s 0.769s 60 1.32x
🌐 Redis Next.js (Turbopack) 0.261s 1.004s 0.743s 60 1.46x
💻 Local Nitro 0.410s (-32.2% 🟢) 1.004s (-1.7%) 0.594s 60 2.29x
💻 Local Express 0.449s (-19.9% 🟢) 1.004s (~) 0.555s 60 2.51x
🌐 MongoDB Next.js (Turbopack) 1.028s 1.770s 0.742s 34 5.75x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.053s (+100.4% 🔺) 6.298s (+66.0% 🔺) 2.246s 10 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.300s (-39.6% 🟢) 1.006s (~) 0.706s 90 1.00x
🐘 Postgres Express 0.314s (-38.4% 🟢) 1.007s (~) 0.693s 90 1.05x
🌐 Redis Next.js (Turbopack) 0.431s 1.004s 0.573s 90 1.44x
🐘 Postgres Next.js (Turbopack) 0.455s 1.006s 0.550s 90 1.52x
💻 Local Express 2.143s (-14.7% 🟢) 2.714s (-9.8% 🟢) 0.572s 34 7.15x
💻 Local Nitro 2.165s (-14.7% 🟢) 2.765s (-8.1% 🟢) 0.600s 33 7.22x
🌐 MongoDB Next.js (Turbopack) 2.573s 3.006s 0.433s 30 8.58x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 8.287s (+134.4% 🔺) 10.464s (+101.5% 🔺) 2.176s 9 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.606s (-23.3% 🟢) 1.006s (~) 0.400s 120 1.00x
🐘 Postgres Express 0.632s (-22.8% 🟢) 1.006s (-1.1%) 0.373s 120 1.04x
🌐 Redis Next.js (Turbopack) 0.810s 1.004s 0.195s 120 1.34x
🐘 Postgres Next.js (Turbopack) 0.958s 1.387s 0.430s 87 1.58x
🌐 MongoDB Next.js (Turbopack) 5.307s 6.011s 0.704s 20 8.76x
💻 Local Nitro 9.751s (-12.9% 🟢) 10.445s (-10.4% 🟢) 0.694s 12 16.09x
💻 Local Express 10.904s (-2.6%) 11.399s (-4.5%) 0.496s 11 17.99x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 20.304s (+96.6% 🔺) 22.967s (+86.9% 🔺) 2.663s 6 1.00x
▲ Vercel Express ⚠️ missing - - - -
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack)

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.131s (+451.5% 🔺) 2.000s (+100.3% 🔺) 0.001s (-31.3% 🟢) 2.010s (+98.8% 🔺) 0.879s 10 1.00x
💻 Local Nitro 1.131s (+429.3% 🔺) 2.004s (+99.5% 🔺) 0.011s (-15.2% 🟢) 2.017s (+98.0% 🔺) 0.886s 10 1.00x
🐘 Postgres Nitro 1.132s (+452.2% 🔺) 2.001s (+100.1% 🔺) 0.001s (-26.7% 🟢) 2.009s (+98.7% 🔺) 0.877s 10 1.00x
💻 Local Express 1.141s (+473.3% 🔺) 2.005s (+99.6% 🔺) 0.012s (~) 2.019s (+98.3% 🔺) 0.878s 10 1.01x
🐘 Postgres Next.js (Turbopack) 1.201s 2.001s 0.001s 2.011s 0.810s 10 1.06x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.713s (-31.2% 🟢) 5.161s (-40.3% 🟢) 1.482s (+134.6% 🔺) 8.473s (-13.4% 🟢) 3.760s 10 1.00x
▲ Vercel Express ⚠️ missing - - - - -
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.505s (+139.0% 🔺) 2.003s (+99.0% 🔺) 0.004s (+0.9%) 2.026s (+98.0% 🔺) 0.520s 30 1.00x
🐘 Postgres Nitro 1.522s (+143.9% 🔺) 2.006s (+99.3% 🔺) 0.004s (-15.4% 🟢) 2.024s (+97.9% 🔺) 0.502s 30 1.01x
💻 Local Express 1.570s (+107.4% 🔺) 2.012s (+95.6% 🔺) 0.011s (+14.7% 🔺) 2.025s (+94.8% 🔺) 0.455s 30 1.04x
🐘 Postgres Next.js (Turbopack) 1.664s 2.011s 0.004s 2.025s 0.361s 30 1.11x
💻 Local Nitro 1.688s (+101.3% 🔺) 2.011s (+98.7% 🔺) 0.009s (-4.0%) 2.201s (+97.2% 🔺) 0.513s 28 1.12x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 12.267s (-27.5% 🟢) 13.897s (-23.8% 🟢) 0.343s (+62.3% 🔺) 15.237s (-19.5% 🟢) 2.969s 5 1.00x
▲ Vercel Express ⚠️ missing - - - - -
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.642s (-33.7% 🟢) 1.016s (-18.5% 🟢) 0.000s (-59.3% 🟢) 1.023s (-18.6% 🟢) 0.381s 59 1.00x
🐘 Postgres Express 0.692s (-27.9% 🟢) 1.047s (-18.0% 🟢) 0.000s (+21.1% 🔺) 1.060s (-18.8% 🟢) 0.368s 57 1.08x
🐘 Postgres Next.js (Turbopack) 0.826s 1.071s 0.000s 1.078s 0.252s 56 1.29x
💻 Local Nitro 1.335s (+9.2% 🔺) 2.015s (~) 0.000s (+100.0% 🔺) 2.017s (~) 0.681s 30 2.08x
💻 Local Express 1.386s (+13.2% 🔺) 2.015s (~) 0.000s (-80.0% 🟢) 2.017s (~) 0.631s 30 2.16x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.379s (-37.3% 🟢) 7.433s (-35.5% 🟢) 0.000s (NaN%) 8.871s (-26.4% 🟢) 2.492s 7 1.00x
▲ Vercel Express ⚠️ missing - - - - -
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack)

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.252s (-29.3% 🟢) 1.996s (-8.3% 🟢) 0.000s (+Infinity% 🔺) 2.034s (-7.5% 🟢) 0.782s 30 1.00x
🐘 Postgres Nitro 1.354s (-24.4% 🟢) 2.105s (-1.7%) 0.000s (+93.1% 🔺) 2.123s (-2.4%) 0.769s 29 1.08x
🐘 Postgres Next.js (Turbopack) 1.678s 2.262s 0.000s 2.286s 0.608s 27 1.34x
💻 Local Nitro 3.014s (-11.0% 🟢) 3.842s (-4.7%) 0.001s (-6.2% 🟢) 3.844s (-4.8%) 0.831s 16 2.41x
💻 Local Express 3.243s (-6.5% 🟢) 3.968s (-1.6%) 0.000s (-45.3% 🟢) 3.970s (-1.7%) 0.726s 16 2.59x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 8.615s (+53.4% 🔺) 10.007s (+43.3% 🔺) 0.000s (+33.3% 🔺) 11.037s (+46.4% 🔺) 2.422s 6 1.00x
▲ Vercel Express ⚠️ missing - - - - -
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 17/21
🐘 Postgres Nitro 11/21
▲ Vercel Next.js (Turbopack) 21/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 16/21
Next.js (Turbopack) 🐘 Postgres 11/21
Nitro 🐘 Postgres 15/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)

📋 View full workflow run


Some benchmark jobs failed:

  • Local: failure
  • Postgres: success
  • Vercel: failure

Check the workflow run for details.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 925 0 219 1144
✅ 💻 Local Development 1237 0 219 1456
✅ 📦 Local Production 1237 0 219 1456
✅ 🐘 Local Postgres 1237 0 219 1456
✅ 🪟 Windows 104 0 0 104
✅ 📋 Other 552 0 176 728
Total 5292 0 1052 6344

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 78 0 26
✅ example 78 0 26
✅ express 78 0 26
✅ fastify 78 0 26
✅ hono 78 0 26
✅ nextjs-turbopack 102 0 2
✅ nextjs-webpack 102 0 2
✅ nitro 78 0 26
✅ nuxt 78 0 26
✅ sveltekit 97 0 7
✅ vite 78 0 26
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 104 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 79 0 25
✅ e2e-local-dev-tanstack-start- 79 0 25
✅ e2e-local-postgres-nest-stable 79 0 25
✅ e2e-local-postgres-tanstack-start- 79 0 25
✅ e2e-local-prod-nest-stable 79 0 25
✅ e2e-local-prod-tanstack-start- 79 0 25
✅ e2e-vercel-prod-tanstack-start 78 0 26

📋 View full workflow run

Comment thread .changeset/fix-step-vs-wait-race.md Outdated
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
@VaguelySerious VaguelySerious merged commit 3535caf into main May 5, 2026
112 of 115 checks passed
@VaguelySerious VaguelySerious deleted the peter/fix-step-vs-wait-race branch May 5, 2026 00:49
@github-actions github-actions Bot mentioned this pull request May 5, 2026
pranaygp added a commit that referenced this pull request May 5, 2026
* origin/main:
  [core] Skip inline step execution when suspension also has a wait (#1924)
  [errors] Replace chalk import in @workfow/errors with inline ANSI shim (#1915)
  Fix compatibility with Zod 4.4.x (#1902)
  Serialize `run_failed`/`step_failed` errors through serialization pipeline (#1851)
  tarballs: redesign preview tarballs index page (#1911)
  Remove extra changeset (#1922)
  Add stable Next.js eager and lazy test coverage (#1747)
  Enforce per-(run, correlation) uniqueness for entity-creating events in world-postgres (#1878)
  fix(world-vercel): add default request timeout to workflow-server HTTP calls (#1807)
pranaygp added a commit that referenced this pull request May 5, 2026
PR #1924 added the same sleep/step race workflows directly to main
while this branch was open. The textual concat from `git merge`
left both copies in 99_e2e.ts; this drops the duplicate set so the
file matches origin/main verbatim and the e2e tests pick up the
upstream definitions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pranaygp added a commit that referenced this pull request May 5, 2026
…ignal

* origin/main:
  [core] Skip inline step execution when suspension also has a wait (#1924)
  [errors] Replace chalk import in @workfow/errors with inline ANSI shim (#1915)
  Fix compatibility with Zod 4.4.x (#1902)
  Serialize `run_failed`/`step_failed` errors through serialization pipeline (#1851)
  tarballs: redesign preview tarballs index page (#1911)
  Remove extra changeset (#1922)
  Add stable Next.js eager and lazy test coverage (#1747)
  Enforce per-(run, correlation) uniqueness for entity-creating events in world-postgres (#1878)
  fix(world-vercel): add default request timeout to workflow-server HTTP calls (#1807)
  Allow disabling step sourcemap with new `sourcemap` option in builders (#1842)
  [ci] Enable Vercel-prod e2e for tanstack-start (#1904)
  web: configure vercelPreset() for Vercel deployments (#1815)
  [core] Combine flow+step bundle and process steps eagerly (#1338)
  [world-vercel] Revert stream close control framing (#1891)
  [tarballs] Use turbo to build workspace deps before packing (#1908)

# Conflicts:
#	packages/core/src/runtime/step-handler.test.ts
#	packages/core/src/runtime/step-handler.ts
#	packages/core/src/runtime/suspension-handler.ts
#	packages/core/src/step.test.ts
#	packages/world-local/src/storage/events-storage.ts
#	packages/world-postgres/src/drizzle/migrations/meta/_journal.json
pranaygp added a commit that referenced this pull request May 5, 2026
* [e2e] Add step-vs-sleep race tests + dev-tmux skill

Adds two race workflows (sleepWinsRaceWorkflow, stepWinsRaceWorkflow)
that exercise Promise.race between a step function and a sleep call.
The current `sleepWinsRaceWorkflow` test fails — surfacing how the
replay engine resolves a previously-completed step instantly while
sleep still has to elapse.

Also adds a `dev-tmux` skill that documents the 3-pane tmux + portless
setup for testing workflows interactively in a worktree alongside the
observability UI.

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

* [workbench/nextjs-turbopack] Allow *.turbopack.localhost in dev

Adds allowedDevOrigins entries so portless-style worktree-prefixed
.localhost URLs (e.g. https://<branch>.turbopack.localhost) can hit
HMR and dev-only endpoints without Next's cross-origin protection
flooding the logs with warnings.

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

* Drop duplicate race workflows after merging main

PR #1924 added the same sleep/step race workflows directly to main
while this branch was open. The textual concat from `git merge`
left both copies in 99_e2e.ts; this drops the duplicate set so the
file matches origin/main verbatim and the e2e tests pick up the
upstream definitions.

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

* [skills/dev-tmux] Narrow activation, robust pane IDs, statusline helper

- Tighten activation phrases so the skill only fires for the specific
  portless+tmux setup it documents, not the generic "start the dev
  server" task. Addresses #1916 review.
- Capture pane IDs at split time (-P -F '#{pane_id}') so the snippet
  works under both pane-base-index 0 and 1. Addresses Copilot review.
- Add `statusline.sh` that filters `portless list` to the current
  worktree's routes and emits a one-line summary, plus instructions
  for wiring it into Claude Code's `statusLine.command`.
- Bump version to 1.1.

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

* [skills/dev-tmux] Recommend primary-checkout path for statusline

Worktrees get deleted, so wiring the statusline to a worktree path
breaks the moment the worktree is removed. Update the skill and the
script header to recommend pointing `statusLine.command` at the
primary checkout (`$HOME/github/vercel/workflow/...`). The script
itself is already worktree-aware via Claude's `workspace.current_dir`
stdin JSON, so the same invocation surfaces routes for whichever
worktree the session is in.

Bump version to 1.2.

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

* [skills/dev-tmux] OSC 8 link statusline + worktree-named tmux session

- Statusline overlay now renders `[dev]  ·  [obs]  ·  tmux:<prefix>`,
  with the bracketed labels emitted as OSC 8 hyperlinks (clickable in
  any modern terminal) styled cyan + underline so they stand out.
  Replaces the old long-URL form that was hard to scan and click.
- Add a tmux-session indicator: shown when a session named exactly the
  worktree prefix exists (uses `tmux has-session -t =<prefix>` for
  exact matching).
- Change the skill's tmux session naming convention from the fixed
  `workflow-dev` to `<worktree-prefix>` (basename of the branch — same
  string portless uses as the subdomain prefix). This lets the
  statusline locate the session deterministically and lets multiple
  worktrees run dev sessions concurrently without manual disambiguation.
- Bump skill to v1.3.

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

* [skills/dev-tmux] Statusline: print full `tmux attach -t <name>` command

Replaces the abbreviated `tmux:<prefix>` indicator with the full
copy-paste-ready `tmux attach -t <prefix>` invocation. Saves a step
when grabbing the session from another shell.

Bump skill to v1.4.

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

* [skills/dev-tmux] Brighter statusline + Nerd Font icons

- Drop the dim styling that made the overlay hard to read; use bold
  bright cyan + underline for links and bold bright green for the
  tmux command.
- Add Nerd Font glyphs:  for dev,  for obs,  for the
  tmux copy-paste hint. Falls back to box-drawing if the font lacks
  Nerd Font ranges; layout is unaffected.
- Visual differentiation: cyan + underline = clickable hyperlink;
  green = copy this command.

Bump skill to v1.5.

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

* [skills/dev-tmux] Restore Nerd Font icons via Unicode escapes

The copy glyph in `emit_tmux` was a literal Nerd Font byte embedded in
the printf string and got stripped during a prior rewrite. Promote all
three icons (rocket / graph / copy) to top-level shell variables that
use \uHHHH-equivalent UTF-8 escapes, so the source survives editor
round-trips that don't preserve Private Use Area code points.

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

* [skills/internal-dev-workbench] Rename from dev-tmux, set author + reset version

- Rename `skills/dev-tmux/` → `skills/internal-dev-workbench/` to make
  the name self-explanatory about the skill's scope (an internal
  contributor's local dev workbench, not a generic tmux helper).
- Author: Pranay Prakash. Version: 0.1 (first release of the skill).
- Update internal references in SKILL.md and statusline.sh accordingly.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants