Skip to content

[errors] Replace chalk import with inline ANSI shim#1915

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/errors-no-chalk
May 5, 2026
Merged

[errors] Replace chalk import with inline ANSI shim#1915
VaguelySerious merged 2 commits into
mainfrom
peter/errors-no-chalk

Conversation

@VaguelySerious
Copy link
Copy Markdown
Member

Summary

@workflow/errors/ansi imports chalk, which transitively require('os')s via supports-color. That module is reachable from the workflow-VM bundle through:

workflow → @workflow/core/workflow/index.ts
        → context-errors.ts
        → context-violation-error.ts
        → @workflow/errors/ansi   ← imports chalk

The workflow VM has no require(), so importing chalk crashes every workflow at registration time:

./src/workflows/v2/workflow:2131
    var os = require("os");
             ^

ReferenceError: require is not defined
    at .../node_modules/.pnpm/supports-color@7.2.0/.../index.js:2:11
    at __require (./src/workflows/v2/workflow:11:50)
    at .../node_modules/.pnpm/chalk@4.1.2/.../source/index.js:3:53
    at __require (./src/workflows/v2/workflow:11:50)
    at .../@workflow/errors/src/ansi.ts:1:18
    at Script.runInContext (node:vm:149:12)

Fix

Replace chalk with a 25-line inline SGR helper that exposes the same call surface (chalk.red, chalk.bold, …). Color detection mirrors chalk's defaults at a coarse level — FORCE_COLOR on, NO_COLOR off, otherwise gated on process.stdout.isTTY — so non-TTY logs and the workflow VM (no process) get plain text, matching the prior behavior in tests and in production log drains.

Drops the chalk runtime dependency from @workflow/errors and removes the now-unused __mocks__/chalk.ts Vitest mock. All 820 @workflow/core unit tests + 11 @workflow/errors snapshot tests pass.

Test plan

  • pnpm --filter @workflow/errors test (26 tests pass)
  • pnpm --filter @workflow/core test (820 unit tests pass; e2e excluded)
  • CI green
  • Reproduce: install latest tarballs in a v2-flow consumer (vade) and confirm step registration no longer throws ReferenceError: require is not defined

🤖 Generated with Claude Code

`@workflow/errors/ansi` is reachable from the workflow-VM bundle via
`@workflow/core/workflow` → `context-errors` → `context-violation-error`
→ here. The real `chalk` package pulls in `supports-color`, which calls
`require('os')` at module load — crashing every workflow with
`ReferenceError: require is not defined` in the sandboxed VM the moment
any user step is registered:

  ./src/workflows/v2/workflow:2131
      var os = require("os");
               ^
  ReferenceError: require is not defined
      at .../node_modules/.pnpm/supports-color@7.2.0/.../index.js:2:11
      at __require (./src/workflows/v2/workflow:11:50)
      at .../node_modules/.pnpm/chalk@4.1.2/.../source/index.js:3:53
      at __require (./src/workflows/v2/workflow:11:50)
      at .../@workflow/errors/src/ansi.ts:1:18
      at Script.runInContext (node:vm:149:12)

Replace `chalk` with a 25-line inline SGR helper exposing the same call
surface (`chalk.red`, `chalk.bold`, …). Color detection mirrors chalk's
default at a coarse level — `FORCE_COLOR` on, `NO_COLOR` off, otherwise
gated on `process.stdout.isTTY` — so non-TTY logs and the workflow VM
(no `process`) get plain text, matching previous behavior in tests and
in production log drains.

Drops the `chalk` runtime dependency from `@workflow/errors` and removes
the now-unused `__mocks__/chalk.ts` Vitest mock.

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

vercel Bot commented May 4, 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 4, 2026 10:59am
example-nextjs-workflow-webpack Ready Ready Preview, Comment May 4, 2026 10:59am
example-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-astro-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-express-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-fastify-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-hono-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-nitro-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-nuxt-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-sveltekit-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-tanstack-start-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workbench-vite-workflow Ready Ready Preview, Comment May 4, 2026 10:59am
workflow-docs Ready Ready Preview, Comment, Open in v0 May 4, 2026 10:59am
workflow-swc-playground Ready Ready Preview, Comment May 4, 2026 10:59am
workflow-tarballs Ready Ready Preview, Comment May 4, 2026 10:59am
workflow-web Ready Ready Preview, Comment May 4, 2026 10:59am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 4, 2026

🦋 Changeset detected

Latest commit: 47be549

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

