Skip to content

Changelog

Track all updates, features, and improvements to Kubb
Every update to Kubb
Every release is listed here, with the newest one first.

v5.10.0

Latestminor

@kubb/adapter-oas

Feature
Keep server variables on InputMeta.servers. InputServer gains an optional variables field with the source URL template's variables, copied as-is next to the resolved url, so a consumer can tell a templated server from a literal one. It is absent when the server declares no variables. (#4315)
Fix
Carry vendor extensions on the AST. OperationNode and InputMeta gain an optional extensions bag with every x-* key copied as-is, set only when the source has one. The OAS adapter fills it from the operation object and the document root, so plugins can read keys like x-org-ignore without walking the raw document. Path-level extensions are not copied. (#4311)

@kubb/cli

Fix
Remove KUBB_AGENT_TOKEN from kubb studio. The CLI now connects only through a paired machine, and in CI you run kubb studio snapshot with KUBB_TOKEN instead. (#4317)

@kubb/studio

Feature
Add a separate allowReadAst permission (--allow-read-ast) for reading the parsed spec. allowRead now covers only generated files, so projects that granted allowRead before are asked once more about the spec. (#4320)

v5.9.0

minor

@kubb/cli

Feature
The Kubb registry is stable. kubb add installs a reviewed plugin, adapter, or parser at the version the registry pins, kubb update moves installed extensions to that version, and kubb list shows what is installed. Registry support landed across 5.8.1 to 5.8.4.

unplugin-kubb

Fix
Generate once per build in every bundler. webpack and Rspack no longer rebuild forever in watch mode with output.clean, and Astro no longer generates twice. (#4266)
Fix
Register the Nuxt module with the Rspack builder too, and generate only in the client build of nuxt build. The module now needs @nuxt/kit 3.14 or later. (#4266)
Fix
Fail the build when config is missing, and log ✗ Generation failed when generation fails. (#4266)

v5.8.4

patch

@kubb/core

Feature
Registry entries can pin a GitHub release. kubb add and kubb update install it as github:<owner>/<repo>#<commit>. (#4264)

v5.8.3

patch

@kubb/core

Feature
Add maintainers and dependencies to kubb-extension.json. Each package now ships its overview, options page, and guides in a docs/ folder. (#4260)

v5.8.2

patch

@kubb/core

Feature

Add defineExtension to define a plugin, an adapter, or a parser. definePlugin, defineParser, and createAdapter still work but are deprecated. (#4258)

export const pluginZod = defineExtension<PluginZod>({
  kind: 'plugin',
  meta: { name: 'plugin-zod' },
  setup(options, kubb) {
    kubb.addGenerator(zodGenerator)
    return options
  },
})

v5.8.1

patch

@kubb/cli

Feature
Add kubb add, kubb update, and kubb list to install and update extensions from the Kubb registry. (#4253)

@kubb/core

Feature
Add the kubb-extension.json manifest. Studio runs installed third-party plugins that ship one. (#4253)
Feature
createAdapter takes an object with meta, setup, and build, like definePlugin. defineParser takes build instead of setup. (#4249)
Fix
Remove the options schema from definePlugin and @kubb/kit/options, both added in 5.8.0. Type plugin options with TypeScript and apply their defaults in setup. (#4252)

@kubb/plugin-barrel

Fix
A barrel: false plugin that writes to the output root no longer removes the other plugins' barrels. (#4254)
Fix
A plugin without output.path no longer takes over the other plugins' barrels. (#4255)

v5.8.0

minor

@kubb/core

Feature
Add an options schema to definePlugin, and shared Zod schemas in @kubb/kit/options. 5.8.1 removed both. (#4244, #4245)
Fix
Composables such as setResolver() work in plugins that a CommonJS config loads, instead of failing with KUBB_NO_CONTEXT. (#4246)

v5.7.0

minor

@kubb/core

Feature
definePlugin and defineParser accept an object with meta, dependencies, and setup(options, kubb). The factory form is deprecated. A mismatch in meta.compatibility or dependencies fails the run with KUBB_INCOMPATIBLE_EXTENSION, KUBB_MISSING_DEPENDENCY, or KUBB_INCOMPATIBLE_DEPENDENCY. (#4241)
Feature
Add composables to kubb/kit, such as addGenerator(), setResolver(), and useOptions(), so a plugin can call setup helpers without passing ctx around. (#4240)

v5.6.3

patch

@kubb/core

Fix
Add ctx.requirePlugin(name) and assertPluginOption() for plugin setup checks, and createMockedSetupContext() in @kubb/kit/testing for unit tests. (#4238)

@kubb/mcp

Fix
Validate MCP tool arguments with Zod Mini instead of valibot. Invalid arguments now return Zod's error messages. (#4234)

@kubb/studio

Fix
Harden the kubb studio agent's config edits and sandbox input, and reload JavaScript configs on every generation. (#4233)

v5.6.2

patch

@kubb/studio

Fix
kubb studio snapshot works when kubb.config.ts does not set storage, and no longer leaves a temp folder behind. (#4231, #4229)

v5.6.1

patch

@kubb/cli

Fix
Rebuild once per editor save in kubb generate --watch. An atomic save (write a temp file, then rename it) could trigger two rebuilds, because the 100 ms debounce matched chokidar's 100 ms atomic-save window. The debounce is now 250 ms. (#4227, 4ba64cf)

@kubb/core

Fix
Add kubbStorage and resolveKubbDir for the files Kubb keeps for itself under ~/.kubb (or KUBB_HOME). The file and html reporters write through it. (#4225, 30f9f4d)

@kubb/studio

Fix
Connect to Kubb Studio over one WebSocket, and publish CI snapshots in one request. Needs a Kubb Studio release that accepts Kubb 5.6.1 agents. kubb studio snapshot drops --timeout and the --allow-* flags. (#4225, 30f9f4d)

v5.6.0

minor

@kubb/adapter-oas

Fix
Internal cleanup of @kubb/adapter-oas with no change to generated output. (#4216, 8708135)

@kubb/ast

Fix
Type a format: 'date-time' schema as a plain string node in InferSchemaNode when dateType is false, matching what the adapter produces. (#4217, 396dde2)
Fix
Internal cleanup of @kubb/ast with no change in behavior. (#4204, b87f7e4)
Fix

Visit schemas inside a tuple's rest and inside patternProperties, so refs there are collected, transformed by macros, and imported in generated files.

  • transform, collect and collectImportedRefNames now reach rest and patternProperties on a SchemaNode.
  • createInput() gives every node its own schemas, operations and meta objects instead of sharing one default. (#4188, 62485c5)

@kubb/cli

Fix
Run output.format, output.lint and output.postGenerate through @kubb/core instead of the CLI's own copies, so every host runs the same passes. (#4215, ecf2b25)
Fix
Reorganize the CLI internals: config discovery moves to its own module, the logger helpers fold into the loggers that use them, and every command loads its runner the same way. Every command, flag and printed line stays the same. (#4211, a2c9cd7)
Fix
kubb studio accepts a flag value after a space, such as kubb studio --open --url http://localhost:3000 or --config ./kubb.config.ts, instead of failing with "Command not found". (#4221, 8dc93fc)
Fix
Keep stdout clean for the MCP stdio transport: the telemetry notice and the kubb mcp startup banner print on stderr, so the JSON-RPC stream no longer starts with a stray line. @kubb/mcp also declares jiti as a dependency instead of bundling its own copy. (#4189, 10c1f3b)

@kubb/core

Feature

Run output.format, output.lint and output.postGenerate from Kubb.generate() by default, so every host gets the same passes.

  • Adds runOutputPasses and runHook, the one implementation of the format, lint and post-generate steps. runHook spawns the command with node:child_process, in the config root, and emits kubb:hook:start, kubb:hook:line and kubb:hook:end itself.
  • generate({ processOutput }) still replaces the passes when a host needs to; its context now also carries hooks and signal.
  • unplugin-kubb and kubb mcp start honoring output.format, output.lint and output.postGenerate, which they ignored before. (#4196, 50617dd)
Fix
Import types from the modules that define them instead of internal re-export barrels. The public exports are unchanged. (#4222, 2667074)
Fix

Run output.format, output.lint and output.postGenerate commands through tinyexec, which resolves Windows command shims and the project's node_modules/.bin.

Formatter and linter detection for 'auto' also finds a tool installed only in node_modules/.bin under config.root, the folder the tool then runs from. (#4218, 0fb79d5)

Fix
Fold single-use helpers and duplicated types in the core driver, resolver, storage and diagnostics. Generated output and the plugin API do not change. (#4203, d1b5a6a)
Fix
Keep a failing hook listener's error message to the hook name. The message no longer serializes the hook arguments, which could be a whole config or AST subtree. (#4193, ee09318)
Fix
Correct doc comments so they match what the code does: group.name keeps the first path segment as written for path groups, and the defaultBanner example shows the banner Kubb writes. (#4186, 425998f)

@kubb/kit

Fix
@kubb/kit now exports the Diagnostic type. @kubb/ast exports collectSchemaRefs, the set of schema names a node references. @kubb/adapter-oas depends on @kubb/kit only, with no change to generated output. (#4210, 76d1ec8)

@kubb/mcp

Fix
The validate tool no longer prints the unreachable 'install @kubb/adapter-oas' hint. (#4197, 465e220)

@kubb/parser-ts

Fix
Load TypeScript only on the first print or copy call, so a run that only parses files starts faster. (#4205, 12428cc)
Fix
Resolve a relative import path from the importing file's directory instead of dropping the first ../, which produced a wrong path when the target sat outside that directory. (#4190, 2dbb0cd)

@kubb/plugin-barrel

Fix
The @kubb/core peer dependency warning is gone. A plugin output.path that resolves outside config.output.path is now reported as a KUBB_PATH_TRAVERSAL diagnostic. Generated barrels are unchanged. (#4202, e872176)

@kubb/renderer-jsx

Fix
Type JSX children as an array instead of any iterable, which the renderer never walked, so a Set or generator passed as children is now a type error instead of silently rendering nothing. The element type also carries its $typeof brand, and the renderer only walks elements the Kubb JSX runtime created. (#4192, 068f4a9)
Fix
Internal rewrite of the JSX renderer with no change to the rendered FileNode output. (#4202, e872176)

@kubb/studio

Feature
Studio runs a generation through @kubb/core, so the format, lint, and output.postGenerate passes run there too. (#4214, 56a24f2)
Fix
Internal cleanup of @kubb/studio, including the agent connection and the snapshot upload. (#4208, #4212, #4191)

unplugin-kubb

Fix
unplugin-kubb declares @kubb/core as a dependency only, so the peer dependency warning is gone. @kubb/parser-md has no behavior change. (#4201, 719f6bd)

v5.5.6

patch

@kubb/adapter-oas

Fix
Preserve metadata (deprecated, nullable, readOnly, writeOnly, default, examples) on schemas without explicit type when falling back to emptySchemaType. (#4179, 66a20f1)
Fix
Resolve required-only oneOf and anyOf union branches against sibling schemas and properties. (#4180, 7e2c4c2)

@kubb/cli

Fix
Report kubb as the telemetry service name instead of kubb-core. (#4177, 04e7b50)

v5.5.5

patch

@kubb/adapter-oas

Fix

Fix a batch of small bugs:

  • @kubb/adapter-oas: resolve local $ref pointers per RFC 6901, so #/paths/~1pets/get and keys with ~ or an encoded / resolve. On Windows, an absolute input such as C:\specs\api.yaml no longer counts as a URL, so a missing file now reports KUBB_INPUT_NOT_FOUND instead of failing later.
  • @kubb/mcp: reload kubb.config.ts on every tool call. The server cached the first load, so edits only showed up after a restart.
  • @kubb/cli: CI=false and CI=0 no longer count as running in CI, and kubb init detects Bun from bun.lock as well as bun.lockb.
  • @kubb/studio: a failing format, lint or postGenerate command reports one kubb:error instead of two.
  • @kubb/renderer-jsx: fix the meta prop type on <kubb-file>, which referenced FileNode without importing it. (#4175, 11cd291)

v5.5.4

patch

@kubb/adapter-oas

Fix
Report spec validation problems as KUBB_INVALID_SPEC warnings during kubb generate. The adapter validated the spec by default but discarded the result, so an invalid spec generated silently. Each problem is now listed and generation continues. Set validate: false on the adapter to skip the check, which on a large spec saves about 20% of the run. (#4172, 75b2c47)

@kubb/cli

Fix
Print output and errors for a kubb.config.ts that does not use defineConfig. Such a config has no reporters, so kubb generate attached no logger and exited with code 1 without saying why. It now falls back to the built-in reporters. (#4170, dd2a728)
Fix
Print one ✗ before an error instead of two. The error handler added its own ✗, and the spinner it stopped added another, so a failing plugin setup printed ✗ ✗ No client plugin is registered. (#4173, 464523a)

@kubb/parser-ts

Fix
Load typescript with require instead of import. When ESM code imports a CommonJS package, Node keeps a second copy of its source, and for TypeScript that copy is about 9 MB. With plugin-ts and plugin-zod loaded, heap drops by about 9 MB and RSS by about 25 MB, which matters most for the long-running kubb studio agent. (#4169, 34b95e8)

@kubb/studio

Fix
Lower the memory the kubb studio agent uses while idle. tsdown and magicast now load only when Studio packs a snapshot or reads or edits kubb.config.ts. The agent also drops its reference to a finished generation's output, which held every generated file in memory when allowWrite was off. (#4169, c705ba7)

v5.5.3

patch

@kubb/cli

Fix
Restore the telemetry source header so CLI usage events reach the existing ingestion source. (acff588)
Fix
Make plugin usage easier to filter in telemetry. Send plugin names in kubb.plugins and boolean usage flags in kubb.plugin.<name>. Preserve detailed options under kubb.plugin_options. (#4167, 4766cf9)

v5.5.2

patch

@kubb/studio

Fix
Keep plugin and adapter options from kubb.config.ts that can't be sent as JSON, such as macros, resolver functions, and RegExp patterns, when merging Studio's options for a generate. Before, Studio's lossy copy replaced them, so custom macros stopped running. (#4162, d798e0a)

v5.5.1

patch

@kubb/core

Fix
Point diagnostic documentation links to the matching sections in the consolidated diagnostic reference. (#4156, d3711ad)

v5.5.0

minor

@kubb/adapter-oas

Feature
Automatically recognize OpenAPI 3.1 oneOf/anyOf const unions as named enums when their members have distinct, non-empty titles and distinct string or number values. Member titles and descriptions are retained alongside their original wire values, without an additional adapter option. Recognition runs after Kubb's existing upgrade to OpenAPI 3.1. Ordinary enum unions and incomplete, ambiguous or additionally constrained unions retain their existing representation. Recognition can change generated enum exports, such as a literal-union Status type becoming an enum-backed StatusKey with @kubb/plugin-ts and enum.type: 'asConst'. (#4155, 0d3468f)

v5.4.5

patch

@kubb/adapter-oas

Fix
Numbers with a format such as double, float or int32 keep their minimum, maximum, exclusiveMinimum, exclusiveMaximum and multipleOf constraints, so { type: 'number', format: 'double', minimum: -90, maximum: 90 } generates z.number().min(-90).max(90) again. int64 and uint64 now keep multipleOf as well. (#4149, 8ff2b1e)

@kubb/parser-ts

Fix
Keep package import and export specifiers unchanged when applying the extension option. (#4147, 31ad673)

v5.4.4

patch

@kubb/cli

Fix
The background worker started by kubb studio start now shows up as Kubb in process lists, like the main CLI. (#4145, 81aa079)

v5.4.3

patch

@kubb/studio

Fix
Add an optional cursor and limit to readFiles, so a caller can page through a large generated file. The reply carries only that page's lines plus pages[path] with the nextCursor (null after the last page) and the file's totalLines. Reads without a limit behave as before. (#4140, 3bb9df6)

v5.4.2

patch

@kubb/cli

Fix
Log Studio commands, warnings and each generation run in the background worker log, so it no longer stops at connected. (#4135, 9e33c7e)

kubb

Fix
Describe Kubb as a way to turn your API spec into type-safe code in the package description, README and CLI intro. (#4137, b25ce0d)

v5.4.1

patch

@kubb/cli

Fix

Add kubb studio start and stop for a background connection per project. status reports its connection state and log path, and logout stops it before removing credentials. Rejected tokens stop the worker until you log in again.

Use one shared connection loop for the CLI and Docker agent. Abort pending registration on shutdown and wait for canceled generation cleanup before reconnecting. (#4128, 5d9151c)

v5.4.0

minor

@kubb/core

Feature
Add this.import(...) to printer handlers and printer.drainImports(), so a printer.nodes handler can declare the import its output needs. Allow resolver.imports to be overridden through ResolverPatch without a cast. (#4130, 0d737e2)

v5.3.19

patch

@kubb/studio

Fix
Fix kubb studio snapshot saying "No snapshot of main to compare with" even when a CI agent for the base branch already exists and simply has no snapshot of this package yet, such as a package newly added in the pull request. branchChanges now carries baseFound, and the summary line tells the two cases apart: "No snapshot of main to compare with" (no agent has run there) versus "No snapshot of main for this package yet" (the agent exists, this package is new to it). (#4123, 3561e19)
Fix
Remove allowInput from AgentPermissions and the --allow-input/KUBB_AGENT_ALLOW_INPUT flag. Only a sandbox agent can generate from an OpenAPI spec sent by Studio; every other agent always reads its spec from disk, so this was never actually a permission a host could opt into. (#4124, 292350e)

v5.3.18

patch

@kubb/studio

Fix
Organize the Studio runtime into protocol, operations, and runtime layers. (#4121, 63f951a)
Fix

kubb studio snapshot runs its snapshot job on the agent process it connected, so two overlapping pipelines of the same CI agent never build each other's checkout.

  • createJob accepts instanceId, and sends it on POST /api/jobs. A Studio that does not know the field ignores it.
  • createClient accepts an instanceId, so a host that queues its own jobs can name its process. Without one, each client still gets a random id. (#4119, 955b6b5)
Fix
Remove memoryBudgetMb from AgentCapacity, along with the KUBB_AGENT_MEMORY_BUDGET_MB environment variable. An agent no longer refuses a job for memory, and its heartbeat always reports accepting: true. (#4117, d3996ef)

v5.3.17

patch

@kubb/studio

Fix
Improve Studio agent connections, job isolation, retries, capacity reporting, and close handling. Add GitHub/GitLab branch snapshots and fail-fast token rejection handling to the CLI. (#4110, 327bfe9)

v5.3.16

patch

@kubb/studio

Fix
Align how kubb studio, the Docker agent, and kubb studio snapshot pair, connect, and log. The runtime no longer prints or knows its host, pairing takes a type through the new pairAgent, and snapshots report the files changed since the previous one. (#4098, 555e057)

v5.3.15

patch

@kubb/core

Fix
Files emitted with copy now follow the parser's extension option. Parsers can implement the new copy(file, source) hook to turn a copied file into nodes, and parserTs/parserTsx use it to lift a template's imports and exports into import and export nodes. (#4096, 050f6f9)

v5.3.14

patch

@kubb/adapter-oas

Fix
Keep a binary response or request body typed as a blob for any non-JSON media type (application/pdf, image/png, ...), not just application/octet-stream. A newer @scalar/openapi-upgrader release started emptying format: 'binary' schemas for every media type on the OAS 3.1 upgrade, not just application/octet-stream, so those bodies fell back to emptySchemaType instead of resolving to a blob. (#4094, cfcb497)

@kubb/ast

Fix
Add isBareRef for detecting unmodified schema references. (#4093, c7a9157)

v5.3.13

patch

@kubb/studio

Fix
Keep recent generations by job id and snapshot the output directory before each run, so Studio can diff a run against an earlier one or against the files on disk. Agents with a project keep them in node_modules/.cache/kubb, so they survive a restart, and sandboxes keep them in memory. KUBB_AGENT_MAX_GENERATIONS (default 8), KUBB_AGENT_MAX_GENERATIONS_MB (default 100) and KUBB_AGENT_MAX_SNAPSHOT_MB (default 50) set the limits. Breaking for the Studio connection: readFiles now takes a jobId and a source, and GenerateResult.changes is replaced by hashes and disk.hashes. @kubb/core now exports cacheStorage. (#4090, 7b517b8)

v5.3.12

patch

@kubb/studio

Fix

Report which files a Studio run added, changed, or removed, and serve the previous run's contents so Studio can show a diff.

  • GenerateResult.changes maps each path that differs from the session's previous successful run to added, changed, or removed. Unchanged files are left out, and the field is absent on a session's first run.
  • readFiles takes revision: 'previous' to read the run before the latest one, including files the latest run removed. The previous run is read into memory before the next run starts, so a session that writes to disk can still be diffed after its files are overwritten.
  • A failed run leaves the last successful run as the one to compare against.
  • FileChange is exported from @kubb/studio. (#4086, 300186d)

v5.3.11

patch

@kubb/adapter-oas

Fix
Generate Blob for multipart binary properties after upgrading an OpenAPI 3.0 document to 3.1. (#4083, 95d93a7)

v5.3.10

patch

@kubb/cli

Fix
Show sponsor tips again for successful kubb generate runs and when starting a kubb studio session. (#4077, 15c644e)

v5.3.9

patch

@kubb/adapter-oas

Fix
Update the OpenAPI parser, upgrader, and unplugin dependencies. (#4068, d88ab19)

@kubb/cli

Fix
Scope Kubb Studio help by subcommand and reject flags passed to the wrong Studio command. (#4068, d88ab19)

kubb

Fix
Apply the same adapter, parser, and plugin defaults to programmatic createKubb builds as the CLI configuration. (#4072, 4afe194)

v5.3.8

patch

@kubb/studio

Fix

Carry an agent's organization slug through pairing and connecting, so a host can log and trace it alongside the agent's own slug.

PairingResult.agent and the studio:connected hook context gain an optional organizationSlug, absent for a sandbox or global agent, which has none. studio:connected also gains agentSlug, refreshed on every connect so a rename in Studio shows up without a re-pair. Both fields are additive: a host built against an older type just ignores them. (#4066, eb5fa50)

v5.3.7

patch

@kubb/studio

Fix
Fix a snapshot package's package.json pointing main/module/exports['.'] at dist/index.* even when the generation had no top-level barrel, and add a wildcard exports['./*'] so individual generated files stay importable by path. (#4064, d2ce0c4)

v5.3.6

patch

@kubb/studio

Fix
Replace the agent WebSocket command protocol with typed Cap'n Web RPC and remove the legacy JSON envelopes. Agents and Studio must upgrade together; mismatched versions cannot communicate. (#4061, f880342)
Fix

Fix generation and heartbeat lifecycle bugs left over from the Cap'n Web RPC cutover:

  • A dropped Studio connection now cancels the in-flight generation instead of letting it finish unwatched.
  • Two startGeneration calls arriving in the same tick can no longer both start a run.
  • A heartbeat ping that never settles (a half-open socket) now closes the session instead of hanging it indefinitely.
  • Removed an unreachable error path left over from the old JSON transport. (#4061, f880342)

v5.3.5

patch

@kubb/studio

Fix

Stop holding a whole generation's output in memory for the life of a Studio session.

studio:files and studio:snapshot used to read every generated file into one Record<string, string> the moment a run finished, and kept that map alive until the next generation. A run producing gigabytes of source meant the agent process held gigabytes in RAM, whether or not anyone ever opened a file or took a snapshot.

The agent now keeps the live Storage a run wrote through, plus the list of paths it produced, and reads a file's content back from Storage only when studio:files or studio:snapshot actually asks for it. A path outside that list is refused before it reaches storage, so this changes nothing about what a session can read, only when the read happens. (#4059, 351e3c9)

Fix

Stop streaming generated source over the agent WebSocket by default. Reading it now needs --allow-read (or KUBB_AGENT_ALLOW_READ=true), matching the other four Studio permissions.

Every kubb studio session used to send the full text of every generated file on kubb:generation:end, whether or not anyone in the browser opened one. A spec producing hundreds of files could put megabytes of source on the wire per run, and nothing gated it: allowWrite, allowConfigEdit, allowInput, and allowExec all cover what Studio may do to a project, but reading generated output back was never one of the four.

kubb:generation:end now carries nothing. Everything it used to carry moved somewhere better:

  • The list of generated files is on kubb:build:end, which already carried every path and fires earlier in a run. Its paths are now relative to the agent's root, matching every other path on the wire, where they used to be absolute.
  • The file count is on kubb:generation:summary, which already had it and was always the accurate number (kubb:generation:end's old count went to 0 for a CI connection).
  • File contents are fetched on demand with a new studio:files command, which the browser sends when someone opens a file. The agent replies with agent:files, refusing unless allowRead was granted.
  • Peer dependency metadata, previously sent on every generation and round-tripped straight back into studio:snapshot, now travels with the agent:snapshot reply instead, since the CI snapshot flow is its only consumer. studio:snapshot takes bundledDependencies in place of peerDependencies.

--allow-read is off by default everywhere, like every other permission. A sandbox or global agent is always granted it, since its output is the only thing it has:

kubb studio --allow-read   # show generated files in the browser

An older Studio instance talking to this version of the agent (or the reverse) can fail: a snapshot build errors because bundledDependencies and peerDependencies no longer line up between the two ends, and a plain session shows an empty editor with no file contents. Point --url at a Studio build that matches this version.

The in-process kubb:generation:end hook (kubb.hooks.hook('kubb:generation:end', ...), or a plugin's own listener) is unaffected. It still carries config, storage, diagnostics, status, hrStart, and filesCreated, exactly as before. Only the payload this event sends over the Studio WebSocket changed. (#4059, 351e3c9)

v5.3.4

patch

@kubb/studio

Fix

Back off while polling a Studio job, so a long snapshot stops exhausting the API key rate limit.

waitForJob polled GET /api/jobs/{id} every second, starting the instant the job was queued. The CLI's kubb studio snapshot waits up to 10 minutes by default, which is up to 600 requests against a budget of 100 per window. The window only resets after a whole window with no request, so a one-second poll could never escape the limit once it hit it, and every later call failed until the run gave up. The budget belongs to the organization key, so concurrent CI runs share it.

The first poll now waits two seconds, since a job runs a generation and packs a tarball before it can possibly finish. From there the interval doubles to a 30 second ceiling, bringing a 10 minute wait down from 600 requests to 22. A 429 pushes the next poll out by the tryAgainIn Studio returns and never pulls it back in, and retry: false stops ofetch retrying a 429 with no delay. (#4057, 52637b6)

v5.3.3

patch

@kubb/studio

Fix

The agent runtime now packs snapshot tarballs itself. A new studio:snapshot command builds the npm-installable tarball from the session's most recent generation and uploads it to a Studio endpoint, instead of Studio building the tarball on its own server. A snapshot request with no prior generation is refused.

A CI connection also keeps generated files off every kubb:generation:end reply, since it has no UI to render them in. kubb studio snapshot and the Studio UI's "Create snapshot" button keep working as before, now backed by this protocol message. (#4052, 19e9c2c)

Fix

The background reconnect loop's "Retrying connection" and "Reconnect attempt failed" lines, and the teardown notice disconnect() prints on the way out, now go through console.error instead of console.info/console.log, and only print when a host passes a logLevel above silent to StudioSession. Previously they always printed unconditionally, which a CI runner that only streams a child process's stderr live (such as kubb-labs/action) never surfaces, and which contradicted installLogger's own "prints nothing when left out" default.

kubb studio and kubb studio snapshot now pass their --log-level flag through, so these lines respect the same flag as the rest of the command's output. (#4052, 19e9c2c)

v5.3.2

patch

@kubb/cli

Fix

CLI flags are now kebab-case, matching the convention used by most command-line tools.

  • kubb generate --log-level and kubb generate --dry-run replace --logLevel and --dryRun.
  • kubb studio --allow-write, --allow-config-edit, --allow-input, and --allow-exec replace --allowWrite, --allowConfigEdit, --allowInput, and --allowExec.
  • kubb init --dry-run replaces --dryRun.

To upgrade, replace any camelCase flag in a script or CI job with its kebab-case name. The CLI now rejects an unrecognized flag with an error instead of silently ignoring it.

# Before
kubb studio --allowWrite --allowExec

# After
kubb studio --allow-write --allow-exec
``` ([#4046](https://github.com/kubb-labs/kubb/pull/4046), [`e5ecdda`](https://github.com/kubb-labs/kubb/commit/e5ecdda06acbd3b99c2716384b2a8ac56eedfad8))

@kubb/studio

Fix

Renamed the studio:ping heartbeat reply to studio:pong, matching the ping/pong pattern agent:ping already implies (StudioPingMessage is now StudioPongMessage, isStudioPingMessage is now isStudioPongMessage). This is a wire-protocol change: an agent running an older @kubb/studio and a Studio running the new one won't recognize each other's heartbeat reply. Update both sides together.

Also documented the full studio:/agent: message table in packages/studio/src/protocol/index.ts, including why studio:generate has no dedicated agent:generate reply (its result rides the agent:data/kubb:generation:end event stream instead, unlike studio:save/studio:snapshot, which reply directly). (#4053, 76dd283)

v5.3.0

minor

@kubb/core

Feature
Add an opt-in HTML report with generated files, plugin timings, and diagnostics. (#4041, be705de)

v5.2.8

patch

@kubb/cli

Fix

Add kubb studio snapshot to generate and publish a Kubb Studio snapshot from any CI, not only GitHub Actions.

  • Registers or reuses a CI agent, connects it, queues a snapshot job, and polls until the tarball is ready.
  • Reads the organization CI API key from --token or KUBB_TOKEN.
  • Detects the calling CI (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI) to reuse one agent per pull or merge request, or takes an explicit --id on any other CI.
  • Prints a summary, or one JSON object with --json for a script to read.
  • @kubb/studio now also exports createAgent and machineTokenFrom, so a host can register a CI agent without hand-rolling the request.
KUBB_TOKEN=$KUBB_TOKEN kubb studio snapshot --json
``` ([#4038](https://github.com/kubb-labs/kubb/pull/4038), [`4cd9f5e`](https://github.com/kubb-labs/kubb/commit/4cd9f5e311e5dc6edb14287c13db0a5466b4e892))

v5.2.7

patch

@kubb/cli

Fix
Create a separate Kubb Studio agent connection for each project directory while reusing the same agent within that directory. (af87dbc)

@kubb/studio

Fix
Add createJob and waitForJob for Studio's async /api/jobs endpoints. (#4035, 5382ff0)

v5.2.6

patch

@kubb/studio

Fix
Add job ID correlation to Studio commands and streamed agent events. (0a1e553)

v5.2.5

patch

@kubb/studio

Fix

Add a studio:ready acknowledgement so a host can tell "the socket is open" apart from "Studio has registered this connection and will dispatch jobs to it".

A connected socket announces itself with agent:connect but never waited for a reply, so a job could arrive at Studio moments before the agent was actually registered. StudioSession now waits up to 10 seconds for studio:ready after sending that handshake and fires a new studio:ready hook once it lands, warning instead of failing if an older Studio never sends one. kubb studio prints ✓ Ready to receive jobs once it does. (#4028, b93eb64)

v5.2.4

patch

@kubb/studio

Fix

Report the package a plugin ships from, so plugin-ts reaches Studio as @kubb/plugin-ts while a third-party plugin keeps its own name.

The connect payload scoped every plugin name under @kubb/, which claimed a third-party plugin as one of Kubb's. It now follows the same rule the dependency check already used. (#4026, 628c98b)

v5.2.3

patch

@kubb/cli

Fix
kubb generate --watch now works with URL inputs. A remote document emits no filesystem events, so watch mode polls the URL (every 2 seconds) and regenerates when the response body changes. Each poll request times out after 10 seconds, so a hung server never stalls the watcher. An unreachable server is reported once per outage and polling continues. After recovery, a rebuild only happens when the document actually changed, unless the server was already down at startup, in which case the first successful poll regenerates so the output catches up. Previously --watch was silently ignored for URL inputs and the CLI exited after a single build. (#4022, 5f4fd20)

@kubb/studio

Fix
Report installed peer dependency versions and missing dependencies with each generation result. (#4021, 6187109)

v5.2.2

patch

@kubb/adapter-oas

Fix
A oneOf/anyOf without a declared OpenAPI discriminator now infers one when a property carries a distinct single literal value on every branch. UnionSchemaNode.discriminatorPropertyName is set from that inference, so every printer that narrows on it (plugin-zod, plugin-faker) picks it up without reimplementing the same scan. (#4019, c89f215)

v5.2.1

patch

@kubb/adapter-oas

Fix
Keep a binary response body under application/octet-stream typed as a blob instead of falling back to emptySchemaType. (#4013, dd9a902)

@kubb/core

Fix
Add a kubb.dev/sponsors entry to each published package's funding field, alongside the existing GitHub Sponsors and Open Collective links. (#4007, b063738)

@kubb/studio

Fix

Trim @kubb/studio's public API to what the kubb studio CLI command and the Docker agent actually use.

  • Removed the unused hook context types StudioCommandStartContext, StudioCommandEndContext, StudioConnectingContext, StudioDisconnectedContext, StudioErrorContext, and StudioWarnContext from the package's root export. StudioConnectedContext stays exported. Hook payloads for studio:connecting, studio:command:start, studio:command:end, studio:disconnected, studio:warn, and studio:error still type-check through Hookable<KubbHooks>['hook'], since the underlying types are still declared, just no longer importable by name.
  • Removed ConnectionOutcome and TokenRejection from the root export. Both stay inferable from runConnection's return value and onTokenRejected callback.

Neither the CLI nor the Docker agent imports any of these by name, so this does not change their behavior. A consumer that did import one of them by name gets the same type through inference at the call site instead, such as runConnection's return value or a hooks.hook('studio:warn', ...) callback's parameter. (#4012, 109abe8)

v5.2.0

minor

@kubb/adapter-oas

Fix
5ccc52c - Bump @readme/openapi-parser to v8. Spec validation behavior is unchanged. (5ccc52c)

@kubb/ast

Feature
Add utilities for resolving object properties through references and intersections and for reading literal values from enum schemas. Plugin authors can use these utilities to handle discriminated unions without implementing their own schema traversal. (#3989, a2b5924)

@kubb/cli

Fix
kubb init and kubb generate --watch now print plain lines when the terminal cannot carry clack's gutter, such as a piped run or CI. They wrote box-drawing and cursor escapes into the output before. Spinner steps print as lines there instead of disappearing with the animation. (#3983, d1b123e)
Fix
kubb mcp and kubb validate now load @kubb/mcp and @kubb/adapter-oas only when their commands run. Every other command, including kubb --help, no longer touches either optional peer. (#3968, 0e4dc40)

@kubb/core

Fix
Moved shared-utility logic used by only one package out of @internals/utils and into that package (@kubb/core, @kubb/cli, @kubb/kit). No public API or behavior changed. (#3968, 0e4dc40)

@kubb/studio

Feature
Add the Kubb Studio CLI for connecting a local Kubb project to Kubb Studio. (#3972, 0cd4c7b)

v5.1.0

minor

@kubb/adapter-oas

Feature

Let dateType set date-time, date, and time independently, instead of one value driving all three

Pass an object to represent timestamps as a JS Date while keeping date-only and time-only fields as strings, since Date cannot round-trip those without inventing a timezone.

adapterOas({
  dateType: {
    dateTime: 'date',
    date: 'string',
    time: 'string',
  },
})

The scalar form (dateType: 'date') still applies one value to all three formats. (#3957, 9fca8e9)

Fix
Explicit types fields for each package.json exports entry, so that it works with tsconfig.json moduleResolution: 'bundler' (#3964, be4cd17)

v5.0.6

patch

@kubb/cli

Fix
Adds --dryRun to generate and init to preview a run without writing files, installing packages, formatting, linting, or running post-generate commands. When an AI coding agent runs the CLI, generate now uses the plain logger instead of the interactive one, and anonymous telemetry records the agent's name. (#3951, 9849de3)

v5.0.5

patch

@kubb/core

Fix
2869e6d - Avoids duplicate filesystem reads during generated file writes and uses native Node.js promise timers in asynchronous tests. (2869e6d)

v5.0.4

patch

unplugin-kubb

Fix

Move unplugin-kubb past its squatted npm version range.

Versions 5.0.1 through 5.0.30 were already published on npm from unplugin-kubb's pre-monorepo history and depend on kubb v4, so the package's version was set directly to 5.0.31 to clear that range. This changeset picks up from that 5.0.31 baseline and puts unplugin-kubb back through the normal release process, independent of kubb and @kubb/*. (#3940, b45071e)

v5.0.3

patch

@kubb/adapter-oas

Fix
Keep every discriminator mapping key that targets the same schema, and apply the discriminant to children declared with allOf (#3929, 58d9625)

v5.0.2

patch

@kubb/kit

Fix

Fix Url.toPath producing route masks that path-to-regexp (used by MSW/Express) rejects or misparses:

  • A parameter name starting with a character outside [A-Za-z0-9_] (e.g. {$id}) now sanitizes to a safe capture name instead of keeping the disallowed character.
  • Distinct parameter names that normalize to the same identifier (e.g. {group-id} and {group.id}) are now deduplicated with an incrementing suffix (groupId, groupId2) instead of producing two identically named captures. (#3922, 56a072c)

v5.0.1

patch

@kubb/adapter-oas

Fix
Fix an OpenAPI 3.1 multi-type array collapsing to one type when paired with format. type: ["null", "integer", "string"], format: "int32" generated integer | null, dropping string. The multi-type rule now runs before format, so each type parses on its own. (#3916, 3d0098c)
Fix
Fix an OpenAPI 3.1 multi-type array dropping its other types when null came first. type: ["null", "string"] generated null instead of string | null, while type: ["string", "null"] generated the right type, so the output depended on the order the types happened to be written in. The normalized type now takes the first non-null entry, and type: ["null"] stays a null schema. (#3912, 331558e)

@kubb/cli

Fix
Bump verkit to 0.4.0 and @tmcp/transport-stdio to 0.5.0. (#3909, 77e95a7)

@kubb/kit

Fix
Fix Url.toPath producing an invalid Express-style route for a hyphenated path parameter (e.g. {point-id} became :point-id). path-to-regexp treats a hyphen as ending the parameter name, so the generated MSW handler matched :point followed by a literal -id and rejected valid values. Url.toPath now camelCases the parameter name the same way Url.toTemplateString already does, so {point-id} becomes :pointId. (#3895, bf9bdc8)

v5.0.0

major

Kubb v5 rebuilds code generation around adapters, a universal AST, parsers, and storage, and generates code up to 5.4x faster than v4. Config gets shorter, generated client calls change shape, and plugins move to their own repo (kubb-labs/plugins).

Read the release blog post for the highlights, and the migration guide for the full, per-package breaking-change list and upgrade steps.

For prior releases, see GitHub Releases.