- Bump the bundled Wrangler to 4.120.0, which includes undici 7.29.0 without the package-level override.
- Reject unsupported Wrangler
triggers.eventssubscriptions before bundling instead of silently dropping them from the WDL deploy manifest.
[wdl] session_policy = "restart"opts a Worker into session restarts, matching Cloudflare's default deploy behavior. The default remainspreserve.wdl deployrefuses to promote when control does not confirm the policy.
- Reject a bare TOML datetime where a config table is expected, instead of reading it as an empty table and silently dropping the section.
- Report an unknown promotion outcome when a timeout, transport failure, 3xx/5xx or unconfirmed response answers the promote, instead of claiming the version was not promoted.
- Override
undicito^7.29.0and refreshbrace-expansionto 5.0.9, clearing five undici advisories and GHSA-rgw5-rvv9-x895. Both reach this repository's install tree only, through the miniflare dev server the CLI never runs and through ESLint.
- Pin Prettier and enforce repository formatting in CI and release validation.
- Routed Workers with at least one custom route can set
workers_dev = falseto disable their platform-domain URL. Deploy summaries print the active platform URL and route-pattern URL hints, omitting the disabled URL.
- Bump the bundled
wranglerto 4.114.0, which vendors a patched sharp (0.35.2) and clears a high-severity libvips advisory (GHSA-f88m-g3jw-g9cj) reachable only through the miniflare dev server, which the CLI never runs.
wdl workersandwdl workflows listnow expose workflow-definition state, including retired definitions. Delete dry-runs report worker-secret and workflow-definition presence without claiming blocked data will be deleted.- Local deploy URLs now preserve the scheme and port from
CONTROL_URL. wdl deploynow pins Wrangler 4.112.0, rejects unmappedaddressesanddependencies_instrumentation, and suppresses Wrangler's banner, routine update check, and telemetry during dry-run. Unknown-field diagnostics may still query the npm registry.
wdl deploynow explainscompatibility_flag_unsupportederrors.- Workflow human output now escapes control-plane fields without changing
--jsonoutput.
wdl deployno longer passes WDL-only[[exports]],[[platform_bindings]],[[triggers.schedules]], or[[services]].nsto Wrangler's temporary bundle config. This avoids theexportsschema collision in Wrangler 4.107+ while preserving the fields in the WDL deploy manifest.
wdl deploynow selectswrangler.json, thenwrangler.jsonc, thenwrangler.toml, parses both JSON filenames as JSONC, and resolves Wrangler from explicit/project/package/PATHsources (npxremains opt-in). It rejects Python modules, unmapped runtime fields, and binding collisions before upload; runtime/workerd bundle policy remains canonical in control.- New projects use
compatibility_date = "2026-06-17"unless a feature requires newer behavior. - Control requests now identify the CLI version, cap buffered JSON responses at
16 MiB, and consistently honor validated
CONTROL_CONNECT_HOSThost, port, URL, and IPv6 overrides. wdl doctor --strictprovides a failing CI gate while default doctor remains report-only. Successful help writes to stdout, andwdl help <command>shows command-specific help.- Deploy, D1 migrations, and doctor report lower-priority Wrangler configs that were ignored; tail reconnects cleanly when control recycles an idle or expired session.
- R2 object keys preserve empty segments while rejecting
.and..; list validates--limit, and get requires--outbefore writing bytes to a TTY. Workflow status requires--include-stepswhenever--step-limitis used.
- Control connection failures, invalid 2xx JSON, unreadable project
.envor D1 input files, and unexpected arguments now use escaped CLI diagnostics instead of raw Node errors or silently ignored input. - Deploy failures now retain control warnings and actionable secret, environment-budget, and caller-secret guidance.
- D1 migrations reject symlinked SQL files, invalid
.assetsignorepatterns identify the offending rule, and project.envparsing tolerates unrelated dotenv extensions. - Secret mutation failures explain environment-budget, contention, and envelope errors, including when no mutation was written; token list safely renders stored labels and endpoints.
- Token-store writes are atomic and symlink-safe, serialized by a recoverable lock, use unguessable temporary names, and escape filesystem diagnostics.
- Tail bounds malformed SSE lines, and deploy cleans temporary Wrangler config files on normal exit and signals.
- Assets docs now show
await env.ASSETS.url(...), matching the runtime API and the example workers.
wdl d1 executenow requires exactly one SQL source (--sqlor--file) and rejects empty SQL locally before contacting control. Even--sql ""conflicts with--file.wdl deploynow rejects more malformed Wrangler config locally instead of silently dropping invalid input: non-arraykv_namespaces, malformed KV entries, present-but-non-table[assets], and several validated fields that previously reached the manifest with loose types. Wrangler local-dev KV fieldspreview_idandremoteremain allowed but are ignored by deploy.
wdl token setand any other credential write now refuse a group- or world-writable store directory: a 0600 file there can still be deleted, replaced, or symlink-swapped by another user, so the write fails with achmod 700hint instead. POSIX only.wdl r2 object head --jsonparses custom metadata without prototype pollution — anx-amz-meta-__proto__header stays an own key, and an emptyx-amz-meta-header is dropped.
- Docs and the npm description point at the now-public platform repo (wdl-dev/wdl), frame the CLI as its companion, and add a self-host note.
wdl d1 execute --mode execrejects--paramslocally before the control plane round-trip (any value, including[]and an empty string); an invalid non-exec--paramsnow fails the JSON-array check instead of being silently dropped.- A local deploy prints a direct
http://<ns>.<domain>:8080/<worker>/URL instead of acurl -H 'Host: ...'hint, and a control plane reached via a.test/.localhost is recognized as local (previously only localhost / 127.0.0.1). - KV docs (GUIDE and
docs/kv.md) describe the 512-byte key / list-prefix cap the platform now enforces; they previously said it was not checked. Documented thatwdl d1 execute --mode exectakes no--params.
--no-token-store(andWDL_TOKEN_STORE=off) resolves credentials from flags / env /.envonly, never reading the global token store — for deploying less-trusted projects, or for deterministic credential resolution in CI.wdl doctorreports the global token store: how many namespaces it holds and that project build code can read it during a deploy.
- Documentation now recommends the local token store (
wdl token set) as the default way to supply a control URL and admin token, ahead of a per-shell export or a project.env. CONTROL_CONNECT_HOSTis documented (GUIDE, thewdl-deployskill) as a local-dev / debug-only override for the TCP connection target — the HTTP Host header and TLS SNI still trackCONTROL_URL, and it must not be set persistently in a CI or production shell.
- Breaking: top-level
allowed_callersinwrangler.toml/.jsoncis no longer accepted. Cross-namespace service-binding access is declared on the target Worker via[[exports]](entrypoint = "default"for the default handler, or the class name for a named entrypoint, withallowed_callers).wdl deploynow fails fast before bundling with the migration path, matching the control plane, which rejects a deploy carrying a worker-levelallowedCallers.[[exports]]-based ACLs are unchanged.
- Control-plane error context keys are now escaped before printing, as the values already were. A malicious or compromised control plane could put terminal control bytes (ESC / OSC / C1) in a JSON error property name and have them written unescaped to stderr (OSC 52 clipboard writes, display spoofing).
- Control-plane responses now abort the connection when the body exceeds the 10 MiB cap, instead of rejecting the result while continuing to read the stream — the cap bounds resource use, not just the returned value.
- The trusted-publishing release job pins the npm CLI to an exact reviewed
version instead of installing
npm@latest, so a compromised npm release can't run in the job that holds the npm OIDC token and publish a tampered, provenance-signed artifact. - Documented that
wdl deployruns project-local build code as your OS user, which can read the on-disk token store (the environment scrub closes only the env path, not the file). Deploy only projects you trust;--no-token-storeresolves credentials without reading the store. Seedocs/token.md. - Bump the bundled
wranglerto^4.102.0, which vendors a patched undici (7.28.0) and clears a high-severity advisory (TLS validation bypass / shared cache disclosure) reachable only through the miniflare dev server, which the CLI never runs.
wdl token set/list/use/rmmanages a local credential store at~/.config/wdl/credentials($XDG_CONFIG_HOME/%APPDATA%honored), so commands resolve a control URL and token without a per-shellADMIN_TOKENexport or a token in every project's.env.setreads the token from stdin (hidden on a TTY) and validates it against/whoamibefore storing it under the namespace;rmdeletes the local copy without revoking it. The store is the samedotenv/INI dialect as a project.env, written0600, and is the lowest-precedence credential layer:flag > shell env > project .env > token store. It is trusted (home directory, same-source token + endpoint) and is not subject to the cross-origin.envguard, while a project.envendpoint is still dropped when the token comes from the store.wdl config explainshowstoken store [<ns>].…as a value's source.- The store carries a default namespace (a base
WDL_NS, the analogue of a project.env's baseWDL_NS): the first stored namespace becomes the default,wdl token set --defaultandwdl token use <ns>change it, andwdl token listmarks it with*. With a default set, commands resolve a namespace without--ns; the selection chain is--ns > shell WDL_NS > project .env WDL_NS > store default, andwdl config explainshowstoken store defaultas the namespace source.
wdl init's--nsis now optional. With--ns, the scaffoldednpm run deploykeepswdl deploy . --ns <ns>; without it the script iswdl deploy .and the namespace is resolved at deploy time (--ns/WDL_NS/ project.env/ awdl tokendefault).initalso no longer autoloads control credentials, so a corrupt token store cannot block scaffolding.
- BREAKING: the
--adminflag and theADMIN_URLenvironment variable — legacy compatibility aliases for the control endpoint — are removed. Use--control-url <url>and theCONTROL_URLenvironment variable instead.--adminis now an unknown option andADMIN_URLis no longer read from the shell or.env.
wdl secret putno longer echoes the typed secret on a TTY: input is read in raw mode (hidden), and fails closed — it errors rather than echo if the terminal cannot hide input..envvalues containing literal backslash escape sequences (e.g. a token with a backslash followed byn) now round-trip correctly instead of being decoded as control characters.
- Pinned
wsto^8.21.0via npmoverridesto clear GHSA-96hv-2xvq-fx4p in thewrangler→miniflare→wsdependency chain, keepingwrangleron v4. The DoS is reachable only through miniflare's dev server, which the CLI never starts (it only runswrangler deploy --dry-run), but the pin keeps the dependency tree clean.
Initial open-source release.
wdl initscaffolding for new WDL Worker projects, with bundled examples covering assets, KV, D1, R2, cron triggers, queues, Durable Objects, Workflows, and environment overrides.wdl deployfor Wrangler v4 projects: local bundling, manifest validation, upload, and promote against the WDL control plane.- Resource management commands:
wdl d1,wdl r2,wdl secret,wdl workers,wdl workflows,wdl delete. - Diagnostics:
wdl config explain,wdl doctor,wdl whoami, and live log streaming viawdl tail.