This PR includes changesets to release 22 packages
Name Type
@workflow/errors Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/core Patch
@workflow/web Patch
workflow Patch
@workflow/world-local Patch
@workflow/world-postgres Patch
@workflow/world-vercel Patch
tarballs Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/vitest Patch
@workflow/world-testing Patch
@workflow/web-shared Patch
@workflow/ai Patch
@workflow/nuxt 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 4, 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 🥇 Nitro 0.033s (-24.6% 🟢) 1.005s (~) 0.973s 10 1.00x
💻 Local Express 0.035s (-20.1% 🟢) 1.006s (~) 0.970s 10 1.09x
🐘 Postgres Express 0.046s (-19.8% 🟢) 1.011s (~) 0.964s 10 1.43x
💻 Local Next.js (Turbopack) 0.049s 1.005s 0.956s 10 1.50x
🐘 Postgres Nitro 0.052s (-45.5% 🟢) 1.011s (-3.0%) 0.959s 10 1.60x
🌐 Redis Next.js (Turbopack) 0.054s 1.005s 0.951s 10 1.65x
🐘 Postgres Next.js (Turbopack) 0.057s 1.011s 0.953s 10 1.76x
🌐 MongoDB Next.js (Turbopack) 0.091s 1.007s 0.916s 10 2.81x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 0.295s (+25.2% 🔺) 2.353s (+10.2% 🔺) 2.058s 10 1.00x
▲ Vercel Nitro 0.366s (-10.6% 🟢) 2.033s (-19.0% 🟢) 1.667s 10 1.24x
▲ Vercel Next.js (Turbopack) 0.558s (+122.1% 🔺) 2.742s (+17.5% 🔺) 2.183s 10 1.90x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.070s (-5.4% 🟢) 2.007s (~) 0.937s 10 1.00x
💻 Local Express 1.072s (-4.7%) 2.007s (~) 0.935s 10 1.00x
🐘 Postgres Express 1.082s (-5.6% 🟢) 2.009s (~) 0.927s 10 1.01x
🐘 Postgres Nitro 1.084s (-4.9%) 2.009s (~) 0.925s 10 1.01x
💻 Local Next.js (Turbopack) 1.110s 2.006s 0.896s 10 1.04x
🌐 Redis Next.js (Turbopack) 1.111s 2.008s 0.897s 10 1.04x
🐘 Postgres Next.js (Turbopack) 1.114s 2.010s 0.897s 10 1.04x
🌐 MongoDB Next.js (Turbopack) 1.148s 2.009s 0.861s 10 1.07x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.586s (-15.4% 🟢) 3.902s (+2.5%) 2.317s 10 1.00x
▲ Vercel Nitro 1.641s (-57.8% 🟢) 4.080s (-30.9% 🟢) 2.439s 10 1.04x
▲ Vercel Next.js (Turbopack) 2.861s (+40.6% 🔺) 4.792s (+25.1% 🔺) 1.931s 10 1.80x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 10.400s (-5.1% 🟢) 11.014s (~) 0.614s 3 1.00x
🐘 Postgres Nitro 10.402s (-4.3%) 11.015s (~) 0.613s 3 1.00x
💻 Local Express 10.409s (-4.7%) 11.022s (~) 0.613s 3 1.00x
💻 Local Nitro 10.422s (-4.8%) 11.023s (~) 0.601s 3 1.00x
🌐 MongoDB Next.js (Turbopack) 10.655s 11.023s 0.368s 3 1.02x
🐘 Postgres Next.js (Turbopack) 10.667s 11.015s 0.348s 3 1.03x
🌐 Redis Next.js (Turbopack) 10.669s 11.023s 0.354s 3 1.03x
💻 Local Next.js (Turbopack) 10.682s 11.020s 0.338s 3 1.03x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 13.559s (-42.9% 🟢) 15.361s (-38.8% 🟢) 1.802s 2 1.00x
▲ Vercel Express 13.917s (-18.0% 🟢) 15.853s (-20.8% 🟢) 1.936s 2 1.03x
▲ Vercel Next.js (Turbopack) 14.322s (-17.3% 🟢) 16.622s (-14.3% 🟢) 2.299s 2 1.06x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 13.471s (-7.6% 🟢) 14.017s (-6.7% 🟢) 0.546s 5 1.00x
💻 Local Express 13.477s (-10.0% 🟢) 14.027s (-6.7% 🟢) 0.550s 5 1.00x
🐘 Postgres Nitro 13.481s (-7.6% 🟢) 14.021s (-6.7% 🟢) 0.540s 5 1.00x
💻 Local Nitro 13.483s (-10.5% 🟢) 14.027s (-12.5% 🟢) 0.544s 5 1.00x
🌐 MongoDB Next.js (Turbopack) 13.835s 14.025s 0.190s 5 1.03x
🌐 Redis Next.js (Turbopack) 14.050s 15.030s 0.980s 4 1.04x
💻 Local Next.js (Turbopack) 14.060s 14.628s 0.569s 5 1.04x
🐘 Postgres Next.js (Turbopack) 14.069s 15.020s 0.951s 4 1.04x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.544s (-66.6% 🟢) 23.739s (-64.4% 🟢) 2.195s 3 1.00x
▲ Vercel Express 22.795s (-54.7% 🟢) 25.107s (-52.2% 🟢) 2.312s 3 1.06x
▲ Vercel Next.js (Turbopack) 23.551s (-55.2% 🟢) 26.276s (-51.9% 🟢) 2.725s 3 1.09x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 11.836s (-15.5% 🟢) 12.015s (-17.7% 🟢) 0.179s 8 1.00x
💻 Local Nitro 11.946s (-28.8% 🟢) 12.272s (-27.9% 🟢) 0.326s 8 1.01x
💻 Local Express 11.949s (-28.0% 🟢) 12.146s (-28.7% 🟢) 0.197s 8 1.01x
🐘 Postgres Nitro 11.970s (-14.3% 🟢) 12.394s (-13.4% 🟢) 0.424s 8 1.01x
🌐 MongoDB Next.js (Turbopack) 12.590s 13.024s 0.433s 7 1.06x
💻 Local Next.js (Turbopack) 12.972s 13.452s 0.480s 7 1.10x
🌐 Redis Next.js (Turbopack) 13.100s 13.884s 0.784s 7 1.11x
🐘 Postgres Next.js (Turbopack) 13.185s 14.020s 0.835s 7 1.11x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 34.548s (-71.5% 🟢) 36.366s (-70.6% 🟢) 1.818s 3 1.00x
▲ Vercel Nitro 35.156s (-91.7% 🟢) 37.155s (-91.2% 🟢) 1.999s 3 1.02x
▲ Vercel Next.js (Turbopack) 35.694s (-90.9% 🟢) 37.608s (-90.5% 🟢) 1.913s 3 1.03x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.147s (-9.0% 🟢) 2.007s (~) 0.860s 15 1.00x
🐘 Postgres Nitro 1.156s (-9.3% 🟢) 2.007s (~) 0.851s 15 1.01x
💻 Local Nitro 1.188s (-27.2% 🟢) 2.006s (-3.3%) 0.818s 15 1.04x
💻 Local Express 1.197s (-19.6% 🟢) 2.006s (~) 0.808s 15 1.04x
🐘 Postgres Next.js (Turbopack) 1.213s 2.008s 0.794s 15 1.06x
🌐 Redis Next.js (Turbopack) 1.268s 2.006s 0.738s 15 1.10x
💻 Local Next.js (Turbopack) 1.378s 2.073s 0.695s 15 1.20x
🌐 MongoDB Next.js (Turbopack) 2.011s 2.591s 0.580s 12 1.75x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.918s (+3.6%) 4.656s (+7.7% 🔺) 1.738s 7 1.00x
▲ Vercel Next.js (Turbopack) 4.329s (+27.4% 🔺) 6.218s (+26.1% 🔺) 1.889s 5 1.48x
▲ Vercel Express 4.519s (+58.0% 🔺) 6.298s (+36.2% 🔺) 1.779s 5 1.55x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.226s (-48.1% 🟢) 2.007s (-33.3% 🟢) 0.780s 15 1.00x
🐘 Postgres Nitro 1.234s (-47.5% 🟢) 2.007s (-33.3% 🟢) 0.773s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.356s 2.007s 0.651s 15 1.11x
💻 Local Nitro 1.791s (-43.0% 🟢) 2.007s (-48.4% 🟢) 0.216s 15 1.46x
💻 Local Express 1.792s (-39.3% 🟢) 2.006s (-41.9% 🟢) 0.214s 15 1.46x
💻 Local Next.js (Turbopack) 1.806s 2.073s 0.267s 15 1.47x
🌐 Redis Next.js (Turbopack) 2.385s 3.008s 0.623s 10 1.94x
🌐 MongoDB Next.js (Turbopack) 3.564s 4.008s 0.444s 8 2.91x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 4.458s (+23.2% 🔺) 6.268s (+22.7% 🔺) 1.811s 5 1.00x
▲ Vercel Next.js (Turbopack) 5.613s (-20.9% 🟢) 7.797s (-12.4% 🟢) 2.184s 4 1.26x
▲ Vercel Nitro 6.080s (+50.1% 🔺) 8.092s (+36.7% 🔺) 2.012s 4 1.36x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.364s (-60.9% 🟢) 2.006s (-50.0% 🟢) 0.642s 15 1.00x
🐘 Postgres Nitro 1.374s (-60.5% 🟢) 2.007s (-49.9% 🟢) 0.633s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.627s 2.007s 0.380s 15 1.19x
🌐 Redis Next.js (Turbopack) 3.621s 4.009s 0.389s 8 2.65x
💻 Local Next.js (Turbopack) 5.000s 5.511s 0.511s 6 3.67x
💻 Local Nitro 5.331s (-36.2% 🟢) 5.847s (-35.2% 🟢) 0.517s 6 3.91x
💻 Local Express 5.417s (-35.0% 🟢) 5.679s (-37.1% 🟢) 0.263s 6 3.97x
🌐 MongoDB Next.js (Turbopack) 6.223s 7.012s 0.788s 5 4.56x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 6.257s (+47.6% 🔺) 8.386s (+36.9% 🔺) 2.129s 4 1.00x
▲ Vercel Next.js (Turbopack) 7.288s (-18.3% 🟢) 9.279s (-15.3% 🟢) 1.991s 4 1.16x
▲ Vercel Nitro 8.700s (+146.8% 🔺) 10.899s (+96.9% 🔺) 2.199s 3 1.39x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.153s (-8.3% 🟢) 2.009s (~) 0.857s 15 1.00x
🐘 Postgres Express 1.154s (-8.2% 🟢) 2.009s (~) 0.855s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.210s 2.007s 0.797s 15 1.05x
🌐 Redis Next.js (Turbopack) 1.257s 2.006s 0.749s 15 1.09x
💻 Local Next.js (Turbopack) 1.353s 2.006s 0.653s 15 1.17x
💻 Local Express 1.384s (-26.9% 🟢) 2.006s (-15.1% 🟢) 0.622s 15 1.20x
💻 Local Nitro 1.397s (-25.1% 🟢) 2.007s (-14.3% 🟢) 0.610s 15 1.21x
🌐 MongoDB Next.js (Turbopack) 2.013s 2.590s 0.577s 12 1.75x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.363s (-8.5% 🟢) 4.099s (-5.8% 🟢) 1.736s 8 1.00x
▲ Vercel Nitro 3.169s (+28.9% 🔺) 5.005s (+20.0% 🔺) 1.836s 7 1.34x
▲ Vercel Next.js (Turbopack) 3.909s (+33.3% 🔺) 6.008s (+29.4% 🔺) 2.100s 5 1.65x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.231s (-47.4% 🟢) 2.009s (-33.3% 🟢) 0.778s 15 1.00x
🐘 Postgres Express 1.232s (-47.4% 🟢) 2.007s (-33.3% 🟢) 0.776s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.354s 2.008s 0.654s 15 1.10x
💻 Local Nitro 2.049s (-33.1% 🟢) 2.509s (-35.4% 🟢) 0.460s 12 1.67x
💻 Local Next.js (Turbopack) 2.074s 2.735s 0.661s 11 1.69x
💻 Local Express 2.135s (-31.8% 🟢) 2.593s (-31.1% 🟢) 0.457s 12 1.74x
🌐 Redis Next.js (Turbopack) 2.370s 3.008s 0.639s 10 1.93x
🌐 MongoDB Next.js (Turbopack) 3.577s 4.009s 0.432s 8 2.91x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.907s (+20.8% 🔺) 5.774s (+13.7% 🔺) 1.867s 6 1.00x
▲ Vercel Express 4.205s (+31.7% 🔺) 6.052s (+26.3% 🔺) 1.847s 5 1.08x
▲ Vercel Next.js (Turbopack) 4.751s (+51.2% 🔺) 6.510s (+44.0% 🔺) 1.759s 5 1.22x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.358s (-61.2% 🟢) 2.008s (-49.9% 🟢) 0.650s 15 1.00x
🐘 Postgres Nitro 1.366s (-60.7% 🟢) 2.008s (-49.9% 🟢) 0.642s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.651s 2.009s 0.358s 15 1.22x
🌐 Redis Next.js (Turbopack) 3.648s 4.010s 0.362s 8 2.69x
💻 Local Express 5.565s (-36.8% 🟢) 6.015s (-35.1% 🟢) 0.450s 5 4.10x
💻 Local Next.js (Turbopack) 5.704s 6.214s 0.510s 5 4.20x
💻 Local Nitro 5.946s (-35.0% 🟢) 6.348s (-36.7% 🟢) 0.402s 6 4.38x
🌐 MongoDB Next.js (Turbopack) 6.250s 7.013s 0.763s 5 4.60x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.891s (+15.7% 🔺) 7.641s (+12.1% 🔺) 1.750s 4 1.00x
▲ Vercel Express 6.208s (-3.2%) 7.682s (-6.1% 🟢) 1.474s 4 1.05x
▲ Vercel Next.js (Turbopack) 6.830s (+1.1%) 8.929s (+4.5%) 2.099s 4 1.16x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.451s (-46.2% 🟢) 1.006s (-1.7%) 0.555s 60 1.00x
🐘 Postgres Nitro 0.453s (-44.7% 🟢) 1.006s (~) 0.553s 60 1.01x
💻 Local Nitro 0.471s (-52.0% 🟢) 1.004s (-8.2% 🟢) 0.533s 60 1.04x
💻 Local Express 0.506s (-48.6% 🟢) 1.022s (-5.1% 🟢) 0.515s 59 1.12x
🌐 MongoDB Next.js (Turbopack) 0.597s 1.006s 0.409s 60 1.32x
🌐 Redis Next.js (Turbopack) 0.639s 1.004s 0.365s 60 1.42x
🐘 Postgres Next.js (Turbopack) 0.662s 1.006s 0.344s 60 1.47x
💻 Local Next.js (Turbopack) 0.711s 1.004s 0.293s 60 1.58x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 4.747s (-78.5% 🟢) 6.670s (-72.2% 🟢) 1.923s 10 1.00x
▲ Vercel Express 4.916s (-74.1% 🟢) 6.991s (-67.2% 🟢) 2.075s 9 1.04x
▲ Vercel Next.js (Turbopack) 6.804s (-53.1% 🟢) 8.802s (-45.3% 🟢) 1.998s 7 1.43x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.032s (-47.8% 🟢) 1.458s (-35.4% 🟢) 0.426s 62 1.00x
🐘 Postgres Nitro 1.047s (-45.7% 🟢) 1.507s (-28.3% 🟢) 0.459s 60 1.01x
💻 Local Express 1.184s (-60.7% 🟢) 2.006s (-44.1% 🟢) 0.821s 45 1.15x
💻 Local Nitro 1.191s (-60.8% 🟢) 2.006s (-46.6% 🟢) 0.815s 45 1.15x
🌐 MongoDB Next.js (Turbopack) 1.503s 2.007s 0.504s 45 1.46x
🐘 Postgres Next.js (Turbopack) 1.587s 2.007s 0.419s 45 1.54x
🌐 Redis Next.js (Turbopack) 1.611s 2.028s 0.417s 45 1.56x
💻 Local Next.js (Turbopack) 1.741s 2.005s 0.265s 45 1.69x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 12.285s (-64.4% 🟢) 14.394s (-60.9% 🟢) 2.108s 7 1.00x
▲ Vercel Nitro 12.810s (-67.6% 🟢) 15.636s (-62.1% 🟢) 2.825s 6 1.04x
▲ Vercel Next.js (Turbopack) 15.611s (-68.7% 🟢) 18.106s (-65.0% 🟢) 2.494s 6 1.27x

