From 0bd88211bb7be2d35fa9d01284bb84cca23f0393 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:30:16 +0000 Subject: [PATCH 1/7] docs: add kubb studio command reference and integration guide The kubb studio command shipped in kubb v5 with no page on kubb.dev. Adds a CLI reference covering the four actions, the flags, pairing, and the permission model, plus an integration guide for connecting a project, running headless in CI, and pointing at a self-hosted Studio. Lists the command in the commands index and notes on the integrations index that Studio is a session rather than a bundler entrypoint. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- docs/5.x/guide/integrations/index.md | 2 + docs/5.x/guide/integrations/studio.md | 112 ++++++++++++++++++++ docs/5.x/reference/commands/index.md | 16 +-- docs/5.x/reference/commands/studio.md | 145 ++++++++++++++++++++++++++ 4 files changed, 269 insertions(+), 6 deletions(-) create mode 100644 docs/5.x/guide/integrations/studio.md create mode 100644 docs/5.x/reference/commands/studio.md diff --git a/docs/5.x/guide/integrations/index.md b/docs/5.x/guide/integrations/index.md index 61047db0..1d7816e5 100644 --- a/docs/5.x/guide/integrations/index.md +++ b/docs/5.x/guide/integrations/index.md @@ -15,6 +15,8 @@ outline: [2, 3] > [!IMPORTANT] > Vite-based bundlers ([Vite](./vite), [Nuxt](./nuxt), [Astro](./astro)) generate during a build only. They skip generation on dev server startup. Run [`kubb generate`](/docs/5.x/reference/commands/) before you start the dev server. +[Kubb Studio](./studio) is the exception on this page. It is not a bundler entrypoint but a session you open from the CLI, which lets you generate from the browser while Kubb runs on your machine. + ## Installation Install `kubb` as a dev dependency. diff --git a/docs/5.x/guide/integrations/studio.md b/docs/5.x/guide/integrations/studio.md new file mode 100644 index 00000000..6ceb8f9e --- /dev/null +++ b/docs/5.x/guide/integrations/studio.md @@ -0,0 +1,112 @@ +--- +layout: doc +title: Kubb Studio +description: Connect a Kubb project to Kubb Studio and generate from the browser while Kubb runs on your own machine. Covers pairing, permissions, headless runs, and self-hosted instances. +outline: [2, 3] +--- + +# Kubb Studio + +[Kubb Studio](https://kubb.studio) is a browser front end for a Kubb project. You edit plugin options, trigger a generation, and watch the output appear, while the generation itself runs on your machine against the files already on disk. + +That split is the point. Studio sends a command over a WebSocket, your machine runs Kubb, and progress events and generated files stream back to the browser. Your spec and your source never leave your infrastructure, so a private API stays private. + +> [!WARNING] +> This feature is under active development. Use it with caution and expect breaking changes. + +> [!NOTE] +> Unlike the [bundler integrations](./), Studio is not an entrypoint you add to a build. It is a session you open from the CLI and close when you are done. + +## Installation + +Studio ships as an optional peer of the CLI, so a project that never opens a session never installs it. Add `@kubb/studio` next to `kubb`. + +::: code-group + +```shell [bun] +bun add -d kubb @kubb/studio +``` + +```shell [pnpm] +pnpm add -D kubb @kubb/studio +``` + +```shell [npm] +npm install --save-dev kubb @kubb/studio +``` + +```shell [yarn] +yarn add -D kubb @kubb/studio +``` + +::: + +## Connect a project + +Run the command from the project root, next to your `kubb.config.ts`. + +```shell [Terminal] +kubb studio +``` + +The first run pairs the machine. The CLI prints a short code and opens the approval page, you approve it in Studio, and the agent token is stored in `~/.kubb/credentials.json`. Later runs reuse that token and connect straight away. + +Once the session is open, the project shows up in Studio and stays there until you stop the command. Check what a machine is paired as with `kubb studio status`, and drop the token with `kubb studio logout`. + +## Choose what Studio may do + +A session is read-only. Generated files stream to the browser and nothing on disk changes, which makes the first connect safe to try on a real project. + +Four permissions widen that, and each covers one trust boundary. + +| Permission | What it grants | +| ------------------- | ------------------------------------------------------------------------------ | +| `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | +| `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | +| `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | +| `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | + +The CLI asks a yes/no question for each one on the first connect to a project, then remembers the answers per project directory. Pass the flag to skip the question and grant it up front. + +```shell [Terminal] +kubb studio --allowWrite --allowExec +``` + +Grant `--allowConfigEdit` when you want to tune plugin options from the browser and keep the result. Studio patches the matching fields in `kubb.config.ts` and leaves the comments and formatting around them alone. + +## Run headless + +Pairing needs a browser, which a build agent does not have. Pair once on a machine that does, then hand the token to the headless one through `KUBB_AGENT_TOKEN`. + +```shell [Terminal] +KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio +``` + +A token passed this way is used for the session and never written to disk. Permissions are not asked for either, because there is no one to answer: anything without an explicit flag stays off. Grant what the run needs on the command line. + +> [!TIP] +> Treat the token like any other credential. Keep it in your CI secret store and pass it through the environment, never in a committed file. + +## Point at a self-hosted Studio + +`--url` picks the instance to pair and connect with. It defaults to `https://kubb.studio`. + +```shell [Terminal] +kubb studio --url http://localhost:3000 +``` + +Credentials are stored per instance, so pairing with a self-hosted Studio does not replace the token for the hosted one. Switching back needs no extra step, and `kubb studio status` tells you when the instance you are pointing at needs pairing first. + +Set `KUBB_HOME` to move the credentials, the machine secret, and the session registry out of `~/.kubb`. This helps when a container has no stable home directory. + +## Run an agent as a service + +The CLI is one host for the Studio runtime, and it is the right one while you are working in a project. For a shared or always-on setup there is a second host, the `kubblabs/kubb-agent` Docker image, which runs the same runtime with a fixed plugin set and stays connected without a terminal open. + +Reach for the image when a team needs one long-lived connection, or when the project should stay reachable from Studio after you close your laptop. Reach for `kubb studio` for everything else. See the [image on Docker Hub](https://hub.docker.com/r/kubblabs/kubb-agent) for how to run and configure it. + +## See also + +- [`kubb studio` command](/docs/5.x/reference/commands/studio): every action, flag, and environment variable +- [Configuration](/docs/5.x/reference/configuration): the `kubb.config.ts` a session reads +- [Integrations](./): run generation inside your bundler instead diff --git a/docs/5.x/reference/commands/index.md b/docs/5.x/reference/commands/index.md index ec5319c1..98ceb938 100644 --- a/docs/5.x/reference/commands/index.md +++ b/docs/5.x/reference/commands/index.md @@ -1,13 +1,13 @@ --- layout: doc title: Commands -description: Reference for every command and flag exposed by the kubb CLI including init, generate, validate and mcp. +description: Reference for every command and flag exposed by the kubb CLI including init, generate, validate, mcp and studio. outline: [2, 3] --- # Commands -The `kubb` CLI is the main way to run Kubb. It reads your [configuration](/docs/5.x/reference/configuration) and runs the generation pipeline. It also scaffolds projects, validates specs, and starts a Model Context Protocol server for LLM clients. +The `kubb` CLI is the main way to run Kubb. It reads your [configuration](/docs/5.x/reference/configuration) and runs the generation pipeline. It also scaffolds projects, validates specs, starts a Model Context Protocol server for LLM clients, and connects a project to Kubb Studio. ## Usage @@ -19,6 +19,7 @@ COMMANDS generate [input] Generate files based on a 'kubb.config.ts' file (default) validate Validate a Swagger/OpenAPI file mcp Start the MCP server so an MCP client can interact with the LLM + studio [action] Connect this project to Kubb Studio and generate from the browser Use kubb --help for more information about a command. ``` @@ -33,12 +34,15 @@ Run `kubb` with no command and it runs `kubb generate`. | [`kubb generate`](./generate) | Run the code-generation pipeline from your `kubb.config.ts`. | | [`kubb validate`](./validate) | Validate a Swagger/OpenAPI document without running the pipeline. | | [`kubb mcp`](./mcp) | Start a Model Context Protocol server for LLM clients. | +| [`kubb studio`](./studio) | Connect the project to Kubb Studio and generate from the browser. | ## Environment variables The CLI reads these shared environment variables. -| Variable | Type | Used by | Description | -| ------------------------ | --------- | ------- | -------------------------------------------------------------------- | -| `KUBB_DISABLE_TELEMETRY` | `boolean` | all | Turn off anonymous usage telemetry. Set it to `1` or `true`. | -| `DO_NOT_TRACK` | `boolean` | all | Standard opt-out convention. Set it to `1` or `true`. | +| Variable | Type | Used by | Description | +| ------------------------ | --------- | -------- | --------------------------------------------------------------------------------- | +| `KUBB_DISABLE_TELEMETRY` | `boolean` | all | Turn off anonymous usage telemetry. Set it to `1` or `true`. | +| `DO_NOT_TRACK` | `boolean` | all | Standard opt-out convention. Set it to `1` or `true`. | +| `KUBB_HOME` | `string` | `studio` | Directory for the credentials, machine secret, and session registry. Defaults to `~/.kubb`. | +| `KUBB_AGENT_TOKEN` | `string` | `studio` | Connect with an existing agent token instead of pairing interactively. | diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md new file mode 100644 index 00000000..c07e5ba4 --- /dev/null +++ b/docs/5.x/reference/commands/studio.md @@ -0,0 +1,145 @@ +--- +layout: doc +title: kubb studio +description: The studio command connects a project to Kubb Studio, so you can trigger generation from the browser while Kubb keeps running on your own machine. +outline: [2, 3] +--- + +# `kubb studio` + +Run `kubb studio` to connect this project to [Kubb Studio](https://kubb.studio). Kubb keeps running on your machine. It reads the config and the spec from disk, then streams progress and generated files back to the browser over a WebSocket, so nothing in your project is uploaded. + +> [!WARNING] +> This feature is under active development. Use it with caution and expect breaking changes. + +```terminal +command: kubb studio +output: + - ✘ write generated files + - ✘ edit kubb.config.ts + - ✘ use a Studio spec + - ✘ run formatter, linter, postGenerate +``` + +## Installation + +The command lives behind an optional peer dependency, so `kubb --help` never loads it. Install `@kubb/studio` next to `kubb` before the first connect. + +::: code-group + +```shell [bun] +bun add -d @kubb/studio +``` + +```shell [pnpm] +pnpm add -D @kubb/studio +``` + +```shell [npm] +npm install --save-dev @kubb/studio +``` + +```shell [yarn] +yarn add -D @kubb/studio +``` + +::: + +## Usage + +Connect the current project. The first run pairs the machine, and later runs reuse the stored token. + +```shell [Terminal] +kubb studio +``` + +## Actions + +The first positional argument picks what the command does. It defaults to `connect`. + +| Action | Description | +| --------- | ----------------------------------------------------------------------- | +| `connect` | Pair if needed, then hold a session open and generate on request. | +| `login` | Pair this machine and store the token without opening a session. | +| `logout` | Forget the stored token. | +| `status` | Show what this machine is paired as, plus the permissions saved for it. | + +```terminal +command: kubb studio status +output: + - Paired with https://kubb.studio as brave-otter +``` + +## Options + +| Option | Default | Description | +| ------------------------------------------ | --------------------- | ---------------------------------------------------------------------------------- | +| `--config=`, `-c ` | | Path to a config file, such as `./kubb.staging.ts`. | +| `--url=` | `https://kubb.studio` | Base URL of the Studio instance to pair and connect with. | +| `--allowWrite` | `false` | Write generated files to disk. Asked once per project when omitted. | +| `--allowConfigEdit` | `false` | Let Studio change plugin options in `kubb.config.ts`. Asked once per project. | +| `--allowInput` | `false` | Generate from a spec Studio sends instead of the one on disk. Asked once per project. | +| `--allowExec` | `false` | Run the formatter, the linter, and `output.postGenerate`. Asked once per project. | +| `--no-open` | | Do not open the approval page in a browser while pairing. | +| `--logLevel=`, `-l` | `info` | Set the verbosity. | + +> [!IMPORTANT] +> Flags are camelCase. `--allow-write` is not recognized, and the CLI ignores it without a warning, so the permission stays off. + +## Pairing + +The first connect pairs the machine over [RFC 8628](https://www.rfc-editor.org/rfc/rfc8628.html) device authorization. The CLI prints a short code, opens the approval page unless you pass `--no-open`, and waits while you approve it in Studio. Studio mints the token once and stores only its hash, so it can never be read back. + +The token lands in `~/.kubb/credentials.json` at mode `0600`. Set `KUBB_HOME` to keep it, the machine secret, and the session registry somewhere else. + +Pairing is per Studio instance. Running `kubb studio --url` against a different instance asks you to pair again, and `kubb studio status` says so before you connect. + +## Permissions + +The connection is read-only. Generated files stay in memory and stream to the browser, and nothing on disk changes until you grant more. + +| Permission | What it grants | +| ------------------- | ----------------------------------------------------------------------------------- | +| `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | +| `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | +| `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | +| `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | + +On the first connect to a project the CLI asks a separate yes/no question for each permission that has no flag and no saved answer. Answers are stored per project directory in `~/.kubb/credentials.json`, so later runs skip the questions. A flag always wins over a saved answer. + +Nothing is asked in CI or without a TTY. Every permission that has no flag and no saved answer stays off, so an unattended run can never widen its own access. + +## Environment variables + +| Variable | Description | +| ------------------ | ---------------------------------------------------------------------------------------------------- | +| `KUBB_HOME` | Directory for the credentials, the machine secret, and the session registry. Defaults to `~/.kubb`. | +| `KUBB_AGENT_TOKEN` | Connect with an existing agent token instead of pairing. The token is not written to disk. | + +## Examples + +```shell [Terminal] +# Pair on the first run, then connect read-only +kubb studio + +# Let Studio write generated files to disk +kubb studio --allowWrite + +# Also run the formatter, the linter, and postGenerate +kubb studio --allowWrite --allowExec + +# Pair without opening a session +kubb studio login + +# Forget the stored token +kubb studio logout + +# Point at a self-hosted Studio +kubb studio --url http://localhost:3000 +``` + +## See also + +- [Kubb Studio integration guide](/docs/5.x/guide/integrations/studio): connect a project, run headless, and self-host +- [Commands](/docs/5.x/reference/commands/): every command the CLI exposes +- [Configuration](/docs/5.x/reference/configuration): the `kubb.config.ts` Studio reads From 789784e6d31b5adf5ecc63a67bd559b8f6a49c5c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:36:18 +0000 Subject: [PATCH 2/7] docs: move the Studio guide to Going further, add a blog post Integrations covers unplugin bundler entrypoints, so the Studio guide does not belong there. Moves it next to the Claude Code plugin page in Going further, which already holds this kind of integration write-up, and drops the note added to the integrations index. Adds a launch post for Kubb Studio covering the local execution model, pairing, the permission defaults, and config writeback. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- blog/kubb-studio.md | 89 +++++++++++++++++++ .../{integrations => going-further}/studio.md | 8 +- docs/5.x/guide/integrations/index.md | 2 - docs/5.x/reference/commands/studio.md | 4 +- 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 blog/kubb-studio.md rename docs/5.x/guide/{integrations => going-further}/studio.md (85%) diff --git a/blog/kubb-studio.md b/blog/kubb-studio.md new file mode 100644 index 00000000..02b470d9 --- /dev/null +++ b/blog/kubb-studio.md @@ -0,0 +1,89 @@ +--- +layout: doc +title: Introducing Kubb Studio +description: Kubb Studio is a browser front end for a Kubb project. You change plugin options and trigger generation from a tab, while Kubb runs on your own machine and your spec stays on disk. +outline: deep +image: /blog/kubb-studio/cover.svg +date: 2026-09-04 +--- + +[← Blog](/blog) + +Published: 2026-09-04 + +![Introducing Kubb Studio](/blog/kubb-studio/cover.svg) + +# Introducing Kubb Studio + +Tuning a Kubb config is a slow loop. You change one plugin option, run `kubb generate`, open the output folder, decide it was wrong, and start over. The feedback lives in your terminal and your file tree, which is a fine place for it, but not a fast one. + +[Kubb Studio](https://kubb.studio) puts that loop in a browser tab. You pick plugin options in a form, hit generate, and watch files appear as they are written. What you do not do is upload anything. + +> [!WARNING] +> Studio is under active development. Expect breaking changes while it settles. + +## Your code never leaves your machine + +Every hosted code generator has the same problem: to generate from your spec, it needs your spec. For a public Petstore that is fine. For the internal API that describes your billing system, it is a non-starter at most companies, and no amount of encryption-at-rest copy fixes the org chart. + +Studio splits the two halves. The browser holds the UI and the session. Your machine holds the code. When you click generate, Studio sends a command over a WebSocket, Kubb runs locally against the files already on disk, and progress events and generated output stream back to the tab. + +Nothing is uploaded, so the spec, the config, and the generated files stay where they already were. As a side effect you also get the plugin versions from your own `node_modules` rather than whatever a server happens to have installed, so what you see in the browser is what you would have gotten from `kubb generate`. + +## One command to connect + +Install the runtime next to the CLI, then connect from the project root: + +```shell +npm install --save-dev @kubb/studio +kubb studio +``` + +The first run pairs the machine. The CLI prints a short code, opens the approval page, and waits while you approve it. That is [RFC 8628 device authorization](https://www.rfc-editor.org/rfc/rfc8628.html), the same flow a TV app uses when you type a code from your couch. Studio mints an agent token, stores only its hash, and the CLI writes the token to `~/.kubb/credentials.json` at mode `0600`. + +Pairing happens once per machine. Every later `kubb studio` connects straight away. + +## Read-only until you say otherwise + +A tab on the internet can now ask your laptop to run code. We took that seriously, so a fresh session can do almost nothing: generation runs in memory and streams to the browser, and not a single file on disk changes. + +Four permissions open that up, and the CLI asks about each one separately on the first connect to a project: + +| Permission | What it grants | +| ------------------- | ------------------------------------------------------------------------------ | +| `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | +| `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | +| `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | +| `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | + +Your answers are saved per project directory, so you are asked once and not on every connect. Pass the flag to skip the question. + +The rule we cared most about: nothing is ever asked in CI or without a TTY. An unattended run cannot widen its own access, because there is no one there to approve it and a silent default of yes would be the wrong answer. + +## Editing config from the browser + +With `--allowConfigEdit`, the options you change in Studio are written back to your `kubb.config.ts`. This is an AST patch rather than a regeneration, so it edits the fields you touched and leaves your comments, import order, and formatting alone. The diff you get is the diff you would have written by hand. + +That turns the config into something you can actually explore. Try `group.type: 'tag'`, look at the resulting file tree, switch back, all without leaving the tab. + +## Running it somewhere other than a laptop + +Pairing needs a browser, and a build agent does not have one. Pair once where you can, then hand the token over through the environment: + +```shell +KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio +``` + +A token passed this way is used for the session and never written to disk. + +For a connection that outlives your terminal, the `kubblabs/kubb-agent` Docker image runs the same runtime with a fixed plugin set. It suits a team that wants one long-lived agent instead of everyone connecting their own checkout. + +Self-hosting the Studio instance itself works too. Point the CLI at it with `kubb studio --url http://localhost:3000`. Credentials are stored per instance, so a self-hosted pairing does not replace your token for the hosted one. + +If you only want to see what the thing does, there is a shared sandbox agent you can connect to with no local setup at all. Use it for a public spec you do not mind sending, not for your billing API. + +## Try it + +Studio is live at [kubb.studio](https://kubb.studio). The [guide](/docs/5.x/guide/going-further/studio) walks through connecting a project, and the [`kubb studio` reference](/docs/5.x/reference/commands/studio) lists every action and flag. + +Feedback goes to [GitHub](https://github.com/kubb-labs/kubb/issues) or [Discord](https://discord.gg/shfBFeczrm). The permission model in particular is the part we would most like to hear about before it hardens. diff --git a/docs/5.x/guide/integrations/studio.md b/docs/5.x/guide/going-further/studio.md similarity index 85% rename from docs/5.x/guide/integrations/studio.md rename to docs/5.x/guide/going-further/studio.md index 6ceb8f9e..2860cc8e 100644 --- a/docs/5.x/guide/integrations/studio.md +++ b/docs/5.x/guide/going-further/studio.md @@ -15,7 +15,7 @@ That split is the point. Studio sends a command over a WebSocket, your machine r > This feature is under active development. Use it with caution and expect breaking changes. > [!NOTE] -> Unlike the [bundler integrations](./), Studio is not an entrypoint you add to a build. It is a session you open from the CLI and close when you are done. +> Studio is not a [bundler integration](/docs/5.x/guide/integrations/) you add to a build. It is a session you open from the CLI and close when you are done. ## Installation @@ -101,12 +101,12 @@ Set `KUBB_HOME` to move the credentials, the machine secret, and the session reg ## Run an agent as a service -The CLI is one host for the Studio runtime, and it is the right one while you are working in a project. For a shared or always-on setup there is a second host, the `kubblabs/kubb-agent` Docker image, which runs the same runtime with a fixed plugin set and stays connected without a terminal open. +`kubb studio` is the right way to connect while you are working in a project, but the session ends when you close the terminal. The `kubblabs/kubb-agent` Docker image runs the same runtime with a fixed plugin set and stays connected on its own. -Reach for the image when a team needs one long-lived connection, or when the project should stay reachable from Studio after you close your laptop. Reach for `kubb studio` for everything else. See the [image on Docker Hub](https://hub.docker.com/r/kubblabs/kubb-agent) for how to run and configure it. +Use the image when a team wants one long-lived agent instead of everyone connecting their own checkout. Use `kubb studio` for everything else. See the [image on Docker Hub](https://hub.docker.com/r/kubblabs/kubb-agent) for how to run and configure it. ## See also - [`kubb studio` command](/docs/5.x/reference/commands/studio): every action, flag, and environment variable - [Configuration](/docs/5.x/reference/configuration): the `kubb.config.ts` a session reads -- [Integrations](./): run generation inside your bundler instead +- [Integrations](/docs/5.x/guide/integrations/): run generation inside your bundler instead diff --git a/docs/5.x/guide/integrations/index.md b/docs/5.x/guide/integrations/index.md index 1d7816e5..61047db0 100644 --- a/docs/5.x/guide/integrations/index.md +++ b/docs/5.x/guide/integrations/index.md @@ -15,8 +15,6 @@ outline: [2, 3] > [!IMPORTANT] > Vite-based bundlers ([Vite](./vite), [Nuxt](./nuxt), [Astro](./astro)) generate during a build only. They skip generation on dev server startup. Run [`kubb generate`](/docs/5.x/reference/commands/) before you start the dev server. -[Kubb Studio](./studio) is the exception on this page. It is not a bundler entrypoint but a session you open from the CLI, which lets you generate from the browser while Kubb runs on your machine. - ## Installation Install `kubb` as a dev dependency. diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index c07e5ba4..bf662205 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -107,7 +107,7 @@ The connection is read-only. Generated files stay in memory and stream to the br On the first connect to a project the CLI asks a separate yes/no question for each permission that has no flag and no saved answer. Answers are stored per project directory in `~/.kubb/credentials.json`, so later runs skip the questions. A flag always wins over a saved answer. -Nothing is asked in CI or without a TTY. Every permission that has no flag and no saved answer stays off, so an unattended run can never widen its own access. +Nothing is asked in CI or without a TTY. Anything you did not pass a flag for stays off, so an unattended run can never widen its own access. ## Environment variables @@ -140,6 +140,6 @@ kubb studio --url http://localhost:3000 ## See also -- [Kubb Studio integration guide](/docs/5.x/guide/integrations/studio): connect a project, run headless, and self-host +- [Kubb Studio guide](/docs/5.x/guide/going-further/studio): connect a project, run headless, and self-host - [Commands](/docs/5.x/reference/commands/): every command the CLI exposes - [Configuration](/docs/5.x/reference/configuration): the `kubb.config.ts` Studio reads From 5373f9f9896b05dbb630155c4e5c6dd77648982e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:58:44 +0000 Subject: [PATCH 3/7] docs: drop the @kubb/studio install step @kubb/studio now ships as a dependency of @kubb/cli and the kubb meta package (kubb-labs/kubb), so `kubb studio` works on a plain `kubb` install. Removes the install sections from the command reference and the guide, and the install line from the blog post. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- blog/kubb-studio.md | 3 +-- docs/5.x/guide/going-further/studio.md | 26 ++------------------------ docs/5.x/reference/commands/studio.md | 24 ------------------------ 3 files changed, 3 insertions(+), 50 deletions(-) diff --git a/blog/kubb-studio.md b/blog/kubb-studio.md index 02b470d9..7ca3ffa4 100644 --- a/blog/kubb-studio.md +++ b/blog/kubb-studio.md @@ -32,10 +32,9 @@ Nothing is uploaded, so the spec, the config, and the generated files stay where ## One command to connect -Install the runtime next to the CLI, then connect from the project root: +The runtime ships with the CLI, so there is nothing extra to install. Run this from the project root: ```shell -npm install --save-dev @kubb/studio kubb studio ``` diff --git a/docs/5.x/guide/going-further/studio.md b/docs/5.x/guide/going-further/studio.md index 2860cc8e..07964d6f 100644 --- a/docs/5.x/guide/going-further/studio.md +++ b/docs/5.x/guide/going-further/studio.md @@ -17,32 +17,10 @@ That split is the point. Studio sends a command over a WebSocket, your machine r > [!NOTE] > Studio is not a [bundler integration](/docs/5.x/guide/integrations/) you add to a build. It is a session you open from the CLI and close when you are done. -## Installation - -Studio ships as an optional peer of the CLI, so a project that never opens a session never installs it. Add `@kubb/studio` next to `kubb`. - -::: code-group - -```shell [bun] -bun add -d kubb @kubb/studio -``` - -```shell [pnpm] -pnpm add -D kubb @kubb/studio -``` - -```shell [npm] -npm install --save-dev kubb @kubb/studio -``` - -```shell [yarn] -yarn add -D kubb @kubb/studio -``` - -::: - ## Connect a project +The Studio runtime ships with the CLI, so a project that already has `kubb` installed needs nothing else. + Run the command from the project root, next to your `kubb.config.ts`. ```shell [Terminal] diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index bf662205..57e66204 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -21,30 +21,6 @@ output: - ✘ run formatter, linter, postGenerate ``` -## Installation - -The command lives behind an optional peer dependency, so `kubb --help` never loads it. Install `@kubb/studio` next to `kubb` before the first connect. - -::: code-group - -```shell [bun] -bun add -d @kubb/studio -``` - -```shell [pnpm] -pnpm add -D @kubb/studio -``` - -```shell [npm] -npm install --save-dev @kubb/studio -``` - -```shell [yarn] -yarn add -D @kubb/studio -``` - -::: - ## Usage Connect the current project. The first run pairs the machine, and later runs reuse the stored token. From 2734ad55b458d6e570927d9ae1b86b445381eb70 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 05:06:43 +0000 Subject: [PATCH 4/7] docs: move the Studio guide into Integrations Studio belongs next to the bundler entrypoints rather than in Going further, so the guide moves back and the index stops describing the section as unplugin only. The intro now covers both ways to run Kubb outside the CLI, the bundler entrypoints keep their own section, and Studio gets a short one explaining when to reach for it instead. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- docs/5.x/guide/integrations/index.md | 12 +++++++++++- .../guide/{going-further => integrations}/studio.md | 0 docs/5.x/reference/commands/studio.md | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) rename docs/5.x/guide/{going-further => integrations}/studio.md (100%) diff --git a/docs/5.x/guide/integrations/index.md b/docs/5.x/guide/integrations/index.md index 61047db0..aa4aa50a 100644 --- a/docs/5.x/guide/integrations/index.md +++ b/docs/5.x/guide/integrations/index.md @@ -1,12 +1,16 @@ --- layout: doc title: Integrations -description: Run Kubb as part of your bundler with kubb's build integrations. Supported targets include Vite, Rollup, Rolldown, webpack, Rspack, esbuild, Farm, Nuxt and Astro. +description: Run Kubb from somewhere other than the CLI. Generate inside your bundler with Vite, Rollup, Rolldown, webpack, Rspack, esbuild, Farm, Nuxt or Astro, or from the browser with Kubb Studio. outline: [2, 3] --- # Integrations +Kubb runs from the CLI, and it also runs from the places you already work. A bundler integration generates during your build, and [Kubb Studio](./studio) generates from a browser tab while Kubb runs on your machine. + +## Bundlers + `kubb`'s bundler entrypoints run code generation inside your build. You skip the separate `kubb generate` step. Pass the same config you write in `kubb.config.ts`, and Kubb runs it as part of your build instead. Each entrypoint is powered by [`unplugin-kubb`](https://www.npmjs.com/package/unplugin-kubb) under the hood, re-exported from `kubb` so you only install one package. > [!NOTE] @@ -75,3 +79,9 @@ export default defineViteConfig({ plugins: [kubb({ config })], }) ``` + +## Kubb Studio + +[Kubb Studio](./studio) is the other way in, and it works differently from the entrypoints above. Rather than generating during a build, you open a session with `kubb studio` and drive generation from a browser tab. Kubb still runs on your machine against the files on disk, so your spec is never uploaded. + +Reach for it when you want to change plugin options and see the result straight away, and for a bundler entrypoint when generation should happen as part of your build. diff --git a/docs/5.x/guide/going-further/studio.md b/docs/5.x/guide/integrations/studio.md similarity index 100% rename from docs/5.x/guide/going-further/studio.md rename to docs/5.x/guide/integrations/studio.md diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index 57e66204..c9e456d1 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -116,6 +116,6 @@ kubb studio --url http://localhost:3000 ## See also -- [Kubb Studio guide](/docs/5.x/guide/going-further/studio): connect a project, run headless, and self-host +- [Kubb Studio guide](/docs/5.x/guide/integrations/studio): connect a project, run headless, and self-host - [Commands](/docs/5.x/reference/commands/): every command the CLI exposes - [Configuration](/docs/5.x/reference/configuration): the `kubb.config.ts` Studio reads From e0f2848c142a869ad59c42fdd59e8639f96e226a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 05:11:08 +0000 Subject: [PATCH 5/7] docs: describe the Studio connection without the pairing internals Keep the shipped CLI surface (login, logout, status, --no-open) and drop the mechanism behind it: the device-code flow, token minting and hashing, the credentials file path and mode, and the machine secret. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- blog/kubb-studio.md | 12 ++++---- docs/5.x/guide/integrations/studio.md | 14 +++++----- docs/5.x/reference/commands/index.md | 4 +-- docs/5.x/reference/commands/studio.md | 40 +++++++++++++-------------- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/blog/kubb-studio.md b/blog/kubb-studio.md index 7ca3ffa4..50e54dd5 100644 --- a/blog/kubb-studio.md +++ b/blog/kubb-studio.md @@ -38,9 +38,7 @@ The runtime ships with the CLI, so there is nothing extra to install. Run this f kubb studio ``` -The first run pairs the machine. The CLI prints a short code, opens the approval page, and waits while you approve it. That is [RFC 8628 device authorization](https://www.rfc-editor.org/rfc/rfc8628.html), the same flow a TV app uses when you type a code from your couch. Studio mints an agent token, stores only its hash, and the CLI writes the token to `~/.kubb/credentials.json` at mode `0600`. - -Pairing happens once per machine. Every later `kubb studio` connects straight away. +The first run opens the approval page and waits while you approve this machine in Studio. You approve once. Every later `kubb studio` connects straight away. ## Read-only until you say otherwise @@ -67,7 +65,7 @@ That turns the config into something you can actually explore. Try `group.type: ## Running it somewhere other than a laptop -Pairing needs a browser, and a build agent does not have one. Pair once where you can, then hand the token over through the environment: +Approving a machine needs a browser, and a build agent does not have one. Connect once where you can, then hand the agent token over through the environment: ```shell KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio @@ -77,12 +75,12 @@ A token passed this way is used for the session and never written to disk. For a connection that outlives your terminal, the `kubblabs/kubb-agent` Docker image runs the same runtime with a fixed plugin set. It suits a team that wants one long-lived agent instead of everyone connecting their own checkout. -Self-hosting the Studio instance itself works too. Point the CLI at it with `kubb studio --url http://localhost:3000`. Credentials are stored per instance, so a self-hosted pairing does not replace your token for the hosted one. +Self-hosting the Studio instance itself works too. Point the CLI at it with `kubb studio --url http://localhost:3000`. Approval is per instance, so connecting to a self-hosted Studio does not undo the one for the hosted instance. -If you only want to see what the thing does, there is a shared sandbox agent you can connect to with no local setup at all. Use it for a public spec you do not mind sending, not for your billing API. +If you only want to see what the thing does, there is a shared sandbox agent you can use with no local setup at all. Use it for a public spec you do not mind sending, not for your billing API. ## Try it -Studio is live at [kubb.studio](https://kubb.studio). The [guide](/docs/5.x/guide/going-further/studio) walks through connecting a project, and the [`kubb studio` reference](/docs/5.x/reference/commands/studio) lists every action and flag. +Studio is live at [kubb.studio](https://kubb.studio). The [guide](/docs/5.x/guide/integrations/studio) walks through connecting a project, and the [`kubb studio` reference](/docs/5.x/reference/commands/studio) lists every action and flag. Feedback goes to [GitHub](https://github.com/kubb-labs/kubb/issues) or [Discord](https://discord.gg/shfBFeczrm). The permission model in particular is the part we would most like to hear about before it hardens. diff --git a/docs/5.x/guide/integrations/studio.md b/docs/5.x/guide/integrations/studio.md index 07964d6f..ac755510 100644 --- a/docs/5.x/guide/integrations/studio.md +++ b/docs/5.x/guide/integrations/studio.md @@ -1,7 +1,7 @@ --- layout: doc title: Kubb Studio -description: Connect a Kubb project to Kubb Studio and generate from the browser while Kubb runs on your own machine. Covers pairing, permissions, headless runs, and self-hosted instances. +description: Connect a Kubb project to Kubb Studio and generate from the browser while Kubb runs on your own machine. Covers connecting, permissions, headless runs, and self-hosted instances. outline: [2, 3] --- @@ -27,9 +27,9 @@ Run the command from the project root, next to your `kubb.config.ts`. kubb studio ``` -The first run pairs the machine. The CLI prints a short code and opens the approval page, you approve it in Studio, and the agent token is stored in `~/.kubb/credentials.json`. Later runs reuse that token and connect straight away. +The first run opens the approval page in Studio and waits for you to approve this machine. Later runs connect straight away. -Once the session is open, the project shows up in Studio and stays there until you stop the command. Check what a machine is paired as with `kubb studio status`, and drop the token with `kubb studio logout`. +Once the session is open, the project shows up in Studio and stays there until you stop the command. Check what a machine is connected as with `kubb studio status`, and disconnect it with `kubb studio logout`. ## Choose what Studio may do @@ -54,7 +54,7 @@ Grant `--allowConfigEdit` when you want to tune plugin options from the browser ## Run headless -Pairing needs a browser, which a build agent does not have. Pair once on a machine that does, then hand the token to the headless one through `KUBB_AGENT_TOKEN`. +Approving a machine needs a browser, which a build agent does not have. Connect once on a machine that has one, then hand the agent token to the headless one through `KUBB_AGENT_TOKEN`. ```shell [Terminal] KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio @@ -67,15 +67,15 @@ A token passed this way is used for the session and never written to disk. Permi ## Point at a self-hosted Studio -`--url` picks the instance to pair and connect with. It defaults to `https://kubb.studio`. +`--url` picks the instance to connect with. It defaults to `https://kubb.studio`. ```shell [Terminal] kubb studio --url http://localhost:3000 ``` -Credentials are stored per instance, so pairing with a self-hosted Studio does not replace the token for the hosted one. Switching back needs no extra step, and `kubb studio status` tells you when the instance you are pointing at needs pairing first. +Approval is per instance, so connecting to a self-hosted Studio does not undo the approval for the hosted one. Switching back needs no extra step, and `kubb studio status` tells you when the instance you are pointing at needs approval first. -Set `KUBB_HOME` to move the credentials, the machine secret, and the session registry out of `~/.kubb`. This helps when a container has no stable home directory. +Set `KUBB_HOME` to move the CLI's Studio state out of `~/.kubb`. This helps when a container has no stable home directory. ## Run an agent as a service diff --git a/docs/5.x/reference/commands/index.md b/docs/5.x/reference/commands/index.md index 98ceb938..cde9a938 100644 --- a/docs/5.x/reference/commands/index.md +++ b/docs/5.x/reference/commands/index.md @@ -44,5 +44,5 @@ The CLI reads these shared environment variables. | ------------------------ | --------- | -------- | --------------------------------------------------------------------------------- | | `KUBB_DISABLE_TELEMETRY` | `boolean` | all | Turn off anonymous usage telemetry. Set it to `1` or `true`. | | `DO_NOT_TRACK` | `boolean` | all | Standard opt-out convention. Set it to `1` or `true`. | -| `KUBB_HOME` | `string` | `studio` | Directory for the credentials, machine secret, and session registry. Defaults to `~/.kubb`. | -| `KUBB_AGENT_TOKEN` | `string` | `studio` | Connect with an existing agent token instead of pairing interactively. | +| `KUBB_HOME` | `string` | `studio` | Directory the CLI keeps its Studio state in. Defaults to `~/.kubb`. | +| `KUBB_AGENT_TOKEN` | `string` | `studio` | Connect with an existing agent token instead of approving this machine. | diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index c9e456d1..91442755 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -23,7 +23,7 @@ output: ## Usage -Connect the current project. The first run pairs the machine, and later runs reuse the stored token. +Connect the current project. The first run asks you to approve it in Studio, and later runs connect straight away. ```shell [Terminal] kubb studio @@ -35,15 +35,15 @@ The first positional argument picks what the command does. It defaults to `conne | Action | Description | | --------- | ----------------------------------------------------------------------- | -| `connect` | Pair if needed, then hold a session open and generate on request. | -| `login` | Pair this machine and store the token without opening a session. | -| `logout` | Forget the stored token. | -| `status` | Show what this machine is paired as, plus the permissions saved for it. | +| `connect` | Connect, then hold a session open and generate on request. | +| `login` | Connect this machine without opening a session. | +| `logout` | Disconnect this machine from Studio. | +| `status` | Show what this machine is connected as, plus the permissions saved for it. | ```terminal command: kubb studio status output: - - Paired with https://kubb.studio as brave-otter + - Connected to https://kubb.studio as brave-otter ``` ## Options @@ -51,24 +51,22 @@ output: | Option | Default | Description | | ------------------------------------------ | --------------------- | ---------------------------------------------------------------------------------- | | `--config=`, `-c ` | | Path to a config file, such as `./kubb.staging.ts`. | -| `--url=` | `https://kubb.studio` | Base URL of the Studio instance to pair and connect with. | +| `--url=` | `https://kubb.studio` | Base URL of the Studio instance to connect with. | | `--allowWrite` | `false` | Write generated files to disk. Asked once per project when omitted. | | `--allowConfigEdit` | `false` | Let Studio change plugin options in `kubb.config.ts`. Asked once per project. | | `--allowInput` | `false` | Generate from a spec Studio sends instead of the one on disk. Asked once per project. | | `--allowExec` | `false` | Run the formatter, the linter, and `output.postGenerate`. Asked once per project. | -| `--no-open` | | Do not open the approval page in a browser while pairing. | +| `--no-open` | | Do not open the approval page in a browser. | | `--logLevel=`, `-l` | `info` | Set the verbosity. | > [!IMPORTANT] > Flags are camelCase. `--allow-write` is not recognized, and the CLI ignores it without a warning, so the permission stays off. -## Pairing +## Connecting -The first connect pairs the machine over [RFC 8628](https://www.rfc-editor.org/rfc/rfc8628.html) device authorization. The CLI prints a short code, opens the approval page unless you pass `--no-open`, and waits while you approve it in Studio. Studio mints the token once and stores only its hash, so it can never be read back. +The first connect asks you to approve this machine in Studio. The CLI opens the approval page unless you pass `--no-open`, and waits. Later runs connect straight away. -The token lands in `~/.kubb/credentials.json` at mode `0600`. Set `KUBB_HOME` to keep it, the machine secret, and the session registry somewhere else. - -Pairing is per Studio instance. Running `kubb studio --url` against a different instance asks you to pair again, and `kubb studio status` says so before you connect. +Approval is per Studio instance. Pointing `--url` at a different instance asks for approval again, and `kubb studio status` says so before you connect. ## Permissions @@ -81,21 +79,21 @@ The connection is read-only. Generated files stay in memory and stream to the br | `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | | `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | -On the first connect to a project the CLI asks a separate yes/no question for each permission that has no flag and no saved answer. Answers are stored per project directory in `~/.kubb/credentials.json`, so later runs skip the questions. A flag always wins over a saved answer. +On the first connect to a project the CLI asks a separate yes/no question for each permission that has no flag and no saved answer. Answers are saved per project directory, so later runs skip the questions. A flag always wins over a saved answer. Nothing is asked in CI or without a TTY. Anything you did not pass a flag for stays off, so an unattended run can never widen its own access. ## Environment variables -| Variable | Description | -| ------------------ | ---------------------------------------------------------------------------------------------------- | -| `KUBB_HOME` | Directory for the credentials, the machine secret, and the session registry. Defaults to `~/.kubb`. | -| `KUBB_AGENT_TOKEN` | Connect with an existing agent token instead of pairing. The token is not written to disk. | +| Variable | Description | +| ------------------ | ---------------------------------------------------------------------------------- | +| `KUBB_HOME` | Directory the CLI keeps its Studio state in. Defaults to `~/.kubb`. | +| `KUBB_AGENT_TOKEN` | Connect with an existing agent token instead of approving this machine. | ## Examples ```shell [Terminal] -# Pair on the first run, then connect read-only +# Connect read-only kubb studio # Let Studio write generated files to disk @@ -104,10 +102,10 @@ kubb studio --allowWrite # Also run the formatter, the linter, and postGenerate kubb studio --allowWrite --allowExec -# Pair without opening a session +# Connect without opening a session kubb studio login -# Forget the stored token +# Disconnect this machine kubb studio logout # Point at a self-hosted Studio From d5dfafb1f0f9c6e9092fff7b4dc832467cc362b2 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 05:19:26 +0000 Subject: [PATCH 6/7] docs: trim the Studio pages to a 2-3 minute read Cut the blog post, guide, and CLI reference down from 4-5 minutes to around 3, folding duplicate sections and dropping restated detail. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- blog/kubb-studio.md | 42 +++++++------------------ docs/5.x/guide/integrations/studio.md | 45 ++++++--------------------- docs/5.x/reference/commands/studio.md | 45 +++++---------------------- 3 files changed, 28 insertions(+), 104 deletions(-) diff --git a/blog/kubb-studio.md b/blog/kubb-studio.md index 50e54dd5..63c65ec3 100644 --- a/blog/kubb-studio.md +++ b/blog/kubb-studio.md @@ -15,7 +15,7 @@ Published: 2026-09-04 # Introducing Kubb Studio -Tuning a Kubb config is a slow loop. You change one plugin option, run `kubb generate`, open the output folder, decide it was wrong, and start over. The feedback lives in your terminal and your file tree, which is a fine place for it, but not a fast one. +Tuning a Kubb config is a slow loop. You change one plugin option, run `kubb generate`, open the output folder, decide it was wrong, and start over. [Kubb Studio](https://kubb.studio) puts that loop in a browser tab. You pick plugin options in a form, hit generate, and watch files appear as they are written. What you do not do is upload anything. @@ -24,60 +24,40 @@ Tuning a Kubb config is a slow loop. You change one plugin option, run `kubb gen ## Your code never leaves your machine -Every hosted code generator has the same problem: to generate from your spec, it needs your spec. For a public Petstore that is fine. For the internal API that describes your billing system, it is a non-starter at most companies, and no amount of encryption-at-rest copy fixes the org chart. +To generate from your spec, a hosted generator needs your spec. For a public Petstore that is fine. For the internal API that describes your billing system, it usually is not. -Studio splits the two halves. The browser holds the UI and the session. Your machine holds the code. When you click generate, Studio sends a command over a WebSocket, Kubb runs locally against the files already on disk, and progress events and generated output stream back to the tab. - -Nothing is uploaded, so the spec, the config, and the generated files stay where they already were. As a side effect you also get the plugin versions from your own `node_modules` rather than whatever a server happens to have installed, so what you see in the browser is what you would have gotten from `kubb generate`. +Studio splits the two halves. The browser holds the UI, your machine holds the code. When you click generate, Studio sends a command over a WebSocket, Kubb runs locally against the files already on disk, and progress and output stream back to the tab. Nothing is uploaded, so you get the plugin versions already in your `node_modules`, not whatever a server has installed. ## One command to connect -The runtime ships with the CLI, so there is nothing extra to install. Run this from the project root: +The runtime ships with the CLI, so there is nothing extra to install: ```shell kubb studio ``` -The first run opens the approval page and waits while you approve this machine in Studio. You approve once. Every later `kubb studio` connects straight away. +The first run asks you to approve this machine in Studio. Every later `kubb studio` connects straight away. ## Read-only until you say otherwise -A tab on the internet can now ask your laptop to run code. We took that seriously, so a fresh session can do almost nothing: generation runs in memory and streams to the browser, and not a single file on disk changes. - -Four permissions open that up, and the CLI asks about each one separately on the first connect to a project: +A fresh session can do almost nothing: generation runs in memory and streams to the browser, and not a single file on disk changes. Four flags open that up one at a time: | Permission | What it grants | -| ------------------- | ------------------------------------------------------------------------------ | +| -------------------- | ----------------------------------------------------------------------------- | | `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | | `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | | `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | | `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | -Your answers are saved per project directory, so you are asked once and not on every connect. Pass the flag to skip the question. - -The rule we cared most about: nothing is ever asked in CI or without a TTY. An unattended run cannot widen its own access, because there is no one there to approve it and a silent default of yes would be the wrong answer. +The CLI asks about each one on the first connect to a project and remembers your answer. Nothing is ever asked in CI or without a TTY: an unattended run stays at whatever access it was explicitly given. ## Editing config from the browser -With `--allowConfigEdit`, the options you change in Studio are written back to your `kubb.config.ts`. This is an AST patch rather than a regeneration, so it edits the fields you touched and leaves your comments, import order, and formatting alone. The diff you get is the diff you would have written by hand. - -That turns the config into something you can actually explore. Try `group.type: 'tag'`, look at the resulting file tree, switch back, all without leaving the tab. - -## Running it somewhere other than a laptop - -Approving a machine needs a browser, and a build agent does not have one. Connect once where you can, then hand the agent token over through the environment: - -```shell -KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio -``` - -A token passed this way is used for the session and never written to disk. - -For a connection that outlives your terminal, the `kubblabs/kubb-agent` Docker image runs the same runtime with a fixed plugin set. It suits a team that wants one long-lived agent instead of everyone connecting their own checkout. +With `--allowConfigEdit`, the options you change in Studio are written back to your `kubb.config.ts` as an AST patch, not a regeneration, so it touches only the fields you changed and leaves the rest alone. Try `group.type: 'tag'`, look at the resulting file tree, switch back, all without leaving the tab. -Self-hosting the Studio instance itself works too. Point the CLI at it with `kubb studio --url http://localhost:3000`. Approval is per instance, so connecting to a self-hosted Studio does not undo the one for the hosted instance. +## Beyond your laptop -If you only want to see what the thing does, there is a shared sandbox agent you can use with no local setup at all. Use it for a public spec you do not mind sending, not for your billing API. +`kubb studio` also runs from CI or a long-lived server, and the `kubblabs/kubb-agent` Docker image runs the same runtime for a team that wants one shared agent. See the [guide](/docs/5.x/guide/integrations/studio) for how. ## Try it diff --git a/docs/5.x/guide/integrations/studio.md b/docs/5.x/guide/integrations/studio.md index ac755510..43c3a951 100644 --- a/docs/5.x/guide/integrations/studio.md +++ b/docs/5.x/guide/integrations/studio.md @@ -9,7 +9,7 @@ outline: [2, 3] [Kubb Studio](https://kubb.studio) is a browser front end for a Kubb project. You edit plugin options, trigger a generation, and watch the output appear, while the generation itself runs on your machine against the files already on disk. -That split is the point. Studio sends a command over a WebSocket, your machine runs Kubb, and progress events and generated files stream back to the browser. Your spec and your source never leave your infrastructure, so a private API stays private. +That split is the point. Studio sends a command over a WebSocket, your machine runs Kubb, and progress events and generated files stream back to the browser. Your spec and your source never leave your infrastructure. > [!WARNING] > This feature is under active development. Use it with caution and expect breaking changes. @@ -19,69 +19,44 @@ That split is the point. Studio sends a command over a WebSocket, your machine r ## Connect a project -The Studio runtime ships with the CLI, so a project that already has `kubb` installed needs nothing else. - -Run the command from the project root, next to your `kubb.config.ts`. +The Studio runtime ships with the CLI, so a project that already has `kubb` installed needs nothing else. Run this from the project root, next to your `kubb.config.ts`. ```shell [Terminal] kubb studio ``` -The first run opens the approval page in Studio and waits for you to approve this machine. Later runs connect straight away. - -Once the session is open, the project shows up in Studio and stays there until you stop the command. Check what a machine is connected as with `kubb studio status`, and disconnect it with `kubb studio logout`. +The first run opens the approval page in Studio and waits for you to approve this machine. Later runs connect straight away. Once the session is open, the project shows up in Studio and stays there until you stop the command. Check what a machine is connected as with `kubb studio status`, and disconnect it with `kubb studio logout`. ## Choose what Studio may do -A session is read-only. Generated files stream to the browser and nothing on disk changes, which makes the first connect safe to try on a real project. +A session is read-only by default. Generated files stream to the browser and nothing on disk changes, which makes the first connect safe to try on a real project. -Four permissions widen that, and each covers one trust boundary. +Four permissions widen that, and the CLI asks about each one on the first connect to a project, then remembers your answer. | Permission | What it grants | -| ------------------- | ------------------------------------------------------------------------------ | +| -------------------- | ----------------------------------------------------------------------------- | | `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | | `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | | `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | | `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | -The CLI asks a yes/no question for each one on the first connect to a project, then remembers the answers per project directory. Pass the flag to skip the question and grant it up front. - ```shell [Terminal] kubb studio --allowWrite --allowExec ``` Grant `--allowConfigEdit` when you want to tune plugin options from the browser and keep the result. Studio patches the matching fields in `kubb.config.ts` and leaves the comments and formatting around them alone. -## Run headless +## Run headless or self-hosted -Approving a machine needs a browser, which a build agent does not have. Connect once on a machine that has one, then hand the agent token to the headless one through `KUBB_AGENT_TOKEN`. +`kubb studio` also runs on a build agent, with the agent token passed through `KUBB_AGENT_TOKEN` instead of an interactive approval: ```shell [Terminal] KUBB_AGENT_TOKEN=$KUBB_TOKEN kubb studio ``` -A token passed this way is used for the session and never written to disk. Permissions are not asked for either, because there is no one to answer: anything without an explicit flag stays off. Grant what the run needs on the command line. - -> [!TIP] -> Treat the token like any other credential. Keep it in your CI secret store and pass it through the environment, never in a committed file. - -## Point at a self-hosted Studio - -`--url` picks the instance to connect with. It defaults to `https://kubb.studio`. - -```shell [Terminal] -kubb studio --url http://localhost:3000 -``` - -Approval is per instance, so connecting to a self-hosted Studio does not undo the approval for the hosted one. Switching back needs no extra step, and `kubb studio status` tells you when the instance you are pointing at needs approval first. - -Set `KUBB_HOME` to move the CLI's Studio state out of `~/.kubb`. This helps when a container has no stable home directory. - -## Run an agent as a service - -`kubb studio` is the right way to connect while you are working in a project, but the session ends when you close the terminal. The `kubblabs/kubb-agent` Docker image runs the same runtime with a fixed plugin set and stays connected on its own. +Nothing is asked without a TTY, so grant what the run needs with flags on the command line. Point at a self-hosted instance with `--url`, and set `KUBB_HOME` to move the CLI's Studio state out of `~/.kubb`. -Use the image when a team wants one long-lived agent instead of everyone connecting their own checkout. Use `kubb studio` for everything else. See the [image on Docker Hub](https://hub.docker.com/r/kubblabs/kubb-agent) for how to run and configure it. +For a connection that outlives your terminal, the [`kubblabs/kubb-agent` Docker image](https://hub.docker.com/r/kubblabs/kubb-agent) runs the same runtime and stays connected on its own. Use it when a team wants one shared agent instead of everyone connecting their own checkout. ## See also diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index 91442755..1b345fdf 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -7,7 +7,7 @@ outline: [2, 3] # `kubb studio` -Run `kubb studio` to connect this project to [Kubb Studio](https://kubb.studio). Kubb keeps running on your machine. It reads the config and the spec from disk, then streams progress and generated files back to the browser over a WebSocket, so nothing in your project is uploaded. +Run `kubb studio` to connect this project to [Kubb Studio](https://kubb.studio). Kubb keeps running on your machine, reads the config and spec from disk, and streams progress and generated files back to the browser over a WebSocket. > [!WARNING] > This feature is under active development. Use it with caution and expect breaking changes. @@ -62,26 +62,7 @@ output: > [!IMPORTANT] > Flags are camelCase. `--allow-write` is not recognized, and the CLI ignores it without a warning, so the permission stays off. -## Connecting - -The first connect asks you to approve this machine in Studio. The CLI opens the approval page unless you pass `--no-open`, and waits. Later runs connect straight away. - -Approval is per Studio instance. Pointing `--url` at a different instance asks for approval again, and `kubb studio status` says so before you connect. - -## Permissions - -The connection is read-only. Generated files stay in memory and stream to the browser, and nothing on disk changes until you grant more. - -| Permission | What it grants | -| ------------------- | ----------------------------------------------------------------------------------- | -| `--allowWrite` | Generated files are written to disk instead of only streaming to Studio. | -| `--allowConfigEdit` | Studio may change plugin options in your `kubb.config.ts`. | -| `--allowInput` | A spec sent by Studio replaces the one on disk for that generation. | -| `--allowExec` | The formatter, the linter, and `output.postGenerate` run as child processes. | - -On the first connect to a project the CLI asks a separate yes/no question for each permission that has no flag and no saved answer. Answers are saved per project directory, so later runs skip the questions. A flag always wins over a saved answer. - -Nothing is asked in CI or without a TTY. Anything you did not pass a flag for stays off, so an unattended run can never widen its own access. +Approval is per Studio instance, so pointing `--url` at a different instance asks for approval again. The connection is read-only until you grant a permission: on the first connect the CLI asks a yes/no question for each one without a flag, then remembers the answer per project directory. Nothing is asked in CI or without a TTY, so an unattended run stays at whatever access it was given on the command line. ## Environment variables @@ -93,23 +74,11 @@ Nothing is asked in CI or without a TTY. Anything you did not pass a flag for st ## Examples ```shell [Terminal] -# Connect read-only -kubb studio - -# Let Studio write generated files to disk -kubb studio --allowWrite - -# Also run the formatter, the linter, and postGenerate -kubb studio --allowWrite --allowExec - -# Connect without opening a session -kubb studio login - -# Disconnect this machine -kubb studio logout - -# Point at a self-hosted Studio -kubb studio --url http://localhost:3000 +kubb studio # connect read-only +kubb studio --allowWrite --allowExec # write files, run the formatter and linter +kubb studio login # connect without opening a session +kubb studio logout # disconnect this machine +kubb studio --url http://localhost:3000 # self-hosted Studio ``` ## See also From c7dae6ec442f8f8251831e42edecfe5d6ada50c8 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 09:50:42 +0000 Subject: [PATCH 7/7] docs: fix a factual error, drop a stray node_modules reference The status example showed "Connected to ..." but the CLI's actual output is "Paired with ... as ...". The rest of the docs deliberately soften "pairing" to "connecting" in prose, but a terminal block claiming to show real output has to match what the CLI prints. Also reworded the blog's node_modules mention to describe the effect (your project's installed plugin versions) without naming the directory. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018oTZxx4JE5oY1Wb6NC4ojP --- blog/kubb-studio.md | 2 +- docs/5.x/reference/commands/studio.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blog/kubb-studio.md b/blog/kubb-studio.md index 63c65ec3..5bd2fe57 100644 --- a/blog/kubb-studio.md +++ b/blog/kubb-studio.md @@ -26,7 +26,7 @@ Tuning a Kubb config is a slow loop. You change one plugin option, run `kubb gen To generate from your spec, a hosted generator needs your spec. For a public Petstore that is fine. For the internal API that describes your billing system, it usually is not. -Studio splits the two halves. The browser holds the UI, your machine holds the code. When you click generate, Studio sends a command over a WebSocket, Kubb runs locally against the files already on disk, and progress and output stream back to the tab. Nothing is uploaded, so you get the plugin versions already in your `node_modules`, not whatever a server has installed. +Studio splits the two halves. The browser holds the UI, your machine holds the code. When you click generate, Studio sends a command over a WebSocket, Kubb runs locally against the files already on disk, and progress and output stream back to the tab. Nothing is uploaded, so you get the plugin versions already installed in your project, not whatever a server happens to have. ## One command to connect diff --git a/docs/5.x/reference/commands/studio.md b/docs/5.x/reference/commands/studio.md index 1b345fdf..50d11042 100644 --- a/docs/5.x/reference/commands/studio.md +++ b/docs/5.x/reference/commands/studio.md @@ -43,7 +43,7 @@ The first positional argument picks what the command does. It defaults to `conne ```terminal command: kubb studio status output: - - Connected to https://kubb.studio as brave-otter + - Paired with https://kubb.studio as brave-otter ``` ## Options