@kubb/studio 5.12.0 → 5.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +127 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +124 -8
- package/dist/index.js.map +1 -1
- package/dist/{protocol-Dn1jdnFB.d.ts → protocol-CG1bPO_H.d.cts} +10 -3
- package/dist/{protocol-Dn1jdnFB.d.cts → protocol-CG1bPO_H.d.ts} +10 -3
- package/dist/protocol.cjs +1 -0
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +1 -1
- package/dist/protocol.d.ts +1 -1
- package/dist/protocol.js +1 -0
- package/dist/protocol.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["readFile","resolve","writeFile","mkdir","dirname","relative","isAbsolute","createRequire","pathToFileURL","existsSync","isPackageName","Diagnostics","resolveMeta","path","Diagnostics","parseModule","parseExpression","detectCodeFormat","writeFile","structuredPatch","isAbsolute","relative","resolve","createHash","process","Diagnostics","createKubb","sep","fsStorage","randomUUID","ast","stripVTControlCharacters","generationEventTypes","Diagnostics","Diagnostics","fsStorage","path","RpcTarget","tmpdir","randomUUID","cacheStorage","rm","resolveCacheDir","Diagnostics","readInstalledPackages","kubbVersion","version","AgentMessage","mkdtemp","getInputKind","AgentPermission","NodeWebSocket","AGENT_INSTANCE_HEADER","newWebSocketRpcSession","resolveMeta","process","Hookable","AGENT_SOCKET_PATH","AgentCloseCode","delay","hash","Diagnostics","delay","Diagnostics","mkdtemp","join","tmpdir","mkdir","fsStorage","gzipSync","rm","resolve","resolveMeta","readInstalledPackages","MAX_SNAPSHOT_BYTES"],"sources":["../../../internals/utils/src/casing.ts","../../../internals/utils/src/errors.ts","../../../internals/utils/src/runtime.ts","../../../internals/utils/src/fs.ts","../../../internals/utils/src/promise.ts","../../../internals/utils/src/time.ts","../package.json","../src/resolveConfig.ts","../src/configFile.ts","../src/diff.ts","../src/generations.ts","../src/generationEvents.ts","../src/url.ts","../src/connect.ts","../src/pair.ts","../src/snapshot.ts"],"sourcesContent":["type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","/**\n * Coerces an unknown thrown value to an `Error` instance.\n * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.\n *\n * @example\n * ```ts\n * try { ... } catch(err) {\n * throw new Error('Build failed', { cause: toError(err) })\n * }\n * ```\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value))\n}\n\n/**\n * Extracts a human-readable message from any thrown value.\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('oops')) // 'oops'\n * getErrorMessage('plain string') // 'plain string'\n * ```\n */\nexport function getErrorMessage(value: unknown): string {\n return value instanceof Error ? value.message : String(value)\n}\n\n/**\n * Returns `error` followed by every error in its `cause` chain, outermost first. Stops at a\n * non-`Error` cause or a cycle.\n *\n * @example\n * ```ts\n * getErrorChain(new Error('Config failed loading', { cause: new Error('boom') })).map((error) => error.message)\n * // ['Config failed loading', 'boom']\n * ```\n */\nexport function getErrorChain(error: unknown): Array<Error> {\n const chain: Array<Error> = []\n for (let current = error; current instanceof Error && !chain.includes(current); current = current.cause) {\n chain.push(current)\n }\n return chain\n}\n","// Bun polyfills `process.versions.node`, so detection keys off the globals instead.\nconst isBun = typeof Bun !== 'undefined'\nconst isDeno = 'Deno' in globalThis\n\n/**\n * The JavaScript runtime executing the current process: its name, version and whether it is Bun.\n *\n * @example\n * ```ts\n * runtime.name // 'bun' when run with `bun kubb`, 'node' otherwise\n * ```\n */\nexport const runtime = { isBun, ...detect() } as const\n\nfunction detect(): { name: 'bun' | 'deno' | 'node'; version: string } {\n if (isBun) return { name: 'bun', version: process.versions.bun ?? '' }\n if (isDeno) return { name: 'deno', version: (globalThis as { Deno?: { version?: { deno?: string } } }).Deno?.version?.deno ?? '' }\n return { name: 'node', version: process.versions?.node ?? '' }\n}\n","import { access, glob as globNode, mkdir, readFile, writeFile } from 'node:fs/promises'\n\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\n\nexport { existsSync } from 'node:fs'\nexport { mkdir, mkdtemp, rm } from 'node:fs/promises'\n\n/**\n * Resolves to `true` when the file or directory at `path` exists.\n * Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.\n *\n * @example\n * ```ts\n * if (await exists('./kubb.config.ts')) {\n * const content = await read('./kubb.config.ts')\n * }\n * ```\n */\nexport async function exists(path: string): Promise<boolean> {\n if (runtime.isBun) {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\n/**\n * Reads the file at `path` as a UTF-8 string.\n * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.\n *\n * @example\n * ```ts\n * const source = await read('./src/Pet.ts')\n * ```\n */\nexport async function read(path: string): Promise<string> {\n if (runtime.isBun) {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\ntype WriteOptions = {\n /**\n * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\n /**\n * When `true`, re-reads the file immediately after writing and throws if the\n * content does not match — useful for catching write failures on unreliable file systems.\n */\n sanity?: boolean\n}\n\n/**\n * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\n * Creates any missing parent directories automatically.\n * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.\n *\n * @example\n * ```ts\n * await write('./src/Pet.ts', source) // writes and returns the trimmed content plus a newline\n * await write('./src/Pet.ts', source) // null — file unchanged\n * await write('./src/Pet.ts', ' ') // null — empty content skipped\n * ```\n */\nexport async function write(path: string, data: string, options: WriteOptions = {}): Promise<string | null> {\n const trimmed = data.trim()\n if (trimmed === '') return null\n\n const content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n await writeRaw(resolved, content)\n\n if (options.sanity) {\n const savedData = await read(resolved)\n if (savedData !== content) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n return savedData\n }\n\n return content\n}\n\n/**\n * Writes UTF-8 content verbatim, including empty files and surrounding whitespace.\n * Uses Bun.write under Bun and creates missing parent directories under either runtime.\n *\n * @example\n * await writeRaw('./cache/output.ts', ' // keep these bytes\\n\\n')\n */\nexport async function writeRaw(path: string, content: string): Promise<void> {\n const resolved = resolve(path)\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return\n }\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n}\n\n/**\n * Lists non-hidden regular files below `directory` as relative POSIX paths, excluding directories and symlinks.\n * Uses Bun.Glob under Bun because its Node glob compatibility API lacks directory-entry support.\n *\n * @example\n * for await (const path of listFiles('./src')) console.log(path)\n */\nexport async function* listFiles(directory: string): AsyncGenerator<string> {\n const cwd = resolve(directory)\n if (runtime.isBun) {\n yield* new Bun.Glob('**/*').scan({ cwd, dot: false, onlyFiles: true, followSymlinks: false })\n return\n }\n for await (const entry of globNode('**/*', { cwd, withFileTypes: true })) {\n if (entry.isFile()) yield toPosixPath(relative(cwd, join(entry.parentPath, entry.name)))\n }\n}\n\n/**\n * Converts a filesystem path to use POSIX (`/`) separators.\n *\n * Most of the codebase compares and composes paths as strings (prefix matching, joining for\n * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated\n * paths, but on Windows it returns `\\`-separated paths, which breaks every such comparison.\n *\n * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the\n * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is\n * exercisable from POSIX CI.\n *\n * @example\n * toPosixPath('C:\\\\repo\\\\src\\\\pet.ts') // 'C:/repo/src/pet.ts'\n */\nexport function toPosixPath(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n\n/**\n * Strips the file extension from a path or file name.\n * Only removes the last `.ext` segment when the dot is not part of a directory name.\n *\n * @example\n * trimExtName('petStore.ts') // 'petStore'\n * trimExtName('/src/models/pet.ts') // '/src/models/pet'\n * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'\n * trimExtName('noExtension') // 'noExtension'\n */\nexport function trimExtName(text: string): string {\n const dotIndex = text.lastIndexOf('.')\n if (dotIndex > 0 && !text.includes('/', dotIndex)) {\n return text.slice(0, dotIndex)\n }\n return text\n}\n\n/**\n * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","/** A value that may already be resolved or still pending.\n *\n * @example\n * ```ts\n * function load(id: string): PossiblePromise<string> {\n * return cache.get(id) ?? fetchRemote(id)\n * }\n * ```\n */\nexport type PossiblePromise<T> = Promise<T> | T\n\ntype Store<TKey, TValue> = {\n has(key: TKey): boolean\n get(key: TKey): TValue | undefined\n set(key: TKey, value: TValue): unknown\n}\n\n/**\n * Wraps `factory` with a keyed cache backed by the provided store.\n *\n * Pass a `WeakMap` for object keys (results are GC-eligible when the key is\n * collected) or a `Map` for primitive keys. For multi-argument functions,\n * nest two `memoize` calls — the outer keyed by the first argument, the\n * inner (created once per outer miss) keyed by the second.\n *\n * Because the cache is owned by the caller, it can be shared, inspected, or\n * cleared independently of the memoized function.\n *\n * @example Single WeakMap key\n * ```ts\n * const cache = new WeakMap<SchemaNode, Set<string>>()\n * const getRefs = memoize(cache, (node) => collectRefs(node))\n * ```\n *\n * @example Single Map key (primitive)\n * ```ts\n * const cache = new Map<string, Resolver>()\n * const getResolver = memoize(cache, (name) => buildResolver(name))\n * ```\n *\n * @example Two-level (object + primitive)\n * ```ts\n * const outer = new WeakMap<Params[], Map<string, Params[]>>()\n * const fn = memoize(outer, (params) => memoize(new Map(), (key) => transform(params, key)))\n * fn(params)('camelcase')\n * ```\n */\nexport function memoize<TKey, TValue>(store: Store<TKey, TValue>, factory: (key: TKey) => TValue): (key: TKey) => TValue {\n return (key: TKey): TValue => {\n if (store.has(key)) return store.get(key)!\n const value = factory(key)\n store.set(key, value)\n return value\n }\n}\n\ntype ParallelOptions<TItem> = {\n /**\n * Items to work through, handed out in order.\n */\n items: ReadonlyArray<TItem>\n /**\n * How many items may be in flight at once.\n */\n limit: number\n /**\n * Runs once per item, with the item's position so a caller can report progress.\n */\n run(item: TItem, index: number): Promise<void>\n}\n\n/**\n * Runs `run` over every item with at most `limit` in flight. Workers share one iterator, so each\n * takes the next item the moment it frees up instead of waiting for a batch to drain.\n *\n * @example\n * ```ts\n * await inParallel({ items: files, limit: 50, run: (file) => storage.writeItem(file.path, file.source) })\n * ```\n */\nexport async function inParallel<TItem>({ items, limit, run }: ParallelOptions<TItem>): Promise<void> {\n const queue = items.entries()\n\n const worker = async (): Promise<void> => {\n for (const [index, item] of queue) await run(item, index)\n }\n\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n}\n","/**\n * Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.\n * Rounds to 2 decimal places for sub-millisecond precision without noise.\n *\n * @example\n * ```ts\n * const start = process.hrtime()\n * doWork()\n * getElapsedMs(start) // 42.35\n * ```\n */\nexport function getElapsedMs(hrStart: [number, number]): number {\n const [seconds, nanoseconds] = process.hrtime(hrStart)\n const ms = seconds * 1000 + nanoseconds / 1e6\n return Math.round(ms * 100) / 100\n}\n\n/**\n * Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).\n *\n * @example\n * ```ts\n * formatMs(250) // '250ms'\n * formatMs(1500) // '1.50s'\n * formatMs(90000) // '1m 30.0s'\n * ```\n */\nexport function formatMs(ms: number): string {\n if (ms >= 60000) {\n const mins = Math.floor(ms / 60000)\n const secs = ((ms % 60000) / 1000).toFixed(1)\n return `${mins}m ${secs}s`\n }\n\n if (ms >= 1000) {\n return `${(ms / 1000).toFixed(2)}s`\n }\n return `${Math.round(ms)}ms`\n}\n","","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { type Adapter, Diagnostics, type ExtensionKind, isPackageName, type Parser, type Plugin, resolveMeta } from '@kubb/core'\nimport { camelCase, isPathInside, toError } from '@internals/utils'\nimport type { InstalledExtensions, JSONKubbConfig, OptionValue } from './protocol.ts'\n\n/**\n * Turns the JSON config Studio sends back into live Kubb objects.\n *\n * A plugin or adapter instance carries closures (`parse`, `getImports`, ...) that cannot survive\n * JSON, so both sides pass options over the wire and the factory is re-invoked here with the merged\n * result. Only packages {@link isAllowedPlugin} accepts are resolved this way, never an arbitrary\n * module the payload names.\n */\n\n/**\n * Imports a package, falling back to how the user's project would resolve it.\n *\n * `import()` resolves from this file, so a linked or globally installed Studio (`pnpm link`,\n * `npm i -g`) only sees its own `node_modules` and misses the plugins installed next to the user's\n * config. The retry resolves from `process.cwd()` instead.\n */\nasync function importFromProject(packageName: string): Promise<Record<string, unknown>> {\n try {\n return await import(packageName)\n } catch {\n const require = createRequire(pathToFileURL(`${process.cwd()}/`))\n // `require.resolve` picks the package's `require` condition, so prefer the ESM build sitting\n // next to it. Loading the CJS copy would pull in a second `@kubb/core` instance.\n const resolved = require.resolve(packageName)\n const esm = resolved.replace(/\\.cjs$/, '.js')\n\n return await import(pathToFileURL(esm !== resolved && existsSync(esm) ? esm : resolved).href)\n }\n}\n\n/**\n * Strips the `@kubb/` scope from a plugin package name, matching the `name` convention Kubb\n * plugin factories use internally.\n *\n * @example\n * ```ts\n * toPluginName('@kubb/plugin-ts') // 'plugin-ts'\n * ```\n */\nfunction toPluginName(packageName: string): string {\n return packageName.split('/').pop() ?? packageName\n}\n\n/**\n * Adds the `@kubb/` scope a plugin's package carries but its `name` does not, the inverse of\n * {@link toPluginName}. A name outside the `plugin-` convention is left alone, so a third-party\n * plugin is not reported as one of Kubb's.\n *\n * @example\n * ```ts\n * toPackageName('plugin-ts') // '@kubb/plugin-ts'\n * toPackageName('@acme/my-plugin') // '@acme/my-plugin'\n * ```\n */\nexport function toPackageName(name: string): string {\n return name.startsWith('plugin-') ? `@kubb/${name}` : name\n}\n\n/**\n * The name Studio knows an extension by: the package of the installed extension whose manifest\n * `name` matches, otherwise its own `name`, so a plugin defined in the user's project is never\n * reported as a Kubb package that does not exist.\n *\n * @example\n * ```ts\n * toStudioName({ name: 'plugin-ts', extensions }) // '@kubb/plugin-ts'\n * toStudioName({ name: 'plugin-zod-operations', extensions }) // 'plugin-zod-operations', a local plugin\n * ```\n */\nexport function toStudioName({\n name,\n extensions = new Map(),\n kind = 'plugin',\n}: {\n name: string\n extensions?: InstalledExtensions\n kind?: ExtensionKind\n}): string {\n return [...extensions.values()].find(({ manifest }) => manifest.kind === kind && manifest.name === name)?.package ?? name\n}\n\n/**\n * Derives the conventional named export for a `@kubb/*` plugin package from its package name.\n *\n * @example\n * ```ts\n * toExportName('@kubb/plugin-react-query') // 'pluginReactQuery'\n * toExportName('@kubb/plugin-ts') // 'pluginTs'\n * ```\n */\nexport function toExportName(packageName: string): string {\n return camelCase(toPluginName(packageName))\n}\n\nconst KUBB_PLUGIN_SPECIFIER = /^@kubb\\/plugin-[\\w.-]+$/\n\n/**\n * Whether Studio may import `packageName` as a plugin: a `@kubb/plugin-*` package, or an installed\n * package whose `kubb-extension.json` has `kind: \"plugin\"`. A path, URL or arbitrary package is\n * refused before it can execute. `configFile.ts` applies the same rule before printing a plugin name.\n */\nexport function isAllowedPlugin({ packageName, extensions }: { packageName: string; extensions: InstalledExtensions }): boolean {\n if (!isPackageName(packageName)) return false\n return KUBB_PLUGIN_SPECIFIER.test(packageName) || extensions.get(packageName)?.manifest.kind === 'plugin'\n}\n\n/**\n * Dynamically imports an extension package and returns its factory. Callers check\n * {@link isAllowedPlugin} or derive the package from a disk instance first, so an arbitrary module\n * never reaches `import()`.\n *\n * Packages must be pre-installed in the Docker image at build time via the `KUBB_PACKAGES`\n * build ARG, no runtime installation is possible in the distroless container.\n *\n * Resolution order: the manifest's `export`, else the camelCase named export the package name\n * implies (e.g. `pluginTs`), then the default export.\n *\n * @throws if the package cannot be imported or exports no callable factory.\n */\nasync function loadFactory({\n packageName,\n extensions,\n kind = 'plugin',\n}: {\n packageName: string\n extensions: InstalledExtensions\n kind?: ExtensionKind\n}): Promise<(options: unknown) => unknown> {\n const label = { plugin: 'Plugin', adapter: 'Adapter', parser: 'Parser' }[kind]\n let mod: Record<string, unknown>\n try {\n mod = await importFromProject(packageName)\n } catch (cause) {\n throw new Diagnostics.Error({\n code: kind === 'plugin' ? Diagnostics.code.pluginNotFound : Diagnostics.code.unknown,\n severity: 'error',\n message: `${label} \"${packageName}\" could not be loaded. Make sure it is installed: \\`npm install ${packageName}\\``,\n cause: toError(cause),\n })\n }\n\n const manifestExport = extensions.get(packageName)?.manifest.export\n if (manifestExport) {\n if (typeof mod[manifestExport] === 'function') return mod[manifestExport] as (options: unknown) => unknown\n throw new Diagnostics.Error({\n code: Diagnostics.code.incompatibleExtension,\n severity: 'error',\n message: `${label} \"${packageName}\" does not export \"${manifestExport}\", the factory its kubb-extension.json names.`,\n help: 'Install a version of the plugin whose exports match its kubb-extension.json.',\n })\n }\n\n const exportName = toExportName(packageName)\n if (typeof mod[exportName] === 'function') return mod[exportName] as (options: unknown) => unknown\n if (typeof mod['default'] === 'function') return mod['default'] as (options: unknown) => unknown\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.incompatibleExtension,\n severity: 'error',\n message: `${label} \"${packageName}\" does not export a callable factory. Tried the named export \"${exportName}\" and \"default\".`,\n help: 'Install a Kubb plugin package that exports its factory.',\n })\n}\n\n/**\n * Resolves each plugin entry by dynamically importing its package and calling its factory with the\n * provided options. Only packages {@link isAllowedPlugin} accepts are loaded.\n *\n * @example\n * ```ts\n * const plugins = await resolvePlugins({\n * plugins: [\n * { name: '@kubb/plugin-react-query', options: { output: { path: './hooks' } } },\n * { name: '@kubb/plugin-ts', options: { output: { path: './types' } } },\n * ],\n * })\n * ```\n */\nexport async function resolvePlugins({\n plugins,\n extensions = new Map(),\n}: {\n plugins: NonNullable<JSONKubbConfig['plugins']>\n extensions?: InstalledExtensions\n}): Promise<Array<Plugin>> {\n return Promise.all(\n plugins.map(async ({ name, options }) => {\n if (!isAllowedPlugin({ packageName: name, extensions })) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.pluginNotFound,\n severity: 'error',\n message: `Plugin \"${name}\" is not an installed Kubb plugin. Studio loads @kubb/plugin-* packages and installed packages that ship a kubb-extension.json with kind \"plugin\".`,\n })\n }\n const factory = await loadFactory({ packageName: name, extensions })\n return factory(options ?? {}) as Plugin\n }),\n )\n}\n\n/**\n * Keys that reach an object's prototype when assigned. Never read from or written into options.\n */\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\n\n/**\n * Whether `key` can be used as an option key without touching an object's prototype.\n */\nexport function isSafeKey(key: string): boolean {\n return !UNSAFE_KEYS.has(key)\n}\n\n/**\n * A JSON copy of plugin or adapter options: functions and other values JSON cannot hold are left\n * out, so nothing callable crosses the socket. Options that cannot be copied at all, such as a\n * circular structure, come back empty.\n *\n * @example\n * ```ts\n * toJSONOptions({ output: { path: 'types' }, group: { name: () => 'x' } }) // { output: { path: 'types' }, group: {} }\n * ```\n */\nexport function toJSONOptions(options: unknown): Record<string, unknown> {\n try {\n const copy = JSON.parse(\n JSON.stringify(options ?? {}, (key, value: unknown) => (isSafeKey(key) && typeof value !== 'bigint' ? value : undefined)),\n ) as unknown\n return isPlainObject(copy) ? copy : {}\n } catch {\n return {}\n }\n}\n\n/**\n * Whether `value` is an object literal or a null-prototype object, not an array or class instance.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === null || prototype === Object.prototype\n}\n\n/**\n * Whether `value` survives a JSON round trip, so it can be printed into a config file as a literal.\n * A function, `undefined`, a non-finite number or a class instance comes back from Studio as a\n * lossy copy, so an edit carrying one is refused rather than written into the user's source.\n */\nexport function isOptionValue(value: unknown): value is OptionValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true\n if (typeof value === 'number') return Number.isFinite(value)\n if (Array.isArray(value)) return value.every(isOptionValue)\n if (isPlainObject(value)) return Object.entries(value).every(([key, entry]) => isSafeKey(key) && isOptionValue(entry))\n\n return false\n}\n\n/**\n * Deep-merges Studio's options over the disk options, with Studio taking priority, except where the\n * disk value cannot survive JSON. Studio only ever saw a lossy copy of such a value, so the disk\n * value is kept rather than replaced by what Studio echoes back. Plain objects merge key by key, so\n * Studio can still change a literal that sits next to a function (e.g. `group.type` beside `group.name`).\n *\n * @example\n * ```ts\n * mergeOptions({ macros: [camelCaseMacro], syntaxType: 'type' }, { macros: [{ name: 'camelCase' }], syntaxType: 'interface' })\n * // { macros: [camelCaseMacro], syntaxType: 'interface' }\n * mergeOptions({ emptySchemaType: 'any' }, { emptySchemaType: null }) // {}\n * ```\n */\nexport function mergeOptions(disk: Record<string, unknown>, studio: Record<string, unknown>): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...disk }\n\n for (const [key, value] of Object.entries(studio)) {\n if (!isSafeKey(key)) continue\n const current = disk[key]\n\n // A `null` from Studio is a field set back to \"unset\", so the factory default applies again.\n if (value === null) {\n if (current === undefined || isOptionValue(current)) delete merged[key]\n continue\n }\n\n if (isPlainObject(current) && isPlainObject(value)) {\n merged[key] = mergeOptions(current, value)\n continue\n }\n if (current !== undefined && !isOptionValue(current)) continue\n\n merged[key] = value\n }\n\n return merged\n}\n\n/**\n * Merges studio plugin options with disk config plugins.\n * Studio takes priority: options from studio win over disk (except values only the disk config\n * can express, see {@link mergeOptions}), and a plugin Studio explicitly\n * disabled is dropped even when the disk config still lists it. Disk plugins without a studio\n * counterpart are kept as-is. Studio plugins not present on disk are appended.\n *\n * For plugins present in both configs, the plugin is re-instantiated with merged options\n * so that all internal closures correctly reference the merged values.\n */\nexport async function mergePlugins({\n diskPlugins,\n studioPlugins,\n extensions = new Map(),\n}: {\n diskPlugins: Array<Plugin> | undefined\n studioPlugins: JSONKubbConfig['plugins'] | undefined\n extensions?: InstalledExtensions\n}): Promise<Array<Plugin> | undefined> {\n const pluginNameOf = (packageName: string) => extensions.get(packageName)?.manifest.name ?? toPluginName(packageName)\n // Matched on the package's base name rather than by instantiating first. Every Kubb plugin\n // factory returns exactly that (`@kubb/plugin-ts` → `plugin-ts`), enforced by the `satisfies` on\n // each factory's name.\n const disabledNames = new Set((studioPlugins ?? []).filter((entry) => entry.disabled).map((entry) => pluginNameOf(entry.name)))\n const activeDiskPlugins = disabledNames.size ? diskPlugins?.filter((plugin) => !disabledNames.has(resolveMeta(plugin).name)) : diskPlugins\n const activeStudioPlugins = studioPlugins?.filter((entry) => !entry.disabled)\n\n if (!activeDiskPlugins && !activeStudioPlugins?.length) return undefined\n if (!activeStudioPlugins?.length) return activeDiskPlugins\n\n if (!activeDiskPlugins) return resolvePlugins({ plugins: activeStudioPlugins, extensions })\n\n const studioEntryByName = new Map(activeStudioPlugins.map((entry) => [pluginNameOf(entry.name), entry] as const))\n const diskNames = new Set(activeDiskPlugins.map((plugin) => plugin.name))\n\n // Each plugin is instantiated once, with its final options. Resolving the whole payload first\n // just to read the names would build every overlapping plugin twice and discard the first.\n const merged = await Promise.all(\n activeDiskPlugins.map(async (diskPlugin) => {\n const studioEntry = studioEntryByName.get(resolveMeta(diskPlugin).name)\n if (!studioEntry) return diskPlugin\n\n // Disk as base, studio overrides, then re-instantiate so the plugin's closures reference the\n // merged values. A plugin that never sets `options` (e.g. `@kubb/plugin-barrel`) leaves\n // `diskPlugin.options` undefined.\n const diskOptions = (diskPlugin.options as Record<string, unknown>) ?? {}\n const options = mergeOptions(diskOptions, (studioEntry.options as Record<string, unknown>) ?? {})\n // A plugin defined in the user's project has no package to re-instantiate it from. Studio\n // echoing its options back unchanged is fine, any real change can only be made on disk.\n const unchanged = JSON.stringify(toJSONOptions(options)) === JSON.stringify(toJSONOptions(diskOptions))\n const [resolved] = await resolvePlugins({ plugins: [{ name: studioEntry.name, options }], extensions }).catch((cause: unknown) => {\n if (unchanged) return [diskPlugin]\n throw new Diagnostics.Error({\n code: Diagnostics.code.pluginNotFound,\n severity: 'error',\n message: `Plugin \"${diskPlugin.name}\" is not an installed @kubb/plugin-* package or Kubb extension, so Studio cannot change its options. Edit it in the config file, or only enable or disable it from Studio.`,\n cause: toError(cause),\n })\n })\n\n return resolved ?? diskPlugin\n }),\n )\n\n const studioOnly = activeStudioPlugins.filter((entry) => !diskNames.has(pluginNameOf(entry.name)))\n\n return [...merged, ...(await resolvePlugins({ plugins: studioOnly, extensions }))]\n}\n\n/**\n * Throws `KUBB_PATH_TRAVERSAL` when a plugin would write outside the config's output folder to a path\n * the disk config does not set. Studio can change `output.path`, also inside `override`, and add\n * plugins, so without this check any member of the Studio organization could write any file the agent\n * can reach, including `node_modules` code the next run imports. A path from the config file stays\n * allowed, since a monorepo may write outside its root.\n */\nexport function assertOutputPaths({\n plugins,\n diskPlugins,\n root,\n outputPath,\n}: {\n plugins: Array<Plugin>\n diskPlugins: Array<Plugin>\n root: string\n outputPath: string\n}): void {\n const base = path.resolve(root, outputPath)\n const targetsOf = (plugin: Plugin): Array<string> => {\n const { output, override } = (plugin.options ?? {}) as { output?: { path?: unknown }; override?: Array<{ options?: { output?: { path?: unknown } } }> }\n const outputs = [output, ...(Array.isArray(override) ? override.map((entry) => entry?.options?.output) : [])]\n return outputs.flatMap((entry) => (typeof entry?.path === 'string' ? [path.resolve(base, entry.path)] : []))\n }\n const diskTargets = new Set(diskPlugins.flatMap(targetsOf))\n\n for (const plugin of plugins) {\n const target = targetsOf(plugin).find((resolved) => !diskTargets.has(resolved) && !isPathInside(resolved, base))\n if (!target) continue\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.pathTraversal,\n severity: 'error',\n message: `Plugin \"${plugin.name}\" would write to \"${target}\", outside the output folder \"${base}\". Studio can only set an output path inside it.`,\n help: 'Choose an output path inside the output folder, or set this path in the config file.',\n location: { kind: 'config' },\n plugin: plugin.name,\n })\n }\n}\n\n/**\n * Re-invokes the factory behind a disk adapter or parser with Studio's options merged over its own.\n * An instance carries live functions (`parse`, `print`, ...) that cannot survive JSON, so Studio's\n * options are a patch, not a replacement, and the factory is found from the disk instance itself: the\n * installed extension whose manifest names it, or the `@kubb/<kind>-<name>` package for a built-in\n * one. Throws when no factory resolves, as `mergePlugins` does, so an override Studio sent is never\n * dropped without a word. An extension without a manifest, such as `parserTsx`, has no options in\n * Studio, so Studio never sends one for it.\n */\nasync function rebuildExtension<T extends Adapter | Parser>({\n disk,\n studioOptions,\n kind,\n extensions,\n}: {\n disk: T\n studioOptions: object | undefined\n kind: ExtensionKind\n extensions: InstalledExtensions\n}): Promise<T> {\n if (!studioOptions || !Object.keys(studioOptions).length) return disk\n\n const { name } = resolveMeta(disk)\n const installed = [...extensions.values()].find(({ manifest }) => manifest.kind === kind && manifest.name === name)\n const packageName = installed?.package ?? `@kubb/${kind}-${name}`\n const factory = await loadFactory({ packageName, extensions, kind }).catch((cause: unknown) => {\n throw new Diagnostics.Error({\n code: kind === 'plugin' ? Diagnostics.code.pluginNotFound : Diagnostics.code.unknown,\n severity: 'error',\n message: `The ${kind} \"${name}\" is not an installed Kubb extension, so Studio cannot change its options. Edit it in the config file.`,\n cause: toError(cause),\n })\n })\n\n return factory(mergeOptions((disk.options as Record<string, unknown>) ?? {}, studioOptions as Record<string, unknown>)) as T\n}\n\n/**\n * Merges Studio-provided adapter option overrides into the disk config's adapter, see {@link rebuildExtension}.\n */\nexport async function mergeAdapter(diskAdapter: Adapter | undefined, studioOptions: object | undefined, extensions: InstalledExtensions = new Map()) {\n if (!diskAdapter) return diskAdapter\n\n return rebuildExtension({ disk: diskAdapter, studioOptions, kind: 'adapter', extensions })\n}\n\n/**\n * Merges Studio-provided parser option overrides into the disk config's parsers, matched by the name\n * Studio knows each parser by, see {@link rebuildExtension}. Parsers Studio does not name are kept as is.\n */\nexport async function mergeParsers({\n diskParsers,\n studioParsers,\n extensions = new Map(),\n}: {\n diskParsers: Array<Parser>\n studioParsers: JSONKubbConfig['parsers'] | undefined\n extensions?: InstalledExtensions\n}): Promise<Array<Parser>> {\n if (!studioParsers?.length) return diskParsers\n\n const studioOptions = new Map(studioParsers.map((entry) => [entry.name, entry.options]))\n\n return Promise.all(\n diskParsers.map((parser) =>\n rebuildExtension({\n disk: parser,\n studioOptions: studioOptions.get(toStudioName({ name: resolveMeta(parser).name, extensions, kind: 'parser' })),\n kind: 'parser',\n extensions,\n }),\n ),\n )\n}\n","import { writeFile } from 'node:fs/promises'\nimport { Diagnostics, type ExtensionKind } from '@kubb/core'\nimport { getErrorMessage, read } from '@internals/utils'\nimport { detectCodeFormat, parseExpression, parseModule } from 'magicast'\nimport type { ASTNode, ProxifiedModule } from 'magicast'\nimport type { ConfigEdit, ConfigEditOutcome, ConfigFileView, ConfigView, InstalledExtensions, OptionValue, PluginView } from './protocol.ts'\nimport { isAllowedPlugin, isOptionValue, isSafeKey, toExportName } from './resolveConfig.ts'\n\n/**\n * A valid JavaScript identifier, so an import name can only ever print as `import { name } from`,\n * never as source that breaks out of the import statement.\n */\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/\n\n/**\n * The marker line a `disable-plugin` writes above the block it comments out. It carries the block's\n * line count, so `enable-plugin` restores exactly those lines and not whatever comments follow.\n */\nconst DISABLED_MARKER = /^\\/\\/ kubb:disabled (.+)\\s+(\\d+)$/\n\nconst OPERATIONS = new Set<string>(['set', 'remove', 'add-plugin', 'disable-plugin', 'enable-plugin'])\nconst KINDS = new Set<string>(['plugin', 'adapter', 'parser'])\n\ntype ObjectNode = Extract<ASTNode, { type: 'ObjectExpression' }>\ntype ArrayNode = Extract<ASTNode, { type: 'ArrayExpression' }>\ntype CallNode = Extract<ASTNode, { type: 'CallExpression' }>\n/** A member of an object literal: `key: value`, a method or accessor, or a `...spread`. */\ntype ObjectMember = ObjectNode['properties'][number]\n/** How the file exports its config, which decides how an import for a new plugin is written. */\ntype ModuleKind = 'esm' | 'cjs'\ntype Quote = `'` | `\"`\n/** What one edit did: the rewritten source, or why it was refused. */\ntype EditResult = { source: string } | { reason: string }\ntype ParsedConfig = { mod: ProxifiedModule; configs: Array<ObjectNode>; kind: ModuleKind }\n\n/**\n * Why an edit from Studio cannot be applied as sent, checked before anything reads its fields.\n * The edit crossed the wire, so its declared type is a promise the sender may not have kept.\n */\nfunction invalidEdit(edit: ConfigEdit): string | undefined {\n const { operation, plugin, config, path, kind } = (typeof edit === 'object' && edit !== null ? edit : {}) as Record<string, unknown>\n\n if (typeof operation !== 'string' || !OPERATIONS.has(operation)) return `unknown operation ${JSON.stringify(operation)}`\n if (typeof plugin !== 'string' || !plugin) return 'the edit names no plugin'\n if (kind !== undefined && (typeof kind !== 'string' || !KINDS.has(kind))) return `unknown kind ${JSON.stringify(kind)}`\n if (kind !== undefined && operation !== 'set' && operation !== 'remove') return `${operation} edits the plugins array, so it takes no kind`\n if (config !== undefined && typeof config !== 'string' && !Number.isSafeInteger(config)) return 'config must name an entry or give its index'\n if (operation === 'set' || operation === 'remove') {\n if (!Array.isArray(path) || !path.every((key) => typeof key === 'string' && key)) return 'path must be a list of option names'\n if (!path.length) return 'no option path given'\n const unsafe = path.find((key: string) => !isSafeKey(key))\n if (unsafe !== undefined) return `${unsafe} cannot be used as an option name`\n }\n return undefined\n}\n\n/** Where a node sits in the source text. */\nfunction rangeOf(node: { start?: number | null; end?: number | null }): { start: number; end: number } {\n if (typeof node.start !== 'number' || typeof node.end !== 'number')\n throw new Diagnostics.Error({\n code: Diagnostics.code.internalError,\n severity: 'error',\n message: 'the config file could not be mapped back to its source text',\n })\n return { start: node.start, end: node.end }\n}\n\n/** `source` with the text between `start` and `end` replaced by `text`. */\nfunction splice(source: string, start: number, end: number, text = ''): string {\n return `${source.slice(0, start)}${text}${source.slice(end)}`\n}\n\nfunction bodyOf(mod: ProxifiedModule): Array<ASTNode> {\n return mod.$ast.type === 'Program' ? mod.$ast.body : []\n}\n\n/**\n * Steps through a config's wrappers to the object literal underneath: a `satisfies`/`as`\n * assertion, a `() => ...` factory, or a factory whose block body returns the config.\n */\nfunction unwrap(node: ASTNode | null | undefined): ASTNode | undefined {\n if (!node) return undefined\n if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression') return unwrap(node.expression)\n if (node.type !== 'ArrowFunctionExpression' && node.type !== 'FunctionExpression') return node\n if (node.body.type !== 'BlockStatement') return unwrap(node.body)\n\n const returned = node.body.body.find((statement): statement is Extract<ASTNode, { type: 'ReturnStatement' }> => statement.type === 'ReturnStatement')\n return unwrap(returned?.argument)\n}\n\nfunction isModuleExports(node: ASTNode): boolean {\n return (\n node.type === 'MemberExpression' &&\n !node.computed &&\n node.object.type === 'Identifier' &&\n node.object.name === 'module' &&\n node.property.type === 'Identifier' &&\n node.property.name === 'exports'\n )\n}\n\n/**\n * Parses `source` and finds every config object in `export default defineConfig(...)` or\n * `module.exports = defineConfig(...)`, or why the file is unmanaged. An array export gets one entry\n * per element, matching a numeric `config` index.\n *\n * Walks the parsed AST rather than magicast's proxies, which throw on node types they cannot\n * cast, most of what an unmanaged config file is made of.\n */\nfunction parseConfigs(source: string): ParsedConfig | { reason: string } {\n let mod: ProxifiedModule\n try {\n mod = parseModule(source)\n } catch {\n return { reason: 'the config file could not be parsed' }\n }\n\n let exported: ASTNode | null | undefined\n let kind: ModuleKind = 'esm'\n for (const node of bodyOf(mod)) {\n if (node.type === 'ExportDefaultDeclaration') {\n exported = node.declaration\n break\n }\n if (node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression' && isModuleExports(node.expression.left)) {\n exported = node.expression.right\n kind = 'cjs'\n break\n }\n }\n\n const value = unwrap(exported)\n if (!value) return { reason: 'no `export default` or `module.exports` found' }\n if (value.type !== 'CallExpression' || value.callee.type !== 'Identifier' || value.callee.name !== 'defineConfig') {\n return { reason: 'the exported config is not a defineConfig(...) call' }\n }\n\n const argument = unwrap(value.arguments[0])\n if (!argument) return { reason: 'defineConfig(...) was called without a config' }\n\n const entries = argument.type === 'ArrayExpression' ? argument.elements.map((element) => unwrap(element)) : [argument]\n const configs = entries.filter((entry): entry is ObjectNode => entry?.type === 'ObjectExpression')\n if (configs.length !== entries.length) return { reason: 'config is not an object literal' }\n\n return { mod, configs, kind }\n}\n\n/** The name of a `key` or `'key'` member, `undefined` for a spread or a computed key. */\nfunction memberKey(entry: ObjectMember): string | undefined {\n if (entry.type === 'SpreadElement' || entry.computed) return undefined\n return entry.key.type === 'Identifier' ? entry.key.name : entry.key.type === 'StringLiteral' ? entry.key.value : undefined\n}\n\n/** The member named `key`. The last one wins when the key repeats, as it does when the object is evaluated. */\nfunction findMember(node: ObjectNode, key: string): { member: ObjectMember; index: number } | undefined {\n const index = node.properties.findLastIndex((entry) => memberKey(entry) === key)\n return index === -1 ? undefined : { member: node.properties[index]!, index }\n}\n\n/** The value node of a member. A method or accessor is its own value: it is code, never a literal. */\nfunction property(node: ObjectNode, key: string): ASTNode | undefined {\n const member = findMember(node, key)?.member\n return member?.type === 'ObjectProperty' ? member.value : member\n}\n\nfunction configName(config: ObjectNode): string | undefined {\n const name = property(config, 'name')\n return name?.type === 'StringLiteral' ? name.value : undefined\n}\n\n/** Whether a `...spread` after the member at `index` could override it. */\nfunction isShadowed(node: ObjectNode, index: number): boolean {\n return node.properties.slice(index + 1).some((entry) => entry.type === 'SpreadElement')\n}\n\n/**\n * Reads a literal node's value: a primitive, or an object/array built only from primitives.\n * `undefined` for anything else, so a caller can use this both to read a value and to check\n * whether a node is a literal at all.\n */\nfunction readLiteral(node: ASTNode | null | undefined): OptionValue | undefined {\n switch (node?.type) {\n case 'StringLiteral':\n case 'NumericLiteral':\n case 'BooleanLiteral':\n return node.value\n case 'NullLiteral':\n return null\n case 'TemplateLiteral':\n return node.expressions.length ? undefined : (node.quasis[0]?.value.cooked ?? '')\n case 'UnaryExpression': {\n const value = readLiteral(node.argument)\n if (typeof value !== 'number') return undefined\n return node.operator === '-' ? -value : node.operator === '+' ? value : undefined\n }\n case 'ArrayExpression': {\n const values = node.elements.map((element) => readLiteral(element))\n return values.every((value) => value !== undefined) ? values : undefined\n }\n case 'ObjectExpression': {\n const entries: Record<string, OptionValue> = {}\n for (const entry of node.properties) {\n if (entry.type !== 'ObjectProperty') return undefined\n const key = memberKey(entry)\n const value = readLiteral(entry.value)\n // A `__proto__` key would replace the object's prototype instead of adding an entry.\n if (key === undefined || !isSafeKey(key) || value === undefined) return undefined\n entries[key] = value\n }\n return entries\n }\n }\n return undefined\n}\n\n/** Writes `value` as a single-line literal with the file's quote style. */\nfunction printValue(value: OptionValue, quote: Quote): string {\n if (typeof value === 'string') {\n // JSON's escaping covers every character that could end the literal or the line.\n const escaped = JSON.stringify(value).slice(1, -1)\n return quote === `\"` ? `\"${escaped}\"` : `'${escaped.replaceAll(`\\\\\"`, `\"`).replaceAll(`'`, `\\\\'`)}'`\n }\n if (value === null || typeof value !== 'object') return String(value)\n if (Array.isArray(value)) return `[${value.map((item) => printValue(item, quote)).join(', ')}]`\n\n const entries = Object.entries(value)\n return entries.length ? `{ ${entries.map(([key, item]) => `${printKey(key, quote)}: ${printValue(item, quote)}`).join(', ')} }` : '{}'\n}\n\n/** An object key as source text: bare when it is an identifier, quoted otherwise. */\nfunction printKey(key: string, quote: Quote): string {\n return IDENTIFIER.test(key) ? key : printValue(key, quote)\n}\n\n/** `value` wrapped in one object per key of `path`: `nest(['enum', 'type'], 'enum')` is `{ enum: { type: 'enum' } }`. */\nfunction nest(path: Array<string>, value: OptionValue): OptionValue {\n return path.reduceRight<OptionValue>((inner, key) => ({ [key]: inner }), value)\n}\n\n/**\n * Adds `text` as the last item of an object or array literal, following its layout: on a line of\n * its own with the last item's indentation when the literal spans lines, inline otherwise.\n */\nfunction insertItem(source: string, container: ObjectNode | ArrayNode, text: string): string {\n const { start, end } = rangeOf(container)\n const items: Array<ASTNode | null> = container.type === 'ObjectExpression' ? container.properties : container.elements\n const last = items.filter((item): item is ASTNode => item !== null).at(-1)\n\n if (!last) {\n const inner = source.slice(start + 1, end - 1)\n // A comment inside the empty literal stays, after the new item.\n if (inner.trim()) return splice(source, start + 1, start + 1, /^\\s/.test(inner) ? `${text},` : `${text}, `)\n return splice(source, start, end, container.type === 'ObjectExpression' ? `{ ${text} }` : `[${text}]`)\n }\n\n const lastRange = rangeOf(last)\n const between = source.slice(lastRange.end, end - 1)\n // The closing bracket shares the last item's line: add the item inline.\n if (!between.includes('\\n')) return splice(source, lastRange.end, lastRange.end, `, ${text}`)\n\n const lineStart = source.lastIndexOf('\\n', lastRange.start - 1) + 1\n const indent = source.slice(lineStart).match(/^[ \\t]*/)?.[0] ?? ''\n // After the last item's comma and any comment on its line, so neither moves. `between` holds a\n // newline, so one always follows.\n const lineEnd = source.indexOf('\\n', lastRange.end)\n const comma = /^\\s*,/.test(between)\n\n return `${source.slice(0, lastRange.end)}${comma ? '' : ','}${source.slice(lastRange.end, lineEnd)}\\n${indent}${text}${comma ? ',' : ''}${source.slice(lineEnd)}`\n}\n\n/** Drops the member at `index` from an object literal, with its own lines when it sits on them alone. */\nfunction removeMember(source: string, node: ObjectNode, index: number): string {\n if (node.properties.length === 1) return splice(source, rangeOf(node).start, rangeOf(node).end, '{}')\n\n const { start, end } = rangeOf(node.properties[index]!)\n const lineStart = source.lastIndexOf('\\n', start - 1) + 1\n const nextNewline = source.indexOf('\\n', end)\n const lineEnd = nextNewline === -1 ? source.length : nextNewline\n if (!source.slice(lineStart, start).trim() && /^\\s*,?\\s*(\\/\\/.*)?$/.test(source.slice(end, lineEnd))) {\n return splice(source, lineStart, Math.min(lineEnd + 1, source.length))\n }\n\n const next = node.properties[index + 1]\n return next ? splice(source, start, rangeOf(next).start) : splice(source, rangeOf(node.properties[index - 1]!).end, end)\n}\n\n/** The module a `require('...')` call loads, when `node` is one. */\nfunction requiredModule(node: ASTNode | null | undefined): string | undefined {\n if (node?.type !== 'CallExpression' || node.callee.type !== 'Identifier' || node.callee.name !== 'require') return undefined\n const [argument] = node.arguments\n return argument?.type === 'StringLiteral' ? argument.value : undefined\n}\n\n/** Where an identifier the file imports comes from: its module and the name it is exported under. */\ntype Import = { from: string; exported: string }\n\n/** Maps each identifier the file imports, through `import { x } from` or `const { x } = require(...)`, to its module. */\nfunction importedFrom(mod: ProxifiedModule): Map<string, Import> {\n const imports = new Map<string, Import>()\n\n for (const statement of bodyOf(mod)) {\n if (statement.type === 'ImportDeclaration') {\n for (const specifier of statement.specifiers) {\n // A default or namespace import has no exported name of its own, so its local name stands in.\n const imported = specifier.type === 'ImportSpecifier' ? specifier.imported : specifier.local\n imports.set(specifier.local.name, { from: statement.source.value, exported: imported.type === 'Identifier' ? imported.name : imported.value })\n }\n continue\n }\n if (statement.type !== 'VariableDeclaration') continue\n for (const declarator of statement.declarations) {\n const from = requiredModule(declarator.init)\n if (from === undefined || declarator.id.type !== 'ObjectPattern') continue\n for (const entry of declarator.id.properties) {\n if (entry.type === 'ObjectProperty' && entry.value.type === 'Identifier') {\n imports.set(entry.value.name, { from, exported: memberKey(entry) ?? entry.value.name })\n }\n }\n }\n }\n return imports\n}\n\n/**\n * Every factory call of one kind that resolves to an import: the `pluginX(...)` elements of the\n * `plugins` array, the `adapter` value, or the elements of the `parsers` array.\n */\nfunction factoryCalls(\n mod: ProxifiedModule,\n config: ObjectNode,\n kind: ExtensionKind = 'plugin',\n): Array<{ importName: string; exportName: string; packageName: string; call: CallNode }> {\n const node = property(config, kind === 'adapter' ? 'adapter' : `${kind}s`)\n const elements = kind === 'adapter' ? [node] : node?.type === 'ArrayExpression' ? node.elements : []\n\n const imports = importedFrom(mod)\n return elements.flatMap((element) => {\n if (element?.type !== 'CallExpression' || element.callee.type !== 'Identifier') return []\n const imported = imports.get(element.callee.name)\n return imported ? [{ importName: element.callee.name, exportName: imported.exported, packageName: imported.from, call: element }] : []\n })\n}\n\n/**\n * The blocks a previous `disable-plugin` commented out of this config, read from the marker lines\n * since a commented-out call is no longer a node. `code` holds the block's lines as they were.\n */\nfunction disabledBlocks(source: string, config: ObjectNode): Array<{ packageName: string; line: number; end: number; code: Array<string> }> {\n const lines = source.split('\\n')\n const first = config.loc?.start.line ?? 0\n const last = config.loc?.end.line ?? Number.POSITIVE_INFINITY\n\n return lines.flatMap((text, index) => {\n const match = text.trim().match(DISABLED_MARKER)\n // Only markers inside this entry, so an array config never touches another entry's plugin.\n if (!match || index + 1 < first || index + 1 > last) return []\n\n const end = index + 1 + Number(match[2])\n // A blank line comes back empty, not as the indentation the comment carried.\n const code = lines.slice(index + 1, end).map((line) => line.replace(/^(\\s*)\\/\\/ ?/, '$1').replace(/^\\s+$/, ''))\n return [{ packageName: match[1]!, line: index + 1, end, code }]\n })\n}\n\n/**\n * Reads an object option that holds some code: its literal members as `value`, and the paths of\n * the members that are code as `locked`. `set` can write any path outside `locked`, so Studio\n * edits those fields. `undefined` for a computed key, since it could set any path.\n */\nfunction readPartial(node: ObjectNode, prefix: Array<string> = []): { value: Record<string, OptionValue>; locked: Array<Array<string>> } | undefined {\n const value: Record<string, OptionValue> = {}\n const locked: Array<Array<string>> = []\n\n for (const [index, entry] of node.properties.entries()) {\n if (entry.type === 'SpreadElement') continue\n const key = memberKey(entry)\n if (key === undefined) return undefined\n // The last member wins when a key repeats.\n if (findMember(node, key)?.index !== index) continue\n\n const path = [...prefix, key]\n // A `__proto__` key replaces the prototype, so it reads as code.\n if (!isSafeKey(key)) {\n locked.push(path)\n continue\n }\n const member = entry.type === 'ObjectProperty' && !isShadowed(node, index) ? entry.value : undefined\n const literal = readLiteral(member)\n if (literal !== undefined) {\n value[key] = literal\n continue\n }\n if (member?.type !== 'ObjectExpression') {\n locked.push(path)\n continue\n }\n const nested = readPartial(member, path)\n if (!nested) return undefined\n value[key] = nested.value\n locked.push(...nested.locked)\n }\n return { value, locked }\n}\n\n/** The top-level options of a plugin call, each flagged with whether Studio may write it. */\nfunction readOptions(call: CallNode): PluginView['options'] {\n const entries: PluginView['options'] = {}\n const options = call.arguments[0]\n if (options?.type !== 'ObjectExpression') return entries\n\n for (const [index, entry] of options.properties.entries()) {\n const key = memberKey(entry)\n if (key === undefined || !isSafeKey(key)) continue\n // A spread after the option can override it, so `set` refuses it like code.\n const member = entry.type === 'ObjectProperty' && !isShadowed(options, index) ? entry.value : undefined\n const value = readLiteral(member)\n const partial = value === undefined && member?.type === 'ObjectExpression' ? readPartial(member) : undefined\n entries[key] = value !== undefined ? { literal: true, value } : { literal: false, ...partial }\n }\n return entries\n}\n\n/** The options a commented-out plugin call holds, so Studio can show them while it is disabled. */\nfunction readDisabledOptions(code: Array<string>): PluginView['options'] {\n try {\n const call = (parseExpression(code.join('\\n').trim().replace(/,$/, '')) as { $ast: ASTNode }).$ast\n return call.type === 'CallExpression' ? readOptions(call) : {}\n } catch {\n return {}\n }\n}\n\n/**\n * Reads which plugins the file declares and which of their options Studio may write.\n *\n * @example\n * ```ts\n * const view = readConfig(await readFile('kubb.config.ts', 'utf8'))\n * if (view.managed) {\n * view.configs.forEach((config) => console.log(config.name, config.plugins.length))\n * }\n * ```\n */\nexport function readConfig(source: string): ConfigFileView {\n const parsed = parseConfigs(source)\n if ('reason' in parsed) return { managed: false, reason: parsed.reason }\n\n const { mod, configs } = parsed\n const importNames = new Map([...importedFrom(mod)].map(([local, { from }]) => [from, local]))\n\n return {\n managed: true,\n configs: configs.map((config): ConfigView => {\n const active = factoryCalls(mod, config).map(({ importName, packageName, call }) => ({\n line: call.loc?.start.line ?? 0,\n plugin: { importName, packageName, options: readOptions(call) },\n }))\n const disabled = disabledBlocks(source, config).map(({ packageName, line, code }) => ({\n line,\n plugin: {\n importName: importNames.get(packageName) ?? toExportName(packageName),\n packageName,\n options: readDisabledOptions(code),\n disabled: true as const,\n },\n }))\n\n // In source order, so a disabled plugin keeps its place in the list.\n const plugins = [...active, ...disabled].sort((a, b) => a.line - b.line).map(({ plugin }) => plugin)\n const toView = ({ importName, packageName, call }: ReturnType<typeof factoryCalls>[number]): PluginView => ({\n importName,\n packageName,\n options: readOptions(call),\n })\n const [adapter] = factoryCalls(mod, config, 'adapter').map(toView)\n const parsers = factoryCalls(mod, config, 'parser').map(toView)\n return { name: configName(config), plugins, ...(adapter && { adapter }), ...(parsers.length ? { parsers } : {}) }\n }),\n }\n}\n\n/** The modules the config file imports, in source order. Empty when the file cannot be parsed. */\nexport function readImports(source: string): Array<string> {\n try {\n return [...new Set([...importedFrom(parseModule(source)).values()].map(({ from }) => from))]\n } catch {\n return []\n }\n}\n\n/**\n * Walks `path` through a plugin's options to the literal at its last key. Returns `missing` with\n * the index of the first key that is not there yet, so `set` can write the rest of the path as one\n * nested literal and `remove` can report it as unset. Refuses a value customized in code, so it is\n * never overwritten.\n */\nfunction walk(\n options: ObjectNode,\n path: Array<string>,\n): { object: ObjectNode; index: number; value: ASTNode } | { object: ObjectNode; missing: number } | { reason: string } {\n let object = options\n\n for (const [depth, key] of path.entries()) {\n const found = findMember(object, key)\n if (!found) return { object, missing: depth }\n if (isShadowed(object, found.index)) {\n return { reason: `${path.slice(0, depth + 1).join('.')} can be overridden by a spread after it, so it is customized in code` }\n }\n\n const { member, index } = found\n if (depth === path.length - 1) {\n return member.type === 'ObjectProperty' && readLiteral(member.value) !== undefined\n ? { object, index, value: member.value }\n : { reason: `${path.join('.')} is customized in code` }\n }\n if (member.type !== 'ObjectProperty' || member.value.type !== 'ObjectExpression')\n return { reason: `${key} is not an object, so ${path.join('.')} cannot be reached` }\n object = member.value\n }\n return { reason: 'no option path given' }\n}\n\n/** Writes `value` at `path` inside a plugin call's options, adding the options object and any intermediate object it needs. */\nfunction applySet(source: string, call: CallNode, path: Array<string>, value: unknown, quote: Quote): EditResult {\n if (!isOptionValue(value)) return { reason: 'the value is not a literal that can be written to a config file' }\n\n const options = call.arguments[0]\n if (!options) {\n const closing = rangeOf(call).end - 1\n if (source[closing] !== ')') return { reason: 'the factory call could not be located in the file' }\n return { source: splice(source, closing, closing, printValue(nest(path, value), quote)) }\n }\n if (options.type !== 'ObjectExpression') return { reason: 'the factory was not called with an object literal' }\n\n const target = walk(options, path)\n if ('reason' in target) return target\n if ('missing' in target) {\n const [key, ...rest] = path.slice(target.missing)\n return { source: insertItem(source, target.object, `${printKey(key!, quote)}: ${printValue(nest(rest, value), quote)}`) }\n }\n return { source: splice(source, rangeOf(target.value).start, rangeOf(target.value).end, printValue(value, quote)) }\n}\n\n/**\n * Deletes the option at `path`, falling the plugin back to its default for it. An option the file\n * does not set already has its default, so removing it changes nothing.\n */\nfunction applyRemove(source: string, call: CallNode, path: Array<string>): EditResult {\n const options = call.arguments[0]\n if (!options) return { source }\n if (options.type !== 'ObjectExpression') return { reason: 'the factory was not called with an object literal' }\n\n const target = walk(options, path)\n if ('reason' in target) return target\n if ('missing' in target) return { source }\n return { source: removeMember(source, target.object, target.index) }\n}\n\n/**\n * Writes an import after the last one already in the file, matching its quote style and whether it\n * ends in a semicolon: `import { x } from '...'`, or `const { x } = require('...')` in a CommonJS file.\n * The last import is read off the AST, so a multi-line `import {\\n x,\\n} from '...'` counts to its closing line.\n */\nfunction insertImport(source: string, { mod, kind }: ParsedConfig, importName: string, moduleSpecifier: string): string {\n const lastImport = bodyOf(mod).findLast((node) =>\n kind === 'esm'\n ? node.type === 'ImportDeclaration'\n : node.type === 'VariableDeclaration' && node.declarations.some((declarator) => requiredModule(declarator.init) !== undefined),\n )\n const afterLine = lastImport?.loc?.end.line ?? 0\n const lines = source.split('\\n')\n\n const lastImportLine = afterLine > 0 ? lines[afterLine - 1] : undefined\n const quote = lastImportLine?.includes(`\"`) ? `\"` : `'`\n const semicolon = lastImportLine?.trimEnd().endsWith(';') ? ';' : ''\n const specifier = `${quote}${moduleSpecifier}${quote}`\n lines.splice(\n afterLine,\n 0,\n kind === 'esm' ? `import { ${importName} } from ${specifier}${semicolon}` : `const { ${importName} } = require(${specifier})${semicolon}`,\n )\n if (afterLine === 0) lines.splice(1, 0, '')\n\n return lines.join('\\n')\n}\n\n/**\n * Adds a `pluginX(...)` call to a config's plugins array, and its import. Replaying the same add is\n * a no-op, while an import name collision with an unrelated package remains an error.\n */\nfunction applyAddPlugin({\n source,\n parsed,\n config,\n edit,\n quote,\n extensions,\n}: {\n source: string\n parsed: ParsedConfig\n config: ObjectNode\n edit: Extract<ConfigEdit, { operation: 'add-plugin' }>\n quote: Quote\n extensions: InstalledExtensions\n}): EditResult {\n if (!isAllowedPlugin({ packageName: edit.plugin, extensions })) {\n return { reason: `\"${edit.plugin}\" is not a @kubb/plugin-* package or an installed Kubb plugin` }\n }\n\n const importName = extensions.get(edit.plugin)?.manifest.export ?? toExportName(edit.plugin)\n if (!IDENTIFIER.test(importName)) return { reason: `\"${importName}\" is not a valid import name` }\n if (factoryCalls(parsed.mod, config).some((plugin) => plugin.packageName === edit.plugin)) return { source }\n\n const taken = importedFrom(parsed.mod).get(importName)?.from\n if (taken && taken !== edit.plugin) return { reason: `${importName} is already imported from ${taken}` }\n\n const options = edit.options ?? {}\n if (!isOptionValue(options)) return { reason: 'the options are not literals that can be written to a config file' }\n\n const plugins = property(config, 'plugins')\n if (plugins?.type !== 'ArrayExpression') return { reason: 'plugins is not an array literal' }\n\n // The array sits below the imports, so adding to it first leaves the import lines where they are.\n const next = insertItem(source, plugins, `${importName}(${Object.keys(options).length ? printValue(options, quote) : ''})`)\n return { source: taken ? next : insertImport(next, parsed, importName, edit.plugin) }\n}\n\n/**\n * Rewrites the config's `plugins` array with one item per line, so a call can be commented out without\n * taking its neighbors with it. Not done when a comment sits between the items, which would have to move.\n */\nfunction expandPluginsArray(source: string, config: ObjectNode): string | undefined {\n const array = property(config, 'plugins')\n if (array?.type !== 'ArrayExpression') return undefined\n\n const items = array.elements.flatMap((element) => (element ? [element] : []))\n const { start, end } = rangeOf(array)\n const ranges = items.map(rangeOf)\n const gaps = [\n source.slice(start + 1, ranges[0]?.start ?? end - 1),\n ...ranges.map((range, index) => source.slice(range.end, ranges[index + 1]?.start ?? end - 1)),\n ]\n if (!items.length || gaps.some((gap) => !/^[\\s,]*$/.test(gap))) return undefined\n\n const lineStart = source.lastIndexOf('\\n', start - 1) + 1\n const indent = source.slice(lineStart).match(/^[ \\t]*/)?.[0] ?? ''\n const lines = ranges.map((range) => `${indent} ${source.slice(range.start, range.end)},`)\n\n return splice(source, start, end, `[\\n${lines.join('\\n')}\\n${indent}]`)\n}\n\n/** Comments out a plugin call in place, keeping its options on disk so `enable-plugin` can restore them exactly. */\nfunction disablePlugin(source: string, mod: ProxifiedModule, config: ObjectNode, plugin: string): EditResult {\n const loc = factoryCalls(mod, config).find((entry) => entry.packageName === plugin)?.call.loc\n if (!loc) return { reason: `${plugin} is not in the plugins array` }\n\n const lines = source.split('\\n')\n const from = loc.start.line - 1\n const to = loc.end.line - 1\n const firstLine = lines[from] ?? ''\n\n // Only safe when the call sits alone on its lines: anything else on its first line, or on its last\n // line besides a trailing comma, would be swallowed into the comment and corrupt the file.\n if (firstLine.slice(0, loc.start.column).trim() || !/^,?\\s*$/.test((lines[to] ?? '').slice(loc.end.column))) {\n return { reason: `${plugin} shares a line with other code, so it cannot be commented out safely` }\n }\n\n const indent = firstLine.match(/^\\s*/)?.[0] ?? ''\n const commented = lines.slice(from, to + 1).map((line) => (line.trim() ? `${indent}// ${line.slice(indent.length)}` : `${indent}//`))\n lines.splice(from, commented.length, `${indent}// kubb:disabled ${plugin} ${commented.length}`, ...commented)\n\n return { source: lines.join('\\n') }\n}\n\n/** Uncomments the block a previous `disable-plugin` left behind for `plugin` in this config. */\nfunction enablePlugin(source: string, config: ObjectNode, plugin: string): EditResult {\n const block = disabledBlocks(source, config).find((entry) => entry.packageName === plugin)\n if (!block) return { reason: `${plugin} is not disabled` }\n\n const lines = source.split('\\n')\n lines.splice(block.line - 1, block.end - block.line + 1, ...block.code)\n return { source: lines.join('\\n') }\n}\n\n/** Applies one edit to `source`. Every edit re-parses the file, since the previous one rewrote it. */\nfunction applyEdit({ source, edit, quote, extensions }: { source: string; edit: ConfigEdit; quote: Quote; extensions: InstalledExtensions }): EditResult {\n const parsed = parseConfigs(source)\n if ('reason' in parsed) return parsed\n\n const ref = edit.config\n const findConfig = (entries: ParsedConfig) =>\n typeof ref === 'string' ? entries.configs.find((entry) => configName(entry) === ref) : entries.configs[ref ?? 0]\n const config = findConfig(parsed)\n if (!config) return { reason: `no config entry found for ${JSON.stringify(ref)}` }\n\n if (edit.operation === 'disable-plugin') {\n const result = disablePlugin(source, parsed.mod, config, edit.plugin)\n if (!('reason' in result) || !result.reason.includes('shares a line')) return result\n\n // A one-line `plugins: [a(), b()]`, which is also what `add-plugin` writes, gets one item per line first.\n const expanded = expandPluginsArray(source, config)\n const reparsed = expanded === undefined ? undefined : parseConfigs(expanded)\n const reparsedConfig = reparsed && !('reason' in reparsed) ? findConfig(reparsed) : undefined\n return expanded !== undefined && reparsed && !('reason' in reparsed) && reparsedConfig\n ? disablePlugin(expanded, reparsed.mod, reparsedConfig, edit.plugin)\n : result\n }\n if (edit.operation === 'enable-plugin') return enablePlugin(source, config, edit.plugin)\n if (edit.operation === 'add-plugin') return applyAddPlugin({ source, parsed, config, edit, quote, extensions })\n\n const kind = edit.kind ?? 'plugin'\n // A package can ship several factories (`parserTs` and `parserTsx`), so among its calls prefer the\n // export its manifest names: that is the one Studio knows the package by, whatever the file calls it.\n const calls = factoryCalls(parsed.mod, config, kind).filter((entry) => entry.packageName === edit.plugin)\n const exportName = extensions.get(edit.plugin)?.manifest.export ?? toExportName(edit.plugin)\n const call = (calls.find((entry) => entry.exportName === exportName) ?? calls[0])?.call\n if (!call) {\n if (kind === 'adapter') return { reason: `${edit.plugin} is not the config's adapter` }\n const disabled = kind === 'plugin' && disabledBlocks(source, config).some((block) => block.packageName === edit.plugin)\n return { reason: disabled ? `${edit.plugin} is disabled, enable it first` : `${edit.plugin} is not in the ${kind}s array` }\n }\n return edit.operation === 'set' ? applySet(source, call, edit.path, edit.value, quote) : applyRemove(source, call, edit.path)\n}\n\n/**\n * Applies edits to a `kubb.config.ts` in place. Each edit rewrites only the text it targets, so\n * comments, formatting, and hand-written code around the config survive.\n *\n * Edits are independent: one that cannot be applied is reported in `outcomes` and the rest still run.\n *\n * @example\n * ```ts\n * const { source, outcomes } = applyConfigEdits({\n * source: current,\n * edits: [{ operation: 'set', plugin: '@kubb/plugin-ts', path: ['enum', 'type'], value: 'enum' }],\n * })\n * ```\n */\nexport function applyConfigEdits({ source, edits, extensions = new Map() }: { source: string; edits: Array<ConfigEdit>; extensions?: InstalledExtensions }): {\n source: string\n outcomes: Array<ConfigEditOutcome>\n changed: boolean\n} {\n let current = source\n const quote: Quote = detectCodeFormat(source).quote === 'double' ? `\"` : `'`\n\n const outcomes = edits.map((edit): ConfigEditOutcome => {\n const invalid = invalidEdit(edit)\n if (invalid) return { edit, applied: false, reason: invalid }\n\n try {\n const result = applyEdit({ source: current, edit, quote, extensions })\n if ('reason' in result) return { edit, applied: false, reason: result.reason }\n current = result.source\n return { edit, applied: true }\n } catch (error) {\n return { edit, applied: false, reason: getErrorMessage(error) }\n }\n })\n\n return { source: current, outcomes, changed: current !== source }\n}\n\n/**\n * Applies `edits` to the config file at `filePath`, writing it only when something changed.\n * `add-plugin` accepts `@kubb/plugin-*` packages and the plugins in `extensions`.\n */\nexport async function writeConfigEdits({ filePath, edits, extensions }: { filePath: string; edits: Array<ConfigEdit>; extensions?: InstalledExtensions }) {\n const current = await read(filePath)\n const result = applyConfigEdits({ source: current, edits, extensions })\n if (result.changed) await writeFile(filePath, result.source, 'utf-8')\n return result\n}\n","import { structuredPatch, type StructuredPatchHunk } from 'diff'\nimport type { DiffHunk, DiffStats } from './protocol.ts'\n\nconst CONTEXT_LINES = 3\n// Past this, each remaining segment shows as one replace block.\nconst DIFF_TIMEOUT_MS = 1_000\n\n// Lines keep their `\\n`, so a last line without one differs from the same line with one.\nconst splitLines = (text: string) => (text === '' ? [] : text.split(/(?<=\\n)/))\n\n// Longest increasing subsequence of `values`, as indexes into it.\nfunction longestIncreasing(values: Array<number>): Array<number> {\n const tails: Array<number> = []\n const prev: Array<number> = []\n for (const [index, value] of values.entries()) {\n let low = 0\n let high = tails.length\n while (low < high) {\n const mid = (low + high) >> 1\n if (values[tails[mid]!]! < value) low = mid + 1\n else high = mid\n }\n prev[index] = low > 0 ? tails[low - 1]! : -1\n tails[low] = index\n }\n const result: Array<number> = []\n for (let index = tails.at(-1) ?? -1; index !== -1; index = prev[index]!) result.push(index)\n return result.reverse()\n}\n\n// Where to cut both files so each segment diffs on its own: inside each unchanged stretch that keeps a full\n// context on both sides, so no hunk crosses a cut. Lines that occur once in each file, in the same order, find them.\nfunction cutPoints(before: Array<string>, after: Array<string>): Array<[number, number]> {\n const counts = new Map<string, { before: number; after: number; index: number }>()\n for (const [index, line] of before.entries()) {\n const count = counts.get(line)\n if (count) count.before++\n else counts.set(line, { before: 1, after: 0, index })\n }\n const afterIndex = new Map<string, number>()\n for (const [index, line] of after.entries()) {\n const count = counts.get(line)\n if (!count) continue\n count.after++\n afterIndex.set(line, index)\n }\n // Map order is insertion order, so these are sorted by their index in `before`.\n const unique = [...counts]\n .filter(([, count]) => count.before === 1 && count.after === 1)\n .map(([line, count]) => [count.index, afterIndex.get(line)!] as const)\n const anchors = longestIncreasing(unique.map(([, index]) => index)).map((index) => unique[index]!)\n\n const cuts: Array<[number, number]> = [[0, 0]]\n let run = { before: 0, after: 0, length: 0 }\n const closeRun = () => {\n if (run.length > 2 * CONTEXT_LINES) cuts.push([run.before + CONTEXT_LINES, run.after + CONTEXT_LINES])\n }\n let i = 0\n let j = 0\n for (const [anchorBefore, anchorAfter] of anchors) {\n // The lines between two anchors are unchanged when both sides hold the same lines.\n const unchanged = anchorBefore - i === anchorAfter - j && before.slice(i, anchorBefore).every((line, offset) => line === after[j + offset])\n if (unchanged && run.length && run.before + run.length === i) {\n run.length += anchorBefore - i + 1\n } else {\n closeRun()\n run = unchanged ? { before: i, after: j, length: anchorBefore - i + 1 } : { before: anchorBefore, after: anchorAfter, length: 1 }\n }\n i = anchorBefore + 1\n j = anchorAfter + 1\n }\n closeRun()\n cuts.push([before.length, after.length])\n return cuts\n}\n\n// A segment with no time left to diff shows as one block that replaces everything between its shared first and last lines.\nfunction replaceHunk(before: Array<string>, after: Array<string>): Array<StructuredPatchHunk> {\n let start = 0\n while (start < before.length && start < after.length && before[start] === after[start]) start++\n let end = 0\n while (end < before.length - start && end < after.length - start && before[before.length - 1 - end] === after[after.length - 1 - end]) end++\n const removed = before.slice(start, before.length - end)\n const added = after.slice(start, after.length - end)\n if (!removed.length && !added.length) return []\n\n const lines = (prefix: string, rows: Array<string>) =>\n rows.flatMap((row) => (row.endsWith('\\n') ? [`${prefix}${row.slice(0, -1)}`] : [`${prefix}${row}`, '\\\']))\n // Same numbering as `structuredPatch`, which starts an empty side at line 1 too.\n return [{ oldStart: start + 1, oldLines: removed.length, newStart: start + 1, newLines: added.length, lines: [...lines('-', removed), ...lines('+', added)] }]\n}\n\n// One Myers diff over a whole file grows with lines times changes and stalls on large specs, so each segment\n// between cuts is diffed on its own.\nexport function diffHunks(before: string, after: string, timeout = DIFF_TIMEOUT_MS): { hunks: Array<StructuredPatchHunk>; stats: DiffStats } {\n const beforeLines = splitLines(before)\n const afterLines = splitLines(after)\n const cuts = cutPoints(beforeLines, afterLines)\n const deadline = Date.now() + timeout\n\n const hunks: Array<StructuredPatchHunk> = []\n let coarse = false\n for (const [index, [beforeStart, afterStart]] of cuts.slice(0, -1).entries()) {\n const [beforeEnd, afterEnd] = cuts[index + 1]!\n const segmentBefore = beforeLines.slice(beforeStart, beforeEnd)\n const segmentAfter = afterLines.slice(afterStart, afterEnd)\n const patch = structuredPatch('', '', segmentBefore.join(''), segmentAfter.join(''), undefined, undefined, {\n context: CONTEXT_LINES,\n timeout: Math.max(0, deadline - Date.now()),\n })\n if (!patch) coarse = true\n for (const hunk of patch?.hunks ?? replaceHunk(segmentBefore, segmentAfter)) {\n hunks.push({ ...hunk, oldStart: hunk.oldStart + beforeStart, newStart: hunk.newStart + afterStart })\n }\n }\n\n const lines = hunks.flatMap((hunk) => hunk.lines)\n const stats: DiffStats = {\n additions: lines.filter((line) => line[0] === '+').length,\n deletions: lines.filter((line) => line[0] === '-').length,\n hunks: hunks.length,\n lines: lines.length,\n coarse,\n }\n return { hunks, stats }\n}\n\n// Pages hold whole hunks, so a hunk is cut only when it alone is longer than a page. Its parts share its `index`.\nexport function pageHunks({ hunks, cursor, limit }: { hunks: Array<StructuredPatchHunk>; cursor: number; limit: number }): {\n hunks: Array<DiffHunk>\n nextCursor: number | null\n} {\n const page: Array<DiffHunk> = []\n let used = 0\n let start = 0\n for (const [index, hunk] of hunks.entries()) {\n const offset = Math.max(0, cursor - start)\n start += hunk.lines.length\n const remaining = hunk.lines.length - offset\n if (remaining <= 0) continue\n if (used > 0 && remaining > limit - used) break\n let take = Math.min(remaining, limit - used)\n // A `\\ No newline` marker stays with its line, so no part starts with one.\n if (hunk.lines[offset + take]?.startsWith('\\\\')) take++\n page.push({ index, ...hunk, lines: hunk.lines.slice(offset, offset + take) })\n used += take\n if (used >= limit) break\n }\n const total = hunks.reduce((sum, hunk) => sum + hunk.lines.length, 0)\n return { hunks: page, nextCursor: cursor + used < total ? cursor + used : null }\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\nimport process from 'node:process'\nimport { inParallel } from '@internals/utils'\nimport { ast, type InputNode } from '@kubb/ast'\nimport { type Config, createKubb, type Diagnostic, Diagnostics, fsStorage, type Hookable, type KubbHooks, type Storage } from '@kubb/core'\nimport { type FilePage, type ReadFilesResult } from './protocol.ts'\n\nconst READ_CONCURRENCY = 50\nconst MB = 1024 * 1024\nconst INDEX_KEY = 'studio/generations.json'\n\n/**\n * Files a run produced, or the output directory held, keyed by path relative to `root`.\n */\nexport type SourceFiles = { storage: Storage; root: string; paths: Set<string> }\n\n/**\n * The path form {@link SourceFiles} keys on: relative to `root`, with forward slashes.\n */\nexport function relativeStoragePath({ root, filePath }: { root: string; filePath: string }): string {\n return (isAbsolute(filePath) ? relative(resolve(root), filePath) : filePath).replaceAll('\\\\', '/')\n}\n\n/**\n * A set as kept in the store.\n */\ntype KeptSet = {\n /**\n * The paths a read is checked against. Empty when the set was too large to keep its content.\n */\n paths: Array<string>\n hashes: Record<string, string>\n bytes: number\n}\n\ntype KeptGeneration = {\n jobId: string\n initial?: boolean\n /** When the store took it, in epoch milliseconds. Absent on an index written before it existed. */\n keptAt?: number\n output: KeptSet\n inputBytes?: number\n}\n\n/**\n * The content fingerprint Studio compares snapshots by. Agent runs and CI uploads must agree on it.\n */\nexport const hashOf = (content: string) => createHash('sha1').update(content).digest('hex').slice(0, 16)\n\n/**\n * The bytes `entries` keep on disk: output, written files, and kept input.\n */\nconst totalBytes = (entries: Array<KeptGeneration>) => entries.reduce((sum, { output, inputBytes }) => sum + output.bytes + (inputBytes ?? 0), 0)\n\nfunction positiveNumber(value: string | undefined): number | undefined {\n const parsed = Number(value)\n return value && Number.isFinite(parsed) && parsed > 0 ? parsed : undefined\n}\n\n/**\n * How many generations an agent keeps and how large they may get, read from\n * `KUBB_AGENT_MAX_GENERATIONS` and `KUBB_AGENT_MAX_GENERATIONS_MB`.\n * An unset or invalid value keeps the default.\n */\nexport function resolveGenerationLimits(): { maxCount: number; maxMb: number } {\n return {\n maxCount: Math.max(1, Math.floor(positiveNumber(process.env.KUBB_AGENT_MAX_GENERATIONS) ?? 8)),\n maxMb: positiveNumber(process.env.KUBB_AGENT_MAX_GENERATIONS_MB) ?? 100,\n }\n}\n\n/**\n * Folds error-severity diagnostics into one thrown error so logs name the failing plugin or pass.\n */\nfunction generationFailure(diagnostics: ReadonlyArray<Diagnostic>): Error {\n const reasons = diagnostics\n .filter(Diagnostics.isProblem)\n .filter((diagnostic) => diagnostic.severity === 'error')\n .map((diagnostic) => (diagnostic.plugin ? `${diagnostic.plugin}: ${diagnostic.message}` : diagnostic.message))\n\n if (!reasons.length) return new Error('Generation failed')\n\n return new Error(`Generation failed: ${reasons.length} error${reasons.length === 1 ? '' : 's'}: ${reasons.join('; ')}`)\n}\n\n/**\n * Runs one generation and returns the files it produced. The formatter, the linter, and\n * `output.postGenerate` only run with `allowExec`. Throws when any plugin reports an error.\n */\nexport async function generate({\n config,\n hooks,\n signal,\n allowExec,\n}: {\n config: Config\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n allowExec: boolean\n}): Promise<SourceFiles & { input: InputNode | null }> {\n const output = allowExec ? config.output : { ...config.output, format: false as const, lint: false as const, postGenerate: [] }\n const kubb = createKubb({ ...config, output }, { hooks, signal })\n let input: InputNode | null = null\n // The driver drops its `inputNode` once the build is over, so read it as the build ends.\n const unhook = kubb.hooks.hook('kubb:build:end', (ctx) => {\n if (ctx.config === kubb.config) input = kubb.driver.inputNode\n })\n const result = await kubb.generate().finally(unhook)\n if (!result.success) throw generationFailure(result.diagnostics)\n\n // `kubb.config` carries the defaults, such as the fs storage a config loaded by the CLI leaves unset.\n const { storage, root } = kubb.config\n return {\n storage,\n root,\n paths: new Set(result.files.map((file) => relativeStoragePath({ root, filePath: file.path }))),\n input,\n }\n}\n\n/**\n * What the output directory holds when the editor connects. `undefined` when `outputPath` is not a real\n * subdirectory of `root` (listing the root would take in every source file) or holds more than `maxFiles`.\n */\nexport async function listDisk({ root, outputPath, maxFiles }: { root: string; outputPath: string; maxFiles: number }): Promise<SourceFiles | undefined> {\n const outputDir = resolve(root, outputPath)\n const fromRoot = relative(resolve(root), outputDir)\n if (!fromRoot || fromRoot.startsWith('..') || fromRoot.startsWith(sep)) return undefined\n\n const storage = fsStorage()\n const keys = await storage.readKeys(outputDir)\n if (keys.length > maxFiles) return undefined\n\n const paths = keys\n .filter((key) => !key.split('/').includes('node_modules'))\n .map((key) => relative(resolve(root), resolve(outputDir, key)).replaceAll('\\\\', '/'))\n return { storage, root, paths: new Set(paths) }\n}\n\n/**\n * Keeps recent generations by job id in `storage`, with an index next to them so a store on disk\n * survives a restart. A generation is only ever looked up by its job id, so on a pooled sandbox one\n * tenant never reaches another's output. Initial disk output and generated jobs each get their\n * own `maxCount` and `maxMb` budget. Each budget always keeps its newest entry.\n */\nexport function createGenerationStore({\n storage,\n maxCount,\n maxMb,\n ttlMs,\n now = Date.now,\n}: {\n storage: Storage\n maxCount: number\n maxMb: number\n /** How long a generation stays readable. Unset, it stays until count or size pushes it out. */\n ttlMs?: number\n now?: () => number\n}) {\n let index: Array<KeptGeneration> | undefined\n\n // An entry from before `keptAt` existed never expires, so upgrading drops nothing.\n const isLive = (generation: KeptGeneration) => ttlMs === undefined || generation.keptAt === undefined || now() - generation.keptAt < ttlMs\n\n // Hashed so a job id from the wire can never point outside the store.\n const dirOf = (jobId: string) => `studio/generations/${hashOf(jobId)}/`\n\n async function load(): Promise<Array<KeptGeneration>> {\n if (index) return index\n const stored = await storage.readItem(INDEX_KEY).catch(() => null)\n try {\n index = stored ? (JSON.parse(stored) as Array<KeptGeneration>) : []\n } catch {\n index = []\n }\n return index\n }\n\n /**\n * Copies `files` into the store as one set of `jobId`. Above `maxSetMb` only the hashes are kept.\n */\n async function keep({ jobId, files, maxSetMb }: { jobId: string; files: SourceFiles; maxSetMb: number }): Promise<KeptSet> {\n const maxSetBytes = maxSetMb * MB\n const hashes: Record<string, string> = {}\n let bytes = 0\n await inParallel({\n items: [...files.paths],\n limit: READ_CONCURRENCY,\n run: async (path) => {\n // Output outside the root would land outside the store too.\n if (path.split('/').includes('..')) return\n const content = await files.storage.readItem(resolve(files.root, path))\n if (content === null) return\n hashes[path] = hashOf(content)\n bytes += Buffer.byteLength(content)\n if (bytes <= maxSetBytes) await storage.writeItem(`${dirOf(jobId)}output/${path}`, content)\n },\n })\n if (bytes > maxSetBytes) {\n await storage.empty(`${dirOf(jobId)}output/`)\n return { paths: [], hashes, bytes: 0 }\n }\n return { paths: Object.keys(hashes), hashes, bytes }\n }\n\n async function drop(jobId: string): Promise<void> {\n await storage.empty(dirOf(jobId))\n }\n\n async function add(generation: KeptGeneration): Promise<void> {\n const current = await load()\n for (const expired of current.filter((entry) => !isLive(entry))) await drop(expired.jobId)\n const live = current.filter((entry) => entry.jobId !== generation.jobId && isLive(entry))\n const sharesBudget = (entry: KeptGeneration) => Boolean(entry.initial) === Boolean(generation.initial)\n const entries = live.filter(sharesBudget)\n entries.push({ ...generation, keptAt: now() })\n while (entries.length > 1 && (entries.length > maxCount || totalBytes(entries) > maxMb * MB)) {\n await drop(entries.shift()!.jobId)\n }\n index = [...live.filter((entry) => !sharesBudget(entry)), ...entries]\n await storage.writeItem(INDEX_KEY, JSON.stringify(index))\n }\n\n return {\n keep,\n drop,\n /**\n * Captures initial disk output, reusing a retained ID when its hashes and readable paths match.\n * A temporary candidate is discarded on reuse, so reconnects do not consume retention slots.\n */\n async keepInitial(files: SourceFiles): Promise<KeptGeneration> {\n const jobId = randomUUID()\n const output = await keep({ jobId, files, maxSetMb: maxMb })\n const hashes = Object.entries(output.hashes)\n const previous = (await load()).findLast(\n (entry) =>\n entry.initial &&\n isLive(entry) &&\n entry.output.paths.length === output.paths.length &&\n Object.keys(entry.output.hashes).length === hashes.length &&\n hashes.every(([path, hash]) => entry.output.hashes[path] === hash),\n )\n if (previous) {\n await drop(jobId)\n await add(previous)\n return previous\n }\n const generation = { jobId, output, initial: true }\n await add(generation)\n return generation\n },\n /**\n * Keeps the `InputNode` of `jobId` and returns its size in bytes, or 0 when it keeps none. A ref schema loses\n * the copy of its target, which `input.schemas` holds: with it, a large spec outgrows what `JSON.stringify` can return.\n */\n async keepInput({ jobId, input, maxSetMb }: { jobId: string; input: InputNode | null; maxSetMb: number }): Promise<number> {\n if (!input) return 0\n let json: string\n try {\n json = JSON.stringify(ast.transform(input, { schema: (node) => (node.type === 'ref' && node.schema ? { ...node, schema: undefined } : undefined) }))\n } catch {\n // An adapter can return what JSON cannot hold, which must not fail a finished generation.\n return 0\n }\n const bytes = Buffer.byteLength(json)\n if (bytes > maxSetMb * MB) return 0\n await storage.writeItem(`${dirOf(jobId)}input.json`, json)\n return bytes\n },\n /**\n * The input `keepInput` kept for `jobId`, or `undefined` when there is none.\n */\n async readInput(jobId: string): Promise<InputNode | undefined> {\n const stored = await storage.readItem(`${dirOf(jobId)}input.json`)\n return stored === null ? undefined : (JSON.parse(stored) as InputNode)\n },\n get: async (jobId: string) => (await load()).find((generation) => generation.jobId === jobId && isLive(generation)),\n add,\n /**\n * Reads the requested paths the set holds, skipping any it does not, one page of lines when `limit` is given.\n */\n async read({\n generation,\n paths,\n cursor = 0,\n limit,\n }: {\n generation: KeptGeneration\n paths: Array<string>\n cursor?: number\n limit?: number\n }): Promise<ReadFilesResult> {\n const kept = new Set(generation.output.paths)\n const files: Record<string, string> = {}\n const pages: Record<string, FilePage> = {}\n await inParallel({\n items: paths.filter((path) => kept.has(path)),\n limit: READ_CONCURRENCY,\n run: async (path) => {\n const content = await storage.readItem(`${dirOf(generation.jobId)}output/${path}`)\n if (content === null) return\n if (limit === undefined) {\n files[path] = content\n return\n }\n const lines = content.split(/\\r\\n|\\r|\\n/)\n const end = Math.min(cursor + limit, lines.length)\n files[path] = lines.slice(cursor, end).join('\\n')\n pages[path] = { nextCursor: end < lines.length ? end : null, totalLines: lines.length }\n },\n })\n return limit === undefined ? { files } : { files, pages }\n },\n }\n}\n\nexport type GenerationStore = ReturnType<typeof createGenerationStore>\n","import { stripVTControlCharacters } from 'node:util'\nimport { getElapsedMs } from '@internals/utils'\nimport { Diagnostics, type Hookable, type KubbHooks } from '@kubb/core'\nimport { type GenerationEvent, type GenerationEventPayloads, type GenerationEventType, generationEventTypes } from './protocol.ts'\nimport { relativeStoragePath } from './generations.ts'\n\n/** How each published hook's context becomes its wire payload; a hook without a projection fails to compile. */\ntype Projections = { [Type in GenerationEventType]: (...args: KubbHooks[Type]) => GenerationEventPayloads[Type] }\n\nconst MAX_QUEUED_EVENTS = 1_024\nconst RESERVED_EVENTS = 64\nconst isDiscardable = (type: GenerationEventType) => type === 'kubb:files:processing:update' || type === 'kubb:info' || type === 'kubb:success'\n\n/** Forwards selected Kubb lifecycle events to a native Cap'n Web stream. */\nexport function createGenerationStream(\n hooks: Hookable<KubbHooks>,\n jobId: string,\n): { stream: ReadableStream<GenerationEvent>; close: () => Promise<void>; fail: (error?: unknown) => void } {\n const unhooks: Array<() => void> = []\n let root = ''\n let controller!: ReadableStreamDefaultController<GenerationEvent>\n let closed = false\n const stream = new ReadableStream<GenerationEvent>(\n {\n start: (value) => {\n controller = value\n },\n cancel: () => {\n closed = true\n detach()\n },\n },\n { highWaterMark: MAX_QUEUED_EVENTS },\n )\n\n /**\n * Registers a listener and keeps its remover, so one generation's listeners come off the session\n * emitter again when that generation ends.\n */\n function on<TName extends keyof KubbHooks & string>(name: TName, handler: (...args: KubbHooks[TName]) => unknown): void {\n unhooks.push(hooks.hook(name, handler))\n }\n\n function emitEvent<Type extends GenerationEventType>(type: Type, data: GenerationEventPayloads[Type]): void {\n if (closed) return\n const event = { jobId, type, data, version: 1 as const, timestamp: Date.now() } as unknown as GenerationEvent\n if (controller.desiredSize! <= RESERVED_EVENTS && isDiscardable(type)) return\n if (controller.desiredSize! <= 0) {\n fail(new Error(`Generation event stream exceeded ${MAX_QUEUED_EVENTS} queued events`))\n return\n }\n controller.enqueue(event)\n }\n\n const projections: Projections = {\n 'kubb:plugin:start': ({ plugin }) => [{ plugin: { name: plugin.name } }],\n 'kubb:plugin:end': ({ plugin, duration, success }) => [{ plugin: { name: plugin.name }, duration, success }],\n 'kubb:build:start': ({ config, adapter }) => [{ config: { name: config.name }, adapter: { name: adapter.name } }],\n 'kubb:build:end': ({ files, config, outputDir }) => [\n { files: files.map((file) => ({ path: relativeStoragePath({ root: config.root, filePath: file.path }), name: file.name })), outputDir },\n ],\n 'kubb:files:processing:start': ({ files }) => [{ total: files.length }],\n 'kubb:files:processing:update': ({ files }) => [\n {\n files: files.map(({ file, processed, total, percentage }) => ({\n file: relativeStoragePath({ root, filePath: file.path }),\n processed,\n total,\n percentage,\n })),\n },\n ],\n 'kubb:files:processing:end': ({ files }) => [{ total: files.length }],\n 'kubb:info': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:success': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:warn': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:error': ({ error }) => [{ message: error.message, stack: error.stack }],\n 'kubb:diagnostic': ({ diagnostic }) => [\n {\n code: diagnostic.code,\n message: diagnostic.message,\n severity: diagnostic.severity,\n location: 'location' in diagnostic ? diagnostic.location : undefined,\n help: 'help' in diagnostic ? diagnostic.help : undefined,\n plugin: 'plugin' in diagnostic ? diagnostic.plugin : undefined,\n stack: 'cause' in diagnostic ? diagnostic.cause?.stack : undefined,\n },\n ],\n 'kubb:generation:start': ({ config }) => [{ name: config.name, plugins: config.plugins.length }],\n 'kubb:generation:end': () => [],\n 'kubb:generation:summary': ({ duration, fileCount, failedPlugins, status }) => [{ duration, fileCount, failedPlugins, status }],\n 'kubb:lifecycle:start': () => [],\n 'kubb:lifecycle:end': () => [],\n 'kubb:format:start': () => [],\n 'kubb:format:end': () => [],\n 'kubb:lint:start': () => [],\n 'kubb:lint:end': () => [],\n 'kubb:hooks:start': () => [],\n 'kubb:hooks:end': () => [],\n 'kubb:hook:start': ({ id, command, args }) => [{ id, command, args: args ? [...args] : undefined }],\n 'kubb:hook:line': ({ id, line }) => [{ id, line }],\n 'kubb:hook:end': ({ id, command, args, success, error }) => [\n { id, command, args: args ? [...args] : undefined, success, error: error ? { message: error.message, stack: error.stack } : undefined },\n ],\n }\n\n function forward<Type extends GenerationEventType>(type: Type): void {\n on(type, (...args: KubbHooks[Type]) => {\n emitEvent(type, projections[type](...args))\n // Generators render in memory without awaiting I/O, so the socket only sends once the event loop gets a turn.\n if (!isDiscardable(type)) return new Promise<void>((resolve) => setImmediate(resolve))\n })\n }\n\n // Paths in `kubb:files:processing:update` are made relative to the root the build announced.\n on('kubb:build:start', ({ config }) => {\n root = config.root\n })\n\n for (const type of generationEventTypes) forward(type)\n\n // Registered after the loop so the summary follows its `kubb:generation:end`; core never emits it.\n on('kubb:generation:end', ({ diagnostics = [], status, hrStart, filesCreated }) => {\n if (!hrStart) {\n return\n }\n\n const duration = Math.round(getElapsedMs(hrStart))\n\n emitEvent('kubb:generation:summary', [\n { duration, fileCount: filesCreated ?? 0, failedPlugins: Diagnostics.failedPlugins(diagnostics).length, status: status ?? 'success' },\n ])\n })\n\n /**\n * Takes this generation's listeners off the session emitter. Safe to call twice.\n */\n function detach(): void {\n for (const unhook of unhooks) unhook()\n unhooks.length = 0\n }\n\n async function close(): Promise<void> {\n if (closed) {\n return\n }\n closed = true\n detach()\n controller.close()\n }\n\n function fail(error?: unknown): void {\n detach()\n if (closed) {\n return\n }\n closed = true\n controller.error(error)\n }\n\n return { stream, close, fail }\n}\n","import { Diagnostics } from '@kubb/core'\n\n/**\n * Hosted Kubb Studio URL, used when a host passes none.\n */\nexport const defaultStudioUrl = 'https://kubb.studio'\n\n// `URL` keeps IPv6 brackets, so `::1` is `[::1]`.\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]'\n}\n\n/**\n * Appends `path` to the Studio URL and refuses plaintext to anything but this machine, so a token\n * or API key never crosses the network unencrypted. `socket` switches the scheme to `ws:`/`wss:`.\n *\n * @example\n * ```ts\n * secureUrl({ studioUrl: 'https://kubb.studio', path: '/api/agent/socket', socket: true }).href // 'wss://kubb.studio/api/agent/socket'\n * ```\n */\nexport function secureUrl({ studioUrl, path, socket = false }: { studioUrl: string; path: string; socket?: boolean }): URL {\n const url = new URL(`${studioUrl.replace(/\\/+$/, '')}${path}`)\n\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && isLoopbackHost(url.hostname))) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Refusing to reach Kubb Studio at ${url.origin}: use an https:// URL, or a loopback host for local development`,\n })\n }\n if (socket) url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'\n\n return url\n}\n","import { randomUUID } from 'node:crypto'\nimport { tmpdir } from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getErrorMessage, mkdtemp, read, rm, toError } from '@internals/utils'\nimport {\n Diagnostics,\n cacheStorage,\n type Config,\n fsStorage,\n getInputKind,\n Hookable,\n type KubbHooks,\n type Storage,\n readInstalledPackages,\n resolveCacheDir,\n resolveMeta,\n} from '@kubb/core'\nimport { newWebSocketRpcSession, RpcTarget } from 'capnweb'\nimport { version as kubbVersion } from '../package.json'\nimport { readConfig, readImports, writeConfigEdits } from './configFile.ts'\nimport { diffHunks, pageHunks } from './diff.ts'\nimport { createGenerationStream } from './generationEvents.ts'\nimport { createGenerationStore, generate, type GenerationStore, listDisk, resolveGenerationLimits } from './generations.ts'\nimport {\n AGENT_INSTANCE_HEADER,\n AGENT_SOCKET_PATH,\n type AgentApi,\n AgentPermission,\n AgentCloseCode,\n AgentMessage,\n type AgentConnectInfo,\n type AgentPermissions,\n type ConfigEntryView,\n type ConfigFileView,\n type ConfigRef,\n type ConnectMessagePayload,\n type DiskOutput,\n type GenerateInput,\n type GenerateResult,\n type GenerationEvent,\n type GenerationRun,\n type InstalledExtensions,\n MAX_FILES_PER_REQUEST,\n MAX_PAGE_LINES,\n type ReadDiffInput,\n type ReadDiffResult,\n type ReadFilesInput,\n type ReadFilesResult,\n type ReadInputInput,\n type ReadInputResult,\n type SaveConfigInput,\n type SaveResult,\n type StudioApi,\n} from './protocol.ts'\nimport { assertOutputPaths, mergeAdapter, mergeParsers, mergePlugins, toJSONOptions, toStudioName } from './resolveConfig.ts'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\nconst HEARTBEAT_INTERVAL_MS = 30_000\n// Studio marks an agent offline after its liveness window, so a slower cadence would look dead.\nconst MAX_HEARTBEAT_INTERVAL_MS = 60_000\nconst PING_TIMEOUT_MS = 10_000\nconst OPEN_TIMEOUT_MS = 5_000\nconst MAX_RETRY_DELAY_MS = 30_000\nconst DISK_SNAPSHOT_MAX_FILES = 10_000\n// Sandboxes keep temporary output sets with a short lifetime.\nconst SANDBOX_GENERATION_TTL_MS = 15 * 60_000\n/** Extensions `kubb` ships with, so they count as installed without being a direct dependency. */\nconst BUILT_IN_PACKAGES = ['@kubb/adapter-oas', '@kubb/parser-ts', '@kubb/parser-md', '@kubb/plugin-barrel']\n\n/**\n * Studio closed with {@link AgentCloseCode.UNAUTHORIZED}. Hosts forget the token and pair again.\n */\nexport class InvalidAgentTokenError extends Error {\n constructor(studioUrl: string) {\n super(`Kubb Studio rejected this agent's token. It expired or was revoked, or the agent was deleted in ${studioUrl}.`)\n this.name = 'InvalidAgentTokenError'\n }\n}\n\n/**\n * Studio closed with {@link AgentCloseCode.INCOMPATIBLE}. Only an upgrade helps.\n */\nexport class IncompatibleAgentError extends Error {\n constructor({ studioUrl, detail }: { studioUrl: string; detail?: string }) {\n super(`Kubb Studio at ${studioUrl} requires a newer agent${detail ? `: ${detail}` : ''}. Upgrade kubb or the Kubb agent image.`)\n this.name = 'IncompatibleAgentError'\n }\n}\n\nexport type StudioConnectedContext = AgentConnectInfo & {\n url: string\n /**\n * The Studio, runtime, and host versions, so a host can show a mismatch.\n */\n versions: { studio: string; kubb: string; agent: string }\n}\n\ndeclare global {\n namespace Kubb {\n interface KubbHooksRegistry {\n /**\n * Fired after each handshake, including reconnects.\n */\n 'studio:connected': [ctx: StudioConnectedContext]\n 'studio:disconnected': [ctx: { code: number; reason: string }]\n 'studio:reconnecting': [ctx: { delayMs: number }]\n /**\n * A finished command and what it did, such as `applied 2/3 edits to kubb.config.ts`.\n */\n 'studio:command': [\n ctx: {\n command: 'generate' | 'saveConfig' | 'readFiles' | 'readInput' | 'readDiff'\n info: string\n /**\n * The Studio user who asked for the command, when Studio names one.\n */\n requestedBy?: string\n /**\n * Set when a generation failed. Its diagnostics went out through `kubb:generation:end`.\n */\n failed?: boolean\n },\n ]\n /**\n * A refused or ignored request, with the missing permission so the host can add a remedy.\n */\n 'studio:warn': [ctx: { message: string; permission?: AgentPermission }]\n 'studio:error': [ctx: { error: Error }]\n }\n }\n}\n\nexport type ConnectAgentOptions = {\n /**\n * The agent's bearer token, from {@link pairAgent}.\n */\n token: string\n studioUrl?: string\n /**\n * The config path shown in Studio, relative to `root` unless absolute.\n */\n configPath: string\n /**\n * Called for every handshake and every generation, so edits on disk show up. One entry per\n * `defineConfig(...)` entry, and a generation names the one it runs.\n */\n loadConfigs: () => Promise<Array<Config>>\n /**\n * The host's own version, reported to Studio next to the runtime's.\n */\n version: string\n /**\n * The project root generation runs against.\n * @default process.cwd()\n */\n root?: string\n /**\n * What Studio may do in this project. Every permission is off unless granted.\n */\n permissions?: Partial<AgentPermissions>\n /**\n * Receives the `studio:*` hooks and the `kubb:*` hooks of every generation.\n */\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n /**\n * Longest wait between reconnect attempts, in milliseconds.\n * @default 30000\n */\n maxRetryDelay?: number\n /**\n * Milliseconds between keep-alive pings, at most 60000.\n * @default 30000\n */\n heartbeatInterval?: number\n}\n\ntype ResolvedOptions = Required<Omit<ConnectAgentOptions, 'signal'>> & {\n signal?: AbortSignal\n permissions: AgentPermissions\n configFile: string\n}\n\ntype Rpc = { studio: StudioApi; closed: Promise<{ code: number; reason: string }>; close: () => void }\n\n// Tests swap in an in-process pair.\nexport type OpenRpc = (input: { url: URL; token: string; instanceId: string; agent: AgentApi }) => Rpc\n\ntype Session = {\n info?: AgentConnectInfo\n connected: PromiseWithResolvers<AgentConnectInfo>\n closed: boolean\n active?: { jobId: string; abort: () => void; settled: Promise<void> }\n}\n\n// A throwing host listener must not break the connection.\nfunction emit<TName extends keyof KubbHooks & string>(hooks: Hookable<KubbHooks>, name: TName, ...args: KubbHooks[TName]): Promise<void> {\n return Promise.resolve(hooks.callHook(name, ...args)).catch(() => {})\n}\n\nfunction isValidPage({ cursor, limit }: Pick<ReadFilesInput, 'cursor' | 'limit'>): boolean {\n if (limit === undefined) return cursor === undefined\n if (cursor !== undefined && (!Number.isSafeInteger(cursor) || cursor < 0)) return false\n return Number.isSafeInteger(limit) && limit >= 1 && limit <= MAX_PAGE_LINES\n}\n\n/**\n * Maps generated paths into a temporary directory while keeping the project root for input resolution.\n */\nfunction stagingStorage({ root, directory }: { root: string; directory: string }): Storage {\n const storage = fsStorage()\n const target = (key: string) => {\n const relative = path.relative(root, path.resolve(root, key))\n if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error('Output path escapes the project root')\n return path.join(directory, relative)\n }\n return {\n name: 'fs',\n readItem: (key) => storage.readItem(target(key)),\n writeItem: (key, value) => storage.writeItem(target(key), value),\n removeItem: (key) => storage.removeItem(target(key)),\n readKeys: (base) => storage.readKeys(base ? target(base) : directory),\n empty: (base) => (base ? storage.empty(target(base)) : Promise.resolve()),\n }\n}\n\ntype RunHandle = { stream: ReadableStream<GenerationEvent>; result: Promise<GenerateResult>; stop: () => void }\n\nclass GenerationRunTarget extends RpcTarget implements GenerationRun {\n readonly #run: RunHandle\n\n constructor(run: RunHandle) {\n super()\n this.#run = run\n }\n\n async events() {\n return this.#run.stream\n }\n result() {\n return this.#run.result\n }\n async cancel() {\n this.#run.stop()\n }\n // Cap'n Web also calls this when the peer session is torn down, so a dropped socket stops the run.\n [Symbol.dispose]() {\n this.#run.stop()\n }\n}\n\n// Cap'n Web exposes only prototype methods, so the public methods are exactly `AgentApi`.\nclass Agent extends RpcTarget implements AgentApi {\n readonly #options: ResolvedOptions\n readonly #session: Session\n readonly #limits = resolveGenerationLimits()\n #store: GenerationStore | undefined\n readonly #sandboxCacheRoot = path.join(tmpdir(), `kubb-studio-${randomUUID()}`)\n // Kept sets never change, so a diff is computed once and its pages are cut from it.\n readonly #diffs = new Map<string, ReturnType<typeof diffHunks>>()\n\n constructor({ options, session }: { options: ResolvedOptions; session: Session }) {\n super()\n this.#options = options\n this.#session = session\n }\n\n get #sandbox(): boolean {\n return this.#session.info?.sandbox === true\n }\n\n // A sandbox has no project to write to or edit, and Studio may always read what it generated there.\n get #permissions(): AgentPermissions {\n const { permissions } = this.#options\n return this.#sandbox ? { ...permissions, allowWrite: false, allowConfigEdit: false, allowRead: true, allowReadAst: true } : permissions\n }\n\n // Owned agents retain output in the project cache. Each sandbox connection has a temporary cache.\n get #generations(): GenerationStore {\n this.#store ??= createGenerationStore({\n storage: cacheStorage({ root: this.#sandbox ? this.#sandboxCacheRoot : this.#options.root }),\n maxCount: this.#limits.maxCount,\n maxMb: this.#limits.maxMb,\n ttlMs: this.#sandbox ? SANDBOX_GENERATION_TTL_MS : undefined,\n })\n return this.#store\n }\n\n async clear() {\n if (this.#sandbox) await rm(resolveCacheDir(this.#sandboxCacheRoot), { recursive: true, force: true })\n }\n\n #warn({ message, permission }: { message: string; permission?: AgentPermission }): Promise<void> {\n return emit(this.#options.hooks, 'studio:warn', { message, permission })\n }\n\n // Studio shows the thrown message, and the host logs the same text.\n async #refuse({ message, permission }: { message: string; permission?: AgentPermission }): Promise<never> {\n await this.#warn({ message, permission })\n throw new Diagnostics.Error({ code: Diagnostics.code.unknown, severity: 'error', message })\n }\n\n #assertConnected(): void {\n if (!this.#session.info)\n throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Studio must call connect() before any other command' })\n }\n\n #logCommand(command: KubbHooks['studio:command'][0]['command'], info: string, requestedBy?: string, failed?: boolean): Promise<void> {\n return emit(this.#options.hooks, 'studio:command', { command, info, requestedBy, failed })\n }\n\n // Not cached: the user can edit the file between two Studio actions.\n async #readConfigFileView(source: Promise<string>): Promise<ConfigFileView | undefined> {\n if (!this.#permissions.allowConfigEdit) return undefined\n\n try {\n return readConfig(await source)\n } catch (error) {\n await this.#warn({ message: `Could not read ${this.#options.configFile}: ${getErrorMessage(error)}` })\n return undefined\n }\n }\n\n // Not cached either: the user can install a plugin while the agent runs. Keeps each project\n // dependency, config import and built-in that resolves and ships a valid `kubb-extension.json`.\n async #installedExtensions(source = read(this.#options.configFile)): Promise<InstalledExtensions> {\n const imports = await source.then(readImports, () => [])\n const installed = await readInstalledPackages({ root: this.#options.root, packages: [...imports, ...BUILT_IN_PACKAGES], resolveFrom: ['kubb'] })\n\n return new Map(\n installed.flatMap(({ package: name, version, manifest }) =>\n version !== undefined && manifest ? [[name, { package: name, version, manifest }] as const] : [],\n ),\n )\n }\n\n async connect(info: AgentConnectInfo): Promise<ConnectMessagePayload> {\n this.#session.info = info\n const { configPath, root, version, loadConfigs, configFile } = this.#options\n const source = read(configFile)\n const [configs, file, extensions] = await Promise.all([loadConfigs(), this.#readConfigFileView(source), this.#installedExtensions(source)])\n // Copied through JSON: Cap'n Web would otherwise pass every function in the options as a stub\n // Studio could call, running the user's config code in this process.\n const entries: Array<ConfigEntryView> = []\n for (const config of configs) {\n const disk = await this.#readDiskOutput(config).catch(async (error: unknown) => {\n await this.#warn({ message: `Could not read the output directory: ${getErrorMessage(error)}` })\n return undefined\n })\n entries.push({ ...toEntryView(config, extensions), ...(disk && { disk }) })\n }\n this.#session.connected.resolve(info)\n\n return {\n versions: { kubb: kubbVersion, agent: version },\n root,\n config: { path: configPath, file, extensions: [...extensions.values()], configs: entries },\n permissions: this.#permissions,\n }\n }\n\n async #readDiskOutput(config: Config): Promise<DiskOutput | undefined> {\n if (this.#sandbox || !this.#permissions.allowRead || this.#session.active) return undefined\n const files = await listDisk({ root: this.#options.root, outputPath: config.output.path, maxFiles: DISK_SNAPSHOT_MAX_FILES })\n if (!files) return undefined\n\n const { jobId, output } = await this.#generations.keepInitial(files)\n return { jobId, files: output.paths, hashes: output.hashes }\n }\n\n startGeneration(input: GenerateInput): GenerationRun {\n const stream = createGenerationStream(this.#options.hooks, input.jobId)\n const controller = new AbortController()\n const result = this.#runGeneration(input, controller).then(\n (value) => stream.close().then(() => value),\n (error: unknown) => {\n stream.fail(error)\n throw error\n },\n )\n // A disconnect can reject this after the remote caller disappeared.\n void result.catch(() => {})\n\n return new GenerationRunTarget({\n stream: stream.stream,\n result,\n stop: () => {\n controller.abort(new Error('Generation canceled'))\n stream.fail()\n },\n })\n }\n\n /**\n * Keeps a job's output and permitted parsed input, then cleans up its temporary generation directories.\n */\n async #runGeneration(input: GenerateInput, controller: AbortController): Promise<GenerateResult> {\n this.#assertConnected()\n // Checked before the first `await`, so two calls in the same tick can't both pass.\n if (this.#session.closed) throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Connection is closed' })\n if (this.#session.active) return this.#refuse({ message: AgentMessage.GENERATION_IN_PROGRESS })\n const settled = Promise.withResolvers<void>()\n this.#session.active = { jobId: input.jobId, abort: () => controller.abort(new Error('Generation canceled')), settled: settled.promise }\n let root = this.#options.root\n let outputRoot: string | undefined\n\n try {\n // Kubb keys its manifest cache by root, so sandbox tenants sharing one root would read each other's.\n if (this.#sandbox) root = await mkdtemp(path.join(tmpdir(), 'kubb-job-'))\n if (!this.#sandbox && !this.#permissions.allowWrite) outputRoot = await mkdtemp(path.join(tmpdir(), 'kubb-output-'))\n return await this.#generate({ input, root, outputRoot, signal: controller.signal })\n } finally {\n if (root !== this.#options.root) {\n await Promise.all([rm(root, { recursive: true, force: true }), rm(resolveCacheDir(root), { recursive: true, force: true })]).catch(() => {})\n }\n if (outputRoot) await rm(outputRoot, { recursive: true, force: true })\n this.#session.active = undefined\n settled.resolve()\n }\n }\n\n /**\n * Merges Studio's config over the project config and confines generation to the configured output folder.\n */\n async #generate({\n input,\n root,\n outputRoot,\n signal,\n }: {\n input: GenerateInput\n root: string\n outputRoot?: string\n signal: AbortSignal\n }): Promise<GenerateResult> {\n const { jobId, config: patch } = input\n // A sandbox has no spec on disk, so it only ever generates from the content Studio sends. A path\n // or URL would make it read host files or fetch internal addresses on behalf of any tenant.\n const studioInput = this.#sandbox ? patch?.input : undefined\n if (this.#sandbox && (typeof studioInput !== 'string' || !studioInput.trim() || getInputKind(studioInput) !== 'inline')) {\n return this.#refuse({ message: AgentMessage.SANDBOX_INPUT_ONLY })\n }\n\n const [configs, extensions] = await Promise.all([this.#options.loadConfigs(), this.#installedExtensions()])\n const config = pickConfig(configs, patch?.config)\n if (!config) return this.#refuse({ message: AgentMessage.CONFIG_ENTRY_NOT_FOUND })\n const [plugins, adapter, parsers] = await Promise.all([\n mergePlugins({ diskPlugins: config.plugins, studioPlugins: patch?.plugins, extensions }).then((merged) => {\n assertOutputPaths({ plugins: merged ?? [], diskPlugins: config.plugins, root, outputPath: config.output.path })\n return merged\n }),\n mergeAdapter(config.adapter, patch?.adapter, extensions),\n mergeParsers({ diskParsers: config.parsers, studioParsers: patch?.parsers, extensions }),\n ]).catch(async (error: unknown) => {\n // Thrown before core runs, so nothing else reports it to the host.\n await emit(this.#options.hooks, 'kubb:error', { error: toError(error) })\n throw error\n })\n\n const activePlugins = plugins ?? config.plugins\n\n if (patch?.input && !this.#sandbox) {\n // A `kubb:warn` rather than `studio:warn`, so the generation's event stream carries it to Studio too.\n await emit(this.#options.hooks, 'kubb:warn', {\n message: 'Ignored the spec from Studio: generating from a Studio spec is only available to a sandbox agent',\n })\n }\n\n const files = await generate({\n config: {\n ...config,\n root,\n input: studioInput ?? config.input,\n storage: outputRoot ? stagingStorage({ root, directory: outputRoot }) : fsStorage(),\n plugins: activePlugins,\n adapter,\n parsers,\n },\n hooks: this.#options.hooks,\n signal,\n allowExec: this.#permissions.allowWrite && this.#permissions.allowExec,\n }).catch(async (error: unknown) => {\n await this.#generations.drop(jobId)\n await this.#logCommand('generate', getErrorMessage(error), input.requestedBy, true)\n throw error\n })\n\n const output = await this.#generations.keep({ jobId, files, maxSetMb: this.#limits.maxMb })\n // Only `readInput` reads it, which needs `allowReadAst`.\n const inputBytes = await this.#generations.keepInput({ jobId, input: this.#permissions.allowReadAst ? files.input : null, maxSetMb: this.#limits.maxMb })\n if (!output.paths.length && Object.keys(output.hashes).length) {\n await this.#warn({ message: 'Kept only the hashes of this generation: its output is too large to keep' })\n }\n await this.#generations.add({ jobId, output, inputBytes })\n await this.#logCommand(\n 'generate',\n `${activePlugins.length} plugin${activePlugins.length === 1 ? '' : 's'}, ${this.#permissions.allowWrite ? 'written to disk' : 'staged on disk'}${studioInput !== undefined ? ', from a Studio spec' : ''}`,\n input.requestedBy,\n )\n\n return {\n status: 'success',\n files: [...files.paths],\n fileCount: files.paths.size,\n hashes: output.hashes,\n }\n }\n\n async saveConfig(input: SaveConfigInput): Promise<SaveResult> {\n this.#assertConnected()\n const { configPath, configFile } = this.#options\n\n if (!Array.isArray(input.edits)) {\n await this.#warn({ message: 'Ignored save: the message carried no edits' })\n return { outcomes: [], changed: false }\n }\n\n const edits = input.edits\n const refuse = (reason: string): SaveResult => ({ outcomes: edits.map((edit) => ({ edit, applied: false, reason })), changed: false })\n\n if (!this.#permissions.allowConfigEdit) {\n await this.#warn({ message: 'Ignored save: editing kubb.config.ts was not granted' })\n return refuse('the agent was not granted permission to edit kubb.config.ts')\n }\n\n // A running generation reloads the config, so it would see half the change.\n if (this.#session.active) return refuse('a generation is in progress')\n\n try {\n const { outcomes, changed } = await writeConfigEdits({ filePath: configFile, edits, extensions: await this.#installedExtensions() })\n const applied = outcomes.filter((outcome) => outcome.applied).length\n await this.#logCommand('saveConfig', `applied ${applied}/${outcomes.length} edits to ${configPath}`, input.requestedBy)\n\n return { outcomes, changed }\n } catch (error) {\n // Refuse every edit so Studio hears back instead of waiting.\n await emit(this.#options.hooks, 'studio:error', { error: toError(error) })\n return refuse(getErrorMessage(error))\n }\n }\n\n /**\n * Returns the Kubb AST a kept job parsed its spec into. Refused without `allowReadAst`.\n */\n async readInput(input: ReadInputInput): Promise<ReadInputResult> {\n this.#assertConnected()\n if (!this.#permissions.allowReadAst) return this.#refuse({ message: AgentMessage.READ_AST_NOT_ALLOWED, permission: AgentPermission.READ_AST })\n if (typeof input.jobId !== 'string' || !input.jobId) return this.#refuse({ message: AgentMessage.JOB_REQUIRED })\n\n const generation = await this.#generations.get(input.jobId)\n if (!generation) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n // A rerun of the job can leave an earlier run's input on disk, so trust only what this run kept.\n const kept = generation.inputBytes ? await this.#generations.readInput(input.jobId) : undefined\n if (!kept) return this.#refuse({ message: AgentMessage.NO_INPUT })\n await this.#logCommand('readInput', 'read the API input')\n\n return { input: kept }\n }\n\n /**\n * Returns the requested files of a kept job, one page of lines at a time. Refused without `allowRead`.\n */\n async readFiles(input: ReadFilesInput): Promise<ReadFilesResult> {\n this.#assertConnected()\n if (!this.#permissions.allowRead) return this.#refuse({ message: AgentMessage.READ_NOT_ALLOWED, permission: AgentPermission.READ })\n if (!Array.isArray(input.paths) || typeof input.jobId !== 'string' || !input.jobId) {\n return this.#refuse({ message: AgentMessage.FILE_REQUEST_INVALID })\n }\n const { paths } = input\n if (paths.length > MAX_FILES_PER_REQUEST) return this.#refuse({ message: AgentMessage.TOO_MANY_FILES })\n if (!isValidPage(input)) return this.#refuse({ message: AgentMessage.INVALID_PAGE })\n\n const generation = await this.#generations.get(input.jobId)\n if (!generation) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n\n // Only paths the set holds are read, never an arbitrary path.\n const result = await this.#generations.read({ generation, paths, cursor: input.cursor, limit: input.limit })\n await this.#logCommand('readFiles', `read ${Object.keys(result.files).length}/${paths.length} requested file${paths.length === 1 ? '' : 's'}`)\n\n return result\n }\n\n /**\n * Returns one page of the line diff of a file between two kept sets. Refused without `allowRead`.\n */\n async readDiff(input: ReadDiffInput): Promise<ReadDiffResult> {\n this.#assertConnected()\n if (!this.#permissions.allowRead) return this.#refuse({ message: AgentMessage.READ_NOT_ALLOWED, permission: AgentPermission.READ })\n const { jobId, path, base, cursor = 0, limit } = input\n if (typeof jobId !== 'string' || !jobId || typeof path !== 'string' || !path || typeof base?.jobId !== 'string' || !base.jobId) {\n return this.#refuse({ message: AgentMessage.DIFF_REQUEST_INVALID })\n }\n if (!isValidPage({ cursor, limit })) {\n return this.#refuse({ message: AgentMessage.INVALID_PAGE })\n }\n\n const [generation, baseGeneration] = await Promise.all([this.#generations.get(jobId), this.#generations.get(base.jobId)])\n if (!generation || !baseGeneration) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n\n // Only paths the sets hold are read, never an arbitrary path.\n const [after, before] = await Promise.all([\n this.#generations.read({ generation, paths: [path] }),\n this.#generations.read({ generation: baseGeneration, paths: [path] }),\n ])\n const afterContent = after.files[path]\n // Over the size cap only hashes are kept, which must not read as a deleted file.\n if (afterContent === undefined && path in generation.output.hashes) return this.#refuse({ message: AgentMessage.HASHES_ONLY })\n const beforeContent = before.files[path]\n if (beforeContent === undefined)\n return { hunks: [], nextCursor: null, hasBase: false, stats: { additions: 0, deletions: 0, hunks: 0, lines: 0, coarse: false } }\n\n const key = JSON.stringify([jobId, base.jobId, path])\n let diff = this.#diffs.get(key)\n if (!diff) {\n diff = diffHunks(beforeContent, afterContent ?? '')\n this.#diffs.set(key, diff)\n // A few recent diffs cover paging through the open file and switching back to the last one.\n if (this.#diffs.size > 4) this.#diffs.delete(this.#diffs.keys().next().value!)\n }\n await this.#logCommand('readDiff', `read the diff of ${path}`)\n\n return { ...pageHunks({ hunks: diff.hunks, cursor, limit }), hasBase: true, stats: diff.stats }\n }\n}\n\nconst openWebSocketRpc: OpenRpc = ({ url, token, instanceId, agent }) => {\n // Node's `WebSocket` takes undici's `headers` option, which the DOM typing leaves out.\n const NodeWebSocket = WebSocket as unknown as new (url: URL, init: { headers: Record<string, string> }) => WebSocket\n const socket = new NodeWebSocket(url, { headers: { Authorization: `Bearer ${token}`, [AGENT_INSTANCE_HEADER]: instanceId } })\n const timer = setTimeout(() => socket.close(3008, 'Connection timeout'), OPEN_TIMEOUT_MS)\n socket.addEventListener('open', () => clearTimeout(timer), { once: true })\n\n const closed = new Promise<Awaited<Rpc['closed']>>((resolve) => {\n socket.addEventListener('close', ({ code, reason }) => resolve({ code, reason }), { once: true })\n // Node fires only `error` when the handshake itself fails.\n socket.addEventListener('error', () => {\n if (socket.readyState !== WebSocket.OPEN) resolve({ code: 1006, reason: '' })\n })\n }).finally(() => clearTimeout(timer))\n\n const studio = newWebSocketRpcSession<StudioApi>(socket, agent)\n studio.onRpcBroken(() => socket.close())\n\n return {\n studio,\n closed,\n close: () => {\n studio[Symbol.dispose]()\n socket.close()\n },\n }\n}\n\nasync function runSession({ options, openRpc, url, instanceId }: { options: ResolvedOptions; openRpc: OpenRpc; url: URL; instanceId: string }) {\n const { hooks, signal, heartbeatInterval, token, studioUrl, version } = options\n const session: Session = { connected: Promise.withResolvers(), closed: false }\n const agent = new Agent({ options, session })\n const rpc = openRpc({ url, token, instanceId, agent })\n signal?.addEventListener('abort', rpc.close, { once: true })\n let timer: ReturnType<typeof setTimeout> | undefined\n\n // Races each ping against a deadline, so a half-open socket can't hang it forever.\n const heartbeat = async (): Promise<void> => {\n let deadline: ReturnType<typeof setTimeout> | undefined\n const timedOut = new Promise<boolean>((resolve) => (deadline = setTimeout(resolve, PING_TIMEOUT_MS, true)))\n const failed = await Promise.race([\n Promise.resolve(rpc.studio.ping()).then(\n () => false,\n () => true,\n ),\n timedOut,\n ])\n clearTimeout(deadline)\n if (failed) return rpc.close()\n if (!session.closed) timer = setTimeout(heartbeat, heartbeatInterval)\n }\n\n void session.connected.promise.then(\n async (info) => {\n await emit(hooks, 'studio:connected', { ...info, url: studioUrl, versions: { studio: info.studioVersion, kubb: kubbVersion, agent: version } })\n if (!session.closed) timer = setTimeout(heartbeat, heartbeatInterval)\n },\n () => {},\n )\n\n const close = await rpc.closed\n session.closed = true\n clearTimeout(timer)\n signal?.removeEventListener('abort', rpc.close)\n session.connected.reject(new Error('The socket closed before Studio called connect()'))\n // Captured and aborted before the warning, so a slow listener neither keeps the run going nor\n // sees it finish and clear `session.active` first.\n const active = session.active\n if (active) {\n active.abort()\n await emit(hooks, 'studio:warn', { message: 'Canceled the running generation: the connection to Kubb Studio closed' })\n }\n await active?.settled\n await agent.clear()\n\n return { ...close, connected: session.info !== undefined }\n}\n\n/**\n * The connection loop with a swappable transport. {@link connectAgent} passes a real WebSocket.\n */\n/** The entry Studio named by position or `name`, else the first. `undefined` for one the file does not have. */\nfunction pickConfig(configs: Array<Config>, ref: ConfigRef | undefined): Config | undefined {\n if (typeof ref === 'string') return configs.find((config) => config.name === ref)\n if (ref !== undefined && !Number.isSafeInteger(ref)) return undefined\n return configs[ref ?? 0]\n}\n\n/** The input path or URL Studio may show: no inline document, and no credentials from a URL. */\nfunction reportedInput(input: Config['input']): string | undefined {\n if (typeof input !== 'string') return undefined\n const kind = getInputKind(input)\n if (kind === 'inline') return undefined\n // The scp-style git form (`git+git@host:org/repo.git`) is no URL and carries no password.\n if ((kind !== 'url' && kind !== 'git') || !URL.canParse(input)) return input\n const url = new URL(input)\n url.username = ''\n url.password = ''\n return url.href\n}\n\n/** A JSON copy of one resolved entry, each extension named by the package its manifest is in. */\nfunction toEntryView(config: Config, extensions: InstalledExtensions): ConfigEntryView {\n const input = reportedInput(config.input)\n return {\n ...(config.name !== undefined && { name: config.name }),\n ...(input !== undefined && { input }),\n output: config.output.path,\n plugins: config.plugins.map((plugin) => ({\n name: toStudioName({ name: resolveMeta(plugin).name, extensions }),\n options: toJSONOptions(plugin.options),\n })),\n adapter: config.adapter && {\n name: toStudioName({ name: resolveMeta(config.adapter).name, extensions, kind: 'adapter' }),\n options: toJSONOptions(config.adapter.options),\n },\n parsers: config.parsers.map((parser) => ({\n name: toStudioName({ name: resolveMeta(parser).name, extensions, kind: 'parser' }),\n options: toJSONOptions(parser.options),\n })),\n }\n}\n\nexport async function runAgent({ options, openRpc }: { options: ConnectAgentOptions; openRpc: OpenRpc }): Promise<void> {\n const root = options.root ?? process.cwd()\n const resolved: ResolvedOptions = {\n ...options,\n studioUrl: options.studioUrl ?? defaultStudioUrl,\n root,\n configFile: path.resolve(root, options.configPath),\n permissions: { allowWrite: false, allowConfigEdit: false, allowExec: false, allowRead: false, allowReadAst: false, ...options.permissions },\n hooks: options.hooks ?? new Hookable<KubbHooks>(),\n maxRetryDelay: options.maxRetryDelay ?? MAX_RETRY_DELAY_MS,\n heartbeatInterval: Math.min(options.heartbeatInterval ?? HEARTBEAT_INTERVAL_MS, MAX_HEARTBEAT_INTERVAL_MS),\n }\n const { studioUrl, hooks, signal, maxRetryDelay } = resolved\n const url = secureUrl({ studioUrl, path: AGENT_SOCKET_PATH, socket: true })\n // One per call, so a reconnect is the same process to Studio and a restart is a new one.\n const instanceId = randomUUID()\n let attempt = 0\n\n while (!signal?.aborted) {\n const { code, reason, connected } = await runSession({ options: resolved, openRpc, url, instanceId })\n if (signal?.aborted) return\n await emit(hooks, 'studio:disconnected', { code, reason })\n\n if (code === AgentCloseCode.UNAUTHORIZED) throw new InvalidAgentTokenError(studioUrl)\n if (code === AgentCloseCode.INCOMPATIBLE) throw new IncompatibleAgentError({ studioUrl, detail: reason })\n if (code === AgentCloseCode.SUPERSEDED) return\n\n // Reset only once Studio called connect(), so a socket that opens and closes again backs off.\n if (connected) attempt = 0\n const delayMs = Math.random() * Math.min(1_000 * 2 ** Math.min(attempt++, 16), maxRetryDelay)\n await emit(hooks, 'studio:reconnecting', { delayMs })\n await delay(delayMs, undefined, { signal }).catch(() => {})\n }\n}\n\n/**\n * Connects this project to Kubb Studio and serves its commands until `signal` aborts. Reconnects\n * with jittered backoff, and resolves when another process of the agent takes over. Rejects with\n * {@link InvalidAgentTokenError} so the host can pair again, or {@link IncompatibleAgentError}.\n *\n * @example\n * ```ts\n * const hooks = new Hookable<KubbHooks>()\n * hooks.hook('studio:connected', ({ agentSlug }) => console.log(`Connected as ${agentSlug}`))\n *\n * await connectAgent({ token, configPath: 'kubb.config.ts', loadConfigs, version: '1.0.0', hooks, signal })\n * ```\n */\nexport function connectAgent(options: ConnectAgentOptions): Promise<void> {\n return runAgent({ options, openRpc: openWebSocketRpc })\n}\n","import { hash } from 'node:crypto'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { toError } from '@internals/utils'\nimport { Diagnostics } from '@kubb/core'\nimport { ofetch } from 'ofetch'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\n/**\n * RFC 8628 device-authorization response from Studio's `/api/auth/device/code` endpoint.\n * Field names match the RFC; the CLI polls with `device_code` and shows `user_code` to the user.\n */\nexport type PairingSession = {\n device_code: string\n user_code: string\n verification_uri: string\n verification_uri_complete: string\n expires_in: number\n interval: number\n}\n\ntype PairingResult = {\n /**\n * Bearer token for this machine. Write credentials with mode 0600 and never log the value.\n */\n token: string\n agent: {\n /**\n * Stable agent id in Studio.\n */\n id: string\n /**\n * Short slug used in logs and the UI (for example `brave-otter`).\n */\n slug: string\n /**\n * Display name chosen at pairing time.\n */\n name: string\n /**\n * This agent's organization slug, absent for a sandbox or global agent, which has none.\n */\n organizationSlug?: string\n }\n}\n\n/**\n * What this machine registers as. Any member may approve `cli` (`kubb studio`); only an admin may\n * approve `user` and `sandbox` (the Docker image). A `ci` agent never pairs.\n */\ntype PairingAgentType = 'cli' | 'user' | 'sandbox'\n\n/** Labels, not secrets: a person approving the code in the browser is what authorizes a pairing. */\nconst CLIENT_IDS = { cli: 'kubb-cli', agent: 'kubb-agent' } as const\n\n/**\n * Thrown when a caller aborts `startPairing` or `pollForPairingToken` through their `signal`, such\n * as a `kubb studio` shutdown mid-pairing. Distinct from a denial or an expired code, so a host can\n * exit quietly instead of reporting a pairing failure.\n */\nexport class PairingCanceledError extends Error {\n constructor() {\n super('Pairing was canceled')\n this.name = 'PairingCanceledError'\n }\n}\n\n/** Thrown when the code expired unapproved. A fresh code can still succeed. */\nexport class PairingExpiredError extends Error {\n constructor(message = 'The pairing code expired, pair again') {\n super(message)\n this.name = 'PairingExpiredError'\n }\n}\n\n/** Thrown when the pairing was denied in the browser, including by the organization's agent limit. */\nexport class PairingDeniedError extends Error {\n constructor(message = 'Pairing was denied in the browser') {\n super(message)\n this.name = 'PairingDeniedError'\n }\n}\n\ntype StartPairingOptions = {\n studioUrl?: string\n type: PairingAgentType\n /**\n * Display name for the agent, usually the project or machine name.\n */\n name: string\n hostname: string\n /**\n * A stable secret the host keeps for this machine. Studio stores its hash against the agent, so\n * the same machine pairing again rotates one agent's token instead of creating a second agent.\n */\n machineId: string\n /**\n * Aborting this cancels the request in flight and rejects with {@link PairingCanceledError}.\n */\n signal?: AbortSignal\n}\n\n/**\n * Asks Studio for a pairing code, sending the hashed machine id with it.\n */\nexport async function startPairing({ studioUrl = defaultStudioUrl, type, name, hostname, machineId, signal }: StartPairingOptions): Promise<PairingSession> {\n try {\n const pairing = await ofetch<PairingSession>(secureUrl({ studioUrl, path: '/api/auth/device/code' }).href, {\n method: 'POST',\n body: {\n client_id: type === 'cli' ? CLIENT_IDS.cli : CLIENT_IDS.agent,\n name,\n hostname,\n machine_token: hash('sha256', machineId),\n agent_kind: type === 'cli' ? undefined : type,\n },\n signal,\n })\n if (typeof pairing?.device_code !== 'string')\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Kubb Studio returned no pairing code',\n help: 'Try again later. If it keeps failing, check the Kubb Studio status.',\n })\n\n return pairing\n } catch (error) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n throw error\n }\n}\n\ntype PollOptions = {\n studioUrl?: string\n session: PairingSession\n /**\n * Aborting this stops polling and rejects with {@link PairingCanceledError}, whether the abort\n * lands between polls or during the wait for the next one.\n */\n signal?: AbortSignal\n /** Called when a poll could not reach Studio. Polling carries on. */\n onRetry?: (error: Error) => void\n}\n\ntype PollError = 'authorization_pending' | 'slow_down' | 'expired_token' | 'access_denied' | 'invalid_grant'\n\ntype PollResponse =\n | PairingResult\n | {\n error: PollError | string\n /**\n * Why, when Studio has something more useful to say than the RFC code. An approval that hits\n * the organization's agent limit comes back as `access_denied` with the limit spelled out.\n */\n error_description?: string\n }\n\nfunction isPairingResult(response: PollResponse): response is PairingResult {\n return 'token' in response && typeof response.token === 'string'\n}\n\n/**\n * Polls until the user approves or denies, honoring the server's `slow_down` back-off.\n *\n * Studio's own endpoint is used rather than the auth layer's `/device/token`, because an approved\n * Kubb pairing is worth an agent bearer token, not a user session.\n *\n * @throws {PairingExpiredError} when the code expires before anyone approves it.\n * @throws {PairingDeniedError} when the pairing is denied in the browser.\n * @throws {PairingCanceledError} when `signal` aborts.\n */\nexport async function pollForPairingToken({ studioUrl = defaultStudioUrl, session, signal, onRetry }: PollOptions): Promise<PairingResult> {\n // Both fields cross the network, so neither is trusted as-is: a missing or zero `interval` would\n // spin the poll loop, and a missing or zero `expires_in` would expire the code before the first\n // poll. `> 0` is also false for `NaN` and for a missing field, so it doubles as the type guard.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let intervalMs = (session.interval > 0 ? session.interval : 5) * 1000\n\n while (Date.now() < deadline) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n try {\n await delay(intervalMs, undefined, { signal })\n } catch {\n throw new PairingCanceledError()\n }\n\n let response: PollResponse\n try {\n // A denial, an expiry, and \"not yet\" all come back as 4xx with a body to switch on.\n const { status, _data } = await ofetch.raw<PollResponse>(secureUrl({ studioUrl, path: '/api/agent/token' }).href, {\n method: 'POST',\n body: { device_code: session.device_code },\n signal,\n ignoreResponseError: true,\n })\n if (status >= 500 || !_data || typeof _data !== 'object')\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio answered with status ${status}`,\n help: 'Try again later.',\n })\n response = _data\n } catch (error) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n // Studio can be briefly unreachable (a deploy) while the code is still valid, so retry.\n onRetry?.(toError(error))\n continue\n }\n\n if (isPairingResult(response)) {\n return response\n }\n\n if (!('error' in response) || typeof response.error !== 'string') {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Kubb Studio returned an empty pairing response, pair again',\n })\n }\n\n if (response.error === 'authorization_pending') {\n continue\n }\n\n if (response.error === 'slow_down') {\n intervalMs += 5_000\n continue\n }\n\n if (response.error === 'access_denied') {\n throw new PairingDeniedError(response.error_description)\n }\n\n if (response.error === 'expired_token' || response.error === 'invalid_grant') {\n throw new PairingExpiredError(response.error_description)\n }\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: response.error_description ?? `Pairing failed (${response.error})`,\n help: 'Pair again with `kubb studio login`.',\n })\n }\n\n throw new PairingExpiredError()\n}\n\ntype PairAgentOptions = StartPairingOptions & {\n /** Shows the code to whoever approves it. Called again for each fresh code. */\n onCode: (session: PairingSession, attempt: number) => void | Promise<void>\n /** Called when a poll could not reach Studio. Polling carries on. */\n onRetry?: (error: Error) => void\n /**\n * Codes to ask for in total when one expires unapproved. A denial or abort ends it at once.\n * @default 1\n */\n maxAttempts?: number\n}\n\n/**\n * Pairs this machine with Studio: asks for a code, hands it to the host to show, and waits for approval.\n */\nexport async function pairAgent({ onCode, onRetry, maxAttempts = 1, ...options }: PairAgentOptions): Promise<PairingResult> {\n for (let attempt = 1; ; attempt++) {\n const session = await startPairing(options)\n await onCode(session, attempt)\n\n try {\n return await pollForPairingToken({ studioUrl: options.studioUrl, session, signal: options.signal, onRetry })\n } catch (error) {\n if (!(error instanceof PairingExpiredError) || attempt >= maxAttempts) {\n throw error\n }\n }\n }\n}\n","import { tmpdir } from 'node:os'\nimport { join, resolve } from 'node:path'\nimport { gzipSync } from 'node:zlib'\nimport { mkdir, mkdtemp, read, rm, writeRaw } from '@internals/utils'\nimport { type Config, Diagnostics, fsStorage, type Hookable, type KubbHooks, readInstalledPackages, resolveMeta } from '@kubb/core'\nimport { ofetch } from 'ofetch'\nimport { generate, hashOf } from './generations.ts'\nimport { MAX_SNAPSHOT_BYTES, type PublishedSnapshot, type SnapshotUploadMetadata } from './protocol.ts'\nimport { toPackageName } from './resolveConfig.ts'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\nconst UPLOAD_TIMEOUT_MS = 120_000\n\n// Plugins whose output a snapshot carries without depending on the plugin package.\nconst BUNDLED_DEPENDENCIES = ['@kubb/plugin-barrel']\n\ntype SnapshotFiles = Record<string, string>\ntype SnapshotPackage = { name: string; version: string; peerDependencies: Record<string, string> }\n\n/**\n * Maps a generated file to its path in the package, from its `src`/`dist` segment on, without `..` parts that could escape it.\n */\nfunction packagePath(filePath: string): string {\n const normalized = filePath.replaceAll('\\\\', '/')\n const relativePath = normalized.match(/\\/(?:src|dist)\\/.*$/)?.[0] ?? normalized\n return relativePath\n .split('/')\n .filter((part) => part && part !== '.' && part !== '..')\n .join('/')\n}\n\n/**\n * Splits a tar path into the 100-byte USTAR `name` and the 155-byte `prefix`, and throws for a path that fits neither.\n */\nfunction splitEntryPath(path: string): { name: string; prefix: string } {\n if (Buffer.byteLength(path) <= 100) return { name: path, prefix: '' }\n for (let i = path.lastIndexOf('/'); i > 0; i = path.lastIndexOf('/', i - 1)) {\n const prefix = path.slice(0, i)\n const name = path.slice(i + 1)\n if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(name) <= 100) return { name, prefix }\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Snapshot path is too long for a tar entry: ${path}`,\n help: 'Shorten the output path or the generated file names.',\n })\n}\n\nfunction header(path: string, size: number): Buffer {\n const { name, prefix } = splitEntryPath(path)\n const value = Buffer.alloc(512)\n value.write(name)\n value.write('0000644\\0', 100)\n for (const offset of [108, 116, 265, 297]) value.write('0000000\\0', offset)\n value.write(`${size.toString(8).padStart(11, '0')}\\0`, 124)\n // npm's fixed mtime, so the same files always pack to the same integrity.\n value.write('03560116604\\0', 136)\n value.fill(32, 148, 156)\n value.write('0', 156)\n value.write('ustar\\0', 257)\n value.write('00', 263)\n value.write(prefix, 345)\n const checksum = value.reduce((sum, byte) => sum + byte, 0)\n value.write(`${checksum.toString(8).padStart(6, '0')}\\0 `, 148)\n return value\n}\n\n/**\n * Packs a generation's files into a gzipped, npm-installable tarball: a `package/` root with the\n * generated sources, a `tsdown`-built `dist/` (esm + cjs), and a `package.json` manifest.\n */\nexport async function createSnapshotPackage({ files, packageInfo }: { files: SnapshotFiles; packageInfo: SnapshotPackage }): Promise<Buffer> {\n const sources = new Map<string, { name: string; content: string }>()\n for (const [name, content] of Object.entries(files)) {\n const path = packagePath(name)\n const owner = sources.get(path)?.name\n if (owner)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Snapshot has two generated files that sanitize to the same path \"package/${path}\": \"${owner}\" and \"${name}\"`,\n help: 'Rename one of the generated files, for example with a plugin resolver.',\n })\n sources.set(path, { name, content })\n }\n const root = await mkdtemp(join(tmpdir(), 'kubb-snapshot-'))\n const dist = join(root, 'dist')\n\n try {\n await mkdir(dist)\n await Promise.all(\n [...sources].map(async ([path, { content }]) => {\n await writeRaw(join(root, path), content)\n }),\n )\n const entry = [...sources.keys()].filter((path) => /\\.(?:[cm]?[jt]sx?)$/.test(path)).map((path) => join(root, path))\n if (entry.length) {\n // Loaded on first use: tsdown is large, and most agent processes never pack a snapshot.\n const { build } = await import('tsdown')\n // `fixedExtension` emits the `.mjs`/`.cjs` the manifest names, whatever \"type\" the host's own package.json sets.\n await build({\n entry,\n outDir: dist,\n format: ['esm', 'cjs'],\n dts: false,\n sourcemap: false,\n unbundle: true,\n report: false,\n logLevel: 'silent',\n fixedExtension: true,\n })\n }\n const built = await fsStorage().readKeys(dist)\n // Only `@kubb/plugin-barrel` produces a `dist/index.*` for `main`, `module`, and `exports['.']` to name.\n const hasBarrel = built.includes('index.mjs') && built.includes('index.cjs')\n const manifest = {\n ...packageInfo,\n type: 'module',\n ...(hasBarrel ? { main: './dist/index.cjs', module: './dist/index.mjs' } : {}),\n // `exports` denies any subpath it does not list, so the wildcard keeps each generated file importable.\n exports: {\n ...(hasBarrel ? { '.': { import: './dist/index.mjs', require: './dist/index.cjs' } } : {}),\n './*': { import: './dist/*.mjs', require: './dist/*.cjs' },\n },\n }\n const entries = new Map<string, string>([\n ['package.json', JSON.stringify(manifest, null, 2)],\n ...[...sources].map(([path, { content }]) => [path, content] as const),\n ...(await Promise.all(built.map(async (key) => [`dist/${key}`, await read(join(dist, key))] as const))),\n ])\n const chunks = [...entries].flatMap(([path, content]) => {\n const bytes = Buffer.from(content)\n return [header(`package/${path}`, bytes.length), bytes, Buffer.alloc((512 - (bytes.length % 512)) % 512)]\n })\n return gzipSync(Buffer.concat([...chunks, Buffer.alloc(1024)]))\n } finally {\n await rm(root, { recursive: true, force: true })\n }\n}\n\ntype CreateSnapshotOptions = Omit<SnapshotUploadMetadata, 'hashes' | 'peerDependencies'> & {\n studioUrl?: string\n /**\n * Organization CI API key, sent as `x-api-key`.\n */\n apiKey: string\n /**\n * The project's Kubb config, generated like `kubb generate`: formatter, linter, and `output.postGenerate` included.\n */\n config: Config\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n}\n\n/**\n * Generates the project, packs it as an npm tarball, and publishes it to Studio in one `POST /api/snapshots` request.\n *\n * @example\n * ```ts\n * const { url } = await createSnapshot({ apiKey: process.env.KUBB_TOKEN!, config, id: 'gh:123:pr-4', name: 'acme/api#4', packageName: '@acme/api', version: '1.0.0' })\n * ```\n */\nexport async function createSnapshot({\n studioUrl = defaultStudioUrl,\n apiKey,\n config,\n hooks,\n signal,\n ...metadata\n}: CreateSnapshotOptions): Promise<PublishedSnapshot> {\n const url = secureUrl({ studioUrl, path: '/api/snapshots' })\n const generated = await generate({ config: { ...config, storage: fsStorage() }, hooks, signal, allowExec: true })\n const files = Object.fromEntries(\n await Promise.all(\n [...generated.paths].map(async (path) => {\n const content = await generated.storage.readItem(resolve(generated.root, path))\n if (content === null)\n throw new Diagnostics.Error({\n code: Diagnostics.code.internalError,\n severity: 'error',\n message: `The generation listed ${path} but did not keep its content`,\n })\n return [path, content] as const\n }),\n ),\n )\n const pluginNames = config.plugins.map((plugin) => resolveMeta(plugin).name)\n const installed = await readInstalledPackages({ root: config.root, packages: pluginNames.map(toPackageName), resolveFrom: ['kubb'] })\n // A third-party plugin is found by the manifest its package ships, as `@kubb/plugin-x` only names a built-in.\n const packageOf = (name: string) => installed.find(({ manifest }) => manifest?.kind === 'plugin' && manifest.name === name)?.package ?? toPackageName(name)\n const names = [...new Set(pluginNames.map(packageOf))]\n const peerDependencies = Object.fromEntries(installed.flatMap(({ package: name, version }) => (names.includes(name) && version ? [[name, version]] : [])))\n // The package would declare no version for a plugin that is not installed.\n const missing = names.filter((name) => !(name in peerDependencies) && !BUNDLED_DEPENDENCIES.includes(name))\n if (missing.length)\n throw new Diagnostics.Error({\n code: Diagnostics.code.missingDependency,\n severity: 'error',\n message: `Missing dependencies: ${missing.join(', ')}`,\n help: 'Install the listed plugin packages in the project.',\n })\n\n const bytes = await createSnapshotPackage({ files, packageInfo: { name: metadata.packageName, version: metadata.version, peerDependencies } })\n if (bytes.length > MAX_SNAPSHOT_BYTES) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `The snapshot is ${Math.ceil(bytes.length / 1024 / 1024)} MB, over the ${MAX_SNAPSHOT_BYTES / 1024 / 1024} MB limit`,\n help: 'Generate fewer files, for example with `include` or `exclude` on the plugins.',\n })\n }\n\n const hashes = Object.fromEntries(Object.entries(files).map(([path, content]) => [path, hashOf(content)]))\n const body = new FormData()\n body.set('metadata', JSON.stringify({ ...metadata, hashes, peerDependencies } satisfies SnapshotUploadMetadata))\n body.set('tarball', new Blob([new Uint8Array(bytes)], { type: 'application/gzip' }), 'snapshot.tgz')\n\n const timeout = AbortSignal.timeout(UPLOAD_TIMEOUT_MS)\n // A redirect would forward the CI key and tarball to wherever it points.\n const { ok, status, _data } = await ofetch.raw<{ snapshot?: PublishedSnapshot; message?: string; data?: { upgradeUrl?: string } }>(url.href, {\n method: 'POST',\n headers: { 'x-api-key': apiKey },\n body,\n redirect: 'error',\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n ignoreResponseError: true,\n })\n if (!ok) {\n const upgrade = _data?.data?.upgradeUrl ? ` Upgrade at ${_data.data.upgradeUrl}.` : ''\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio refused the snapshot (status ${status})${_data?.message ? `: ${_data.message}` : ''}.${upgrade}`,\n help: 'Check the API key and your plan, then try again.',\n })\n }\n if (!_data?.snapshot)\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio returned no snapshot (status ${status})`,\n help: 'Try again later.',\n })\n return _data.snapshot\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["readFile","resolve","writeFile","mkdir","dirname","relative","isAbsolute","createRequire","pathToFileURL","existsSync","isPackageName","Diagnostics","resolveMeta","path","Diagnostics","parseModule","parseExpression","detectCodeFormat","writeFile","structuredPatch","isAbsolute","relative","resolve","createHash","process","Diagnostics","createKubb","sep","fsStorage","randomUUID","ast","stripVTControlCharacters","generationEventTypes","Diagnostics","isPublicAddress","net","https","http","Transform","Readable","Diagnostics","fsStorage","path","RpcTarget","tmpdir","randomUUID","cacheStorage","rm","resolveCacheDir","Diagnostics","readInstalledPackages","kubbVersion","version","AgentMessage","mkdtemp","getInputKind","checkoutGitInput","AgentPermission","NodeWebSocket","AGENT_INSTANCE_HEADER","newWebSocketRpcSession","resolveMeta","process","Hookable","AGENT_SOCKET_PATH","AgentCloseCode","delay","hash","Diagnostics","delay","Diagnostics","mkdtemp","join","tmpdir","mkdir","fsStorage","gzipSync","rm","resolve","resolveMeta","readInstalledPackages","MAX_SNAPSHOT_BYTES"],"sources":["../../../internals/utils/src/casing.ts","../../../internals/utils/src/errors.ts","../../../internals/utils/src/runtime.ts","../../../internals/utils/src/fs.ts","../../../internals/utils/src/promise.ts","../../../internals/utils/src/time.ts","../package.json","../src/resolveConfig.ts","../src/configFile.ts","../src/diff.ts","../src/generations.ts","../src/generationEvents.ts","../src/publicFetch.ts","../src/url.ts","../src/connect.ts","../src/pair.ts","../src/snapshot.ts"],"sourcesContent":["type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","/**\n * Coerces an unknown thrown value to an `Error` instance.\n * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.\n *\n * @example\n * ```ts\n * try { ... } catch(err) {\n * throw new Error('Build failed', { cause: toError(err) })\n * }\n * ```\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value))\n}\n\n/**\n * Extracts a human-readable message from any thrown value.\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('oops')) // 'oops'\n * getErrorMessage('plain string') // 'plain string'\n * ```\n */\nexport function getErrorMessage(value: unknown): string {\n return value instanceof Error ? value.message : String(value)\n}\n\n/**\n * Returns `error` followed by every error in its `cause` chain, outermost first. Stops at a\n * non-`Error` cause or a cycle.\n *\n * @example\n * ```ts\n * getErrorChain(new Error('Config failed loading', { cause: new Error('boom') })).map((error) => error.message)\n * // ['Config failed loading', 'boom']\n * ```\n */\nexport function getErrorChain(error: unknown): Array<Error> {\n const chain: Array<Error> = []\n for (let current = error; current instanceof Error && !chain.includes(current); current = current.cause) {\n chain.push(current)\n }\n return chain\n}\n","// Bun polyfills `process.versions.node`, so detection keys off the globals instead.\nconst isBun = typeof Bun !== 'undefined'\nconst isDeno = 'Deno' in globalThis\n\n/**\n * The JavaScript runtime executing the current process: its name, version and whether it is Bun.\n *\n * @example\n * ```ts\n * runtime.name // 'bun' when run with `bun kubb`, 'node' otherwise\n * ```\n */\nexport const runtime = { isBun, ...detect() } as const\n\nfunction detect(): { name: 'bun' | 'deno' | 'node'; version: string } {\n if (isBun) return { name: 'bun', version: process.versions.bun ?? '' }\n if (isDeno) return { name: 'deno', version: (globalThis as { Deno?: { version?: { deno?: string } } }).Deno?.version?.deno ?? '' }\n return { name: 'node', version: process.versions?.node ?? '' }\n}\n","import { access, glob as globNode, mkdir, readFile, writeFile } from 'node:fs/promises'\n\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\n\nexport { existsSync } from 'node:fs'\nexport { mkdir, mkdtemp, rm } from 'node:fs/promises'\n\n/**\n * Resolves to `true` when the file or directory at `path` exists.\n * Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.\n *\n * @example\n * ```ts\n * if (await exists('./kubb.config.ts')) {\n * const content = await read('./kubb.config.ts')\n * }\n * ```\n */\nexport async function exists(path: string): Promise<boolean> {\n if (runtime.isBun) {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\n/**\n * Reads the file at `path` as a UTF-8 string.\n * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.\n *\n * @example\n * ```ts\n * const source = await read('./src/Pet.ts')\n * ```\n */\nexport async function read(path: string): Promise<string> {\n if (runtime.isBun) {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\ntype WriteOptions = {\n /**\n * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\n /**\n * When `true`, re-reads the file immediately after writing and throws if the\n * content does not match — useful for catching write failures on unreliable file systems.\n */\n sanity?: boolean\n}\n\n/**\n * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\n * Creates any missing parent directories automatically.\n * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.\n *\n * @example\n * ```ts\n * await write('./src/Pet.ts', source) // writes and returns the trimmed content plus a newline\n * await write('./src/Pet.ts', source) // null — file unchanged\n * await write('./src/Pet.ts', ' ') // null — empty content skipped\n * ```\n */\nexport async function write(path: string, data: string, options: WriteOptions = {}): Promise<string | null> {\n const trimmed = data.trim()\n if (trimmed === '') return null\n\n const content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n await writeRaw(resolved, content)\n\n if (options.sanity) {\n const savedData = await read(resolved)\n if (savedData !== content) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n return savedData\n }\n\n return content\n}\n\n/**\n * Writes UTF-8 content verbatim, including empty files and surrounding whitespace.\n * Uses Bun.write under Bun and creates missing parent directories under either runtime.\n *\n * @example\n * await writeRaw('./cache/output.ts', ' // keep these bytes\\n\\n')\n */\nexport async function writeRaw(path: string, content: string): Promise<void> {\n const resolved = resolve(path)\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return\n }\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n}\n\n/**\n * Lists non-hidden regular files below `directory` as relative POSIX paths, excluding directories and symlinks.\n * Uses Bun.Glob under Bun because its Node glob compatibility API lacks directory-entry support.\n *\n * @example\n * for await (const path of listFiles('./src')) console.log(path)\n */\nexport async function* listFiles(directory: string): AsyncGenerator<string> {\n const cwd = resolve(directory)\n if (runtime.isBun) {\n yield* new Bun.Glob('**/*').scan({ cwd, dot: false, onlyFiles: true, followSymlinks: false })\n return\n }\n for await (const entry of globNode('**/*', { cwd, withFileTypes: true })) {\n if (entry.isFile()) yield toPosixPath(relative(cwd, join(entry.parentPath, entry.name)))\n }\n}\n\n/**\n * Converts a filesystem path to use POSIX (`/`) separators.\n *\n * Most of the codebase compares and composes paths as strings (prefix matching, joining for\n * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated\n * paths, but on Windows it returns `\\`-separated paths, which breaks every such comparison.\n *\n * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the\n * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is\n * exercisable from POSIX CI.\n *\n * @example\n * toPosixPath('C:\\\\repo\\\\src\\\\pet.ts') // 'C:/repo/src/pet.ts'\n */\nexport function toPosixPath(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n\n/**\n * Strips the file extension from a path or file name.\n * Only removes the last `.ext` segment when the dot is not part of a directory name.\n *\n * @example\n * trimExtName('petStore.ts') // 'petStore'\n * trimExtName('/src/models/pet.ts') // '/src/models/pet'\n * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'\n * trimExtName('noExtension') // 'noExtension'\n */\nexport function trimExtName(text: string): string {\n const dotIndex = text.lastIndexOf('.')\n if (dotIndex > 0 && !text.includes('/', dotIndex)) {\n return text.slice(0, dotIndex)\n }\n return text\n}\n\n/**\n * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","/** A value that may already be resolved or still pending.\n *\n * @example\n * ```ts\n * function load(id: string): PossiblePromise<string> {\n * return cache.get(id) ?? fetchRemote(id)\n * }\n * ```\n */\nexport type PossiblePromise<T> = Promise<T> | T\n\ntype Store<TKey, TValue> = {\n has(key: TKey): boolean\n get(key: TKey): TValue | undefined\n set(key: TKey, value: TValue): unknown\n}\n\n/**\n * Wraps `factory` with a keyed cache backed by the provided store.\n *\n * Pass a `WeakMap` for object keys (results are GC-eligible when the key is\n * collected) or a `Map` for primitive keys. For multi-argument functions,\n * nest two `memoize` calls — the outer keyed by the first argument, the\n * inner (created once per outer miss) keyed by the second.\n *\n * Because the cache is owned by the caller, it can be shared, inspected, or\n * cleared independently of the memoized function.\n *\n * @example Single WeakMap key\n * ```ts\n * const cache = new WeakMap<SchemaNode, Set<string>>()\n * const getRefs = memoize(cache, (node) => collectRefs(node))\n * ```\n *\n * @example Single Map key (primitive)\n * ```ts\n * const cache = new Map<string, Resolver>()\n * const getResolver = memoize(cache, (name) => buildResolver(name))\n * ```\n *\n * @example Two-level (object + primitive)\n * ```ts\n * const outer = new WeakMap<Params[], Map<string, Params[]>>()\n * const fn = memoize(outer, (params) => memoize(new Map(), (key) => transform(params, key)))\n * fn(params)('camelcase')\n * ```\n */\nexport function memoize<TKey, TValue>(store: Store<TKey, TValue>, factory: (key: TKey) => TValue): (key: TKey) => TValue {\n return (key: TKey): TValue => {\n if (store.has(key)) return store.get(key)!\n const value = factory(key)\n store.set(key, value)\n return value\n }\n}\n\ntype ParallelOptions<TItem> = {\n /**\n * Items to work through, handed out in order.\n */\n items: ReadonlyArray<TItem>\n /**\n * How many items may be in flight at once.\n */\n limit: number\n /**\n * Runs once per item, with the item's position so a caller can report progress.\n */\n run(item: TItem, index: number): Promise<void>\n}\n\n/**\n * Runs `run` over every item with at most `limit` in flight. Workers share one iterator, so each\n * takes the next item the moment it frees up instead of waiting for a batch to drain.\n *\n * @example\n * ```ts\n * await inParallel({ items: files, limit: 50, run: (file) => storage.writeItem(file.path, file.source) })\n * ```\n */\nexport async function inParallel<TItem>({ items, limit, run }: ParallelOptions<TItem>): Promise<void> {\n const queue = items.entries()\n\n const worker = async (): Promise<void> => {\n for (const [index, item] of queue) await run(item, index)\n }\n\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n}\n","/**\n * Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.\n * Rounds to 2 decimal places for sub-millisecond precision without noise.\n *\n * @example\n * ```ts\n * const start = process.hrtime()\n * doWork()\n * getElapsedMs(start) // 42.35\n * ```\n */\nexport function getElapsedMs(hrStart: [number, number]): number {\n const [seconds, nanoseconds] = process.hrtime(hrStart)\n const ms = seconds * 1000 + nanoseconds / 1e6\n return Math.round(ms * 100) / 100\n}\n\n/**\n * Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).\n *\n * @example\n * ```ts\n * formatMs(250) // '250ms'\n * formatMs(1500) // '1.50s'\n * formatMs(90000) // '1m 30.0s'\n * ```\n */\nexport function formatMs(ms: number): string {\n if (ms >= 60000) {\n const mins = Math.floor(ms / 60000)\n const secs = ((ms % 60000) / 1000).toFixed(1)\n return `${mins}m ${secs}s`\n }\n\n if (ms >= 1000) {\n return `${(ms / 1000).toFixed(2)}s`\n }\n return `${Math.round(ms)}ms`\n}\n","","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { type Adapter, Diagnostics, type ExtensionKind, isPackageName, type Parser, type Plugin, resolveMeta } from '@kubb/core'\nimport { camelCase, isPathInside, toError } from '@internals/utils'\nimport type { InstalledExtensions, JSONKubbConfig, OptionValue } from './protocol.ts'\n\n/**\n * Turns the JSON config Studio sends back into live Kubb objects.\n *\n * A plugin or adapter instance carries closures (`parse`, `getImports`, ...) that cannot survive\n * JSON, so both sides pass options over the wire and the factory is re-invoked here with the merged\n * result. Only packages {@link isAllowedPlugin} accepts are resolved this way, never an arbitrary\n * module the payload names.\n */\n\n/**\n * Imports a package, falling back to how the user's project would resolve it.\n *\n * `import()` resolves from this file, so a linked or globally installed Studio (`pnpm link`,\n * `npm i -g`) only sees its own `node_modules` and misses the plugins installed next to the user's\n * config. The retry resolves from `process.cwd()` instead.\n */\nasync function importFromProject(packageName: string): Promise<Record<string, unknown>> {\n try {\n return await import(packageName)\n } catch {\n const require = createRequire(pathToFileURL(`${process.cwd()}/`))\n // `require.resolve` picks the package's `require` condition, so prefer the ESM build sitting\n // next to it. Loading the CJS copy would pull in a second `@kubb/core` instance.\n const resolved = require.resolve(packageName)\n const esm = resolved.replace(/\\.cjs$/, '.js')\n\n return await import(pathToFileURL(esm !== resolved && existsSync(esm) ? esm : resolved).href)\n }\n}\n\n/**\n * Strips the `@kubb/` scope from a plugin package name, matching the `name` convention Kubb\n * plugin factories use internally.\n *\n * @example\n * ```ts\n * toPluginName('@kubb/plugin-ts') // 'plugin-ts'\n * ```\n */\nfunction toPluginName(packageName: string): string {\n return packageName.split('/').pop() ?? packageName\n}\n\n/**\n * Adds the `@kubb/` scope a plugin's package carries but its `name` does not, the inverse of\n * {@link toPluginName}. A name outside the `plugin-` convention is left alone, so a third-party\n * plugin is not reported as one of Kubb's.\n *\n * @example\n * ```ts\n * toPackageName('plugin-ts') // '@kubb/plugin-ts'\n * toPackageName('@acme/my-plugin') // '@acme/my-plugin'\n * ```\n */\nexport function toPackageName(name: string): string {\n return name.startsWith('plugin-') ? `@kubb/${name}` : name\n}\n\n/**\n * The name Studio knows an extension by: the package of the installed extension whose manifest\n * `name` matches, otherwise its own `name`, so a plugin defined in the user's project is never\n * reported as a Kubb package that does not exist.\n *\n * @example\n * ```ts\n * toStudioName({ name: 'plugin-ts', extensions }) // '@kubb/plugin-ts'\n * toStudioName({ name: 'plugin-zod-operations', extensions }) // 'plugin-zod-operations', a local plugin\n * ```\n */\nexport function toStudioName({\n name,\n extensions = new Map(),\n kind = 'plugin',\n}: {\n name: string\n extensions?: InstalledExtensions\n kind?: ExtensionKind\n}): string {\n return [...extensions.values()].find(({ manifest }) => manifest.kind === kind && manifest.name === name)?.package ?? name\n}\n\n/**\n * Derives the conventional named export for a `@kubb/*` plugin package from its package name.\n *\n * @example\n * ```ts\n * toExportName('@kubb/plugin-react-query') // 'pluginReactQuery'\n * toExportName('@kubb/plugin-ts') // 'pluginTs'\n * ```\n */\nexport function toExportName(packageName: string): string {\n return camelCase(toPluginName(packageName))\n}\n\nconst KUBB_PLUGIN_SPECIFIER = /^@kubb\\/plugin-[\\w.-]+$/\n\n/**\n * Whether Studio may import `packageName` as a plugin: a `@kubb/plugin-*` package, or an installed\n * package whose `kubb-extension.json` has `kind: \"plugin\"`. A path, URL or arbitrary package is\n * refused before it can execute. `configFile.ts` applies the same rule before printing a plugin name.\n */\nexport function isAllowedPlugin({ packageName, extensions }: { packageName: string; extensions: InstalledExtensions }): boolean {\n if (!isPackageName(packageName)) return false\n return KUBB_PLUGIN_SPECIFIER.test(packageName) || extensions.get(packageName)?.manifest.kind === 'plugin'\n}\n\n/**\n * Dynamically imports an extension package and returns its factory. Callers check\n * {@link isAllowedPlugin} or derive the package from a disk instance first, so an arbitrary module\n * never reaches `import()`.\n *\n * Packages must be pre-installed in the Docker image at build time via the `KUBB_PACKAGES`\n * build ARG, no runtime installation is possible in the distroless container.\n *\n * Resolution order: the manifest's `export`, else the camelCase named export the package name\n * implies (e.g. `pluginTs`), then the default export.\n *\n * @throws if the package cannot be imported or exports no callable factory.\n */\nasync function loadFactory({\n packageName,\n extensions,\n kind = 'plugin',\n}: {\n packageName: string\n extensions: InstalledExtensions\n kind?: ExtensionKind\n}): Promise<(options: unknown) => unknown> {\n const label = { plugin: 'Plugin', adapter: 'Adapter', parser: 'Parser' }[kind]\n let mod: Record<string, unknown>\n try {\n mod = await importFromProject(packageName)\n } catch (cause) {\n throw new Diagnostics.Error({\n code: kind === 'plugin' ? Diagnostics.code.pluginNotFound : Diagnostics.code.unknown,\n severity: 'error',\n message: `${label} \"${packageName}\" could not be loaded. Make sure it is installed: \\`npm install ${packageName}\\``,\n cause: toError(cause),\n })\n }\n\n const manifestExport = extensions.get(packageName)?.manifest.export\n if (manifestExport) {\n if (typeof mod[manifestExport] === 'function') return mod[manifestExport] as (options: unknown) => unknown\n throw new Diagnostics.Error({\n code: Diagnostics.code.incompatibleExtension,\n severity: 'error',\n message: `${label} \"${packageName}\" does not export \"${manifestExport}\", the factory its kubb-extension.json names.`,\n help: 'Install a version of the plugin whose exports match its kubb-extension.json.',\n })\n }\n\n const exportName = toExportName(packageName)\n if (typeof mod[exportName] === 'function') return mod[exportName] as (options: unknown) => unknown\n if (typeof mod['default'] === 'function') return mod['default'] as (options: unknown) => unknown\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.incompatibleExtension,\n severity: 'error',\n message: `${label} \"${packageName}\" does not export a callable factory. Tried the named export \"${exportName}\" and \"default\".`,\n help: 'Install a Kubb plugin package that exports its factory.',\n })\n}\n\n/**\n * Resolves each plugin entry by dynamically importing its package and calling its factory with the\n * provided options. Only packages {@link isAllowedPlugin} accepts are loaded.\n *\n * @example\n * ```ts\n * const plugins = await resolvePlugins({\n * plugins: [\n * { name: '@kubb/plugin-react-query', options: { output: { path: './hooks' } } },\n * { name: '@kubb/plugin-ts', options: { output: { path: './types' } } },\n * ],\n * })\n * ```\n */\nexport async function resolvePlugins({\n plugins,\n extensions = new Map(),\n}: {\n plugins: NonNullable<JSONKubbConfig['plugins']>\n extensions?: InstalledExtensions\n}): Promise<Array<Plugin>> {\n return Promise.all(\n plugins.map(async ({ name, options }) => {\n if (!isAllowedPlugin({ packageName: name, extensions })) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.pluginNotFound,\n severity: 'error',\n message: `Plugin \"${name}\" is not an installed Kubb plugin. Studio loads @kubb/plugin-* packages and installed packages that ship a kubb-extension.json with kind \"plugin\".`,\n })\n }\n const factory = await loadFactory({ packageName: name, extensions })\n return factory(options ?? {}) as Plugin\n }),\n )\n}\n\n/**\n * Keys that reach an object's prototype when assigned. Never read from or written into options.\n */\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\n\n/**\n * Whether `key` can be used as an option key without touching an object's prototype.\n */\nexport function isSafeKey(key: string): boolean {\n return !UNSAFE_KEYS.has(key)\n}\n\n/**\n * A JSON copy of plugin or adapter options: functions and other values JSON cannot hold are left\n * out, so nothing callable crosses the socket. Options that cannot be copied at all, such as a\n * circular structure, come back empty.\n *\n * @example\n * ```ts\n * toJSONOptions({ output: { path: 'types' }, group: { name: () => 'x' } }) // { output: { path: 'types' }, group: {} }\n * ```\n */\nexport function toJSONOptions(options: unknown): Record<string, unknown> {\n try {\n const copy = JSON.parse(\n JSON.stringify(options ?? {}, (key, value: unknown) => (isSafeKey(key) && typeof value !== 'bigint' ? value : undefined)),\n ) as unknown\n return isPlainObject(copy) ? copy : {}\n } catch {\n return {}\n }\n}\n\n/**\n * Whether `value` is an object literal or a null-prototype object, not an array or class instance.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === null || prototype === Object.prototype\n}\n\n/**\n * Whether `value` survives a JSON round trip, so it can be printed into a config file as a literal.\n * A function, `undefined`, a non-finite number or a class instance comes back from Studio as a\n * lossy copy, so an edit carrying one is refused rather than written into the user's source.\n */\nexport function isOptionValue(value: unknown): value is OptionValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true\n if (typeof value === 'number') return Number.isFinite(value)\n if (Array.isArray(value)) return value.every(isOptionValue)\n if (isPlainObject(value)) return Object.entries(value).every(([key, entry]) => isSafeKey(key) && isOptionValue(entry))\n\n return false\n}\n\n/**\n * Deep-merges Studio's options over the disk options, with Studio taking priority, except where the\n * disk value cannot survive JSON. Studio only ever saw a lossy copy of such a value, so the disk\n * value is kept rather than replaced by what Studio echoes back. Plain objects merge key by key, so\n * Studio can still change a literal that sits next to a function (e.g. `group.type` beside `group.name`).\n *\n * @example\n * ```ts\n * mergeOptions({ macros: [camelCaseMacro], syntaxType: 'type' }, { macros: [{ name: 'camelCase' }], syntaxType: 'interface' })\n * // { macros: [camelCaseMacro], syntaxType: 'interface' }\n * mergeOptions({ emptySchemaType: 'any' }, { emptySchemaType: null }) // {}\n * ```\n */\nexport function mergeOptions(disk: Record<string, unknown>, studio: Record<string, unknown>): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...disk }\n\n for (const [key, value] of Object.entries(studio)) {\n if (!isSafeKey(key)) continue\n const current = disk[key]\n\n // A `null` from Studio is a field set back to \"unset\", so the factory default applies again.\n if (value === null) {\n if (current === undefined || isOptionValue(current)) delete merged[key]\n continue\n }\n\n if (isPlainObject(current) && isPlainObject(value)) {\n merged[key] = mergeOptions(current, value)\n continue\n }\n if (current !== undefined && !isOptionValue(current)) continue\n\n merged[key] = value\n }\n\n return merged\n}\n\n/**\n * Merges studio plugin options with disk config plugins.\n * Studio takes priority: options from studio win over disk (except values only the disk config\n * can express, see {@link mergeOptions}), and a plugin Studio explicitly\n * disabled is dropped even when the disk config still lists it. Disk plugins without a studio\n * counterpart are kept as-is. Studio plugins not present on disk are appended.\n *\n * For plugins present in both configs, the plugin is re-instantiated with merged options\n * so that all internal closures correctly reference the merged values.\n */\nexport async function mergePlugins({\n diskPlugins,\n studioPlugins,\n extensions = new Map(),\n}: {\n diskPlugins: Array<Plugin> | undefined\n studioPlugins: JSONKubbConfig['plugins'] | undefined\n extensions?: InstalledExtensions\n}): Promise<Array<Plugin> | undefined> {\n const pluginNameOf = (packageName: string) => extensions.get(packageName)?.manifest.name ?? toPluginName(packageName)\n // Matched on the package's base name rather than by instantiating first. Every Kubb plugin\n // factory returns exactly that (`@kubb/plugin-ts` → `plugin-ts`), enforced by the `satisfies` on\n // each factory's name.\n const disabledNames = new Set((studioPlugins ?? []).filter((entry) => entry.disabled).map((entry) => pluginNameOf(entry.name)))\n const activeDiskPlugins = disabledNames.size ? diskPlugins?.filter((plugin) => !disabledNames.has(resolveMeta(plugin).name)) : diskPlugins\n const activeStudioPlugins = studioPlugins?.filter((entry) => !entry.disabled)\n\n if (!activeDiskPlugins && !activeStudioPlugins?.length) return undefined\n if (!activeStudioPlugins?.length) return activeDiskPlugins\n\n if (!activeDiskPlugins) return resolvePlugins({ plugins: activeStudioPlugins, extensions })\n\n const studioEntryByName = new Map(activeStudioPlugins.map((entry) => [pluginNameOf(entry.name), entry] as const))\n const diskNames = new Set(activeDiskPlugins.map((plugin) => plugin.name))\n\n // Each plugin is instantiated once, with its final options. Resolving the whole payload first\n // just to read the names would build every overlapping plugin twice and discard the first.\n const merged = await Promise.all(\n activeDiskPlugins.map(async (diskPlugin) => {\n const studioEntry = studioEntryByName.get(resolveMeta(diskPlugin).name)\n if (!studioEntry) return diskPlugin\n\n // Disk as base, studio overrides, then re-instantiate so the plugin's closures reference the\n // merged values. A plugin that never sets `options` (e.g. `@kubb/plugin-barrel`) leaves\n // `diskPlugin.options` undefined.\n const diskOptions = (diskPlugin.options as Record<string, unknown>) ?? {}\n const options = mergeOptions(diskOptions, (studioEntry.options as Record<string, unknown>) ?? {})\n // A plugin defined in the user's project has no package to re-instantiate it from. Studio\n // echoing its options back unchanged is fine, any real change can only be made on disk.\n const unchanged = JSON.stringify(toJSONOptions(options)) === JSON.stringify(toJSONOptions(diskOptions))\n const [resolved] = await resolvePlugins({ plugins: [{ name: studioEntry.name, options }], extensions }).catch((cause: unknown) => {\n if (unchanged) return [diskPlugin]\n throw new Diagnostics.Error({\n code: Diagnostics.code.pluginNotFound,\n severity: 'error',\n message: `Plugin \"${diskPlugin.name}\" is not an installed @kubb/plugin-* package or Kubb extension, so Studio cannot change its options. Edit it in the config file, or only enable or disable it from Studio.`,\n cause: toError(cause),\n })\n })\n\n return resolved ?? diskPlugin\n }),\n )\n\n const studioOnly = activeStudioPlugins.filter((entry) => !diskNames.has(pluginNameOf(entry.name)))\n\n return [...merged, ...(await resolvePlugins({ plugins: studioOnly, extensions }))]\n}\n\n/**\n * Throws `KUBB_PATH_TRAVERSAL` when a plugin would write outside the config's output folder to a path\n * the disk config does not set. Studio can change `output.path`, also inside `override`, and add\n * plugins, so without this check any member of the Studio organization could write any file the agent\n * can reach, including `node_modules` code the next run imports. A path from the config file stays\n * allowed, since a monorepo may write outside its root.\n */\nexport function assertOutputPaths({\n plugins,\n diskPlugins,\n root,\n outputPath,\n}: {\n plugins: Array<Plugin>\n diskPlugins: Array<Plugin>\n root: string\n outputPath: string\n}): void {\n const base = path.resolve(root, outputPath)\n const targetsOf = (plugin: Plugin): Array<string> => {\n const { output, override } = (plugin.options ?? {}) as { output?: { path?: unknown }; override?: Array<{ options?: { output?: { path?: unknown } } }> }\n const outputs = [output, ...(Array.isArray(override) ? override.map((entry) => entry?.options?.output) : [])]\n return outputs.flatMap((entry) => (typeof entry?.path === 'string' ? [path.resolve(base, entry.path)] : []))\n }\n const diskTargets = new Set(diskPlugins.flatMap(targetsOf))\n\n for (const plugin of plugins) {\n const target = targetsOf(plugin).find((resolved) => !diskTargets.has(resolved) && !isPathInside(resolved, base))\n if (!target) continue\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.pathTraversal,\n severity: 'error',\n message: `Plugin \"${plugin.name}\" would write to \"${target}\", outside the output folder \"${base}\". Studio can only set an output path inside it.`,\n help: 'Choose an output path inside the output folder, or set this path in the config file.',\n location: { kind: 'config' },\n plugin: plugin.name,\n })\n }\n}\n\n/**\n * Re-invokes the factory behind a disk adapter or parser with Studio's options merged over its own.\n * An instance carries live functions (`parse`, `print`, ...) that cannot survive JSON, so Studio's\n * options are a patch, not a replacement, and the factory is found from the disk instance itself: the\n * installed extension whose manifest names it, or the `@kubb/<kind>-<name>` package for a built-in\n * one. Throws when no factory resolves, as `mergePlugins` does, so an override Studio sent is never\n * dropped without a word. An extension without a manifest, such as `parserTsx`, has no options in\n * Studio, so Studio never sends one for it.\n */\nasync function rebuildExtension<T extends Adapter | Parser>({\n disk,\n studioOptions,\n kind,\n extensions,\n}: {\n disk: T\n studioOptions: object | undefined\n kind: ExtensionKind\n extensions: InstalledExtensions\n}): Promise<T> {\n if (!studioOptions || !Object.keys(studioOptions).length) return disk\n\n const { name } = resolveMeta(disk)\n const installed = [...extensions.values()].find(({ manifest }) => manifest.kind === kind && manifest.name === name)\n const packageName = installed?.package ?? `@kubb/${kind}-${name}`\n const factory = await loadFactory({ packageName, extensions, kind }).catch((cause: unknown) => {\n throw new Diagnostics.Error({\n code: kind === 'plugin' ? Diagnostics.code.pluginNotFound : Diagnostics.code.unknown,\n severity: 'error',\n message: `The ${kind} \"${name}\" is not an installed Kubb extension, so Studio cannot change its options. Edit it in the config file.`,\n cause: toError(cause),\n })\n })\n\n return factory(mergeOptions((disk.options as Record<string, unknown>) ?? {}, studioOptions as Record<string, unknown>)) as T\n}\n\n/**\n * Merges Studio-provided adapter option overrides into the disk config's adapter, see {@link rebuildExtension}.\n */\nexport async function mergeAdapter(diskAdapter: Adapter | undefined, studioOptions: object | undefined, extensions: InstalledExtensions = new Map()) {\n if (!diskAdapter) return diskAdapter\n\n return rebuildExtension({ disk: diskAdapter, studioOptions, kind: 'adapter', extensions })\n}\n\n/**\n * Merges Studio-provided parser option overrides into the disk config's parsers, matched by the name\n * Studio knows each parser by, see {@link rebuildExtension}. Parsers Studio does not name are kept as is.\n */\nexport async function mergeParsers({\n diskParsers,\n studioParsers,\n extensions = new Map(),\n}: {\n diskParsers: Array<Parser>\n studioParsers: JSONKubbConfig['parsers'] | undefined\n extensions?: InstalledExtensions\n}): Promise<Array<Parser>> {\n if (!studioParsers?.length) return diskParsers\n\n const studioOptions = new Map(studioParsers.map((entry) => [entry.name, entry.options]))\n\n return Promise.all(\n diskParsers.map((parser) =>\n rebuildExtension({\n disk: parser,\n studioOptions: studioOptions.get(toStudioName({ name: resolveMeta(parser).name, extensions, kind: 'parser' })),\n kind: 'parser',\n extensions,\n }),\n ),\n )\n}\n","import { writeFile } from 'node:fs/promises'\nimport { Diagnostics, type ExtensionKind } from '@kubb/core'\nimport { getErrorMessage, read } from '@internals/utils'\nimport { detectCodeFormat, parseExpression, parseModule } from 'magicast'\nimport type { ASTNode, ProxifiedModule } from 'magicast'\nimport type { ConfigEdit, ConfigEditOutcome, ConfigFileView, ConfigView, InstalledExtensions, OptionValue, PluginView } from './protocol.ts'\nimport { isAllowedPlugin, isOptionValue, isSafeKey, toExportName } from './resolveConfig.ts'\n\n/**\n * A valid JavaScript identifier, so an import name can only ever print as `import { name } from`,\n * never as source that breaks out of the import statement.\n */\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/\n\n/**\n * The marker line a `disable-plugin` writes above the block it comments out. It carries the block's\n * line count, so `enable-plugin` restores exactly those lines and not whatever comments follow.\n */\nconst DISABLED_MARKER = /^\\/\\/ kubb:disabled (.+)\\s+(\\d+)$/\n\nconst OPERATIONS = new Set<string>(['set', 'remove', 'add-plugin', 'disable-plugin', 'enable-plugin'])\nconst KINDS = new Set<string>(['plugin', 'adapter', 'parser'])\n\ntype ObjectNode = Extract<ASTNode, { type: 'ObjectExpression' }>\ntype ArrayNode = Extract<ASTNode, { type: 'ArrayExpression' }>\ntype CallNode = Extract<ASTNode, { type: 'CallExpression' }>\n/** A member of an object literal: `key: value`, a method or accessor, or a `...spread`. */\ntype ObjectMember = ObjectNode['properties'][number]\n/** How the file exports its config, which decides how an import for a new plugin is written. */\ntype ModuleKind = 'esm' | 'cjs'\ntype Quote = `'` | `\"`\n/** What one edit did: the rewritten source, or why it was refused. */\ntype EditResult = { source: string } | { reason: string }\ntype ParsedConfig = { mod: ProxifiedModule; configs: Array<ObjectNode>; kind: ModuleKind }\n\n/**\n * Why an edit from Studio cannot be applied as sent, checked before anything reads its fields.\n * The edit crossed the wire, so its declared type is a promise the sender may not have kept.\n */\nfunction invalidEdit(edit: ConfigEdit): string | undefined {\n const { operation, plugin, config, path, kind } = (typeof edit === 'object' && edit !== null ? edit : {}) as Record<string, unknown>\n\n if (typeof operation !== 'string' || !OPERATIONS.has(operation)) return `unknown operation ${JSON.stringify(operation)}`\n if (typeof plugin !== 'string' || !plugin) return 'the edit names no plugin'\n if (kind !== undefined && (typeof kind !== 'string' || !KINDS.has(kind))) return `unknown kind ${JSON.stringify(kind)}`\n if (kind !== undefined && operation !== 'set' && operation !== 'remove') return `${operation} edits the plugins array, so it takes no kind`\n if (config !== undefined && typeof config !== 'string' && !Number.isSafeInteger(config)) return 'config must name an entry or give its index'\n if (operation === 'set' || operation === 'remove') {\n if (!Array.isArray(path) || !path.every((key) => typeof key === 'string' && key)) return 'path must be a list of option names'\n if (!path.length) return 'no option path given'\n const unsafe = path.find((key: string) => !isSafeKey(key))\n if (unsafe !== undefined) return `${unsafe} cannot be used as an option name`\n }\n return undefined\n}\n\n/** Where a node sits in the source text. */\nfunction rangeOf(node: { start?: number | null; end?: number | null }): { start: number; end: number } {\n if (typeof node.start !== 'number' || typeof node.end !== 'number')\n throw new Diagnostics.Error({\n code: Diagnostics.code.internalError,\n severity: 'error',\n message: 'the config file could not be mapped back to its source text',\n })\n return { start: node.start, end: node.end }\n}\n\n/** `source` with the text between `start` and `end` replaced by `text`. */\nfunction splice(source: string, start: number, end: number, text = ''): string {\n return `${source.slice(0, start)}${text}${source.slice(end)}`\n}\n\nfunction bodyOf(mod: ProxifiedModule): Array<ASTNode> {\n return mod.$ast.type === 'Program' ? mod.$ast.body : []\n}\n\n/**\n * Steps through a config's wrappers to the object literal underneath: a `satisfies`/`as`\n * assertion, a `() => ...` factory, or a factory whose block body returns the config.\n */\nfunction unwrap(node: ASTNode | null | undefined): ASTNode | undefined {\n if (!node) return undefined\n if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression') return unwrap(node.expression)\n if (node.type !== 'ArrowFunctionExpression' && node.type !== 'FunctionExpression') return node\n if (node.body.type !== 'BlockStatement') return unwrap(node.body)\n\n const returned = node.body.body.find((statement): statement is Extract<ASTNode, { type: 'ReturnStatement' }> => statement.type === 'ReturnStatement')\n return unwrap(returned?.argument)\n}\n\nfunction isModuleExports(node: ASTNode): boolean {\n return (\n node.type === 'MemberExpression' &&\n !node.computed &&\n node.object.type === 'Identifier' &&\n node.object.name === 'module' &&\n node.property.type === 'Identifier' &&\n node.property.name === 'exports'\n )\n}\n\n/**\n * Parses `source` and finds every config object in `export default defineConfig(...)` or\n * `module.exports = defineConfig(...)`, or why the file is unmanaged. An array export gets one entry\n * per element, matching a numeric `config` index.\n *\n * Walks the parsed AST rather than magicast's proxies, which throw on node types they cannot\n * cast, most of what an unmanaged config file is made of.\n */\nfunction parseConfigs(source: string): ParsedConfig | { reason: string } {\n let mod: ProxifiedModule\n try {\n mod = parseModule(source)\n } catch {\n return { reason: 'the config file could not be parsed' }\n }\n\n let exported: ASTNode | null | undefined\n let kind: ModuleKind = 'esm'\n for (const node of bodyOf(mod)) {\n if (node.type === 'ExportDefaultDeclaration') {\n exported = node.declaration\n break\n }\n if (node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression' && isModuleExports(node.expression.left)) {\n exported = node.expression.right\n kind = 'cjs'\n break\n }\n }\n\n const value = unwrap(exported)\n if (!value) return { reason: 'no `export default` or `module.exports` found' }\n if (value.type !== 'CallExpression' || value.callee.type !== 'Identifier' || value.callee.name !== 'defineConfig') {\n return { reason: 'the exported config is not a defineConfig(...) call' }\n }\n\n const argument = unwrap(value.arguments[0])\n if (!argument) return { reason: 'defineConfig(...) was called without a config' }\n\n const entries = argument.type === 'ArrayExpression' ? argument.elements.map((element) => unwrap(element)) : [argument]\n const configs = entries.filter((entry): entry is ObjectNode => entry?.type === 'ObjectExpression')\n if (configs.length !== entries.length) return { reason: 'config is not an object literal' }\n\n return { mod, configs, kind }\n}\n\n/** The name of a `key` or `'key'` member, `undefined` for a spread or a computed key. */\nfunction memberKey(entry: ObjectMember): string | undefined {\n if (entry.type === 'SpreadElement' || entry.computed) return undefined\n return entry.key.type === 'Identifier' ? entry.key.name : entry.key.type === 'StringLiteral' ? entry.key.value : undefined\n}\n\n/** The member named `key`. The last one wins when the key repeats, as it does when the object is evaluated. */\nfunction findMember(node: ObjectNode, key: string): { member: ObjectMember; index: number } | undefined {\n const index = node.properties.findLastIndex((entry) => memberKey(entry) === key)\n return index === -1 ? undefined : { member: node.properties[index]!, index }\n}\n\n/** The value node of a member. A method or accessor is its own value: it is code, never a literal. */\nfunction property(node: ObjectNode, key: string): ASTNode | undefined {\n const member = findMember(node, key)?.member\n return member?.type === 'ObjectProperty' ? member.value : member\n}\n\nfunction configName(config: ObjectNode): string | undefined {\n const name = property(config, 'name')\n return name?.type === 'StringLiteral' ? name.value : undefined\n}\n\n/** Whether a `...spread` after the member at `index` could override it. */\nfunction isShadowed(node: ObjectNode, index: number): boolean {\n return node.properties.slice(index + 1).some((entry) => entry.type === 'SpreadElement')\n}\n\n/**\n * Reads a literal node's value: a primitive, or an object/array built only from primitives.\n * `undefined` for anything else, so a caller can use this both to read a value and to check\n * whether a node is a literal at all.\n */\nfunction readLiteral(node: ASTNode | null | undefined): OptionValue | undefined {\n switch (node?.type) {\n case 'StringLiteral':\n case 'NumericLiteral':\n case 'BooleanLiteral':\n return node.value\n case 'NullLiteral':\n return null\n case 'TemplateLiteral':\n return node.expressions.length ? undefined : (node.quasis[0]?.value.cooked ?? '')\n case 'UnaryExpression': {\n const value = readLiteral(node.argument)\n if (typeof value !== 'number') return undefined\n return node.operator === '-' ? -value : node.operator === '+' ? value : undefined\n }\n case 'ArrayExpression': {\n const values = node.elements.map((element) => readLiteral(element))\n return values.every((value) => value !== undefined) ? values : undefined\n }\n case 'ObjectExpression': {\n const entries: Record<string, OptionValue> = {}\n for (const entry of node.properties) {\n if (entry.type !== 'ObjectProperty') return undefined\n const key = memberKey(entry)\n const value = readLiteral(entry.value)\n // A `__proto__` key would replace the object's prototype instead of adding an entry.\n if (key === undefined || !isSafeKey(key) || value === undefined) return undefined\n entries[key] = value\n }\n return entries\n }\n }\n return undefined\n}\n\n/** Writes `value` as a single-line literal with the file's quote style. */\nfunction printValue(value: OptionValue, quote: Quote): string {\n if (typeof value === 'string') {\n // JSON's escaping covers every character that could end the literal or the line.\n const escaped = JSON.stringify(value).slice(1, -1)\n return quote === `\"` ? `\"${escaped}\"` : `'${escaped.replaceAll(`\\\\\"`, `\"`).replaceAll(`'`, `\\\\'`)}'`\n }\n if (value === null || typeof value !== 'object') return String(value)\n if (Array.isArray(value)) return `[${value.map((item) => printValue(item, quote)).join(', ')}]`\n\n const entries = Object.entries(value)\n return entries.length ? `{ ${entries.map(([key, item]) => `${printKey(key, quote)}: ${printValue(item, quote)}`).join(', ')} }` : '{}'\n}\n\n/** An object key as source text: bare when it is an identifier, quoted otherwise. */\nfunction printKey(key: string, quote: Quote): string {\n return IDENTIFIER.test(key) ? key : printValue(key, quote)\n}\n\n/** `value` wrapped in one object per key of `path`: `nest(['enum', 'type'], 'enum')` is `{ enum: { type: 'enum' } }`. */\nfunction nest(path: Array<string>, value: OptionValue): OptionValue {\n return path.reduceRight<OptionValue>((inner, key) => ({ [key]: inner }), value)\n}\n\n/**\n * Adds `text` as the last item of an object or array literal, following its layout: on a line of\n * its own with the last item's indentation when the literal spans lines, inline otherwise.\n */\nfunction insertItem(source: string, container: ObjectNode | ArrayNode, text: string): string {\n const { start, end } = rangeOf(container)\n const items: Array<ASTNode | null> = container.type === 'ObjectExpression' ? container.properties : container.elements\n const last = items.filter((item): item is ASTNode => item !== null).at(-1)\n\n if (!last) {\n const inner = source.slice(start + 1, end - 1)\n // A comment inside the empty literal stays, after the new item.\n if (inner.trim()) return splice(source, start + 1, start + 1, /^\\s/.test(inner) ? `${text},` : `${text}, `)\n return splice(source, start, end, container.type === 'ObjectExpression' ? `{ ${text} }` : `[${text}]`)\n }\n\n const lastRange = rangeOf(last)\n const between = source.slice(lastRange.end, end - 1)\n // The closing bracket shares the last item's line: add the item inline.\n if (!between.includes('\\n')) return splice(source, lastRange.end, lastRange.end, `, ${text}`)\n\n const lineStart = source.lastIndexOf('\\n', lastRange.start - 1) + 1\n const indent = source.slice(lineStart).match(/^[ \\t]*/)?.[0] ?? ''\n // After the last item's comma and any comment on its line, so neither moves. `between` holds a\n // newline, so one always follows.\n const lineEnd = source.indexOf('\\n', lastRange.end)\n const comma = /^\\s*,/.test(between)\n\n return `${source.slice(0, lastRange.end)}${comma ? '' : ','}${source.slice(lastRange.end, lineEnd)}\\n${indent}${text}${comma ? ',' : ''}${source.slice(lineEnd)}`\n}\n\n/** Drops the member at `index` from an object literal, with its own lines when it sits on them alone. */\nfunction removeMember(source: string, node: ObjectNode, index: number): string {\n if (node.properties.length === 1) return splice(source, rangeOf(node).start, rangeOf(node).end, '{}')\n\n const { start, end } = rangeOf(node.properties[index]!)\n const lineStart = source.lastIndexOf('\\n', start - 1) + 1\n const nextNewline = source.indexOf('\\n', end)\n const lineEnd = nextNewline === -1 ? source.length : nextNewline\n if (!source.slice(lineStart, start).trim() && /^\\s*,?\\s*(\\/\\/.*)?$/.test(source.slice(end, lineEnd))) {\n return splice(source, lineStart, Math.min(lineEnd + 1, source.length))\n }\n\n const next = node.properties[index + 1]\n return next ? splice(source, start, rangeOf(next).start) : splice(source, rangeOf(node.properties[index - 1]!).end, end)\n}\n\n/** The module a `require('...')` call loads, when `node` is one. */\nfunction requiredModule(node: ASTNode | null | undefined): string | undefined {\n if (node?.type !== 'CallExpression' || node.callee.type !== 'Identifier' || node.callee.name !== 'require') return undefined\n const [argument] = node.arguments\n return argument?.type === 'StringLiteral' ? argument.value : undefined\n}\n\n/** Where an identifier the file imports comes from: its module and the name it is exported under. */\ntype Import = { from: string; exported: string }\n\n/** Maps each identifier the file imports, through `import { x } from` or `const { x } = require(...)`, to its module. */\nfunction importedFrom(mod: ProxifiedModule): Map<string, Import> {\n const imports = new Map<string, Import>()\n\n for (const statement of bodyOf(mod)) {\n if (statement.type === 'ImportDeclaration') {\n for (const specifier of statement.specifiers) {\n // A default or namespace import has no exported name of its own, so its local name stands in.\n const imported = specifier.type === 'ImportSpecifier' ? specifier.imported : specifier.local\n imports.set(specifier.local.name, { from: statement.source.value, exported: imported.type === 'Identifier' ? imported.name : imported.value })\n }\n continue\n }\n if (statement.type !== 'VariableDeclaration') continue\n for (const declarator of statement.declarations) {\n const from = requiredModule(declarator.init)\n if (from === undefined || declarator.id.type !== 'ObjectPattern') continue\n for (const entry of declarator.id.properties) {\n if (entry.type === 'ObjectProperty' && entry.value.type === 'Identifier') {\n imports.set(entry.value.name, { from, exported: memberKey(entry) ?? entry.value.name })\n }\n }\n }\n }\n return imports\n}\n\n/**\n * Every factory call of one kind that resolves to an import: the `pluginX(...)` elements of the\n * `plugins` array, the `adapter` value, or the elements of the `parsers` array.\n */\nfunction factoryCalls(\n mod: ProxifiedModule,\n config: ObjectNode,\n kind: ExtensionKind = 'plugin',\n): Array<{ importName: string; exportName: string; packageName: string; call: CallNode }> {\n const node = property(config, kind === 'adapter' ? 'adapter' : `${kind}s`)\n const elements = kind === 'adapter' ? [node] : node?.type === 'ArrayExpression' ? node.elements : []\n\n const imports = importedFrom(mod)\n return elements.flatMap((element) => {\n if (element?.type !== 'CallExpression' || element.callee.type !== 'Identifier') return []\n const imported = imports.get(element.callee.name)\n return imported ? [{ importName: element.callee.name, exportName: imported.exported, packageName: imported.from, call: element }] : []\n })\n}\n\n/**\n * The blocks a previous `disable-plugin` commented out of this config, read from the marker lines\n * since a commented-out call is no longer a node. `code` holds the block's lines as they were.\n */\nfunction disabledBlocks(source: string, config: ObjectNode): Array<{ packageName: string; line: number; end: number; code: Array<string> }> {\n const lines = source.split('\\n')\n const first = config.loc?.start.line ?? 0\n const last = config.loc?.end.line ?? Number.POSITIVE_INFINITY\n\n return lines.flatMap((text, index) => {\n const match = text.trim().match(DISABLED_MARKER)\n // Only markers inside this entry, so an array config never touches another entry's plugin.\n if (!match || index + 1 < first || index + 1 > last) return []\n\n const end = index + 1 + Number(match[2])\n // A blank line comes back empty, not as the indentation the comment carried.\n const code = lines.slice(index + 1, end).map((line) => line.replace(/^(\\s*)\\/\\/ ?/, '$1').replace(/^\\s+$/, ''))\n return [{ packageName: match[1]!, line: index + 1, end, code }]\n })\n}\n\n/**\n * Reads an object option that holds some code: its literal members as `value`, and the paths of\n * the members that are code as `locked`. `set` can write any path outside `locked`, so Studio\n * edits those fields. `undefined` for a computed key, since it could set any path.\n */\nfunction readPartial(node: ObjectNode, prefix: Array<string> = []): { value: Record<string, OptionValue>; locked: Array<Array<string>> } | undefined {\n const value: Record<string, OptionValue> = {}\n const locked: Array<Array<string>> = []\n\n for (const [index, entry] of node.properties.entries()) {\n if (entry.type === 'SpreadElement') continue\n const key = memberKey(entry)\n if (key === undefined) return undefined\n // The last member wins when a key repeats.\n if (findMember(node, key)?.index !== index) continue\n\n const path = [...prefix, key]\n // A `__proto__` key replaces the prototype, so it reads as code.\n if (!isSafeKey(key)) {\n locked.push(path)\n continue\n }\n const member = entry.type === 'ObjectProperty' && !isShadowed(node, index) ? entry.value : undefined\n const literal = readLiteral(member)\n if (literal !== undefined) {\n value[key] = literal\n continue\n }\n if (member?.type !== 'ObjectExpression') {\n locked.push(path)\n continue\n }\n const nested = readPartial(member, path)\n if (!nested) return undefined\n value[key] = nested.value\n locked.push(...nested.locked)\n }\n return { value, locked }\n}\n\n/** The top-level options of a plugin call, each flagged with whether Studio may write it. */\nfunction readOptions(call: CallNode): PluginView['options'] {\n const entries: PluginView['options'] = {}\n const options = call.arguments[0]\n if (options?.type !== 'ObjectExpression') return entries\n\n for (const [index, entry] of options.properties.entries()) {\n const key = memberKey(entry)\n if (key === undefined || !isSafeKey(key)) continue\n // A spread after the option can override it, so `set` refuses it like code.\n const member = entry.type === 'ObjectProperty' && !isShadowed(options, index) ? entry.value : undefined\n const value = readLiteral(member)\n const partial = value === undefined && member?.type === 'ObjectExpression' ? readPartial(member) : undefined\n entries[key] = value !== undefined ? { literal: true, value } : { literal: false, ...partial }\n }\n return entries\n}\n\n/** The options a commented-out plugin call holds, so Studio can show them while it is disabled. */\nfunction readDisabledOptions(code: Array<string>): PluginView['options'] {\n try {\n const call = (parseExpression(code.join('\\n').trim().replace(/,$/, '')) as { $ast: ASTNode }).$ast\n return call.type === 'CallExpression' ? readOptions(call) : {}\n } catch {\n return {}\n }\n}\n\n/**\n * Reads which plugins the file declares and which of their options Studio may write.\n *\n * @example\n * ```ts\n * const view = readConfig(await readFile('kubb.config.ts', 'utf8'))\n * if (view.managed) {\n * view.configs.forEach((config) => console.log(config.name, config.plugins.length))\n * }\n * ```\n */\nexport function readConfig(source: string): ConfigFileView {\n const parsed = parseConfigs(source)\n if ('reason' in parsed) return { managed: false, reason: parsed.reason }\n\n const { mod, configs } = parsed\n const importNames = new Map([...importedFrom(mod)].map(([local, { from }]) => [from, local]))\n\n return {\n managed: true,\n configs: configs.map((config): ConfigView => {\n const active = factoryCalls(mod, config).map(({ importName, packageName, call }) => ({\n line: call.loc?.start.line ?? 0,\n plugin: { importName, packageName, options: readOptions(call) },\n }))\n const disabled = disabledBlocks(source, config).map(({ packageName, line, code }) => ({\n line,\n plugin: {\n importName: importNames.get(packageName) ?? toExportName(packageName),\n packageName,\n options: readDisabledOptions(code),\n disabled: true as const,\n },\n }))\n\n // In source order, so a disabled plugin keeps its place in the list.\n const plugins = [...active, ...disabled].sort((a, b) => a.line - b.line).map(({ plugin }) => plugin)\n const toView = ({ importName, packageName, call }: ReturnType<typeof factoryCalls>[number]): PluginView => ({\n importName,\n packageName,\n options: readOptions(call),\n })\n const [adapter] = factoryCalls(mod, config, 'adapter').map(toView)\n const parsers = factoryCalls(mod, config, 'parser').map(toView)\n return { name: configName(config), plugins, ...(adapter && { adapter }), ...(parsers.length ? { parsers } : {}) }\n }),\n }\n}\n\n/** The modules the config file imports, in source order. Empty when the file cannot be parsed. */\nexport function readImports(source: string): Array<string> {\n try {\n return [...new Set([...importedFrom(parseModule(source)).values()].map(({ from }) => from))]\n } catch {\n return []\n }\n}\n\n/**\n * Walks `path` through a plugin's options to the literal at its last key. Returns `missing` with\n * the index of the first key that is not there yet, so `set` can write the rest of the path as one\n * nested literal and `remove` can report it as unset. Refuses a value customized in code, so it is\n * never overwritten.\n */\nfunction walk(\n options: ObjectNode,\n path: Array<string>,\n): { object: ObjectNode; index: number; value: ASTNode } | { object: ObjectNode; missing: number } | { reason: string } {\n let object = options\n\n for (const [depth, key] of path.entries()) {\n const found = findMember(object, key)\n if (!found) return { object, missing: depth }\n if (isShadowed(object, found.index)) {\n return { reason: `${path.slice(0, depth + 1).join('.')} can be overridden by a spread after it, so it is customized in code` }\n }\n\n const { member, index } = found\n if (depth === path.length - 1) {\n return member.type === 'ObjectProperty' && readLiteral(member.value) !== undefined\n ? { object, index, value: member.value }\n : { reason: `${path.join('.')} is customized in code` }\n }\n if (member.type !== 'ObjectProperty' || member.value.type !== 'ObjectExpression')\n return { reason: `${key} is not an object, so ${path.join('.')} cannot be reached` }\n object = member.value\n }\n return { reason: 'no option path given' }\n}\n\n/** Writes `value` at `path` inside a plugin call's options, adding the options object and any intermediate object it needs. */\nfunction applySet(source: string, call: CallNode, path: Array<string>, value: unknown, quote: Quote): EditResult {\n if (!isOptionValue(value)) return { reason: 'the value is not a literal that can be written to a config file' }\n\n const options = call.arguments[0]\n if (!options) {\n const closing = rangeOf(call).end - 1\n if (source[closing] !== ')') return { reason: 'the factory call could not be located in the file' }\n return { source: splice(source, closing, closing, printValue(nest(path, value), quote)) }\n }\n if (options.type !== 'ObjectExpression') return { reason: 'the factory was not called with an object literal' }\n\n const target = walk(options, path)\n if ('reason' in target) return target\n if ('missing' in target) {\n const [key, ...rest] = path.slice(target.missing)\n return { source: insertItem(source, target.object, `${printKey(key!, quote)}: ${printValue(nest(rest, value), quote)}`) }\n }\n return { source: splice(source, rangeOf(target.value).start, rangeOf(target.value).end, printValue(value, quote)) }\n}\n\n/**\n * Deletes the option at `path`, falling the plugin back to its default for it. An option the file\n * does not set already has its default, so removing it changes nothing.\n */\nfunction applyRemove(source: string, call: CallNode, path: Array<string>): EditResult {\n const options = call.arguments[0]\n if (!options) return { source }\n if (options.type !== 'ObjectExpression') return { reason: 'the factory was not called with an object literal' }\n\n const target = walk(options, path)\n if ('reason' in target) return target\n if ('missing' in target) return { source }\n return { source: removeMember(source, target.object, target.index) }\n}\n\n/**\n * Writes an import after the last one already in the file, matching its quote style and whether it\n * ends in a semicolon: `import { x } from '...'`, or `const { x } = require('...')` in a CommonJS file.\n * The last import is read off the AST, so a multi-line `import {\\n x,\\n} from '...'` counts to its closing line.\n */\nfunction insertImport(source: string, { mod, kind }: ParsedConfig, importName: string, moduleSpecifier: string): string {\n const lastImport = bodyOf(mod).findLast((node) =>\n kind === 'esm'\n ? node.type === 'ImportDeclaration'\n : node.type === 'VariableDeclaration' && node.declarations.some((declarator) => requiredModule(declarator.init) !== undefined),\n )\n const afterLine = lastImport?.loc?.end.line ?? 0\n const lines = source.split('\\n')\n\n const lastImportLine = afterLine > 0 ? lines[afterLine - 1] : undefined\n const quote = lastImportLine?.includes(`\"`) ? `\"` : `'`\n const semicolon = lastImportLine?.trimEnd().endsWith(';') ? ';' : ''\n const specifier = `${quote}${moduleSpecifier}${quote}`\n lines.splice(\n afterLine,\n 0,\n kind === 'esm' ? `import { ${importName} } from ${specifier}${semicolon}` : `const { ${importName} } = require(${specifier})${semicolon}`,\n )\n if (afterLine === 0) lines.splice(1, 0, '')\n\n return lines.join('\\n')\n}\n\n/**\n * Adds a `pluginX(...)` call to a config's plugins array, and its import. Replaying the same add is\n * a no-op, while an import name collision with an unrelated package remains an error.\n */\nfunction applyAddPlugin({\n source,\n parsed,\n config,\n edit,\n quote,\n extensions,\n}: {\n source: string\n parsed: ParsedConfig\n config: ObjectNode\n edit: Extract<ConfigEdit, { operation: 'add-plugin' }>\n quote: Quote\n extensions: InstalledExtensions\n}): EditResult {\n if (!isAllowedPlugin({ packageName: edit.plugin, extensions })) {\n return { reason: `\"${edit.plugin}\" is not a @kubb/plugin-* package or an installed Kubb plugin` }\n }\n\n const importName = extensions.get(edit.plugin)?.manifest.export ?? toExportName(edit.plugin)\n if (!IDENTIFIER.test(importName)) return { reason: `\"${importName}\" is not a valid import name` }\n if (factoryCalls(parsed.mod, config).some((plugin) => plugin.packageName === edit.plugin)) return { source }\n\n const taken = importedFrom(parsed.mod).get(importName)?.from\n if (taken && taken !== edit.plugin) return { reason: `${importName} is already imported from ${taken}` }\n\n const options = edit.options ?? {}\n if (!isOptionValue(options)) return { reason: 'the options are not literals that can be written to a config file' }\n\n const plugins = property(config, 'plugins')\n if (plugins?.type !== 'ArrayExpression') return { reason: 'plugins is not an array literal' }\n\n // The array sits below the imports, so adding to it first leaves the import lines where they are.\n const next = insertItem(source, plugins, `${importName}(${Object.keys(options).length ? printValue(options, quote) : ''})`)\n return { source: taken ? next : insertImport(next, parsed, importName, edit.plugin) }\n}\n\n/**\n * Rewrites the config's `plugins` array with one item per line, so a call can be commented out without\n * taking its neighbors with it. Not done when a comment sits between the items, which would have to move.\n */\nfunction expandPluginsArray(source: string, config: ObjectNode): string | undefined {\n const array = property(config, 'plugins')\n if (array?.type !== 'ArrayExpression') return undefined\n\n const items = array.elements.flatMap((element) => (element ? [element] : []))\n const { start, end } = rangeOf(array)\n const ranges = items.map(rangeOf)\n const gaps = [\n source.slice(start + 1, ranges[0]?.start ?? end - 1),\n ...ranges.map((range, index) => source.slice(range.end, ranges[index + 1]?.start ?? end - 1)),\n ]\n if (!items.length || gaps.some((gap) => !/^[\\s,]*$/.test(gap))) return undefined\n\n const lineStart = source.lastIndexOf('\\n', start - 1) + 1\n const indent = source.slice(lineStart).match(/^[ \\t]*/)?.[0] ?? ''\n const lines = ranges.map((range) => `${indent} ${source.slice(range.start, range.end)},`)\n\n return splice(source, start, end, `[\\n${lines.join('\\n')}\\n${indent}]`)\n}\n\n/** Comments out a plugin call in place, keeping its options on disk so `enable-plugin` can restore them exactly. */\nfunction disablePlugin(source: string, mod: ProxifiedModule, config: ObjectNode, plugin: string): EditResult {\n const loc = factoryCalls(mod, config).find((entry) => entry.packageName === plugin)?.call.loc\n if (!loc) return { reason: `${plugin} is not in the plugins array` }\n\n const lines = source.split('\\n')\n const from = loc.start.line - 1\n const to = loc.end.line - 1\n const firstLine = lines[from] ?? ''\n\n // Only safe when the call sits alone on its lines: anything else on its first line, or on its last\n // line besides a trailing comma, would be swallowed into the comment and corrupt the file.\n if (firstLine.slice(0, loc.start.column).trim() || !/^,?\\s*$/.test((lines[to] ?? '').slice(loc.end.column))) {\n return { reason: `${plugin} shares a line with other code, so it cannot be commented out safely` }\n }\n\n const indent = firstLine.match(/^\\s*/)?.[0] ?? ''\n const commented = lines.slice(from, to + 1).map((line) => (line.trim() ? `${indent}// ${line.slice(indent.length)}` : `${indent}//`))\n lines.splice(from, commented.length, `${indent}// kubb:disabled ${plugin} ${commented.length}`, ...commented)\n\n return { source: lines.join('\\n') }\n}\n\n/** Uncomments the block a previous `disable-plugin` left behind for `plugin` in this config. */\nfunction enablePlugin(source: string, config: ObjectNode, plugin: string): EditResult {\n const block = disabledBlocks(source, config).find((entry) => entry.packageName === plugin)\n if (!block) return { reason: `${plugin} is not disabled` }\n\n const lines = source.split('\\n')\n lines.splice(block.line - 1, block.end - block.line + 1, ...block.code)\n return { source: lines.join('\\n') }\n}\n\n/** Applies one edit to `source`. Every edit re-parses the file, since the previous one rewrote it. */\nfunction applyEdit({ source, edit, quote, extensions }: { source: string; edit: ConfigEdit; quote: Quote; extensions: InstalledExtensions }): EditResult {\n const parsed = parseConfigs(source)\n if ('reason' in parsed) return parsed\n\n const ref = edit.config\n const findConfig = (entries: ParsedConfig) =>\n typeof ref === 'string' ? entries.configs.find((entry) => configName(entry) === ref) : entries.configs[ref ?? 0]\n const config = findConfig(parsed)\n if (!config) return { reason: `no config entry found for ${JSON.stringify(ref)}` }\n\n if (edit.operation === 'disable-plugin') {\n const result = disablePlugin(source, parsed.mod, config, edit.plugin)\n if (!('reason' in result) || !result.reason.includes('shares a line')) return result\n\n // A one-line `plugins: [a(), b()]`, which is also what `add-plugin` writes, gets one item per line first.\n const expanded = expandPluginsArray(source, config)\n const reparsed = expanded === undefined ? undefined : parseConfigs(expanded)\n const reparsedConfig = reparsed && !('reason' in reparsed) ? findConfig(reparsed) : undefined\n return expanded !== undefined && reparsed && !('reason' in reparsed) && reparsedConfig\n ? disablePlugin(expanded, reparsed.mod, reparsedConfig, edit.plugin)\n : result\n }\n if (edit.operation === 'enable-plugin') return enablePlugin(source, config, edit.plugin)\n if (edit.operation === 'add-plugin') return applyAddPlugin({ source, parsed, config, edit, quote, extensions })\n\n const kind = edit.kind ?? 'plugin'\n // A package can ship several factories (`parserTs` and `parserTsx`), so among its calls prefer the\n // export its manifest names: that is the one Studio knows the package by, whatever the file calls it.\n const calls = factoryCalls(parsed.mod, config, kind).filter((entry) => entry.packageName === edit.plugin)\n const exportName = extensions.get(edit.plugin)?.manifest.export ?? toExportName(edit.plugin)\n const call = (calls.find((entry) => entry.exportName === exportName) ?? calls[0])?.call\n if (!call) {\n if (kind === 'adapter') return { reason: `${edit.plugin} is not the config's adapter` }\n const disabled = kind === 'plugin' && disabledBlocks(source, config).some((block) => block.packageName === edit.plugin)\n return { reason: disabled ? `${edit.plugin} is disabled, enable it first` : `${edit.plugin} is not in the ${kind}s array` }\n }\n return edit.operation === 'set' ? applySet(source, call, edit.path, edit.value, quote) : applyRemove(source, call, edit.path)\n}\n\n/**\n * Applies edits to a `kubb.config.ts` in place. Each edit rewrites only the text it targets, so\n * comments, formatting, and hand-written code around the config survive.\n *\n * Edits are independent: one that cannot be applied is reported in `outcomes` and the rest still run.\n *\n * @example\n * ```ts\n * const { source, outcomes } = applyConfigEdits({\n * source: current,\n * edits: [{ operation: 'set', plugin: '@kubb/plugin-ts', path: ['enum', 'type'], value: 'enum' }],\n * })\n * ```\n */\nexport function applyConfigEdits({ source, edits, extensions = new Map() }: { source: string; edits: Array<ConfigEdit>; extensions?: InstalledExtensions }): {\n source: string\n outcomes: Array<ConfigEditOutcome>\n changed: boolean\n} {\n let current = source\n const quote: Quote = detectCodeFormat(source).quote === 'double' ? `\"` : `'`\n\n const outcomes = edits.map((edit): ConfigEditOutcome => {\n const invalid = invalidEdit(edit)\n if (invalid) return { edit, applied: false, reason: invalid }\n\n try {\n const result = applyEdit({ source: current, edit, quote, extensions })\n if ('reason' in result) return { edit, applied: false, reason: result.reason }\n current = result.source\n return { edit, applied: true }\n } catch (error) {\n return { edit, applied: false, reason: getErrorMessage(error) }\n }\n })\n\n return { source: current, outcomes, changed: current !== source }\n}\n\n/**\n * Applies `edits` to the config file at `filePath`, writing it only when something changed.\n * `add-plugin` accepts `@kubb/plugin-*` packages and the plugins in `extensions`.\n */\nexport async function writeConfigEdits({ filePath, edits, extensions }: { filePath: string; edits: Array<ConfigEdit>; extensions?: InstalledExtensions }) {\n const current = await read(filePath)\n const result = applyConfigEdits({ source: current, edits, extensions })\n if (result.changed) await writeFile(filePath, result.source, 'utf-8')\n return result\n}\n","import { structuredPatch, type StructuredPatchHunk } from 'diff'\nimport type { DiffHunk, DiffStats } from './protocol.ts'\n\nconst CONTEXT_LINES = 3\n// Past this, each remaining segment shows as one replace block.\nconst DIFF_TIMEOUT_MS = 1_000\n\n// Lines keep their `\\n`, so a last line without one differs from the same line with one.\nconst splitLines = (text: string) => (text === '' ? [] : text.split(/(?<=\\n)/))\n\n// Longest increasing subsequence of `values`, as indexes into it.\nfunction longestIncreasing(values: Array<number>): Array<number> {\n const tails: Array<number> = []\n const prev: Array<number> = []\n for (const [index, value] of values.entries()) {\n let low = 0\n let high = tails.length\n while (low < high) {\n const mid = (low + high) >> 1\n if (values[tails[mid]!]! < value) low = mid + 1\n else high = mid\n }\n prev[index] = low > 0 ? tails[low - 1]! : -1\n tails[low] = index\n }\n const result: Array<number> = []\n for (let index = tails.at(-1) ?? -1; index !== -1; index = prev[index]!) result.push(index)\n return result.reverse()\n}\n\n// Where to cut both files so each segment diffs on its own: inside each unchanged stretch that keeps a full\n// context on both sides, so no hunk crosses a cut. Lines that occur once in each file, in the same order, find them.\nfunction cutPoints(before: Array<string>, after: Array<string>): Array<[number, number]> {\n const counts = new Map<string, { before: number; after: number; index: number }>()\n for (const [index, line] of before.entries()) {\n const count = counts.get(line)\n if (count) count.before++\n else counts.set(line, { before: 1, after: 0, index })\n }\n const afterIndex = new Map<string, number>()\n for (const [index, line] of after.entries()) {\n const count = counts.get(line)\n if (!count) continue\n count.after++\n afterIndex.set(line, index)\n }\n // Map order is insertion order, so these are sorted by their index in `before`.\n const unique = [...counts]\n .filter(([, count]) => count.before === 1 && count.after === 1)\n .map(([line, count]) => [count.index, afterIndex.get(line)!] as const)\n const anchors = longestIncreasing(unique.map(([, index]) => index)).map((index) => unique[index]!)\n\n const cuts: Array<[number, number]> = [[0, 0]]\n let run = { before: 0, after: 0, length: 0 }\n const closeRun = () => {\n if (run.length > 2 * CONTEXT_LINES) cuts.push([run.before + CONTEXT_LINES, run.after + CONTEXT_LINES])\n }\n let i = 0\n let j = 0\n for (const [anchorBefore, anchorAfter] of anchors) {\n // The lines between two anchors are unchanged when both sides hold the same lines.\n const unchanged = anchorBefore - i === anchorAfter - j && before.slice(i, anchorBefore).every((line, offset) => line === after[j + offset])\n if (unchanged && run.length && run.before + run.length === i) {\n run.length += anchorBefore - i + 1\n } else {\n closeRun()\n run = unchanged ? { before: i, after: j, length: anchorBefore - i + 1 } : { before: anchorBefore, after: anchorAfter, length: 1 }\n }\n i = anchorBefore + 1\n j = anchorAfter + 1\n }\n closeRun()\n cuts.push([before.length, after.length])\n return cuts\n}\n\n// A segment with no time left to diff shows as one block that replaces everything between its shared first and last lines.\nfunction replaceHunk(before: Array<string>, after: Array<string>): Array<StructuredPatchHunk> {\n let start = 0\n while (start < before.length && start < after.length && before[start] === after[start]) start++\n let end = 0\n while (end < before.length - start && end < after.length - start && before[before.length - 1 - end] === after[after.length - 1 - end]) end++\n const removed = before.slice(start, before.length - end)\n const added = after.slice(start, after.length - end)\n if (!removed.length && !added.length) return []\n\n const lines = (prefix: string, rows: Array<string>) =>\n rows.flatMap((row) => (row.endsWith('\\n') ? [`${prefix}${row.slice(0, -1)}`] : [`${prefix}${row}`, '\\\']))\n // Same numbering as `structuredPatch`, which starts an empty side at line 1 too.\n return [{ oldStart: start + 1, oldLines: removed.length, newStart: start + 1, newLines: added.length, lines: [...lines('-', removed), ...lines('+', added)] }]\n}\n\n// One Myers diff over a whole file grows with lines times changes and stalls on large specs, so each segment\n// between cuts is diffed on its own.\nexport function diffHunks(before: string, after: string, timeout = DIFF_TIMEOUT_MS): { hunks: Array<StructuredPatchHunk>; stats: DiffStats } {\n const beforeLines = splitLines(before)\n const afterLines = splitLines(after)\n const cuts = cutPoints(beforeLines, afterLines)\n const deadline = Date.now() + timeout\n\n const hunks: Array<StructuredPatchHunk> = []\n let coarse = false\n for (const [index, [beforeStart, afterStart]] of cuts.slice(0, -1).entries()) {\n const [beforeEnd, afterEnd] = cuts[index + 1]!\n const segmentBefore = beforeLines.slice(beforeStart, beforeEnd)\n const segmentAfter = afterLines.slice(afterStart, afterEnd)\n const patch = structuredPatch('', '', segmentBefore.join(''), segmentAfter.join(''), undefined, undefined, {\n context: CONTEXT_LINES,\n timeout: Math.max(0, deadline - Date.now()),\n })\n if (!patch) coarse = true\n for (const hunk of patch?.hunks ?? replaceHunk(segmentBefore, segmentAfter)) {\n hunks.push({ ...hunk, oldStart: hunk.oldStart + beforeStart, newStart: hunk.newStart + afterStart })\n }\n }\n\n const lines = hunks.flatMap((hunk) => hunk.lines)\n const stats: DiffStats = {\n additions: lines.filter((line) => line[0] === '+').length,\n deletions: lines.filter((line) => line[0] === '-').length,\n hunks: hunks.length,\n lines: lines.length,\n coarse,\n }\n return { hunks, stats }\n}\n\n// Pages hold whole hunks, so a hunk is cut only when it alone is longer than a page. Its parts share its `index`.\nexport function pageHunks({ hunks, cursor, limit }: { hunks: Array<StructuredPatchHunk>; cursor: number; limit: number }): {\n hunks: Array<DiffHunk>\n nextCursor: number | null\n} {\n const page: Array<DiffHunk> = []\n let used = 0\n let start = 0\n for (const [index, hunk] of hunks.entries()) {\n const offset = Math.max(0, cursor - start)\n start += hunk.lines.length\n const remaining = hunk.lines.length - offset\n if (remaining <= 0) continue\n if (used > 0 && remaining > limit - used) break\n let take = Math.min(remaining, limit - used)\n // A `\\ No newline` marker stays with its line, so no part starts with one.\n if (hunk.lines[offset + take]?.startsWith('\\\\')) take++\n page.push({ index, ...hunk, lines: hunk.lines.slice(offset, offset + take) })\n used += take\n if (used >= limit) break\n }\n const total = hunks.reduce((sum, hunk) => sum + hunk.lines.length, 0)\n return { hunks: page, nextCursor: cursor + used < total ? cursor + used : null }\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\nimport process from 'node:process'\nimport { inParallel } from '@internals/utils'\nimport { ast, type InputNode } from '@kubb/ast'\nimport { type Config, createKubb, type Diagnostic, Diagnostics, fsStorage, type Hookable, type KubbHooks, type Storage } from '@kubb/core'\nimport { type FilePage, type ReadFilesResult } from './protocol.ts'\n\nconst READ_CONCURRENCY = 50\nconst MB = 1024 * 1024\nconst INDEX_KEY = 'studio/generations.json'\n\n/**\n * Files a run produced, or the output directory held, keyed by path relative to `root`.\n */\nexport type SourceFiles = { storage: Storage; root: string; paths: Set<string> }\n\n/**\n * The path form {@link SourceFiles} keys on: relative to `root`, with forward slashes.\n */\nexport function relativeStoragePath({ root, filePath }: { root: string; filePath: string }): string {\n return (isAbsolute(filePath) ? relative(resolve(root), filePath) : filePath).replaceAll('\\\\', '/')\n}\n\n/**\n * A set as kept in the store.\n */\ntype KeptSet = {\n /**\n * The paths a read is checked against. Empty when the set was too large to keep its content.\n */\n paths: Array<string>\n hashes: Record<string, string>\n bytes: number\n}\n\ntype KeptGeneration = {\n jobId: string\n initial?: boolean\n /** When the store took it, in epoch milliseconds. Absent on an index written before it existed. */\n keptAt?: number\n output: KeptSet\n inputBytes?: number\n}\n\n/**\n * The content fingerprint Studio compares snapshots by. Agent runs and CI uploads must agree on it.\n */\nexport const hashOf = (content: string) => createHash('sha1').update(content).digest('hex').slice(0, 16)\n\n/**\n * The bytes `entries` keep on disk: output, written files, and kept input.\n */\nconst totalBytes = (entries: Array<KeptGeneration>) => entries.reduce((sum, { output, inputBytes }) => sum + output.bytes + (inputBytes ?? 0), 0)\n\nfunction positiveNumber(value: string | undefined): number | undefined {\n const parsed = Number(value)\n return value && Number.isFinite(parsed) && parsed > 0 ? parsed : undefined\n}\n\n/**\n * How many generations an agent keeps and how large they may get, read from\n * `KUBB_AGENT_MAX_GENERATIONS` and `KUBB_AGENT_MAX_GENERATIONS_MB`.\n * An unset or invalid value keeps the default.\n */\nexport function resolveGenerationLimits(): { maxCount: number; maxMb: number } {\n return {\n maxCount: Math.max(1, Math.floor(positiveNumber(process.env.KUBB_AGENT_MAX_GENERATIONS) ?? 8)),\n maxMb: positiveNumber(process.env.KUBB_AGENT_MAX_GENERATIONS_MB) ?? 100,\n }\n}\n\n/**\n * Folds error-severity diagnostics into one thrown error so logs name the failing plugin or pass.\n */\nfunction generationFailure(diagnostics: ReadonlyArray<Diagnostic>): Error {\n const reasons = diagnostics\n .filter(Diagnostics.isProblem)\n .filter((diagnostic) => diagnostic.severity === 'error')\n .map((diagnostic) => (diagnostic.plugin ? `${diagnostic.plugin}: ${diagnostic.message}` : diagnostic.message))\n\n if (!reasons.length) return new Error('Generation failed')\n\n return new Error(`Generation failed: ${reasons.length} error${reasons.length === 1 ? '' : 's'}: ${reasons.join('; ')}`)\n}\n\n/**\n * Runs one generation and returns the files it produced. The formatter, the linter, and\n * `output.postGenerate` only run with `allowExec`. Throws when any plugin reports an error.\n */\nexport async function generate({\n config,\n hooks,\n signal,\n allowExec,\n}: {\n config: Config\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n allowExec: boolean\n}): Promise<SourceFiles & { input: InputNode | null }> {\n const output = allowExec ? config.output : { ...config.output, format: false as const, lint: false as const, postGenerate: [] }\n const kubb = createKubb({ ...config, output }, { hooks, signal })\n let input: InputNode | null = null\n // The driver drops its `inputNode` once the build is over, so read it as the build ends.\n const unhook = kubb.hooks.hook('kubb:build:end', (ctx) => {\n if (ctx.config === kubb.config) input = kubb.driver.inputNode\n })\n const result = await kubb.generate().finally(unhook)\n if (!result.success) throw generationFailure(result.diagnostics)\n\n // `kubb.config` carries the defaults, such as the fs storage a config loaded by the CLI leaves unset.\n const { storage, root } = kubb.config\n return {\n storage,\n root,\n paths: new Set(result.files.map((file) => relativeStoragePath({ root, filePath: file.path }))),\n input,\n }\n}\n\n/**\n * What the output directory holds when the editor connects. `undefined` when `outputPath` is not a real\n * subdirectory of `root` (listing the root would take in every source file) or holds more than `maxFiles`.\n */\nexport async function listDisk({ root, outputPath, maxFiles }: { root: string; outputPath: string; maxFiles: number }): Promise<SourceFiles | undefined> {\n const outputDir = resolve(root, outputPath)\n const fromRoot = relative(resolve(root), outputDir)\n if (!fromRoot || fromRoot.startsWith('..') || fromRoot.startsWith(sep)) return undefined\n\n const storage = fsStorage()\n const keys = await storage.readKeys(outputDir)\n if (keys.length > maxFiles) return undefined\n\n const paths = keys\n .filter((key) => !key.split('/').includes('node_modules'))\n .map((key) => relative(resolve(root), resolve(outputDir, key)).replaceAll('\\\\', '/'))\n return { storage, root, paths: new Set(paths) }\n}\n\n/**\n * Keeps recent generations by job id in `storage`, with an index next to them so a store on disk\n * survives a restart. A generation is only ever looked up by its job id, so on a pooled sandbox one\n * tenant never reaches another's output. Initial disk output and generated jobs each get their\n * own `maxCount` and `maxMb` budget. Each budget always keeps its newest entry.\n */\nexport function createGenerationStore({\n storage,\n maxCount,\n maxMb,\n ttlMs,\n now = Date.now,\n}: {\n storage: Storage\n maxCount: number\n maxMb: number\n /** How long a generation stays readable. Unset, it stays until count or size pushes it out. */\n ttlMs?: number\n now?: () => number\n}) {\n let index: Array<KeptGeneration> | undefined\n\n // An entry from before `keptAt` existed never expires, so upgrading drops nothing.\n const isLive = (generation: KeptGeneration) => ttlMs === undefined || generation.keptAt === undefined || now() - generation.keptAt < ttlMs\n\n // Hashed so a job id from the wire can never point outside the store.\n const dirOf = (jobId: string) => `studio/generations/${hashOf(jobId)}/`\n\n async function load(): Promise<Array<KeptGeneration>> {\n if (index) return index\n const stored = await storage.readItem(INDEX_KEY).catch(() => null)\n try {\n index = stored ? (JSON.parse(stored) as Array<KeptGeneration>) : []\n } catch {\n index = []\n }\n return index\n }\n\n /**\n * Copies `files` into the store as one set of `jobId`. Above `maxSetMb` only the hashes are kept.\n */\n async function keep({ jobId, files, maxSetMb }: { jobId: string; files: SourceFiles; maxSetMb: number }): Promise<KeptSet> {\n const maxSetBytes = maxSetMb * MB\n const hashes: Record<string, string> = {}\n let bytes = 0\n await inParallel({\n items: [...files.paths],\n limit: READ_CONCURRENCY,\n run: async (path) => {\n // Output outside the root would land outside the store too.\n if (path.split('/').includes('..')) return\n const content = await files.storage.readItem(resolve(files.root, path))\n if (content === null) return\n hashes[path] = hashOf(content)\n bytes += Buffer.byteLength(content)\n if (bytes <= maxSetBytes) await storage.writeItem(`${dirOf(jobId)}output/${path}`, content)\n },\n })\n if (bytes > maxSetBytes) {\n await storage.empty(`${dirOf(jobId)}output/`)\n return { paths: [], hashes, bytes: 0 }\n }\n return { paths: Object.keys(hashes), hashes, bytes }\n }\n\n async function drop(jobId: string): Promise<void> {\n await storage.empty(dirOf(jobId))\n }\n\n async function add(generation: KeptGeneration): Promise<void> {\n const current = await load()\n for (const expired of current.filter((entry) => !isLive(entry))) await drop(expired.jobId)\n const live = current.filter((entry) => entry.jobId !== generation.jobId && isLive(entry))\n const sharesBudget = (entry: KeptGeneration) => Boolean(entry.initial) === Boolean(generation.initial)\n const entries = live.filter(sharesBudget)\n entries.push({ ...generation, keptAt: now() })\n while (entries.length > 1 && (entries.length > maxCount || totalBytes(entries) > maxMb * MB)) {\n await drop(entries.shift()!.jobId)\n }\n index = [...live.filter((entry) => !sharesBudget(entry)), ...entries]\n await storage.writeItem(INDEX_KEY, JSON.stringify(index))\n }\n\n return {\n keep,\n drop,\n /**\n * Captures initial disk output, reusing a retained ID when its hashes and readable paths match.\n * A temporary candidate is discarded on reuse, so reconnects do not consume retention slots.\n */\n async keepInitial(files: SourceFiles): Promise<KeptGeneration> {\n const jobId = randomUUID()\n const output = await keep({ jobId, files, maxSetMb: maxMb })\n const hashes = Object.entries(output.hashes)\n const previous = (await load()).findLast(\n (entry) =>\n entry.initial &&\n isLive(entry) &&\n entry.output.paths.length === output.paths.length &&\n Object.keys(entry.output.hashes).length === hashes.length &&\n hashes.every(([path, hash]) => entry.output.hashes[path] === hash),\n )\n if (previous) {\n await drop(jobId)\n await add(previous)\n return previous\n }\n const generation = { jobId, output, initial: true }\n await add(generation)\n return generation\n },\n /**\n * Keeps the `InputNode` of `jobId` and returns its size in bytes, or 0 when it keeps none. A ref schema loses\n * the copy of its target, which `input.schemas` holds: with it, a large spec outgrows what `JSON.stringify` can return.\n */\n async keepInput({ jobId, input, maxSetMb }: { jobId: string; input: InputNode | null; maxSetMb: number }): Promise<number> {\n if (!input) return 0\n let json: string\n try {\n json = JSON.stringify(ast.transform(input, { schema: (node) => (node.type === 'ref' && node.schema ? { ...node, schema: undefined } : undefined) }))\n } catch {\n // An adapter can return what JSON cannot hold, which must not fail a finished generation.\n return 0\n }\n const bytes = Buffer.byteLength(json)\n if (bytes > maxSetMb * MB) return 0\n await storage.writeItem(`${dirOf(jobId)}input.json`, json)\n return bytes\n },\n /**\n * The input `keepInput` kept for `jobId`, or `undefined` when there is none.\n */\n async readInput(jobId: string): Promise<InputNode | undefined> {\n const stored = await storage.readItem(`${dirOf(jobId)}input.json`)\n return stored === null ? undefined : (JSON.parse(stored) as InputNode)\n },\n get: async (jobId: string) => (await load()).find((generation) => generation.jobId === jobId && isLive(generation)),\n add,\n /**\n * Reads the requested paths the set holds, skipping any it does not, one page of lines when `limit` is given.\n */\n async read({\n generation,\n paths,\n cursor = 0,\n limit,\n }: {\n generation: KeptGeneration\n paths: Array<string>\n cursor?: number\n limit?: number\n }): Promise<ReadFilesResult> {\n const kept = new Set(generation.output.paths)\n const files: Record<string, string> = {}\n const pages: Record<string, FilePage> = {}\n await inParallel({\n items: paths.filter((path) => kept.has(path)),\n limit: READ_CONCURRENCY,\n run: async (path) => {\n const content = await storage.readItem(`${dirOf(generation.jobId)}output/${path}`)\n if (content === null) return\n if (limit === undefined) {\n files[path] = content\n return\n }\n const lines = content.split(/\\r\\n|\\r|\\n/)\n const end = Math.min(cursor + limit, lines.length)\n files[path] = lines.slice(cursor, end).join('\\n')\n pages[path] = { nextCursor: end < lines.length ? end : null, totalLines: lines.length }\n },\n })\n return limit === undefined ? { files } : { files, pages }\n },\n }\n}\n\nexport type GenerationStore = ReturnType<typeof createGenerationStore>\n","import { stripVTControlCharacters } from 'node:util'\nimport { getElapsedMs } from '@internals/utils'\nimport { Diagnostics, type Hookable, type KubbHooks } from '@kubb/core'\nimport { type GenerationEvent, type GenerationEventPayloads, type GenerationEventType, generationEventTypes } from './protocol.ts'\nimport { relativeStoragePath } from './generations.ts'\n\n/** How each published hook's context becomes its wire payload; a hook without a projection fails to compile. */\ntype Projections = { [Type in GenerationEventType]: (...args: KubbHooks[Type]) => GenerationEventPayloads[Type] }\n\nconst MAX_QUEUED_EVENTS = 1_024\nconst RESERVED_EVENTS = 64\nconst isDiscardable = (type: GenerationEventType) => type === 'kubb:files:processing:update' || type === 'kubb:info' || type === 'kubb:success'\n\n/** Forwards selected Kubb lifecycle events to a native Cap'n Web stream. */\nexport function createGenerationStream(\n hooks: Hookable<KubbHooks>,\n jobId: string,\n): { stream: ReadableStream<GenerationEvent>; close: () => Promise<void>; fail: (error?: unknown) => void } {\n const unhooks: Array<() => void> = []\n let root = ''\n let controller!: ReadableStreamDefaultController<GenerationEvent>\n let closed = false\n const stream = new ReadableStream<GenerationEvent>(\n {\n start: (value) => {\n controller = value\n },\n cancel: () => {\n closed = true\n detach()\n },\n },\n { highWaterMark: MAX_QUEUED_EVENTS },\n )\n\n /**\n * Registers a listener and keeps its remover, so one generation's listeners come off the session\n * emitter again when that generation ends.\n */\n function on<TName extends keyof KubbHooks & string>(name: TName, handler: (...args: KubbHooks[TName]) => unknown): void {\n unhooks.push(hooks.hook(name, handler))\n }\n\n function emitEvent<Type extends GenerationEventType>(type: Type, data: GenerationEventPayloads[Type]): void {\n if (closed) return\n const event = { jobId, type, data, version: 1 as const, timestamp: Date.now() } as unknown as GenerationEvent\n if (controller.desiredSize! <= RESERVED_EVENTS && isDiscardable(type)) return\n if (controller.desiredSize! <= 0) {\n fail(new Error(`Generation event stream exceeded ${MAX_QUEUED_EVENTS} queued events`))\n return\n }\n controller.enqueue(event)\n }\n\n const projections: Projections = {\n 'kubb:plugin:start': ({ plugin }) => [{ plugin: { name: plugin.name } }],\n 'kubb:plugin:end': ({ plugin, duration, success }) => [{ plugin: { name: plugin.name }, duration, success }],\n 'kubb:build:start': ({ config, adapter }) => [{ config: { name: config.name }, adapter: { name: adapter.name } }],\n 'kubb:build:end': ({ files, config, outputDir }) => [\n { files: files.map((file) => ({ path: relativeStoragePath({ root: config.root, filePath: file.path }), name: file.name })), outputDir },\n ],\n 'kubb:files:processing:start': ({ files }) => [{ total: files.length }],\n 'kubb:files:processing:update': ({ files }) => [\n {\n files: files.map(({ file, processed, total, percentage }) => ({\n file: relativeStoragePath({ root, filePath: file.path }),\n processed,\n total,\n percentage,\n })),\n },\n ],\n 'kubb:files:processing:end': ({ files }) => [{ total: files.length }],\n 'kubb:info': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:success': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:warn': ({ message, info }) => [{ message: stripVTControlCharacters(message), info }],\n 'kubb:error': ({ error }) => [{ message: error.message, stack: error.stack }],\n 'kubb:diagnostic': ({ diagnostic }) => [\n {\n code: diagnostic.code,\n message: diagnostic.message,\n severity: diagnostic.severity,\n location: 'location' in diagnostic ? diagnostic.location : undefined,\n help: 'help' in diagnostic ? diagnostic.help : undefined,\n plugin: 'plugin' in diagnostic ? diagnostic.plugin : undefined,\n stack: 'cause' in diagnostic ? diagnostic.cause?.stack : undefined,\n },\n ],\n 'kubb:generation:start': ({ config }) => [{ name: config.name, plugins: config.plugins.length }],\n 'kubb:generation:end': () => [],\n 'kubb:generation:summary': ({ duration, fileCount, failedPlugins, status }) => [{ duration, fileCount, failedPlugins, status }],\n 'kubb:lifecycle:start': () => [],\n 'kubb:lifecycle:end': () => [],\n 'kubb:format:start': () => [],\n 'kubb:format:end': () => [],\n 'kubb:lint:start': () => [],\n 'kubb:lint:end': () => [],\n 'kubb:hooks:start': () => [],\n 'kubb:hooks:end': () => [],\n 'kubb:hook:start': ({ id, command, args }) => [{ id, command, args: args ? [...args] : undefined }],\n 'kubb:hook:line': ({ id, line }) => [{ id, line }],\n 'kubb:hook:end': ({ id, command, args, success, error }) => [\n { id, command, args: args ? [...args] : undefined, success, error: error ? { message: error.message, stack: error.stack } : undefined },\n ],\n }\n\n function forward<Type extends GenerationEventType>(type: Type): void {\n on(type, (...args: KubbHooks[Type]) => {\n emitEvent(type, projections[type](...args))\n // Generators render in memory without awaiting I/O, so the socket only sends once the event loop gets a turn.\n if (!isDiscardable(type)) return new Promise<void>((resolve) => setImmediate(resolve))\n })\n }\n\n // Paths in `kubb:files:processing:update` are made relative to the root the build announced.\n on('kubb:build:start', ({ config }) => {\n root = config.root\n })\n\n for (const type of generationEventTypes) forward(type)\n\n // Registered after the loop so the summary follows its `kubb:generation:end`; core never emits it.\n on('kubb:generation:end', ({ diagnostics = [], status, hrStart, filesCreated }) => {\n if (!hrStart) {\n return\n }\n\n const duration = Math.round(getElapsedMs(hrStart))\n\n emitEvent('kubb:generation:summary', [\n { duration, fileCount: filesCreated ?? 0, failedPlugins: Diagnostics.failedPlugins(diagnostics).length, status: status ?? 'success' },\n ])\n })\n\n /**\n * Takes this generation's listeners off the session emitter. Safe to call twice.\n */\n function detach(): void {\n for (const unhook of unhooks) unhook()\n unhooks.length = 0\n }\n\n async function close(): Promise<void> {\n if (closed) {\n return\n }\n closed = true\n detach()\n controller.close()\n }\n\n function fail(error?: unknown): void {\n detach()\n if (closed) {\n return\n }\n closed = true\n controller.error(error)\n }\n\n return { stream, close, fail }\n}\n","import dns from 'node:dns'\nimport http from 'node:http'\nimport https from 'node:https'\nimport net from 'node:net'\nimport { Readable, Transform } from 'node:stream'\nimport { isPublicAddress } from '@kubb/core'\n\nconst MAX_REDIRECTS = 5\nconst MAX_BYTES = 50 * 1024 * 1024\nconst REDIRECTS = new Set([301, 302, 303, 307, 308])\nconst NO_BODY = new Set([204, 205, 304])\n\nfunction notPublic(host: string): Error {\n return new Error(`${host} is not a public address, so a managed agent does not fetch from it`)\n}\n\nfunction createLookup(blocked?: net.BlockList): net.LookupFunction {\n return (hostname, options, callback) => {\n dns.lookup(hostname, { ...options, all: true }, (error, addresses) => {\n if (error) return callback(error, '', 0)\n const found = addresses as Array<dns.LookupAddress>\n // One private answer is enough to refuse, so a name cannot mix a public and a private record.\n if (!found.length || found.some(({ address }) => !isPublicAddress(address, blocked))) return callback(notPublic(hostname), '', 0)\n return options.all ? callback(null, found) : callback(null, found[0]!.address, found[0]!.family)\n })\n }\n}\n\nfunction request({ url, blocked, signal }: { url: URL; blocked?: net.BlockList; signal?: AbortSignal | null }): Promise<Response> {\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return Promise.reject(new Error(`Only http and https URLs are fetched, not ${url.protocol}`))\n // An IP literal skips the lookup below, so it is checked here.\n const host = url.hostname.replace(/^\\[|\\]$/g, '')\n if (net.isIP(host) && !isPublicAddress(host, blocked)) return Promise.reject(notPublic(host))\n\n return new Promise((resolve, reject) => {\n const send = url.protocol === 'https:' ? https.request : http.request\n // `lookup` runs for the connection itself, so a name that changes its answer after a check cannot reach a blocked address.\n const req = send(url, { method: 'GET', lookup: createLookup(blocked), signal: signal ?? undefined, headers: { 'accept-encoding': 'identity' } }, (res) => {\n const headers = new Headers()\n for (const [key, value] of Object.entries(res.headers)) {\n for (const item of [value].flat()) if (item !== undefined) headers.append(key, item)\n }\n let total = 0\n const limit = new Transform({\n transform(chunk: Buffer, _encoding, done) {\n total += chunk.length\n done(total > MAX_BYTES ? new Error('The response is larger than 50 MB') : null, chunk)\n },\n })\n res.on('error', (error) => limit.destroy(error))\n res.pipe(limit)\n const body = NO_BODY.has(res.statusCode ?? 0) ? null : (Readable.toWeb(limit) as unknown as ReadableStream)\n resolve(new Response(body, { status: res.statusCode, statusText: res.statusMessage, headers }))\n })\n req.on('error', reject)\n req.end()\n })\n}\n\n/**\n * Builds a `fetch` that only reaches addresses `blocked` does not list. It follows redirects itself\n * and checks every hop, and takes GET requests only, since that is all a spec load needs.\n */\nexport function createPublicFetch(blocked?: net.BlockList): typeof fetch {\n const publicFetch = async (input: Parameters<typeof fetch>[0], init?: RequestInit): Promise<Response> => {\n if (typeof input !== 'string' && !(input instanceof URL)) throw new TypeError('A managed agent fetches by URL only')\n if (init?.method && init.method.toUpperCase() !== 'GET') throw new TypeError('A managed agent only sends GET requests')\n\n let url = new URL(input)\n for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {\n const response = await request({ url, blocked, signal: init?.signal })\n const location = response.headers.get('location')\n if (!REDIRECTS.has(response.status) || !location) return response\n await response.body?.cancel()\n url = new URL(location, url)\n }\n throw new Error(`Stopped after ${MAX_REDIRECTS} redirects from ${String(input)}`)\n }\n return publicFetch as typeof fetch\n}\n\n/**\n * Runs `run` with the global `fetch` limited to public addresses, then puts the original back.\n * A managed agent runs one job at a time, so nothing else shares the window.\n */\nexport async function withPublicFetch<T>(run: () => Promise<T>): Promise<T> {\n const original = globalThis.fetch\n globalThis.fetch = createPublicFetch()\n try {\n return await run()\n } finally {\n globalThis.fetch = original\n }\n}\n","import { Diagnostics } from '@kubb/core'\n\n/**\n * Hosted Kubb Studio URL, used when a host passes none.\n */\nexport const defaultStudioUrl = 'https://kubb.studio'\n\n// `URL` keeps IPv6 brackets, so `::1` is `[::1]`.\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]'\n}\n\n/**\n * Appends `path` to the Studio URL and refuses plaintext to anything but this machine, so a token\n * or API key never crosses the network unencrypted. `socket` switches the scheme to `ws:`/`wss:`.\n *\n * @example\n * ```ts\n * secureUrl({ studioUrl: 'https://kubb.studio', path: '/api/agent/socket', socket: true }).href // 'wss://kubb.studio/api/agent/socket'\n * ```\n */\nexport function secureUrl({ studioUrl, path, socket = false }: { studioUrl: string; path: string; socket?: boolean }): URL {\n const url = new URL(`${studioUrl.replace(/\\/+$/, '')}${path}`)\n\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && isLoopbackHost(url.hostname))) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Refusing to reach Kubb Studio at ${url.origin}: use an https:// URL, or a loopback host for local development`,\n })\n }\n if (socket) url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'\n\n return url\n}\n","import { randomUUID } from 'node:crypto'\nimport { tmpdir } from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getErrorMessage, mkdtemp, read, rm, toError } from '@internals/utils'\nimport {\n Diagnostics,\n cacheStorage,\n checkoutGitInput,\n type Config,\n fsStorage,\n getInputKind,\n type InputKind,\n Hookable,\n type KubbHooks,\n type Storage,\n readInstalledPackages,\n resolveCacheDir,\n resolveMeta,\n} from '@kubb/core'\nimport { newWebSocketRpcSession, RpcTarget } from 'capnweb'\nimport { version as kubbVersion } from '../package.json'\nimport { readConfig, readImports, writeConfigEdits } from './configFile.ts'\nimport { diffHunks, pageHunks } from './diff.ts'\nimport { createGenerationStream } from './generationEvents.ts'\nimport { createGenerationStore, generate, type GenerationStore, listDisk, resolveGenerationLimits } from './generations.ts'\nimport {\n AGENT_INSTANCE_HEADER,\n AGENT_SOCKET_PATH,\n type AgentApi,\n AgentPermission,\n AgentCloseCode,\n AgentMessage,\n type AgentConnectInfo,\n type AgentPermissions,\n type ConfigEntryView,\n type ConfigFileView,\n type ConfigRef,\n type ConnectMessagePayload,\n type DiskOutput,\n type GenerateInput,\n type GenerateResult,\n type GenerationEvent,\n type GenerationRun,\n type InstalledExtensions,\n MAX_FILES_PER_REQUEST,\n MAX_PAGE_LINES,\n type ReadDiffInput,\n type ReadDiffResult,\n type ReadFilesInput,\n type ReadFilesResult,\n type ReadInputInput,\n type ReadInputResult,\n type SaveConfigInput,\n type SaveResult,\n type StudioApi,\n} from './protocol.ts'\nimport { withPublicFetch } from './publicFetch.ts'\nimport { assertOutputPaths, mergeAdapter, mergeParsers, mergePlugins, toJSONOptions, toStudioName } from './resolveConfig.ts'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\nconst HEARTBEAT_INTERVAL_MS = 30_000\n// Studio marks an agent offline after its liveness window, so a slower cadence would look dead.\nconst MAX_HEARTBEAT_INTERVAL_MS = 60_000\nconst PING_TIMEOUT_MS = 10_000\nconst OPEN_TIMEOUT_MS = 5_000\nconst MAX_RETRY_DELAY_MS = 30_000\nconst DISK_SNAPSHOT_MAX_FILES = 10_000\n// Sandboxes keep temporary output sets with a short lifetime.\nconst SANDBOX_GENERATION_TTL_MS = 15 * 60_000\n// What Studio may send a managed agent as its spec. Not `file` or `object`: a path would read the container's disk.\nconst MANAGED_INPUT_KINDS = new Set<InputKind>(['inline', 'url', 'git'])\n/** Extensions `kubb` ships with, so they count as installed without being a direct dependency. */\nconst BUILT_IN_PACKAGES = ['@kubb/adapter-oas', '@kubb/parser-ts', '@kubb/parser-md', '@kubb/plugin-barrel']\n\n/**\n * Studio closed with {@link AgentCloseCode.UNAUTHORIZED}. Hosts forget the token and pair again.\n */\nexport class InvalidAgentTokenError extends Error {\n constructor(studioUrl: string) {\n super(`Kubb Studio rejected this agent's token. It expired or was revoked, or the agent was deleted in ${studioUrl}.`)\n this.name = 'InvalidAgentTokenError'\n }\n}\n\n/**\n * Studio closed with {@link AgentCloseCode.INCOMPATIBLE}. Only an upgrade helps.\n */\nexport class IncompatibleAgentError extends Error {\n constructor({ studioUrl, detail }: { studioUrl: string; detail?: string }) {\n super(`Kubb Studio at ${studioUrl} requires a newer agent${detail ? `: ${detail}` : ''}. Upgrade kubb or the Kubb agent image.`)\n this.name = 'IncompatibleAgentError'\n }\n}\n\nexport type StudioConnectedContext = AgentConnectInfo & {\n url: string\n /**\n * The Studio, runtime, and host versions, so a host can show a mismatch.\n */\n versions: { studio: string; kubb: string; agent: string }\n}\n\ndeclare global {\n namespace Kubb {\n interface KubbHooksRegistry {\n /**\n * Fired after each handshake, including reconnects.\n */\n 'studio:connected': [ctx: StudioConnectedContext]\n 'studio:disconnected': [ctx: { code: number; reason: string }]\n 'studio:reconnecting': [ctx: { delayMs: number }]\n /**\n * A finished command and what it did, such as `applied 2/3 edits to kubb.config.ts`.\n */\n 'studio:command': [\n ctx: {\n command: 'generate' | 'saveConfig' | 'readFiles' | 'readInput' | 'readDiff'\n info: string\n /**\n * The Studio user who asked for the command, when Studio names one.\n */\n requestedBy?: string\n /**\n * Set when a generation failed. Its diagnostics went out through `kubb:generation:end`.\n */\n failed?: boolean\n },\n ]\n /**\n * A refused or ignored request, with the missing permission so the host can add a remedy.\n */\n 'studio:warn': [ctx: { message: string; permission?: AgentPermission }]\n 'studio:error': [ctx: { error: Error }]\n }\n }\n}\n\nexport type ConnectAgentOptions = {\n /**\n * The agent's bearer token, from {@link pairAgent}.\n */\n token: string\n studioUrl?: string\n /**\n * The config path shown in Studio, relative to `root` unless absolute.\n */\n configPath: string\n /**\n * Called for every handshake and every generation, so edits on disk show up. One entry per\n * `defineConfig(...)` entry, and a generation names the one it runs.\n */\n loadConfigs: () => Promise<Array<Config>>\n /**\n * The host's own version, reported to Studio next to the runtime's.\n */\n version: string\n /**\n * The project root generation runs against.\n * @default process.cwd()\n */\n root?: string\n /**\n * What Studio may do in this project. Every permission is off unless granted.\n */\n permissions?: Partial<AgentPermissions>\n /**\n * Receives the `studio:*` hooks and the `kubb:*` hooks of every generation.\n */\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n /**\n * Longest wait between reconnect attempts, in milliseconds.\n * @default 30000\n */\n maxRetryDelay?: number\n /**\n * Milliseconds between keep-alive pings, at most 60000.\n * @default 30000\n */\n heartbeatInterval?: number\n}\n\ntype ResolvedOptions = Required<Omit<ConnectAgentOptions, 'signal'>> & {\n signal?: AbortSignal\n permissions: AgentPermissions\n configFile: string\n}\n\ntype Rpc = { studio: StudioApi; closed: Promise<{ code: number; reason: string }>; close: () => void }\n\n// Tests swap in an in-process pair.\nexport type OpenRpc = (input: { url: URL; token: string; instanceId: string; agent: AgentApi }) => Rpc\n\ntype Session = {\n info?: AgentConnectInfo\n connected: PromiseWithResolvers<AgentConnectInfo>\n closed: boolean\n active?: { jobId: string; abort: () => void; settled: Promise<void> }\n}\n\n// A throwing host listener must not break the connection.\nfunction emit<TName extends keyof KubbHooks & string>(hooks: Hookable<KubbHooks>, name: TName, ...args: KubbHooks[TName]): Promise<void> {\n return Promise.resolve(hooks.callHook(name, ...args)).catch(() => {})\n}\n\nfunction isValidPage({ cursor, limit }: Pick<ReadFilesInput, 'cursor' | 'limit'>): boolean {\n if (limit === undefined) return cursor === undefined\n if (cursor !== undefined && (!Number.isSafeInteger(cursor) || cursor < 0)) return false\n return Number.isSafeInteger(limit) && limit >= 1 && limit <= MAX_PAGE_LINES\n}\n\n/**\n * Maps generated paths into a temporary directory while keeping the project root for input resolution.\n */\nfunction stagingStorage({ root, directory }: { root: string; directory: string }): Storage {\n const storage = fsStorage()\n const target = (key: string) => {\n const relative = path.relative(root, path.resolve(root, key))\n if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error('Output path escapes the project root')\n return path.join(directory, relative)\n }\n return {\n name: 'fs',\n readItem: (key) => storage.readItem(target(key)),\n writeItem: (key, value) => storage.writeItem(target(key), value),\n removeItem: (key) => storage.removeItem(target(key)),\n readKeys: (base) => storage.readKeys(base ? target(base) : directory),\n empty: (base) => (base ? storage.empty(target(base)) : Promise.resolve()),\n }\n}\n\ntype RunHandle = { stream: ReadableStream<GenerationEvent>; result: Promise<GenerateResult>; stop: () => void }\n\nclass GenerationRunTarget extends RpcTarget implements GenerationRun {\n readonly #run: RunHandle\n\n constructor(run: RunHandle) {\n super()\n this.#run = run\n }\n\n async events() {\n return this.#run.stream\n }\n result() {\n return this.#run.result\n }\n async cancel() {\n this.#run.stop()\n }\n // Cap'n Web also calls this when the peer session is torn down, so a dropped socket stops the run.\n [Symbol.dispose]() {\n this.#run.stop()\n }\n}\n\n// Cap'n Web exposes only prototype methods, so the public methods are exactly `AgentApi`.\nclass Agent extends RpcTarget implements AgentApi {\n readonly #options: ResolvedOptions\n readonly #session: Session\n readonly #limits = resolveGenerationLimits()\n #store: GenerationStore | undefined\n readonly #sandboxCacheRoot = path.join(tmpdir(), `kubb-studio-${randomUUID()}`)\n // Kept sets never change, so a diff is computed once and its pages are cut from it.\n readonly #diffs = new Map<string, ReturnType<typeof diffHunks>>()\n\n constructor({ options, session }: { options: ResolvedOptions; session: Session }) {\n super()\n this.#options = options\n this.#session = session\n }\n\n get #sandbox(): boolean {\n return this.#session.info?.sandbox === true\n }\n\n get #managed(): boolean {\n return this.#session.info?.managed === true\n }\n\n // A sandbox has no project to write to or edit, and Studio may always read what it generated there.\n get #permissions(): AgentPermissions {\n const { permissions } = this.#options\n return this.#sandbox ? { ...permissions, allowWrite: false, allowConfigEdit: false, allowRead: true, allowReadAst: true } : permissions\n }\n\n // Owned agents retain output in the project cache. Each sandbox connection has a temporary cache.\n get #generations(): GenerationStore {\n this.#store ??= createGenerationStore({\n storage: cacheStorage({ root: this.#sandbox ? this.#sandboxCacheRoot : this.#options.root }),\n maxCount: this.#limits.maxCount,\n maxMb: this.#limits.maxMb,\n ttlMs: this.#sandbox ? SANDBOX_GENERATION_TTL_MS : undefined,\n })\n return this.#store\n }\n\n async clear() {\n if (this.#sandbox) await rm(resolveCacheDir(this.#sandboxCacheRoot), { recursive: true, force: true })\n }\n\n #warn({ message, permission }: { message: string; permission?: AgentPermission }): Promise<void> {\n return emit(this.#options.hooks, 'studio:warn', { message, permission })\n }\n\n // Studio shows the thrown message, and the host logs the same text.\n async #refuse({ message, permission }: { message: string; permission?: AgentPermission }): Promise<never> {\n await this.#warn({ message, permission })\n throw new Diagnostics.Error({ code: Diagnostics.code.unknown, severity: 'error', message })\n }\n\n #assertConnected(): void {\n if (!this.#session.info)\n throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Studio must call connect() before any other command' })\n }\n\n #logCommand(command: KubbHooks['studio:command'][0]['command'], info: string, requestedBy?: string, failed?: boolean): Promise<void> {\n return emit(this.#options.hooks, 'studio:command', { command, info, requestedBy, failed })\n }\n\n // Not cached: the user can edit the file between two Studio actions.\n async #readConfigFileView(source: Promise<string>): Promise<ConfigFileView | undefined> {\n if (!this.#permissions.allowConfigEdit) return undefined\n\n try {\n return readConfig(await source)\n } catch (error) {\n await this.#warn({ message: `Could not read ${this.#options.configFile}: ${getErrorMessage(error)}` })\n return undefined\n }\n }\n\n // Not cached either: the user can install a plugin while the agent runs. Keeps each project\n // dependency, config import and built-in that resolves and ships a valid `kubb-extension.json`.\n async #installedExtensions(source = read(this.#options.configFile)): Promise<InstalledExtensions> {\n const imports = await source.then(readImports, () => [])\n const installed = await readInstalledPackages({ root: this.#options.root, packages: [...imports, ...BUILT_IN_PACKAGES], resolveFrom: ['kubb'] })\n\n return new Map(\n installed.flatMap(({ package: name, version, manifest }) =>\n version !== undefined && manifest ? [[name, { package: name, version, manifest }] as const] : [],\n ),\n )\n }\n\n async connect(info: AgentConnectInfo): Promise<ConnectMessagePayload> {\n this.#session.info = info\n const { configPath, root, version, loadConfigs, configFile } = this.#options\n const source = read(configFile)\n const [configs, file, extensions] = await Promise.all([loadConfigs(), this.#readConfigFileView(source), this.#installedExtensions(source)])\n // Copied through JSON: Cap'n Web would otherwise pass every function in the options as a stub\n // Studio could call, running the user's config code in this process.\n const entries: Array<ConfigEntryView> = []\n for (const config of configs) {\n const disk = await this.#readDiskOutput(config).catch(async (error: unknown) => {\n await this.#warn({ message: `Could not read the output directory: ${getErrorMessage(error)}` })\n return undefined\n })\n entries.push({ ...toEntryView(config, extensions), ...(disk && { disk }) })\n }\n this.#session.connected.resolve(info)\n\n return {\n versions: { kubb: kubbVersion, agent: version },\n root,\n config: { path: configPath, file, extensions: [...extensions.values()], configs: entries },\n permissions: this.#permissions,\n }\n }\n\n async #readDiskOutput(config: Config): Promise<DiskOutput | undefined> {\n if (this.#sandbox || !this.#permissions.allowRead || this.#session.active) return undefined\n const files = await listDisk({ root: this.#options.root, outputPath: config.output.path, maxFiles: DISK_SNAPSHOT_MAX_FILES })\n if (!files) return undefined\n\n const { jobId, output } = await this.#generations.keepInitial(files)\n return { jobId, files: output.paths, hashes: output.hashes }\n }\n\n startGeneration(input: GenerateInput): GenerationRun {\n const stream = createGenerationStream(this.#options.hooks, input.jobId)\n const controller = new AbortController()\n const result = this.#runGeneration(input, controller).then(\n (value) => stream.close().then(() => value),\n (error: unknown) => {\n stream.fail(error)\n throw error\n },\n )\n // A disconnect can reject this after the remote caller disappeared.\n void result.catch(() => {})\n\n return new GenerationRunTarget({\n stream: stream.stream,\n result,\n stop: () => {\n controller.abort(new Error('Generation canceled'))\n stream.fail()\n },\n })\n }\n\n /**\n * Keeps a job's output and permitted parsed input, then cleans up its temporary generation directories.\n */\n async #runGeneration(input: GenerateInput, controller: AbortController): Promise<GenerateResult> {\n this.#assertConnected()\n // Checked before the first `await`, so two calls in the same tick can't both pass.\n if (this.#session.closed) throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Connection is closed' })\n if (this.#session.active) return this.#refuse({ message: AgentMessage.GENERATION_IN_PROGRESS })\n const settled = Promise.withResolvers<void>()\n this.#session.active = { jobId: input.jobId, abort: () => controller.abort(new Error('Generation canceled')), settled: settled.promise }\n let root = this.#options.root\n let outputRoot: string | undefined\n\n try {\n // Kubb keys its manifest cache by root, so sandbox tenants sharing one root would read each other's.\n if (this.#sandbox) root = await mkdtemp(path.join(tmpdir(), 'kubb-job-'))\n if (!this.#sandbox && !this.#permissions.allowWrite) outputRoot = await mkdtemp(path.join(tmpdir(), 'kubb-output-'))\n return await this.#generate({ input, root, outputRoot, signal: controller.signal })\n } finally {\n if (root !== this.#options.root) {\n await Promise.all([rm(root, { recursive: true, force: true }), rm(resolveCacheDir(root), { recursive: true, force: true })]).catch(() => {})\n }\n if (outputRoot) await rm(outputRoot, { recursive: true, force: true })\n this.#session.active = undefined\n settled.resolve()\n }\n }\n\n /**\n * Merges Studio's config over the project config and confines generation to the configured output folder.\n */\n async #generate({\n input,\n root,\n outputRoot,\n signal,\n }: {\n input: GenerateInput\n root: string\n outputRoot?: string\n signal: AbortSignal\n }): Promise<GenerateResult> {\n const { jobId, config: patch } = input\n // A sandbox has no spec on disk, so it only ever generates from the content Studio sends. A path\n // or URL would make it read host files or fetch internal addresses on behalf of any tenant.\n const studioInput = this.#sandbox || this.#managed ? patch?.input : undefined\n if (this.#sandbox && (typeof studioInput !== 'string' || !studioInput.trim() || getInputKind(studioInput) !== 'inline')) {\n return this.#refuse({ message: AgentMessage.SANDBOX_INPUT_ONLY })\n }\n // Studio may point a managed agent at a URL or a git file, and it falls back to its config's input without one. A file path would read the container's disk.\n if (this.#managed && studioInput !== undefined && !MANAGED_INPUT_KINDS.has(getInputKind(studioInput))) {\n return this.#refuse({ message: AgentMessage.MANAGED_INPUT_KIND })\n }\n\n const [configs, extensions] = await Promise.all([this.#options.loadConfigs(), this.#installedExtensions()])\n const config = pickConfig(configs, patch?.config)\n if (!config) return this.#refuse({ message: AgentMessage.CONFIG_ENTRY_NOT_FOUND })\n const [plugins, adapter, parsers] = await Promise.all([\n mergePlugins({ diskPlugins: config.plugins, studioPlugins: patch?.plugins, extensions }).then((merged) => {\n assertOutputPaths({ plugins: merged ?? [], diskPlugins: config.plugins, root, outputPath: config.output.path })\n return merged\n }),\n mergeAdapter(config.adapter, patch?.adapter, extensions),\n mergeParsers({ diskParsers: config.parsers, studioParsers: patch?.parsers, extensions }),\n ]).catch(async (error: unknown) => {\n // Thrown before core runs, so nothing else reports it to the host.\n await emit(this.#options.hooks, 'kubb:error', { error: toError(error) })\n throw error\n })\n\n const activePlugins = plugins ?? config.plugins\n\n if (patch?.input && !this.#sandbox && !this.#managed) {\n // A `kubb:warn` rather than `studio:warn`, so the generation's event stream carries it to Studio too.\n await emit(this.#options.hooks, 'kubb:warn', {\n message: 'Ignored the spec from Studio: generating from a Studio spec is only available to a sandbox or managed agent',\n })\n }\n\n // A managed agent checks a git input out itself, so the fetch stays on public addresses and follows no redirect.\n const checkout =\n this.#managed && studioInput !== undefined && getInputKind(studioInput) === 'git'\n ? await checkoutGitInput(studioInput, signal, { publicOnly: true }).catch((error: unknown) => this.#refuse({ message: getErrorMessage(error) }))\n : undefined\n const run = () =>\n generate({\n config: {\n ...config,\n root,\n input: checkout?.path ?? studioInput ?? config.input,\n storage: outputRoot ? stagingStorage({ root, directory: outputRoot }) : fsStorage(),\n plugins: activePlugins,\n adapter,\n parsers,\n },\n hooks: this.#options.hooks,\n signal,\n allowExec: this.#permissions.allowWrite && this.#permissions.allowExec,\n })\n // The adapter fetches the URL and every `$ref` in it, so a managed agent limits the fetch itself to public addresses.\n const files = await (this.#managed ? withPublicFetch(run) : run())\n .catch(async (error: unknown) => {\n await this.#generations.drop(jobId)\n await this.#logCommand('generate', getErrorMessage(error), input.requestedBy, true)\n throw error\n })\n .finally(() => checkout?.dispose())\n\n const output = await this.#generations.keep({ jobId, files, maxSetMb: this.#limits.maxMb })\n // Only `readInput` reads it, which needs `allowReadAst`.\n const inputBytes = await this.#generations.keepInput({ jobId, input: this.#permissions.allowReadAst ? files.input : null, maxSetMb: this.#limits.maxMb })\n if (!output.paths.length && Object.keys(output.hashes).length) {\n await this.#warn({ message: 'Kept only the hashes of this generation: its output is too large to keep' })\n }\n await this.#generations.add({ jobId, output, inputBytes })\n await this.#logCommand(\n 'generate',\n `${activePlugins.length} plugin${activePlugins.length === 1 ? '' : 's'}, ${this.#permissions.allowWrite ? 'written to disk' : 'staged on disk'}${studioInput !== undefined ? ', from a Studio spec' : ''}`,\n input.requestedBy,\n )\n\n return {\n status: 'success',\n files: [...files.paths],\n fileCount: files.paths.size,\n hashes: output.hashes,\n }\n }\n\n async saveConfig(input: SaveConfigInput): Promise<SaveResult> {\n this.#assertConnected()\n const { configPath, configFile } = this.#options\n\n if (!Array.isArray(input.edits)) {\n await this.#warn({ message: 'Ignored save: the message carried no edits' })\n return { outcomes: [], changed: false }\n }\n\n const edits = input.edits\n const refuse = (reason: string): SaveResult => ({ outcomes: edits.map((edit) => ({ edit, applied: false, reason })), changed: false })\n\n if (!this.#permissions.allowConfigEdit) {\n await this.#warn({ message: 'Ignored save: editing kubb.config.ts was not granted' })\n return refuse('the agent was not granted permission to edit kubb.config.ts')\n }\n\n // A running generation reloads the config, so it would see half the change.\n if (this.#session.active) return refuse('a generation is in progress')\n\n try {\n const { outcomes, changed } = await writeConfigEdits({ filePath: configFile, edits, extensions: await this.#installedExtensions() })\n const applied = outcomes.filter((outcome) => outcome.applied).length\n await this.#logCommand('saveConfig', `applied ${applied}/${outcomes.length} edits to ${configPath}`, input.requestedBy)\n\n return { outcomes, changed }\n } catch (error) {\n // Refuse every edit so Studio hears back instead of waiting.\n await emit(this.#options.hooks, 'studio:error', { error: toError(error) })\n return refuse(getErrorMessage(error))\n }\n }\n\n /**\n * Returns the Kubb AST a kept job parsed its spec into. Refused without `allowReadAst`.\n */\n async readInput(input: ReadInputInput): Promise<ReadInputResult> {\n this.#assertConnected()\n if (!this.#permissions.allowReadAst) return this.#refuse({ message: AgentMessage.READ_AST_NOT_ALLOWED, permission: AgentPermission.READ_AST })\n if (typeof input.jobId !== 'string' || !input.jobId) return this.#refuse({ message: AgentMessage.JOB_REQUIRED })\n\n const generation = await this.#generations.get(input.jobId)\n if (!generation) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n // A rerun of the job can leave an earlier run's input on disk, so trust only what this run kept.\n const kept = generation.inputBytes ? await this.#generations.readInput(input.jobId) : undefined\n if (!kept) return this.#refuse({ message: AgentMessage.NO_INPUT })\n await this.#logCommand('readInput', 'read the API input')\n\n return { input: kept }\n }\n\n /**\n * Returns the requested files of a kept job, one page of lines at a time. Refused without `allowRead`.\n */\n async readFiles(input: ReadFilesInput): Promise<ReadFilesResult> {\n this.#assertConnected()\n if (!this.#permissions.allowRead) return this.#refuse({ message: AgentMessage.READ_NOT_ALLOWED, permission: AgentPermission.READ })\n if (!Array.isArray(input.paths) || typeof input.jobId !== 'string' || !input.jobId) {\n return this.#refuse({ message: AgentMessage.FILE_REQUEST_INVALID })\n }\n const { paths } = input\n if (paths.length > MAX_FILES_PER_REQUEST) return this.#refuse({ message: AgentMessage.TOO_MANY_FILES })\n if (!isValidPage(input)) return this.#refuse({ message: AgentMessage.INVALID_PAGE })\n\n const generation = await this.#generations.get(input.jobId)\n if (!generation) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n\n // Only paths the set holds are read, never an arbitrary path.\n const result = await this.#generations.read({ generation, paths, cursor: input.cursor, limit: input.limit })\n await this.#logCommand('readFiles', `read ${Object.keys(result.files).length}/${paths.length} requested file${paths.length === 1 ? '' : 's'}`)\n\n return result\n }\n\n /**\n * Returns one page of the line diff of a file between two kept sets. Refused without `allowRead`.\n */\n async readDiff(input: ReadDiffInput): Promise<ReadDiffResult> {\n this.#assertConnected()\n if (!this.#permissions.allowRead) return this.#refuse({ message: AgentMessage.READ_NOT_ALLOWED, permission: AgentPermission.READ })\n const { jobId, path, base, cursor = 0, limit } = input\n if (typeof jobId !== 'string' || !jobId || typeof path !== 'string' || !path || typeof base?.jobId !== 'string' || !base.jobId) {\n return this.#refuse({ message: AgentMessage.DIFF_REQUEST_INVALID })\n }\n if (!isValidPage({ cursor, limit })) {\n return this.#refuse({ message: AgentMessage.INVALID_PAGE })\n }\n\n const [generation, baseGeneration] = await Promise.all([this.#generations.get(jobId), this.#generations.get(base.jobId)])\n if (!generation || !baseGeneration) return this.#refuse({ message: AgentMessage.GENERATION_GONE })\n\n // Only paths the sets hold are read, never an arbitrary path.\n const [after, before] = await Promise.all([\n this.#generations.read({ generation, paths: [path] }),\n this.#generations.read({ generation: baseGeneration, paths: [path] }),\n ])\n const afterContent = after.files[path]\n // Over the size cap only hashes are kept, which must not read as a deleted file.\n if (afterContent === undefined && path in generation.output.hashes) return this.#refuse({ message: AgentMessage.HASHES_ONLY })\n const beforeContent = before.files[path]\n if (beforeContent === undefined)\n return { hunks: [], nextCursor: null, hasBase: false, stats: { additions: 0, deletions: 0, hunks: 0, lines: 0, coarse: false } }\n\n const key = JSON.stringify([jobId, base.jobId, path])\n let diff = this.#diffs.get(key)\n if (!diff) {\n diff = diffHunks(beforeContent, afterContent ?? '')\n this.#diffs.set(key, diff)\n // A few recent diffs cover paging through the open file and switching back to the last one.\n if (this.#diffs.size > 4) this.#diffs.delete(this.#diffs.keys().next().value!)\n }\n await this.#logCommand('readDiff', `read the diff of ${path}`)\n\n return { ...pageHunks({ hunks: diff.hunks, cursor, limit }), hasBase: true, stats: diff.stats }\n }\n}\n\nconst openWebSocketRpc: OpenRpc = ({ url, token, instanceId, agent }) => {\n // Node's `WebSocket` takes undici's `headers` option, which the DOM typing leaves out.\n const NodeWebSocket = WebSocket as unknown as new (url: URL, init: { headers: Record<string, string> }) => WebSocket\n const socket = new NodeWebSocket(url, { headers: { Authorization: `Bearer ${token}`, [AGENT_INSTANCE_HEADER]: instanceId } })\n const timer = setTimeout(() => socket.close(3008, 'Connection timeout'), OPEN_TIMEOUT_MS)\n socket.addEventListener('open', () => clearTimeout(timer), { once: true })\n\n const closed = new Promise<Awaited<Rpc['closed']>>((resolve) => {\n socket.addEventListener('close', ({ code, reason }) => resolve({ code, reason }), { once: true })\n // Node fires only `error` when the handshake itself fails.\n socket.addEventListener('error', () => {\n if (socket.readyState !== WebSocket.OPEN) resolve({ code: 1006, reason: '' })\n })\n }).finally(() => clearTimeout(timer))\n\n const studio = newWebSocketRpcSession<StudioApi>(socket, agent)\n studio.onRpcBroken(() => socket.close())\n\n return {\n studio,\n closed,\n close: () => {\n studio[Symbol.dispose]()\n socket.close()\n },\n }\n}\n\nasync function runSession({ options, openRpc, url, instanceId }: { options: ResolvedOptions; openRpc: OpenRpc; url: URL; instanceId: string }) {\n const { hooks, signal, heartbeatInterval, token, studioUrl, version } = options\n const session: Session = { connected: Promise.withResolvers(), closed: false }\n const agent = new Agent({ options, session })\n const rpc = openRpc({ url, token, instanceId, agent })\n signal?.addEventListener('abort', rpc.close, { once: true })\n let timer: ReturnType<typeof setTimeout> | undefined\n\n // Races each ping against a deadline, so a half-open socket can't hang it forever.\n const heartbeat = async (): Promise<void> => {\n let deadline: ReturnType<typeof setTimeout> | undefined\n const timedOut = new Promise<boolean>((resolve) => (deadline = setTimeout(resolve, PING_TIMEOUT_MS, true)))\n const failed = await Promise.race([\n Promise.resolve(rpc.studio.ping()).then(\n () => false,\n () => true,\n ),\n timedOut,\n ])\n clearTimeout(deadline)\n if (failed) return rpc.close()\n if (!session.closed) timer = setTimeout(heartbeat, heartbeatInterval)\n }\n\n void session.connected.promise.then(\n async (info) => {\n await emit(hooks, 'studio:connected', { ...info, url: studioUrl, versions: { studio: info.studioVersion, kubb: kubbVersion, agent: version } })\n if (!session.closed) timer = setTimeout(heartbeat, heartbeatInterval)\n },\n () => {},\n )\n\n const close = await rpc.closed\n session.closed = true\n clearTimeout(timer)\n signal?.removeEventListener('abort', rpc.close)\n session.connected.reject(new Error('The socket closed before Studio called connect()'))\n // Captured and aborted before the warning, so a slow listener neither keeps the run going nor\n // sees it finish and clear `session.active` first.\n const active = session.active\n if (active) {\n active.abort()\n await emit(hooks, 'studio:warn', { message: 'Canceled the running generation: the connection to Kubb Studio closed' })\n }\n await active?.settled\n await agent.clear()\n\n return { ...close, connected: session.info !== undefined }\n}\n\n/**\n * The connection loop with a swappable transport. {@link connectAgent} passes a real WebSocket.\n */\n/** The entry Studio named by position or `name`, else the first. `undefined` for one the file does not have. */\nfunction pickConfig(configs: Array<Config>, ref: ConfigRef | undefined): Config | undefined {\n if (typeof ref === 'string') return configs.find((config) => config.name === ref)\n if (ref !== undefined && !Number.isSafeInteger(ref)) return undefined\n return configs[ref ?? 0]\n}\n\n/** The input path or URL Studio may show: no inline document, and no credentials from a URL. */\nfunction reportedInput(input: Config['input']): string | undefined {\n if (typeof input !== 'string') return undefined\n const kind = getInputKind(input)\n if (kind === 'inline') return undefined\n // The scp-style git form (`git+git@host:org/repo.git`) is no URL and carries no password.\n if ((kind !== 'url' && kind !== 'git') || !URL.canParse(input)) return input\n const url = new URL(input)\n url.username = ''\n url.password = ''\n return url.href\n}\n\n/** A JSON copy of one resolved entry, each extension named by the package its manifest is in. */\nfunction toEntryView(config: Config, extensions: InstalledExtensions): ConfigEntryView {\n const input = reportedInput(config.input)\n return {\n ...(config.name !== undefined && { name: config.name }),\n ...(input !== undefined && { input }),\n output: config.output.path,\n plugins: config.plugins.map((plugin) => ({\n name: toStudioName({ name: resolveMeta(plugin).name, extensions }),\n options: toJSONOptions(plugin.options),\n })),\n adapter: config.adapter && {\n name: toStudioName({ name: resolveMeta(config.adapter).name, extensions, kind: 'adapter' }),\n options: toJSONOptions(config.adapter.options),\n },\n parsers: config.parsers.map((parser) => ({\n name: toStudioName({ name: resolveMeta(parser).name, extensions, kind: 'parser' }),\n options: toJSONOptions(parser.options),\n })),\n }\n}\n\nexport async function runAgent({ options, openRpc }: { options: ConnectAgentOptions; openRpc: OpenRpc }): Promise<void> {\n const root = options.root ?? process.cwd()\n const resolved: ResolvedOptions = {\n ...options,\n studioUrl: options.studioUrl ?? defaultStudioUrl,\n root,\n configFile: path.resolve(root, options.configPath),\n permissions: { allowWrite: false, allowConfigEdit: false, allowExec: false, allowRead: false, allowReadAst: false, ...options.permissions },\n hooks: options.hooks ?? new Hookable<KubbHooks>(),\n maxRetryDelay: options.maxRetryDelay ?? MAX_RETRY_DELAY_MS,\n heartbeatInterval: Math.min(options.heartbeatInterval ?? HEARTBEAT_INTERVAL_MS, MAX_HEARTBEAT_INTERVAL_MS),\n }\n const { studioUrl, hooks, signal, maxRetryDelay } = resolved\n const url = secureUrl({ studioUrl, path: AGENT_SOCKET_PATH, socket: true })\n // One per call, so a reconnect is the same process to Studio and a restart is a new one.\n const instanceId = randomUUID()\n let attempt = 0\n\n while (!signal?.aborted) {\n const { code, reason, connected } = await runSession({ options: resolved, openRpc, url, instanceId })\n if (signal?.aborted) return\n await emit(hooks, 'studio:disconnected', { code, reason })\n\n if (code === AgentCloseCode.UNAUTHORIZED) throw new InvalidAgentTokenError(studioUrl)\n if (code === AgentCloseCode.INCOMPATIBLE) throw new IncompatibleAgentError({ studioUrl, detail: reason })\n if (code === AgentCloseCode.SUPERSEDED) return\n\n // Reset only once Studio called connect(), so a socket that opens and closes again backs off.\n if (connected) attempt = 0\n const delayMs = Math.random() * Math.min(1_000 * 2 ** Math.min(attempt++, 16), maxRetryDelay)\n await emit(hooks, 'studio:reconnecting', { delayMs })\n await delay(delayMs, undefined, { signal }).catch(() => {})\n }\n}\n\n/**\n * Connects this project to Kubb Studio and serves its commands until `signal` aborts. Reconnects\n * with jittered backoff, and resolves when another process of the agent takes over. Rejects with\n * {@link InvalidAgentTokenError} so the host can pair again, or {@link IncompatibleAgentError}.\n *\n * @example\n * ```ts\n * const hooks = new Hookable<KubbHooks>()\n * hooks.hook('studio:connected', ({ agentSlug }) => console.log(`Connected as ${agentSlug}`))\n *\n * await connectAgent({ token, configPath: 'kubb.config.ts', loadConfigs, version: '1.0.0', hooks, signal })\n * ```\n */\nexport function connectAgent(options: ConnectAgentOptions): Promise<void> {\n return runAgent({ options, openRpc: openWebSocketRpc })\n}\n","import { hash } from 'node:crypto'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { toError } from '@internals/utils'\nimport { Diagnostics } from '@kubb/core'\nimport { ofetch } from 'ofetch'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\n/**\n * RFC 8628 device-authorization response from Studio's `/api/auth/device/code` endpoint.\n * Field names match the RFC; the CLI polls with `device_code` and shows `user_code` to the user.\n */\nexport type PairingSession = {\n device_code: string\n user_code: string\n verification_uri: string\n verification_uri_complete: string\n expires_in: number\n interval: number\n}\n\ntype PairingResult = {\n /**\n * Bearer token for this machine. Write credentials with mode 0600 and never log the value.\n */\n token: string\n agent: {\n /**\n * Stable agent id in Studio.\n */\n id: string\n /**\n * Short slug used in logs and the UI (for example `brave-otter`).\n */\n slug: string\n /**\n * Display name chosen at pairing time.\n */\n name: string\n /**\n * This agent's organization slug, absent for a sandbox or global agent, which has none.\n */\n organizationSlug?: string\n }\n}\n\n/**\n * What this machine registers as. Any member may approve `cli` (`kubb studio`); only an admin may\n * approve `user` and `sandbox` (the Docker image). A `ci` agent never pairs.\n */\ntype PairingAgentType = 'cli' | 'user' | 'sandbox'\n\n/** Labels, not secrets: a person approving the code in the browser is what authorizes a pairing. */\nconst CLIENT_IDS = { cli: 'kubb-cli', agent: 'kubb-agent' } as const\n\n/**\n * Thrown when a caller aborts `startPairing` or `pollForPairingToken` through their `signal`, such\n * as a `kubb studio` shutdown mid-pairing. Distinct from a denial or an expired code, so a host can\n * exit quietly instead of reporting a pairing failure.\n */\nexport class PairingCanceledError extends Error {\n constructor() {\n super('Pairing was canceled')\n this.name = 'PairingCanceledError'\n }\n}\n\n/** Thrown when the code expired unapproved. A fresh code can still succeed. */\nexport class PairingExpiredError extends Error {\n constructor(message = 'The pairing code expired, pair again') {\n super(message)\n this.name = 'PairingExpiredError'\n }\n}\n\n/** Thrown when the pairing was denied in the browser, including by the organization's agent limit. */\nexport class PairingDeniedError extends Error {\n constructor(message = 'Pairing was denied in the browser') {\n super(message)\n this.name = 'PairingDeniedError'\n }\n}\n\ntype StartPairingOptions = {\n studioUrl?: string\n type: PairingAgentType\n /**\n * Display name for the agent, usually the project or machine name.\n */\n name: string\n hostname: string\n /**\n * A stable secret the host keeps for this machine. Studio stores its hash against the agent, so\n * the same machine pairing again rotates one agent's token instead of creating a second agent.\n */\n machineId: string\n /**\n * Aborting this cancels the request in flight and rejects with {@link PairingCanceledError}.\n */\n signal?: AbortSignal\n}\n\n/**\n * Asks Studio for a pairing code, sending the hashed machine id with it.\n */\nexport async function startPairing({ studioUrl = defaultStudioUrl, type, name, hostname, machineId, signal }: StartPairingOptions): Promise<PairingSession> {\n try {\n const pairing = await ofetch<PairingSession>(secureUrl({ studioUrl, path: '/api/auth/device/code' }).href, {\n method: 'POST',\n body: {\n client_id: type === 'cli' ? CLIENT_IDS.cli : CLIENT_IDS.agent,\n name,\n hostname,\n machine_token: hash('sha256', machineId),\n agent_kind: type === 'cli' ? undefined : type,\n },\n signal,\n })\n if (typeof pairing?.device_code !== 'string')\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Kubb Studio returned no pairing code',\n help: 'Try again later. If it keeps failing, check the Kubb Studio status.',\n })\n\n return pairing\n } catch (error) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n throw error\n }\n}\n\ntype PollOptions = {\n studioUrl?: string\n session: PairingSession\n /**\n * Aborting this stops polling and rejects with {@link PairingCanceledError}, whether the abort\n * lands between polls or during the wait for the next one.\n */\n signal?: AbortSignal\n /** Called when a poll could not reach Studio. Polling carries on. */\n onRetry?: (error: Error) => void\n}\n\ntype PollError = 'authorization_pending' | 'slow_down' | 'expired_token' | 'access_denied' | 'invalid_grant'\n\ntype PollResponse =\n | PairingResult\n | {\n error: PollError | string\n /**\n * Why, when Studio has something more useful to say than the RFC code. An approval that hits\n * the organization's agent limit comes back as `access_denied` with the limit spelled out.\n */\n error_description?: string\n }\n\nfunction isPairingResult(response: PollResponse): response is PairingResult {\n return 'token' in response && typeof response.token === 'string'\n}\n\n/**\n * Polls until the user approves or denies, honoring the server's `slow_down` back-off.\n *\n * Studio's own endpoint is used rather than the auth layer's `/device/token`, because an approved\n * Kubb pairing is worth an agent bearer token, not a user session.\n *\n * @throws {PairingExpiredError} when the code expires before anyone approves it.\n * @throws {PairingDeniedError} when the pairing is denied in the browser.\n * @throws {PairingCanceledError} when `signal` aborts.\n */\nexport async function pollForPairingToken({ studioUrl = defaultStudioUrl, session, signal, onRetry }: PollOptions): Promise<PairingResult> {\n // Both fields cross the network, so neither is trusted as-is: a missing or zero `interval` would\n // spin the poll loop, and a missing or zero `expires_in` would expire the code before the first\n // poll. `> 0` is also false for `NaN` and for a missing field, so it doubles as the type guard.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let intervalMs = (session.interval > 0 ? session.interval : 5) * 1000\n\n while (Date.now() < deadline) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n try {\n await delay(intervalMs, undefined, { signal })\n } catch {\n throw new PairingCanceledError()\n }\n\n let response: PollResponse\n try {\n // A denial, an expiry, and \"not yet\" all come back as 4xx with a body to switch on.\n const { status, _data } = await ofetch.raw<PollResponse>(secureUrl({ studioUrl, path: '/api/agent/token' }).href, {\n method: 'POST',\n body: { device_code: session.device_code },\n signal,\n ignoreResponseError: true,\n })\n if (status >= 500 || !_data || typeof _data !== 'object')\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio answered with status ${status}`,\n help: 'Try again later.',\n })\n response = _data\n } catch (error) {\n if (signal?.aborted) {\n throw new PairingCanceledError()\n }\n\n // Studio can be briefly unreachable (a deploy) while the code is still valid, so retry.\n onRetry?.(toError(error))\n continue\n }\n\n if (isPairingResult(response)) {\n return response\n }\n\n if (!('error' in response) || typeof response.error !== 'string') {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Kubb Studio returned an empty pairing response, pair again',\n })\n }\n\n if (response.error === 'authorization_pending') {\n continue\n }\n\n if (response.error === 'slow_down') {\n intervalMs += 5_000\n continue\n }\n\n if (response.error === 'access_denied') {\n throw new PairingDeniedError(response.error_description)\n }\n\n if (response.error === 'expired_token' || response.error === 'invalid_grant') {\n throw new PairingExpiredError(response.error_description)\n }\n\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: response.error_description ?? `Pairing failed (${response.error})`,\n help: 'Pair again with `kubb studio login`.',\n })\n }\n\n throw new PairingExpiredError()\n}\n\ntype PairAgentOptions = StartPairingOptions & {\n /** Shows the code to whoever approves it. Called again for each fresh code. */\n onCode: (session: PairingSession, attempt: number) => void | Promise<void>\n /** Called when a poll could not reach Studio. Polling carries on. */\n onRetry?: (error: Error) => void\n /**\n * Codes to ask for in total when one expires unapproved. A denial or abort ends it at once.\n * @default 1\n */\n maxAttempts?: number\n}\n\n/**\n * Pairs this machine with Studio: asks for a code, hands it to the host to show, and waits for approval.\n */\nexport async function pairAgent({ onCode, onRetry, maxAttempts = 1, ...options }: PairAgentOptions): Promise<PairingResult> {\n for (let attempt = 1; ; attempt++) {\n const session = await startPairing(options)\n await onCode(session, attempt)\n\n try {\n return await pollForPairingToken({ studioUrl: options.studioUrl, session, signal: options.signal, onRetry })\n } catch (error) {\n if (!(error instanceof PairingExpiredError) || attempt >= maxAttempts) {\n throw error\n }\n }\n }\n}\n","import { tmpdir } from 'node:os'\nimport { join, resolve } from 'node:path'\nimport { gzipSync } from 'node:zlib'\nimport { mkdir, mkdtemp, read, rm, writeRaw } from '@internals/utils'\nimport { type Config, Diagnostics, fsStorage, type Hookable, type KubbHooks, readInstalledPackages, resolveMeta } from '@kubb/core'\nimport { ofetch } from 'ofetch'\nimport { generate, hashOf } from './generations.ts'\nimport { MAX_SNAPSHOT_BYTES, type PublishedSnapshot, type SnapshotUploadMetadata } from './protocol.ts'\nimport { toPackageName } from './resolveConfig.ts'\nimport { defaultStudioUrl, secureUrl } from './url.ts'\n\nconst UPLOAD_TIMEOUT_MS = 120_000\n\n// Plugins whose output a snapshot carries without depending on the plugin package.\nconst BUNDLED_DEPENDENCIES = ['@kubb/plugin-barrel']\n\ntype SnapshotFiles = Record<string, string>\ntype SnapshotPackage = { name: string; version: string; peerDependencies: Record<string, string> }\n\n/**\n * Maps a generated file to its path in the package, from its `src`/`dist` segment on, without `..` parts that could escape it.\n */\nfunction packagePath(filePath: string): string {\n const normalized = filePath.replaceAll('\\\\', '/')\n const relativePath = normalized.match(/\\/(?:src|dist)\\/.*$/)?.[0] ?? normalized\n return relativePath\n .split('/')\n .filter((part) => part && part !== '.' && part !== '..')\n .join('/')\n}\n\n/**\n * Splits a tar path into the 100-byte USTAR `name` and the 155-byte `prefix`, and throws for a path that fits neither.\n */\nfunction splitEntryPath(path: string): { name: string; prefix: string } {\n if (Buffer.byteLength(path) <= 100) return { name: path, prefix: '' }\n for (let i = path.lastIndexOf('/'); i > 0; i = path.lastIndexOf('/', i - 1)) {\n const prefix = path.slice(0, i)\n const name = path.slice(i + 1)\n if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(name) <= 100) return { name, prefix }\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Snapshot path is too long for a tar entry: ${path}`,\n help: 'Shorten the output path or the generated file names.',\n })\n}\n\nfunction header(path: string, size: number): Buffer {\n const { name, prefix } = splitEntryPath(path)\n const value = Buffer.alloc(512)\n value.write(name)\n value.write('0000644\\0', 100)\n for (const offset of [108, 116, 265, 297]) value.write('0000000\\0', offset)\n value.write(`${size.toString(8).padStart(11, '0')}\\0`, 124)\n // npm's fixed mtime, so the same files always pack to the same integrity.\n value.write('03560116604\\0', 136)\n value.fill(32, 148, 156)\n value.write('0', 156)\n value.write('ustar\\0', 257)\n value.write('00', 263)\n value.write(prefix, 345)\n const checksum = value.reduce((sum, byte) => sum + byte, 0)\n value.write(`${checksum.toString(8).padStart(6, '0')}\\0 `, 148)\n return value\n}\n\n/**\n * Packs a generation's files into a gzipped, npm-installable tarball: a `package/` root with the\n * generated sources, a `tsdown`-built `dist/` (esm + cjs), and a `package.json` manifest.\n */\nexport async function createSnapshotPackage({ files, packageInfo }: { files: SnapshotFiles; packageInfo: SnapshotPackage }): Promise<Buffer> {\n const sources = new Map<string, { name: string; content: string }>()\n for (const [name, content] of Object.entries(files)) {\n const path = packagePath(name)\n const owner = sources.get(path)?.name\n if (owner)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Snapshot has two generated files that sanitize to the same path \"package/${path}\": \"${owner}\" and \"${name}\"`,\n help: 'Rename one of the generated files, for example with a plugin resolver.',\n })\n sources.set(path, { name, content })\n }\n const root = await mkdtemp(join(tmpdir(), 'kubb-snapshot-'))\n const dist = join(root, 'dist')\n\n try {\n await mkdir(dist)\n await Promise.all(\n [...sources].map(async ([path, { content }]) => {\n await writeRaw(join(root, path), content)\n }),\n )\n const entry = [...sources.keys()].filter((path) => /\\.(?:[cm]?[jt]sx?)$/.test(path)).map((path) => join(root, path))\n if (entry.length) {\n // Loaded on first use: tsdown is large, and most agent processes never pack a snapshot.\n const { build } = await import('tsdown')\n // `fixedExtension` emits the `.mjs`/`.cjs` the manifest names, whatever \"type\" the host's own package.json sets.\n await build({\n entry,\n outDir: dist,\n format: ['esm', 'cjs'],\n dts: false,\n sourcemap: false,\n unbundle: true,\n report: false,\n logLevel: 'silent',\n fixedExtension: true,\n })\n }\n const built = await fsStorage().readKeys(dist)\n // Only `@kubb/plugin-barrel` produces a `dist/index.*` for `main`, `module`, and `exports['.']` to name.\n const hasBarrel = built.includes('index.mjs') && built.includes('index.cjs')\n const manifest = {\n ...packageInfo,\n type: 'module',\n ...(hasBarrel ? { main: './dist/index.cjs', module: './dist/index.mjs' } : {}),\n // `exports` denies any subpath it does not list, so the wildcard keeps each generated file importable.\n exports: {\n ...(hasBarrel ? { '.': { import: './dist/index.mjs', require: './dist/index.cjs' } } : {}),\n './*': { import: './dist/*.mjs', require: './dist/*.cjs' },\n },\n }\n const entries = new Map<string, string>([\n ['package.json', JSON.stringify(manifest, null, 2)],\n ...[...sources].map(([path, { content }]) => [path, content] as const),\n ...(await Promise.all(built.map(async (key) => [`dist/${key}`, await read(join(dist, key))] as const))),\n ])\n const chunks = [...entries].flatMap(([path, content]) => {\n const bytes = Buffer.from(content)\n return [header(`package/${path}`, bytes.length), bytes, Buffer.alloc((512 - (bytes.length % 512)) % 512)]\n })\n return gzipSync(Buffer.concat([...chunks, Buffer.alloc(1024)]))\n } finally {\n await rm(root, { recursive: true, force: true })\n }\n}\n\ntype CreateSnapshotOptions = Omit<SnapshotUploadMetadata, 'hashes' | 'peerDependencies'> & {\n studioUrl?: string\n /**\n * Organization CI API key, sent as `x-api-key`.\n */\n apiKey: string\n /**\n * The project's Kubb config, generated like `kubb generate`: formatter, linter, and `output.postGenerate` included.\n */\n config: Config\n hooks?: Hookable<KubbHooks>\n signal?: AbortSignal\n}\n\n/**\n * Generates the project, packs it as an npm tarball, and publishes it to Studio in one `POST /api/snapshots` request.\n *\n * @example\n * ```ts\n * const { url } = await createSnapshot({ apiKey: process.env.KUBB_TOKEN!, config, id: 'gh:123:pr-4', name: 'acme/api#4', packageName: '@acme/api', version: '1.0.0' })\n * ```\n */\nexport async function createSnapshot({\n studioUrl = defaultStudioUrl,\n apiKey,\n config,\n hooks,\n signal,\n ...metadata\n}: CreateSnapshotOptions): Promise<PublishedSnapshot> {\n const url = secureUrl({ studioUrl, path: '/api/snapshots' })\n const generated = await generate({ config: { ...config, storage: fsStorage() }, hooks, signal, allowExec: true })\n const files = Object.fromEntries(\n await Promise.all(\n [...generated.paths].map(async (path) => {\n const content = await generated.storage.readItem(resolve(generated.root, path))\n if (content === null)\n throw new Diagnostics.Error({\n code: Diagnostics.code.internalError,\n severity: 'error',\n message: `The generation listed ${path} but did not keep its content`,\n })\n return [path, content] as const\n }),\n ),\n )\n const pluginNames = config.plugins.map((plugin) => resolveMeta(plugin).name)\n const installed = await readInstalledPackages({ root: config.root, packages: pluginNames.map(toPackageName), resolveFrom: ['kubb'] })\n // A third-party plugin is found by the manifest its package ships, as `@kubb/plugin-x` only names a built-in.\n const packageOf = (name: string) => installed.find(({ manifest }) => manifest?.kind === 'plugin' && manifest.name === name)?.package ?? toPackageName(name)\n const names = [...new Set(pluginNames.map(packageOf))]\n const peerDependencies = Object.fromEntries(installed.flatMap(({ package: name, version }) => (names.includes(name) && version ? [[name, version]] : [])))\n // The package would declare no version for a plugin that is not installed.\n const missing = names.filter((name) => !(name in peerDependencies) && !BUNDLED_DEPENDENCIES.includes(name))\n if (missing.length)\n throw new Diagnostics.Error({\n code: Diagnostics.code.missingDependency,\n severity: 'error',\n message: `Missing dependencies: ${missing.join(', ')}`,\n help: 'Install the listed plugin packages in the project.',\n })\n\n const bytes = await createSnapshotPackage({ files, packageInfo: { name: metadata.packageName, version: metadata.version, peerDependencies } })\n if (bytes.length > MAX_SNAPSHOT_BYTES) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `The snapshot is ${Math.ceil(bytes.length / 1024 / 1024)} MB, over the ${MAX_SNAPSHOT_BYTES / 1024 / 1024} MB limit`,\n help: 'Generate fewer files, for example with `include` or `exclude` on the plugins.',\n })\n }\n\n const hashes = Object.fromEntries(Object.entries(files).map(([path, content]) => [path, hashOf(content)]))\n const body = new FormData()\n body.set('metadata', JSON.stringify({ ...metadata, hashes, peerDependencies } satisfies SnapshotUploadMetadata))\n body.set('tarball', new Blob([new Uint8Array(bytes)], { type: 'application/gzip' }), 'snapshot.tgz')\n\n const timeout = AbortSignal.timeout(UPLOAD_TIMEOUT_MS)\n // A redirect would forward the CI key and tarball to wherever it points.\n const { ok, status, _data } = await ofetch.raw<{ snapshot?: PublishedSnapshot; message?: string; data?: { upgradeUrl?: string } }>(url.href, {\n method: 'POST',\n headers: { 'x-api-key': apiKey },\n body,\n redirect: 'error',\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n ignoreResponseError: true,\n })\n if (!ok) {\n const upgrade = _data?.data?.upgradeUrl ? ` Upgrade at ${_data.data.upgradeUrl}.` : ''\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio refused the snapshot (status ${status})${_data?.message ? `: ${_data.message}` : ''}.${upgrade}`,\n help: 'Check the API key and your plan, then try again.',\n })\n }\n if (!_data?.snapshot)\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `Kubb Studio returned no snapshot (status ${status})`,\n help: 'Try again later.',\n })\n return _data.snapshot\n}\n"],"mappings":"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"}
|