🔍 Observability: Express | Nitro | 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 1.878s (-52.9% 🟢) 2.076s (-52.5% 🟢) 0.198s 58 1.00x
🐘 Postgres Nitro 2.079s (-49.3% 🟢) 2.550s (-44.6% 🟢) 0.470s 48 1.11x
💻 Local Nitro 2.680s (-71.2% 🟢) 3.008s (-70.0% 🟢) 0.327s 40 1.43x
💻 Local Express 2.692s (-70.8% 🟢) 3.008s (-70.0% 🟢) 0.316s 40 1.43x
🐘 Postgres Next.js (Turbopack) 3.092s 4.009s 0.917s 30 1.65x
🌐 Redis Next.js (Turbopack) 3.096s 3.880s 0.783s 31 1.65x
🌐 MongoDB Next.js (Turbopack) 3.670s 4.013s 0.343s 30 1.95x
💻 Local Next.js (Turbopack) 3.704s 4.008s 0.303s 30 1.97x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 39.197s (-59.6% 🟢) 42.019s (-57.3% 🟢) 2.822s 3 1.00x
▲ Vercel Express 40.332s (-69.0% 🟢) 42.693s (-67.7% 🟢) 2.361s 3 1.03x
▲ Vercel Next.js (Turbopack) 44.774s (-58.2% 🟢) 48.551s (-55.4% 🟢) 3.777s 3 1.14x

🔍 Observability: Nitro | Express | 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.176s (-37.5% 🟢) 1.006s (~) 0.829s 60 1.00x
🐘 Postgres Nitro 0.182s (-35.8% 🟢) 1.005s (~) 0.824s 60 1.03x
🐘 Postgres Next.js (Turbopack) 0.232s 1.006s 0.774s 60 1.32x
🌐 Redis Next.js (Turbopack) 0.242s 1.004s 0.762s 60 1.37x
💻 Local Express 0.439s (-21.6% 🟢) 1.004s (~) 0.565s 60 2.49x
💻 Local Nitro 0.474s (-21.6% 🟢) 1.021s (~) 0.547s 59 2.69x
💻 Local Next.js (Turbopack) 0.539s 1.004s 0.465s 60 3.06x
🌐 MongoDB Next.js (Turbopack) 1.032s 1.825s 0.793s 33 5.85x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.231s (+34.3% 🔺) 4.189s (+25.0% 🔺) 1.958s 15 1.00x
▲ Vercel Express 2.259s (+15.6% 🔺) 4.431s (+21.8% 🔺) 2.172s 14 1.01x
▲ Vercel Next.js (Turbopack) 4.335s (+114.4% 🔺) 6.320s (+66.6% 🔺) 1.984s 10 1.94x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.309s (-39.4% 🟢) 1.006s (~) 0.697s 90 1.00x
🐘 Postgres Nitro 0.312s (-37.2% 🟢) 1.006s (~) 0.694s 90 1.01x
🌐 Redis Next.js (Turbopack) 0.412s 1.004s 0.592s 90 1.33x
🐘 Postgres Next.js (Turbopack) 0.450s 1.006s 0.555s 90 1.46x
💻 Local Nitro 2.179s (-14.2% 🟢) 3.008s (~) 0.829s 30 7.05x
💻 Local Express 2.268s (-9.8% 🟢) 2.911s (-3.3%) 0.644s 31 7.34x
💻 Local Next.js (Turbopack) 2.382s 2.977s 0.595s 31 7.71x
🌐 MongoDB Next.js (Turbopack) 2.594s 3.008s 0.414s 30 8.39x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 7.284s (+139.1% 🔺) 9.227s (+91.9% 🔺) 1.943s 10 1.00x
▲ Vercel Nitro 7.305s (+126.5% 🔺) 9.647s (+100.1% 🔺) 2.342s 10 1.00x
▲ Vercel Next.js (Turbopack) 8.118s (+129.6% 🔺) 10.545s (+103.1% 🔺) 2.427s 9 1.11x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.618s (-24.5% 🟢) 1.006s (-1.1%) 0.388s 120 1.00x
🐘 Postgres Nitro 0.649s (-17.9% 🟢) 1.006s (~) 0.357s 120 1.05x
🌐 Redis Next.js (Turbopack) 0.770s 1.004s 0.233s 120 1.25x
🐘 Postgres Next.js (Turbopack) 0.933s 1.219s 0.286s 99 1.51x
🌐 MongoDB Next.js (Turbopack) 5.361s 6.012s 0.651s 20 8.67x
💻 Local Express 10.227s (-8.6% 🟢) 10.863s (-9.0% 🟢) 0.636s 12 16.54x
💻 Local Nitro 10.251s (-8.4% 🟢) 10.781s (-7.6% 🟢) 0.530s 12 16.58x
💻 Local Next.js (Turbopack) 10.950s 11.757s 0.807s 11 17.71x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 20.578s (+177.3% 🔺) 23.078s (+149.6% 🔺) 2.500s 6 1.00x
▲ Vercel Next.js (Turbopack) 21.742s (+110.5% 🔺) 24.590s (+100.1% 🔺) 2.848s 5 1.06x
▲ Vercel Nitro 25.208s (+226.4% 🔺) 27.039s (+187.6% 🔺) 1.831s 5 1.22x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

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.129s (+450.3% 🔺) 1.997s (+99.9% 🔺) 0.001s (-18.8% 🟢) 2.009s (+98.7% 🔺) 0.881s 10 1.00x
💻 Local Express 1.131s (+468.1% 🔺) 2.005s (+99.6% 🔺) 0.012s (+2.5%) 2.019s (+98.4% 🔺) 0.888s 10 1.00x
💻 Local Nitro 1.132s (+429.6% 🔺) 2.005s (+99.6% 🔺) 0.013s (+4.0%) 2.021s (+98.3% 🔺) 0.889s 10 1.00x
🐘 Postgres Nitro 1.149s (+460.7% 🔺) 1.994s (+99.5% 🔺) 0.002s (+6.7% 🔺) 2.012s (+99.0% 🔺) 0.863s 10 1.02x
💻 Local Next.js (Turbopack) 1.178s 2.003s 0.012s 2.019s 0.840s 10 1.04x
🐘 Postgres Next.js (Turbopack) 1.192s 2.002s 0.001s 2.010s 0.818s 10 1.06x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.184s (-43.0% 🟢) 3.612s (-31.5% 🟢) 1.614s (+117.5% 🔺) 5.719s (-11.8% 🟢) 3.535s 10 1.00x
▲ Vercel Express 2.198s (-12.3% 🟢) 3.538s (-13.5% 🟢) 1.751s (+82.3% 🔺) 5.836s (+4.4%) 3.637s 10 1.01x
▲ Vercel Next.js (Turbopack) 4.942s (-27.9% 🟢) 5.438s (-37.1% 🟢) 1.145s (+81.2% 🔺) 8.364s (-14.6% 🟢) 3.421s 10 2.26x

🔍 Observability: Nitro | Express | 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.496s (+137.4% 🔺) 2.000s (+98.7% 🔺) 0.003s (-9.5% 🟢) 2.026s (+98.1% 🔺) 0.531s 30 1.00x
🐘 Postgres Nitro 1.507s (+141.5% 🔺) 2.002s (+98.8% 🔺) 0.004s (-8.9% 🟢) 2.024s (+97.9% 🔺) 0.517s 30 1.01x
💻 Local Nitro 1.538s (+83.4% 🔺) 2.012s (+98.8% 🔺) 0.010s (+11.7% 🔺) 2.025s (+81.4% 🔺) 0.486s 30 1.03x
🐘 Postgres Next.js (Turbopack) 1.658s 2.009s 0.004s 2.025s 0.367s 30 1.11x
💻 Local Express 1.716s (+126.6% 🔺) 2.012s (+95.5% 🔺) 0.009s (-2.1%) 2.202s (+111.8% 🔺) 0.486s 28 1.15x
💻 Local Next.js (Turbopack) 2.055s 2.009s 0.010s 2.423s 0.368s 25 1.37x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.789s (-80.3% 🟢) 7.537s (-75.5% 🟢) 0.268s (+139.0% 🔺) 8.404s (-73.6% 🟢) 2.615s 8 1.00x
▲ Vercel Express 6.045s (-7.1% 🟢) 7.653s (-4.5%) 0.313s (-23.5% 🟢) 8.503s (-3.8%) 2.457s 8 1.04x
▲ Vercel Next.js (Turbopack) 12.326s (-27.1% 🟢) 13.810s (-24.3% 🟢) 0.429s (+103.2% 🔺) 15.364s (-18.9% 🟢) 3.038s 4 2.13x

🔍 Observability: Nitro | Express | 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.660s (-31.8% 🟢) 1.031s (-17.4% 🟢) 0.000s (+24.1% 🔺) 1.048s (-16.7% 🟢) 0.387s 58 1.00x
🐘 Postgres Express 0.688s (-28.4% 🟢) 1.061s (-17.0% 🟢) 0.000s (+105.4% 🔺) 1.079s (-17.4% 🟢) 0.391s 56 1.04x
🐘 Postgres Next.js (Turbopack) 0.783s 1.090s 0.000s 1.097s 0.314s 56 1.19x
💻 Local Nitro 1.345s (+10.0% 🔺) 2.016s (~) 0.000s (+333.3% 🔺) 2.018s (~) 0.674s 30 2.04x
💻 Local Next.js (Turbopack) 1.400s 2.014s 0.000s 2.017s 0.617s 30 2.12x
💻 Local Express 1.515s (+23.7% 🔺) 2.015s (~) 0.000s (-35.7% 🟢) 2.196s (+8.6% 🔺) 0.681s 28 2.29x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.737s (+22.5% 🔺) 5.067s (+15.4% 🔺) 0.000s (+18.2% 🔺) 5.709s (+18.7% 🔺) 1.972s 11 1.00x
▲ Vercel Express 4.218s (+12.8% 🔺) 5.770s (+13.1% 🔺) 0.000s (+50.0% 🔺) 6.218s (+12.4% 🔺) 2.000s 11 1.13x
▲ Vercel Next.js (Turbopack) 6.160s (-39.5% 🟢) 6.979s (-39.4% 🟢) 0.000s (NaN%) 8.458s (-29.8% 🟢) 2.298s 8 1.65x

🔍 Observability: Nitro | Express | 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 🥇 Nitro 1.286s (-28.2% 🟢) 2.001s (-6.6% 🟢) 0.000s (-100.0% 🟢) 2.020s (-7.1% 🟢) 0.734s 30 1.00x
🐘 Postgres Express 1.384s (-21.9% 🟢) 2.067s (-5.1% 🟢) 0.000s (+Infinity% 🔺) 2.115s (-3.8%) 0.730s 29 1.08x
🐘 Postgres Next.js (Turbopack) 1.629s 2.225s 0.000s 2.239s 0.610s 27 1.27x
💻 Local Next.js (Turbopack) 2.539s 3.125s 0.000s 3.128s 0.589s 20 1.97x
💻 Local Express 3.054s (-11.9% 🟢) 3.903s (-3.2%) 0.000s (-45.3% 🟢) 3.905s (-3.2%) 0.852s 16 2.37x
💻 Local Nitro 3.180s (-6.1% 🟢) 3.966s (-1.6%) 0.000s (-41.4% 🟢) 3.971s (-1.6%) 0.791s 16 2.47x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 6.004s (+30.9% 🔺) 7.517s (+24.8% 🔺) 0.000s (+Infinity% 🔺) 8.103s (+25.5% 🔺) 2.099s 8 1.00x
▲ Vercel Nitro 6.750s (+64.9% 🔺) 8.558s (+59.2% 🔺) 0.000s (-100.0% 🟢) 9.120s (+57.4% 🔺) 2.370s 7 1.12x
▲ Vercel Next.js (Turbopack) 8.561s (+52.4% 🔺) 9.916s (+42.0% 🔺) 0.000s (-100.0% 🟢) 11.240s (+49.1% 🔺) 2.679s 6 1.43x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 11/21
🐘 Postgres Express 17/21
▲ Vercel Nitro 11/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 19/21
Next.js (Turbopack) 🐘 Postgres 11/21
Nitro 🐘 Postgres 17/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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 859 0 219 1078
✅ 💻 Local Development 957 0 219 1176
✅ 📦 Local Production 957 0 219 1176
✅ 🐘 Local Postgres 957 0 219 1176
✅ 🪟 Windows 98 0 0 98
✅ 📋 Other 510 0 176 686
Total 4338 0 1052 5390

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 72 0 26
✅ example 72 0 26
✅ express 72 0 26
✅ fastify 72 0 26
✅ hono 72 0 26
✅ nextjs-turbopack 96 0 2
✅ nextjs-webpack 96 0 2
✅ nitro 72 0 26
✅ nuxt 72 0 26
✅ sveltekit 91 0 7
✅ vite 72 0 26
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 73 0 25
✅ express-stable 73 0 25
✅ fastify-stable 73 0 25
✅ hono-stable 73 0 25
✅ nextjs-turbopack-canary 79 0 19
✅ nextjs-turbopack-stable 98 0 0
✅ nextjs-webpack-canary 79 0 19
✅ nextjs-webpack-stable 98 0 0
✅ nitro-stable 73 0 25
✅ nuxt-stable 73 0 25
✅ sveltekit-stable 92 0 6
✅ vite-stable 73 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 73 0 25
✅ express-stable 73 0 25
✅ fastify-stable 73 0 25
✅ hono-stable 73 0 25
✅ nextjs-turbopack-canary 79 0 19
✅ nextjs-turbopack-stable 98 0 0
✅ nextjs-webpack-canary 79 0 19
✅ nextjs-webpack-stable 98 0 0
✅ nitro-stable 73 0 25
✅ nuxt-stable 73 0 25
✅ sveltekit-stable 92 0 6
✅ vite-stable 73 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 73 0 25
✅ express-stable 73 0 25
✅ fastify-stable 73 0 25
✅ hono-stable 73 0 25
✅ nextjs-turbopack-canary 79 0 19
✅ nextjs-turbopack-stable 98 0 0
✅ nextjs-webpack-canary 79 0 19
✅ nextjs-webpack-stable 98 0 0
✅ nitro-stable 73 0 25
✅ nuxt-stable 73 0 25
✅ sveltekit-stable 92 0 6
✅ vite-stable 73 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 98 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 73 0 25
✅ e2e-local-dev-tanstack-start-stable 73 0 25
✅ e2e-local-postgres-nest-stable 73 0 25
✅ e2e-local-postgres-tanstack-start-stable 73 0 25
✅ e2e-local-prod-nest-stable 73 0 25
✅ e2e-local-prod-tanstack-start-stable 73 0 25
✅ e2e-vercel-prod-tanstack-start 72 0 26

📋 View full workflow run

@VaguelySerious VaguelySerious enabled auto-merge (squash) May 4, 2026 10:41
Move the inline ANSI shim out of `ansi.ts` into its own
`./internal-chalk.ts` so tests can swap it for a tag-emitting mock via
`vi.mock('./internal-chalk.js', …)`. Snapshots for `Ansi.code` /
`Ansi.hint` / `Ansi.note` / `Ansi.help` / `Ansi.docs` go back to the
readable HTML-like form (`<blue><b>hint:</b> try reloading</blue>`),
making it obvious from the test file which fragments are colored and
how — the same review affordance the previous `__mocks__/chalk.ts`
mock provided before the chalk dep was dropped.

`Ansi.frame` and `Ansi.inline` remain plain in snapshots because they
don't apply any styling themselves; that matches the pre-fix behavior.

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

@TooTallNate TooTallNate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The diagnosis is correct, the fix is appropriately surgical, and the shim is well-written.

Verified

Reachability claim — confirmed: packages/core/src/workflow/index.tscontext-errors.tscontext-violation-error.tsimport * as Ansi from '@workflow/errors/ansi'. So any consumer that uses workflow-context-checked APIs (createHook, createWebhook, getWorkflowMetadata, etc.) ends up dragging the entire ansi/chalk transitive graph into the workflow VM bundle.

Output parity — for the only nested call in ansi.ts (code(): chalk.italic(\${chalk.dim('`')}${str}${chalk.dim('`')}`)), the shim produces byte-for-byte the same SGR sequence as chalk@5.6.2`:

\x1b[3m\x1b[2m`\x1b[22mfoo\x1b[2m`\x1b[22m\x1b[23m

The 22 (normal intensity) close after each dim correctly leaves italic (3) on, since 22 only resets bold/dim — same as chalk's behavior.

Bundle effect — built workbench/example from this branch and grepped the workflow VM bundle (the string passed to workflowEntrypoint):

$ grep -cE "supports-color|require\(['\"](node:)?os['\"]|chalk|internal_chalk" /tmp/vm-bundle.txt
0

No chalk, no supports-color, no os anywhere. (The example workbench's VM bundle didn't actually pull in context-violation-error due to tree-shaking in this particular workflow set, so the chalk references were already absent on main for this specific bundle — but the change is still correct, and downstream consumers like vade that exercise the workflow-context paths will get the fix.)

Testspnpm --filter @workflow/errors test passes (4 files, 26 tests including all 11 ansi.test.ts snapshots), pnpm --filter @workflow/core test passes (820 tests).

CI failures are pre-existing flakes

The two red checks (Unit Tests (ubuntu-latest), E2E Required Check) are both from the same flaky world-postgres test:

FAIL  test/spec.test.ts > sequential steps with stream complete in a single flow invocation
AssertionError: expected +0 to be 1 // Object.is equality

This same test fails on origin/main HEAD (run 25343680860 job 74307194029) and is unrelated to this change.

Minor nits (non-blocking)

  • colorEnabled is evaluated once at module-load time, whereas chalk re-evaluates lazily on each call. If a host process programmatically flips FORCE_COLOR/NO_COLOR after @workflow/errors is imported, the shim won't pick up the change. In practice no one in this codebase does that, and the JSDoc on internal-chalk.ts is implicit about it — but if you wanted to be belt-and-braces, wrapping the env-var check inside sgr() would keep parity. Totally fine to leave as-is.

  • The __mocks__/chalk.ts deletion is correct, but worth noting that the module-graph entrypoint for the test mock changed from "the chalk package as resolved by node" to "this sibling file at a literal relative path". That's fine for this codebase but means the mock now relies on vi.mock('./internal-chalk.js', ...) paths rather than package identity — slightly more fragile if ansi.ts is ever moved to a different directory. Fine for now.

Approving.

@VaguelySerious VaguelySerious merged commit 540a2ef into main May 5, 2026
175 of 177 checks passed
@VaguelySerious VaguelySerious deleted the peter/errors-no-chalk branch May 5, 2026 00:47
@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
…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
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