@joycostudio/studio 0.1.6 → 0.2.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/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/core/tool.ts","../src/runtime/runtime.ts","../src/core/result.ts","../src/core/validate.ts","../src/runtime/files.ts","../src/runtime/server.ts","../src/runtime/capture.ts","../src/runtime/mcp.ts","../src/discovery/generate.ts","../src/discovery/settings.ts","../src/runtime/load.ts","../src/runtime/ports.ts","../src/init.ts","../package.json","../src/discovery/scaffold.ts","../src/discovery/watch.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { DEFAULT_PORT } from './core/tool'\nimport { createRuntime, loadConfig } from './runtime'\nimport { freeAppPort, serveBridgeNear } from './runtime/ports'\nimport { init } from './init'\nimport { generate } from './discovery/generate'\nimport { watchDiscovery } from './discovery/watch'\n\nconst HELP = `Usage: studio dev [--config studio.config.ts] [--port ${DEFAULT_PORT}] [--app-url http://localhost:3000] [-- <command...>]\n studio generate [--config studio.config.ts]\n studio install-browser\n studio init [directory] [--no-install]\n\nStarts the Studio runtime with a WebSocket bridge and an HTTP MCP endpoint at /mcp,\nmoving to the next free port when another project's Studio already uses it.\nAnything after \"--\" runs alongside it (e.g. \"next dev\") with STUDIO_PORT set to the runtime port,\nand the runtime stops when that command exits.\nSet appUrl in the config or pass --app-url to enable MCP preview capture. A configured local\nappUrl port is passed to the command as PORT, moved to the next free port when taken.\nRun \"studio install-browser\" once to install Chromium for captures.`\n\nasync function main(argv: string[]) {\n if (argv[0] === 'init') return init(argv.slice(1))\n if (argv[0] === 'install-browser') {\n const require = createRequire(import.meta.url)\n const cli = path.join(\n path.dirname(require.resolve('playwright/package.json')),\n require('playwright/package.json').bin.playwright,\n )\n const child = spawn(process.execPath, [cli, 'install', 'chromium'], { stdio: 'inherit' })\n child.once('error', (cause) => {\n console.error(cause.message)\n process.exit(1)\n })\n child.once('exit', (code) => process.exit(code ?? 1))\n return\n }\n const split = argv.indexOf('--')\n const own = split === -1 ? argv : argv.slice(0, split)\n const command = split === -1 ? [] : argv.slice(split + 1)\n const { positionals, values } = parseArgs({\n args: own,\n allowPositionals: true,\n options: {\n config: { type: 'string' },\n port: { type: 'string' },\n 'app-url': { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n })\n if (positionals[0] === 'generate') {\n await generate(process.cwd(), values.config)\n console.log('[studio] generated tool registry and types')\n return\n }\n if (values.help || positionals[0] !== 'dev') return console.log(HELP)\n\n const { config, root, discovery } = await loadConfig(process.cwd(), values.config)\n const [bin, ...args] = command\n const env = { ...process.env }\n let appUrl = values['app-url'] ?? config.appUrl\n // Projects share the default app port too: claim a free one for the wrapped app so captures follow it.\n const app = bin && !values['app-url'] && !env.PORT && appUrl && URL.canParse(appUrl) ? new URL(appUrl) : undefined\n if (app?.port && ['localhost', '127.0.0.1', '[::1]'].includes(app.hostname)) {\n const preferred = app.port\n app.port = env.PORT = String(await freeAppPort(app.hostname, Number(preferred)))\n if (app.port !== preferred) console.log(`[studio] port ${preferred} is in use, starting the app on ${app.origin}`)\n appUrl = app.href\n }\n\n const runtime = await createRuntime({ root, tools: config.tools })\n const port = Number(values.port ?? config.port ?? DEFAULT_PORT)\n const bridge = await serveBridgeNear(runtime, { port, origins: config.origins, appUrl })\n if (bridge.port !== port) console.log(`[studio] port ${port} is in use, probably by another project's Studio`)\n console.log(\n `[studio] runtime ready on ws://127.0.0.1:${bridge.port} — ${config.tools.length} tool(s) in ${path.relative(process.cwd(), root) || '.'}`,\n )\n console.log(`[studio] MCP ready on http://127.0.0.1:${bridge.port}/mcp`)\n\n let rejected = false\n let accepted = discovery\n const watcher =\n discovery &&\n watchDiscovery(discovery, async () => {\n try {\n const next = await loadConfig(process.cwd(), values.config, false, accepted)\n await runtime.replaceTools(next.config.tools)\n await next.discovery?.write()\n accepted = next.discovery\n rejected = false\n return next.discovery\n } catch (cause) {\n rejected = true\n throw cause\n }\n })\n const unsubscribe = runtime.subscribe((state) => {\n if (rejected && !state.dirty) watcher?.retry()\n })\n const shutdown = async (code = 0) => {\n watcher?.close()\n unsubscribe()\n runtime.close()\n await bridge.close()\n process.exit(code)\n }\n\n if (!bin) {\n process.once('SIGINT', () => void shutdown())\n process.once('SIGTERM', () => void shutdown())\n return\n }\n const child = spawn(bin, args, {\n stdio: 'inherit',\n env: {\n ...env,\n STUDIO_PORT: String(bridge.port),\n NEXT_PUBLIC_STUDIO_RUNTIME: `ws://127.0.0.1:${bridge.port}`,\n STUDIO_DISCOVERY_MANAGED: discovery ? '1' : '',\n ...(values.config ? { STUDIO_CONFIG: path.resolve(values.config) } : {}),\n },\n })\n child.once('exit', (code) => void shutdown(code ?? 0))\n for (const signal of ['SIGINT', 'SIGTERM'] as const) process.once(signal, () => child.kill(signal))\n}\n\nmain(process.argv.slice(2)).catch((cause) => {\n console.error(cause instanceof Error ? cause.message : cause)\n process.exit(1)\n})\n","import type { DebugSchema } from '@joycostudio/xyz/debug'\n\n/**\n * An SVG icon as data: `[tag, attributes]` children of a 24×24 stroke icon.\n * Lucide's core package (`import { Palette } from 'lucide'`) exports exactly this shape.\n */\nexport type ToolIcon = readonly (readonly [tag: string, attrs: Record<string, string | number | undefined>])[]\n\ntype ToolBase = {\n /** Unique, URL-safe identifier. */\n id: string\n title?: string\n /** Shown next to the tool in /studio. Data, not a component, so contracts stay loadable in Node. */\n icon?: ToolIcon\n /** App route that renders this tool's result, shown next to the controls in /studio. */\n preview?: string\n /** Use a bare iframe for tools that already own their canvas layout and headers. */\n previewLayout?: 'canvas' | 'custom'\n}\n\n/**\n * A tool's contract. Isomorphic on purpose: the runtime loads it in Node to\n * validate and persist, the app loads it in the browser to apply and debug.\n *\n * `TConfig` is the one type that is read, edited, applied, and persisted.\n */\nexport type ToolDefinition<TConfig extends object = object> = ToolBase & {\n /** Repo-relative JSON file the config persists to. Import that same file as `initial`. */\n file: string\n /** Config used before the runtime answers (and in production). */\n initial: TConfig\n /**\n * What can be tweaked, as an Xyz/Tweakpane schema bound to `config`.\n * Doubles as the runtime validator: every control's bounds are enforced on write.\n */\n controls: (config: TConfig) => DebugSchema\n}\n\n/** A tool with nothing to tune: a sidebar entry for its preview, without an inspector or config file. */\nexport type PreviewToolDefinition = ToolBase & {\n preview: string\n file?: never\n initial?: never\n controls?: never\n}\n\n/** A tool with a config. */\nexport type AnyTool = ToolDefinition<any>\n\n/** Anything `defineTool` returns: the kind follows from whether it declares a config. */\nexport type StudioTool = AnyTool | PreviewToolDefinition\n\nexport const hasConfig = (tool: StudioTool): tool is AnyTool => tool.controls !== undefined\n\n/** Filled by .studio/types.generated.ts in each consuming project. */\nexport interface DiscoveredToolConfigs {}\n\n/** A discovered declaration is resolved into a full definition by the generated registry. */\nexport type DiscoveredToolDefinition<TConfig extends object = object> = ToolBase & {\n /** JSON source relative to this tool file, or a tsconfig path alias. Defaults to ./config.json. */\n config?: string\n controls: (config: TConfig) => DebugSchema\n file?: never\n initial?: never\n}\nexport type ToolReference<TConfig extends object> = Pick<ToolDefinition<TConfig>, 'id' | 'controls'>\nexport type ConfigOf<TTool> = TTool extends ToolReference<infer TConfig> ? TConfig : never\n\nconst ID = /^[a-z0-9][a-z0-9-]*$/\n\n/** Discovered tools infer their config from the generated ID-to-JSON type map. */\nexport function defineTool<K extends keyof DiscoveredToolConfigs & string>(\n tool: Omit<DiscoveredToolDefinition<Extract<DiscoveredToolConfigs[K], object>>, 'id'> & { id: K },\n): DiscoveredToolDefinition<Extract<DiscoveredToolConfigs[K], object>>\n/** Existing explicitly registered tools remain supported. */\nexport function defineTool<TConfig extends object>(tool: ToolDefinition<TConfig>): ToolDefinition<TConfig>\nexport function defineTool(tool: PreviewToolDefinition): PreviewToolDefinition\n/** A discovered preview-only tool may infer its preview from the adjacent page. */\nexport function defineTool(\n tool: ToolBase & { controls?: never; config?: never; file?: never; initial?: never },\n): ToolBase\nexport function defineTool(tool: StudioTool | DiscoveredToolDefinition<any> | ToolBase) {\n if (!ID.test(tool.id)) throw new Error(`[studio] tool id \"${tool.id}\" must be kebab-case`)\n const value = tool as Partial<AnyTool>\n if (value.file !== undefined || value.initial !== undefined) {\n if (value.file === undefined || value.initial === undefined || value.controls === undefined)\n throw new Error(`[studio] tool \"${tool.id}\" needs all of file, initial, and controls, or none of them`)\n }\n return tool\n}\n\nexport type StudioConfig = {\n /** Explicit registry; omit to enable convention-based discovery. */\n tools?: readonly StudioTool[]\n /**\n * Directory to scan and watch for `studio.tool.ts` files, relative to\n * the project root.\n *\n * Defaults to the active Next.js app directory: `app/` or `src/app/`.\n * Set a narrower directory to reduce scanning and discovery triggers.\n * This does not change preview URLs.\n *\n * @example 'src/app/experiments'\n */\n toolsDir?: string\n /** Runtime WebSocket and HTTP MCP port. Defaults to 5179. */\n port?: number\n /** Browser origins allowed on the bridge and MCP endpoint. Defaults to localhost origins. */\n origins?: readonly string[]\n /** Running app URL (e.g. http://localhost:3000), used for MCP preview captures. */\n appUrl?: string\n}\n\nexport const DEFAULT_PORT = 5179\n\nexport function defineConfig<T extends StudioConfig>(config: T): T {\n return config\n}\n","import { watch, type FSWatcher } from 'node:fs'\nimport path from 'node:path'\nimport type { Op, Operations, ToolState, ToolSummary } from '../core/protocol'\nimport { error, success, type Result } from '../core/result'\nimport { hasConfig, type AnyTool, type StudioTool } from '../core/tool'\nimport { validateConfig } from '../core/validate'\nimport { hashOf, readDisk, resolveToolFile, serialize, writeAtomic } from './files'\n\ntype Entry = {\n tool: AnyTool\n file: string\n state: ToolState\n /** Serializes disk work per tool so saves and external reloads never interleave. */\n queue: Promise<unknown>\n}\n\nexport type RuntimeListener = (state: ToolState, origin: unknown) => void\n\nexport type Runtime = {\n root: string\n run<TOp extends Op>(\n op: TOp,\n params: Operations[TOp]['params'],\n origin?: unknown,\n ): Promise<Result<Operations[TOp]['result']>>\n subscribe(listener: RuntimeListener): () => void\n /** Atomically refresh definitions, retaining valid drafts and rejecting destructive changes. */\n replaceTools(tools: readonly StudioTool[]): Promise<void>\n close(): void\n}\n\nconst equal = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n const keys = Object.keys(a)\n return (\n keys.length === Object.keys(b).length &&\n keys.every((key) => equal((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n )\n}\n\nasync function load(tool: AnyTool, file: string) {\n const disk = await readDisk(file)\n if (!disk) return { value: structuredClone(tool.initial), hash: null }\n const parsed = validateConfig(tool, JSON.parse(disk.content))\n if (!parsed.ok)\n throw new Error(`[studio] ${path.basename(file)} is not a valid \"${tool.id}\" config: ${parsed.message}`)\n return { value: parsed.data, hash: disk.hash }\n}\n\nasync function prepare(root: string, tools: readonly StudioTool[]) {\n const entries = new Map<string, Entry>()\n const files = new Set<string>()\n\n const ids = new Set<string>()\n for (const tool of tools) {\n if (ids.has(tool.id)) throw new Error(`[studio] duplicate tool id \"${tool.id}\"`)\n ids.add(tool.id)\n // Preview-only tools are listed, but have no config for the runtime to own.\n if (!hasConfig(tool)) continue\n const file = await resolveToolFile(root, tool.file)\n if (files.has(file)) throw new Error(`[studio] tool \"${tool.id}\" shares its file with another tool`)\n files.add(file)\n const saved = await load(tool, file)\n entries.set(tool.id, {\n tool,\n file,\n queue: Promise.resolve(),\n state: {\n tool: tool.id,\n draft: { value: structuredClone(saved.value), revision: 0 },\n saved,\n dirty: false,\n conflict: false,\n },\n })\n }\n\n return { entries, ids }\n}\n\n/**\n * The single authority over tool configs: validates every write, owns draft\n * revisions, and is the only thing that touches the persisted files.\n */\nexport async function createRuntime({ root, tools }: { root: string; tools: readonly StudioTool[] }): Promise<Runtime> {\n root = path.resolve(root)\n let { entries, ids } = await prepare(root, tools)\n let changing: Promise<void> = Promise.resolve()\n\n const listeners = new Set<RuntimeListener>()\n const commit = (entry: Entry, next: Partial<ToolState>, origin?: unknown) => {\n const state = { ...entry.state, ...next }\n state.dirty = !equal(state.draft.value, state.saved.value)\n if (!state.dirty) state.conflict = false\n entry.state = state\n for (const listener of listeners) listener(state, origin)\n return state\n }\n const serial = <T>(entry: Entry, task: () => Promise<T>) => {\n const run = entry.queue.then(task)\n entry.queue = run.catch(() => {})\n return run\n }\n\n const handlers: { [TOp in Op]: (params: any, origin: unknown) => Promise<Result<Operations[TOp]['result']>> } = {\n 'tools.list': async () =>\n success(\n tools.map((tool): ToolSummary => ({\n id: tool.id,\n title: tool.title ?? tool.id,\n file: tool.file,\n icon: tool.icon,\n preview: tool.preview,\n })),\n ),\n\n 'tool.get': async ({ tool }) => withEntry(tool, async (entry) => success(entry.state)),\n\n 'tool.update': async ({ tool, value, revision }, origin) =>\n withEntry(tool, async (entry) => {\n if (revision !== undefined && revision !== entry.state.draft.revision)\n return error('stale_revision', `draft is at revision ${entry.state.draft.revision}, not ${revision}`)\n const parsed = validateConfig(entry.tool, value)\n if (!parsed.ok) return parsed\n const draft = { value: parsed.data, revision: entry.state.draft.revision + 1 }\n return success(commit(entry, { draft }, origin))\n }),\n\n 'tool.save': async ({ tool, revision, force = false }, origin) =>\n withEntry(tool, (entry) =>\n serial(entry, async () => {\n const { draft, saved } = entry.state\n if (revision !== draft.revision)\n return error('stale_revision', `draft is at revision ${draft.revision}, not ${revision}`)\n const disk = await readDisk(entry.file)\n if (!force && (entry.state.conflict || (disk?.hash ?? null) !== saved.hash)) {\n commit(entry, { conflict: true })\n return error('conflict', `${entry.tool.file} changed on disk; discard to reload or save with force`)\n }\n const content = serialize(draft.value)\n await writeAtomic(entry.file, content)\n return success(\n commit(entry, { saved: { value: structuredClone(draft.value), hash: hashOf(content) } }, origin),\n )\n }),\n ),\n\n 'tool.discard': async ({ tool, revision }, origin) =>\n withEntry(tool, async (entry) => {\n const { saved, draft } = entry.state\n if (revision !== undefined && revision !== draft.revision)\n return error('stale_revision', `draft is at revision ${draft.revision}, not ${revision}`)\n return success(\n commit(entry, { draft: { value: structuredClone(saved.value), revision: draft.revision + 1 } }, origin),\n )\n }),\n }\n\n async function withEntry<T>(id: unknown, task: (entry: Entry) => Promise<Result<T>>): Promise<Result<T>> {\n const entry = typeof id === 'string' ? entries.get(id) : undefined\n if (entry) return task(entry)\n return ids.has(id as string)\n ? error('no_config', `tool \"${String(id)}\" is preview-only and has no config`)\n : error('unknown_tool', `no tool \"${String(id)}\"`)\n }\n\n /** Pick up edits made outside Studio (editor, git checkout, an agent). */\n const reload = (entry: Entry) =>\n serial(entry, async () => {\n const disk = await readDisk(entry.file)\n const { saved, draft, dirty } = entry.state\n if ((disk?.hash ?? null) === saved.hash) return\n if (!disk) return commit(entry, { saved: { ...saved, hash: null } })\n let value: unknown\n try {\n value = JSON.parse(disk.content)\n } catch {\n return console.warn(`[studio] ignoring unparsable ${entry.tool.file}`)\n }\n const parsed = validateConfig(entry.tool, value)\n if (!parsed.ok) return console.warn(`[studio] ignoring invalid ${entry.tool.file}: ${parsed.message}`)\n const next: Partial<ToolState> = { saved: { value: parsed.data, hash: disk.hash } }\n if (dirty) next.conflict = true\n else next.draft = { value: structuredClone(parsed.data), revision: draft.revision + 1 }\n commit(entry, next)\n })\n\n const timers = new Map<Entry, NodeJS.Timeout>()\n const watchers: FSWatcher[] = []\n const bindWatchers = () => {\n for (const watcher of watchers.splice(0)) watcher.close()\n for (const timer of timers.values()) clearTimeout(timer)\n timers.clear()\n const byDirectory = Map.groupBy(entries.values(), (entry) => path.dirname(entry.file))\n for (const [directory, group] of byDirectory) {\n try {\n const watcher = watch(directory, (_, filename) => {\n for (const entry of group) {\n if (filename && filename !== path.basename(entry.file)) continue\n clearTimeout(timers.get(entry))\n timers.set(\n entry,\n setTimeout(() => {\n void changing\n .then(async () => {\n if (entries.get(entry.tool.id) === entry) await reload(entry)\n })\n .catch((cause) => console.error('[studio] reload failed', cause))\n }, 50),\n )\n }\n })\n watchers.push(watcher)\n } catch {\n console.warn(`[studio] not watching ${path.relative(root, directory)} (it does not exist yet)`)\n }\n }\n }\n bindWatchers()\n\n const replaceTools = (nextTools: readonly StudioTool[]) => {\n const update = changing.then(async () => {\n await Promise.all([...entries.values()].map((entry) => entry.queue))\n const prepared = await prepare(root, nextTools)\n for (const [id, old] of entries) {\n const next = prepared.entries.get(id)\n if ((!next || next.file !== old.file) && old.state.dirty)\n throw new Error(`Save or discard \"${id}\" before removing it or moving its config.`)\n if (!next || next.file !== old.file) continue\n const parsed = validateConfig(next.tool, old.state.draft.value)\n if (!parsed.ok && old.state.dirty)\n throw new Error(\n `Draft for \"${id}\" is incompatible with the new controls; save/discard it first: ${parsed.message}`,\n )\n if (parsed.ok && old.state.dirty) {\n next.state = {\n ...old.state,\n saved: next.state.saved,\n conflict: old.state.conflict || next.state.saved.hash !== old.state.saved.hash,\n draft: { value: parsed.data, revision: old.state.draft.revision + 1 },\n }\n } else {\n next.state.draft.revision = old.state.draft.revision + 1\n }\n }\n entries = prepared.entries\n ids = prepared.ids\n tools = nextTools\n bindWatchers()\n for (const entry of entries.values()) commit(entry, {})\n })\n changing = update.catch(() => {})\n return update\n }\n\n return {\n root,\n run: async (op, params, origin) => {\n await changing\n return handlers[op](params, origin) as never\n },\n replaceTools,\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n close() {\n for (const watcher of watchers) watcher.close()\n for (const timer of timers.values()) clearTimeout(timer)\n listeners.clear()\n },\n }\n}\n","export type Success<T> = { ok: true; data: T }\n\nexport type Failure = {\n ok: false\n /** snake_case wire code, e.g. `invalid_config`. */\n error: string\n message?: string\n}\n\nexport type Result<T> = Success<T> | Failure\n\nexport const success = <T>(data: T): Success<T> => ({ ok: true, data })\n\nexport const error = (code: string, message?: string): Failure => ({\n ok: false,\n error: code,\n ...(message === undefined ? {} : { message }),\n})\n","import type { DebugSchema } from '@joycostudio/xyz/debug'\nimport { error, success, type Result } from './result'\nimport type { ToolDefinition } from './tool'\n\n/**\n * Accept `candidate` as a config for `tool` only if it has the exact shape of\n * `tool.initial` and every control in `tool.controls` accepts its value.\n * Returns a detached copy, never the input.\n */\nexport function validateConfig<TConfig extends object>(\n tool: ToolDefinition<TConfig>,\n candidate: unknown,\n): Result<TConfig> {\n const mismatch = shapeMismatch(tool.initial, candidate, 'config')\n if (mismatch) return error('invalid_config', mismatch)\n const config = structuredClone(candidate) as TConfig\n const invalid = invalidControl(tool.controls(config))\n return invalid ? error('invalid_config', invalid) : success(config)\n}\n\nfunction kind(value: unknown) {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'array'\n return typeof value\n}\n\nfunction shapeMismatch(reference: unknown, value: unknown, path: string): string | null {\n const expected = kind(reference)\n if (kind(value) !== expected) return `${path}: expected ${expected}, got ${kind(value)}`\n if (expected === 'number' && !Number.isFinite(value)) return `${path}: expected a finite number`\n if (expected === 'array') {\n const [first] = reference as unknown[]\n if (first === undefined) return null\n for (const [index, item] of (value as unknown[]).entries()) {\n const nested = shapeMismatch(first, item, `${path}[${index}]`)\n if (nested) return nested\n }\n }\n if (expected === 'object') {\n const ref = reference as Record<string, unknown>\n const obj = value as Record<string, unknown>\n for (const key of Object.keys(obj)) if (!(key in ref)) return `${path}.${key}: unknown key`\n for (const key of Object.keys(ref)) {\n if (!(key in obj)) return `${path}.${key}: missing`\n const nested = shapeMismatch(ref[key], obj[key], `${path}.${key}`)\n if (nested) return nested\n }\n }\n return null\n}\n\nconst isRgb = (value: unknown) =>\n typeof value === 'object' &&\n value !== null &&\n ['r', 'g', 'b'].every((channel) => Number.isFinite((value as Record<string, unknown>)[channel]))\n\nfunction invalidControl(schema: DebugSchema, path = ''): string | null {\n for (const [key, field] of Object.entries(schema)) {\n if (field.kind === 'button') continue\n const name = `${path}${field.label ?? key}`\n if (field.kind === 'folder') {\n const nested = invalidControl(field.definition.schema(), `${name}/`)\n if (nested) return nested\n continue\n }\n const value: unknown = field.read()\n if (field.kind === 'slider') {\n if (typeof value !== 'number' || value < field.min || value > field.max)\n return `${name}: expected a number in [${field.min}, ${field.max}], got ${JSON.stringify(value)}`\n } else if (field.kind === 'bool') {\n if (typeof value !== 'boolean') return `${name}: expected a boolean`\n } else if (field.kind === 'select') {\n const options = Object.values(field.options)\n if (!options.includes(value as string | number))\n return `${name}: expected one of ${JSON.stringify(options)}, got ${JSON.stringify(value)}`\n } else if (field.kind === 'color-string') {\n if (typeof value !== 'string') return `${name}: expected a color string`\n } else if (field.kind === 'color') {\n if (!isRgb(value)) return `${name}: expected an { r, g, b } color`\n }\n }\n return null\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { mkdir, readFile, realpath, rename, rm, stat } from 'node:fs/promises'\nimport { writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nconst inside = (root: string, target: string) => {\n const relative = path.relative(root, target)\n return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative)\n}\n\nconst exists = (target: string) =>\n stat(target).then(\n () => true,\n () => false,\n )\n\n/**\n * Resolve a tool's persistence target, refusing anything that is not a `.json`\n * file inside `root` — including paths that escape through a symlink.\n */\nexport async function resolveToolFile(root: string, file: string): Promise<string> {\n const fail = (reason: string) => new Error(`[studio] tool file \"${file}\" ${reason}`)\n if (path.isAbsolute(file)) throw fail('must be relative to the project root')\n if (path.extname(file) !== '.json') throw fail('must be a .json file')\n const absolute = path.resolve(root, file)\n if (!inside(root, absolute)) throw fail('escapes the project root')\n\n let probe = absolute\n while (!(await exists(probe))) probe = path.dirname(probe)\n if (probe !== root && !inside(await realpath(root), await realpath(probe))) throw fail('escapes the project root')\n return absolute\n}\n\nexport const hashOf = (content: string) => createHash('sha256').update(content).digest('hex').slice(0, 16)\n\nexport const serialize = (value: unknown) => `${JSON.stringify(value, null, 2)}\\n`\n\n/** The file's content and hash, or null when it does not exist. */\nexport async function readDisk(file: string): Promise<{ content: string; hash: string } | null> {\n try {\n const content = await readFile(file, 'utf8')\n return { content, hash: hashOf(content) }\n } catch (cause) {\n if ((cause as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw cause\n }\n}\n\n/** Write through a sibling temp file + rename so readers never see a half-written config. */\nexport async function writeAtomic(file: string, content: string) {\n await mkdir(path.dirname(file), { recursive: true })\n const temp = `${file}.${randomUUID()}.tmp`\n try {\n await writeFile(temp, content, 'utf8')\n await rename(temp, file)\n } catch (cause) {\n await rm(temp, { force: true })\n throw cause\n }\n}\n","import { createServer } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { localhostHostValidation, toNodeHandler } from '@modelcontextprotocol/node'\nimport { createMcpHandler } from '@modelcontextprotocol/server'\nimport { WebSocketServer, type WebSocket } from 'ws'\nimport type { Op, Request, ServerMessage } from '../core/protocol'\nimport { error } from '../core/result'\nimport { createPreviewCapture } from './capture'\nimport { createMcpServer } from './mcp'\nimport type { Runtime } from './runtime'\n\nconst LOCAL_ORIGIN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|\\[::1\\])(:\\d+)?$/\nconst OPS = new Set<string>(['tools.list', 'tool.get', 'tool.update', 'tool.save', 'tool.discard'] satisfies Op[])\n\nexport type BridgeOptions = {\n port: number\n host?: string\n /** Browser origins allowed to connect. Defaults to localhost. Non-browser clients send no origin. */\n origins?: readonly string[]\n /** Running app URL used to resolve registered preview routes for MCP capture. */\n appUrl?: string\n}\n\nexport type Bridge = { port: number; close(): Promise<void> }\n\nfunction parse(raw: string): Request | null {\n try {\n const message = JSON.parse(raw)\n if (typeof message?.id !== 'number' || !OPS.has(message.op)) return null\n return { id: message.id, op: message.op, params: message.params ?? {} }\n } catch {\n return null\n }\n}\n\n/** Share one runtime between the browser WebSocket bridge and the /mcp HTTP endpoint. */\nexport function serveBridge(\n runtime: Runtime,\n { port, host = '127.0.0.1', origins, appUrl }: BridgeOptions,\n): Promise<Bridge> {\n const allowed = (origin: string | undefined) =>\n origin === undefined || (origins ? origins.includes(origin) : LOCAL_ORIGIN.test(origin))\n\n const onerror = (cause: Error) => console.error('[studio] MCP request failed', cause)\n const previews = createPreviewCapture(runtime, { appUrl, runtimePort: () => (http.address() as AddressInfo).port })\n const mcp = createMcpHandler(() => createMcpServer(runtime, previews), { onerror })\n const handleMcp = toNodeHandler(mcp, { onerror })\n const validateHost = localhostHostValidation()\n const http = createServer((request, response) => {\n if (request.url?.split('?')[0] !== '/mcp') {\n response.writeHead(404).end()\n return\n }\n if (!validateHost(request, response)) return\n if (!allowed(request.headers.origin)) {\n response.writeHead(403).end('Origin not allowed')\n return\n }\n void handleMcp(request, response)\n })\n const server = new WebSocketServer({\n server: http,\n verifyClient: ({ origin }: { origin?: string }) => allowed(origin),\n })\n const send = (socket: WebSocket, message: ServerMessage) => {\n if (socket.readyState === socket.OPEN) socket.send(JSON.stringify(message))\n }\n\n server.on('connection', (socket) => {\n socket.on('message', async (raw) => {\n const request = parse(raw.toString())\n if (!request) return send(socket, { type: 'response', id: -1, result: error('bad_request') })\n const result = await runtime\n .run(request.op, request.params, socket)\n .catch((cause: unknown) => error('internal', cause instanceof Error ? cause.message : String(cause)))\n send(socket, { type: 'response', id: request.id, result })\n })\n })\n\n const unsubscribe = runtime.subscribe((state, origin) => {\n for (const client of server.clients) if (client !== origin) send(client, { type: 'state', state })\n })\n\n return new Promise((resolve, reject) => {\n server.once('error', (cause) => {\n unsubscribe()\n server.close()\n void mcp.close()\n void previews.close()\n reject(cause)\n })\n http.once('listening', () =>\n resolve({\n port: (http.address() as AddressInfo).port,\n close: async () => {\n unsubscribe()\n await previews.close()\n for (const client of server.clients) client.terminate()\n await mcp.close()\n await new Promise<void>((done) => server.close(() => done()))\n await new Promise<void>((done) => {\n http.close(() => done())\n http.closeAllConnections()\n })\n },\n }),\n )\n http.listen(port, host)\n })\n}\n","import type { Browser, BrowserContext } from 'playwright'\nimport type { Studio } from '../client/studio'\nimport { error, success, type Result } from '../core/result'\nimport type { Runtime } from './runtime'\n\nexport type CaptureParams = { tool: string; revision?: number; width?: number; height?: number }\ntype CaptureImage = {\n tool: string\n revision: number\n url: string\n width: number\n height: number\n settling: 'automatic'\n png: Buffer\n}\n\n/** Runs in the preview page. Reuse createStudio's HMR registry; tools need no capture integration. */\nfunction previewSnapshot({ port, tool, revision }: { port: number; tool: string; revision: number }) {\n const instances = (globalThis as { __joycoStudio?: Map<string, Studio> }).__joycoStudio\n for (const [address, studio] of instances ?? []) {\n const url = new URL(address)\n if (!['localhost', '127.0.0.1', '[::1]'].includes(url.hostname) || Number(url.port) !== port) continue\n const handle = studio.tools.find((handle) => handle.definition.id === tool)\n if (studio.connection.phase !== 'connected' || !handle?.state || handle.comparing) continue\n if (handle.state.draft.revision < revision) continue\n return { revision: handle.state.draft.revision, version: handle.version }\n }\n return null\n}\n\n/** One lazy browser per bridge, one isolated page per capture. Never writes a draft or a file. */\nexport function createPreviewCapture(\n runtime: Runtime,\n { appUrl, runtimePort, timeoutMs = 20_000 }: { appUrl?: string; runtimePort: () => number; timeoutMs?: number },\n) {\n let browser: Promise<Browser> | undefined\n let active = false\n let closed = false\n\n const capture = async ({\n tool,\n revision,\n width = 1200,\n height = 800,\n }: CaptureParams): Promise<Result<CaptureImage>> => {\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n if (active) return error('capture_busy', 'Another preview is being captured; retry when it finishes')\n const state = await runtime.run('tool.get', { tool })\n if (!state.ok) return state\n revision ??= state.data.draft.revision\n if (revision !== state.data.draft.revision) return error('stale_revision', 'Read the latest draft before capturing')\n const tools = await runtime.run('tools.list', {})\n if (!tools.ok) return tools\n const preview = tools.data.find((entry) => entry.id === tool)?.preview\n if (!preview) return error('preview_missing', `Tool \"${tool}\" has no preview route`)\n if (!appUrl) return error('app_url_missing', 'Set appUrl in studio.config.ts or pass studio dev --app-url <url>')\n let url: URL\n try {\n const base = new URL(appUrl)\n url = new URL(preview, base)\n if (!['http:', 'https:'].includes(base.protocol) || url.origin !== base.origin || url.username || url.password)\n return error('invalid_preview_url', 'The preview must be an HTTP(S) route on the configured app origin')\n } catch {\n return error('invalid_preview_url', 'appUrl must be an absolute HTTP(S) URL and preview must be a valid route')\n }\n\n // Recheck after the asynchronous runtime reads so concurrent MCP callers cannot race this lock.\n if (active) return error('capture_busy', 'Another preview is being captured; retry when it finishes')\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n active = true\n let context: BrowserContext | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n let timedOut = false\n let phase = 'starting the browser'\n try {\n browser ??= import('playwright').then(({ chromium }) => chromium.launch({ headless: true, timeout: 10_000 }))\n let instance: Browser\n try {\n instance = await browser\n } catch (cause) {\n browser = undefined\n return error('capture_unavailable', `Run \"studio install-browser\" to install Chromium. ${String(cause)}`)\n }\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n if (!instance.isConnected()) {\n browser = undefined\n return error('capture_unavailable', 'The capture browser disconnected; retry to start it again')\n }\n context = await instance.newContext({ viewport: { width, height }, deviceScaleFactor: 1 })\n timer = setTimeout(() => {\n timedOut = true\n void context?.close().catch(() => {})\n }, timeoutMs)\n const page = await context.newPage()\n page.setDefaultTimeout(timeoutMs)\n // Preview routes may load external assets, but must not navigate to a different app.\n await page.route('**/*', (route) => {\n const request = route.request()\n return request.isNavigationRequest() &&\n request.frame() === page.mainFrame() &&\n new URL(request.url()).origin !== url.origin\n ? route.abort()\n : route.continue()\n })\n phase = 'opening the preview'\n const response = await page.goto(url.href, { waitUntil: 'load' })\n if (!response?.ok()) return error('preview_failed', `Preview returned HTTP ${response?.status() ?? 'unknown'}`)\n\n phase = 'waiting for the preview to receive the draft'\n const target = { port: runtimePort(), tool, revision }\n const synced = await page.waitForFunction(previewSnapshot, target)\n const initial = await synced.jsonValue()\n await synced.dispose()\n if (initial?.revision !== revision) return error('stale_revision', 'The draft changed while opening the preview')\n\n phase = 'waiting for fonts, images, and animation frames'\n await page.evaluate(async () => {\n await document.fonts.ready\n await Promise.all(Array.from(document.images, (image) => image.decode().catch(() => {})))\n await new Promise<void>((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())))\n })\n const before = await page.evaluate(previewSnapshot, target)\n if (before?.revision !== revision) return error('stale_revision', 'The draft changed while settling the preview')\n\n phase = 'taking the screenshot'\n const png = await page.screenshot({ type: 'png', animations: 'disabled', timeout: timeoutMs })\n const after = await page.evaluate(previewSnapshot, target)\n const latest = await runtime.run('tool.get', { tool })\n if (!latest.ok) return latest\n if (latest.data.draft.revision !== revision || after?.revision !== revision || after.version !== before.version)\n return error('stale_revision', 'The preview changed during capture; read the latest draft and retry')\n return success({ tool, revision, url: page.url(), width, height, settling: 'automatic', png })\n } catch (cause) {\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n return error(\n timedOut || (cause instanceof Error && cause.name === 'TimeoutError') ? 'preview_not_ready' : 'capture_failed',\n `${phase}: ${String(cause)}`,\n )\n } finally {\n clearTimeout(timer)\n await context?.close().catch(() => {})\n active = false\n }\n }\n\n return {\n capture,\n async close() {\n closed = true\n await browser?.then((instance) => instance.close()).catch(() => {})\n browser = undefined\n },\n }\n}\n\nexport type PreviewCapture = ReturnType<typeof createPreviewCapture>\n","import { McpServer, type CallToolResult } from '@modelcontextprotocol/server'\nimport { z } from 'zod/v4'\nimport type { Op, Operations } from '../core/protocol'\nimport { success } from '../core/result'\nimport type { PreviewCapture } from './capture'\nimport type { Runtime } from './runtime'\n\nconst tool = z.string().min(1).describe('Registered Studio tool ID from studio_list_tools.')\nconst revision = z.number().int().nonnegative().describe('Draft revision returned by the latest read or update.')\n\n/** MCP is another caller of the live runtime; it never owns a second draft or writes files itself. */\nexport function createMcpServer(runtime: Runtime, previews: PreviewCapture) {\n const server = new McpServer(\n { name: 'joyco-studio', version: '0.0.0' },\n {\n instructions:\n 'List Studio tools, read the selected tool, then update its complete draft value. Updates appear live in the playground. Saving is a separate operation. If a revision is stale, read again and reconcile your changes before retrying.',\n },\n )\n const run = async <T extends Op>(op: T, params: Operations[T]['params']): Promise<CallToolResult> => {\n const result = await runtime.run(op, params)\n return {\n content: [{ type: 'text', text: JSON.stringify(result) }],\n structuredContent: result,\n isError: !result.ok,\n }\n }\n\n server.registerTool(\n 'studio_list_tools',\n {\n description:\n 'List registered Studio tools with their IDs, titles, config files, and preview routes. Tools without a file are preview-only: they have no config to read, edit, or capture.',\n inputSchema: z.object({}),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n },\n () => run('tools.list', {}),\n )\n server.registerTool(\n 'studio_get_tool',\n {\n description: 'Read a tool’s complete draft, revision, saved value, and dirty/conflict status before editing.',\n inputSchema: z.object({ tool }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n },\n (params) => run('tool.get', params),\n )\n server.registerTool(\n 'studio_update_tool',\n {\n description:\n 'Replace the complete draft config and update all connected previews. Read first and preserve fields you are not changing. The runtime validates types, slider bounds, and select options. Does not save to disk; rejects a stale revision.',\n inputSchema: z.object({ tool, revision, value: z.record(z.string(), z.unknown()) }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },\n },\n (params) => run('tool.update', params),\n )\n server.registerTool(\n 'studio_save_tool',\n {\n description:\n 'Persist a draft to its registered JSON file. Pass the latest draft revision. Rejects stale revisions and changes made on disk; force explicitly overwrites a disk conflict.',\n inputSchema: z.object({ tool, revision, force: z.boolean().optional() }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n },\n (params) => run('tool.save', params),\n )\n server.registerTool(\n 'studio_discard_tool',\n {\n description:\n 'Discard unsaved edits and restore the runtime’s latest saved value in every preview. Read first; rejects a stale revision.',\n inputSchema: z.object({ tool, revision }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },\n },\n (params) => run('tool.discard', params),\n )\n server.registerTool(\n 'studio_capture_preview',\n {\n description:\n 'Capture a registered preview as a PNG in a fresh browser page using the live draft. Requires appUrl and Chromium (studio install-browser). Defaults to the current revision and 1200×800. Waits for draft sync, fonts, images, and two animation frames; automatic settling does not guarantee arbitrary async scenes are finished. Rejects a draft change during capture. Does not share your open tab’s scroll, login, or interaction state.',\n inputSchema: z.object({\n tool,\n revision: revision.optional(),\n width: z.number().int().min(320).max(2560).optional(),\n height: z.number().int().min(240).max(1600).optional(),\n }),\n annotations: { readOnlyHint: true, idempotentHint: false, openWorldHint: true },\n },\n async (params): Promise<CallToolResult> => {\n const captured = await previews.capture(params)\n if (!captured.ok)\n return {\n content: [{ type: 'text', text: JSON.stringify(captured) }],\n structuredContent: captured,\n isError: true,\n }\n const { png, ...metadata } = captured.data\n const result = success(metadata)\n return {\n content: [\n { type: 'text', text: JSON.stringify(result) },\n { type: 'image', mimeType: 'image/png', data: png.toString('base64') },\n ],\n structuredContent: result,\n isError: false,\n }\n },\n )\n return server\n}\n","import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs'\nimport { mkdir, readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { resolveToolFile, writeAtomic } from '../runtime/files'\nimport { readSettings } from './settings'\n\nconst slash = (value: string) => value.split(path.sep).join('/')\nconst relativeImport = (from: string, to: string) => {\n const relative = slash(path.relative(path.dirname(from), to)).replace(/\\.(tsx?|jsx?|mts|mjs)$/, '')\n return /^\\.\\.?\\//.test(relative) ? relative : `./${relative}`\n}\nconst inside = (root: string, file: string) => {\n const relative = path.relative(root, file)\n return relative === '' || (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative))\n}\nconst fail = (file: string, message: string): never => {\n throw new Error(`[studio] ${file}: ${message}`)\n}\nconst HEADER = '// Generated by Studio. Do not edit.\\n'\n\n/** Inputs from a rejected update still need watching so finishing a tool can recover it. */\nexport class DiscoveryInputError extends Error {\n constructor(\n cause: unknown,\n readonly inputs: Set<string>,\n ) {\n super(cause instanceof Error ? cause.message : String(cause), { cause })\n }\n}\n\n// Value edits keep the browser seed stable; a different JSON shape needs a new module.\nfunction shape(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return `[${[...new Set(value.map(shape))].sort().join('|')}]`\n if (typeof value === 'object')\n return `{${Object.entries(value)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${shape(item)}`)\n .join(',')}}`\n return typeof value\n}\n\nexport type Discovery = {\n root: string\n toolsDir: string\n sources: Set<string>\n dependencies: Set<string>\n registry: string\n /** Browser bootstrap values retained across runtime-managed, value-only updates. */\n seeds: Map<string, object>\n declarations: { source: string; preview: string; title: string; file?: string; initial?: object }[]\n /** Publish validated output after the runtime has accepted a refresh. */\n write(): Promise<void>\n}\n\n/** Parse declarations before importing them: their contextual types do not exist on a clean checkout yet. */\nfunction declaration(file: string) {\n const source = ts.createSourceFile(file, readFileSync(file, 'utf8'), ts.ScriptTarget.Latest, true)\n const exported = source.statements.find(ts.isExportAssignment)\n const call = exported?.expression\n if (!call || !ts.isCallExpression(call) || !ts.isIdentifier(call.expression) || call.expression.text !== 'defineTool')\n return fail(file, 'default-export defineTool({ id, controls }) directly so discovery can inspect it.')\n const object = call.arguments[0]\n if (!object || !ts.isObjectLiteralExpression(object)) return fail(file, 'defineTool requires an object literal.')\n const properties = new Map<string, ts.ObjectLiteralElementLike>()\n for (const member of object.properties) {\n if (ts.isSpreadAssignment(member) || !member.name || ts.isComputedPropertyName(member.name))\n return fail(file, 'spread/computed tool options are not supported; put dynamic logic inside controls.')\n const key = member.name.getText(source).replace(/^['\"]|['\"]$/g, '')\n if (properties.has(key)) return fail(file, `duplicate option ${key}`)\n properties.set(key, member)\n }\n const literal = (key: string) => {\n const member = properties.get(key)\n if (!member) return undefined\n if (!ts.isPropertyAssignment(member) || !ts.isStringLiteral(member.initializer))\n return fail(file, `${key} must be a static string literal.`)\n return member.initializer.text\n }\n const id = literal('id')\n if (!id || !/^[a-z0-9][a-z0-9-]*$/.test(id)) return fail(file, 'id must be an explicit kebab-case string.')\n if (properties.has('file') || properties.has('initial'))\n return fail(file, 'discovered tools use config instead of file/initial; omit config for adjacent config.json.')\n const configurable = properties.has('controls')\n const config = literal('config')\n if (config !== undefined && !configurable) return fail(file, 'config requires controls.')\n return { id, config, configurable, preview: literal('preview'), source }\n}\n\nfunction pageRoute(app: string | undefined, file: string, explicit?: string) {\n if (explicit) return explicit\n const directory = path.dirname(file)\n if (!app || !inside(app, directory)) return fail(file, 'tools outside the app tree require an explicit preview URL.')\n if (!['tsx', 'ts', 'jsx', 'js'].some((ext) => existsSync(path.join(directory, `page.${ext}`))))\n return fail(file, 'add an adjacent page.tsx or specify preview explicitly.')\n const segments = slash(path.relative(app, directory)).split('/').filter(Boolean)\n if (segments.some((part) => part.includes('[') || part.startsWith('@') || /^\\(\\./.test(part) || part.startsWith('_')))\n return fail(file, 'dynamic, parallel, intercepted, and private routes require an explicit preview URL.')\n return '/' + segments.filter((part) => !/^\\(.+\\)$/.test(part)).join('/')\n}\n\nfunction walk(directory: string): string[] {\n return readdirSync(directory, { withFileTypes: true })\n .flatMap((entry) => {\n if (entry.name.startsWith('.') || entry.name === 'node_modules' || entry.isSymbolicLink()) return []\n const file = path.join(directory, entry.name)\n return entry.isDirectory() ? walk(file) : entry.name === 'studio.tool.ts' ? [file] : []\n })\n .sort()\n}\n\nfunction compilerConfig(root: string, dependencies: Set<string>) {\n const configFile = path.join(root, 'tsconfig.json')\n if (!existsSync(configFile)) return fail(root, 'discovery requires tsconfig.json.')\n const host: ts.ParseConfigFileHost = {\n ...ts.sys,\n readDirectory: () => [],\n readFile(file) {\n dependencies.add(path.resolve(file))\n return ts.sys.readFile(file)\n },\n onUnRecoverableConfigFileDiagnostic(error) {\n throw new Error(ts.flattenDiagnosticMessageText(error.messageText, '\\n'))\n },\n }\n const parsed = ts.getParsedCommandLineOfConfigFile(configFile, { resolveJsonModule: true }, host)\n if (!parsed) return fail(configFile, 'could not read TypeScript settings.')\n return parsed.options\n}\n\nasync function writeChanged(file: string, content: string) {\n if ((await readFile(file, 'utf8').catch(() => '')) === content) return\n await writeAtomic(file, content)\n}\n\n/** Generate only after all declarations and paths validate. Never loads preview components. */\nexport async function generate(\n cwd: string,\n explicit?: string,\n publish = true,\n previous?: Discovery,\n): Promise<Discovery | undefined> {\n const { root, config, file: settings } = await readSettings(cwd, explicit)\n if (config.tools !== undefined) return undefined\n const app = ['app', 'src/app'].map((dir) => path.join(root, dir)).find(existsSync)\n const toolsDir = config.toolsDir === undefined ? app : path.resolve(root, config.toolsDir)\n if (!toolsDir || !existsSync(toolsDir))\n return fail(root, 'no tools directory found; create app/ or configure toolsDir.')\n if (!inside(realpathSync(root), realpathSync(toolsDir)))\n return fail(toolsDir, 'toolsDir must stay inside the project.')\n const sources = new Set(walk(toolsDir))\n const dependencies = new Set<string>()\n if (settings) dependencies.add(settings)\n const options = compilerConfig(root, dependencies)\n const output = path.join(root, '.studio')\n const registry = path.join(output, 'registry.generated.ts')\n const types = path.join(output, 'types.generated.ts')\n const imports = [\n HEADER,\n '/// <reference path=\"./types.generated.ts\" />',\n \"import type { StudioTool, DiscoveredToolConfigs } from '@joycostudio/studio'\",\n ]\n const typeImports = [HEADER, \"import '@joycostudio/studio'\"]\n const declarations: Discovery['declarations'] = []\n const definitions: string[] = []\n const mappings: string[] = []\n const ids = new Set<string>()\n const destinations = new Set<string>()\n const seeds = new Map<string, object>()\n // Track local control helpers as well as the marker itself, without watching node_modules.\n const trackImports = (file: string) => {\n if (dependencies.has(file)) return\n dependencies.add(file)\n if (!/\\.[cm]?[jt]sx?$/.test(file)) return\n for (const imported of ts.preProcessFile(readFileSync(file, 'utf8')).importedFiles) {\n const resolved = ts.resolveModuleName(imported.fileName, file, options, ts.sys).resolvedModule?.resolvedFileName\n if (\n resolved &&\n inside(root, resolved) &&\n !resolved.includes(`${path.sep}node_modules${path.sep}`) &&\n !inside(output, resolved)\n )\n trackImports(resolved)\n }\n }\n for (const [index, file] of [...sources].entries()) {\n const tool = declaration(file)\n if (ids.has(tool.id)) return fail(file, `duplicate tool id \"${tool.id}\".`)\n ids.add(tool.id)\n trackImports(file)\n const preview = pageRoute(app, file, tool.preview)\n const title = (preview.split('/').filter(Boolean).at(-1) || tool.id)\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n imports.push(`import tool${index} from ${JSON.stringify(relativeImport(registry, file))}`)\n let values = ''\n const resolvedTool: Discovery['declarations'][number] = { source: file, title, preview }\n if (tool.configurable) {\n const inputs = new Set<string>()\n try {\n const specifier = tool.config ?? './config.json'\n const resolutionHost: ts.ModuleResolutionHost = {\n ...ts.sys,\n fileExists(candidate) {\n if (inside(root, candidate) && !candidate.includes(`${path.sep}node_modules${path.sep}`))\n inputs.add(candidate)\n return ts.sys.fileExists(candidate)\n },\n directoryExists(directory) {\n const exists = ts.sys.directoryExists(directory)\n if (!exists && inside(root, directory) && !directory.includes(`${path.sep}node_modules${path.sep}`))\n inputs.add(directory)\n return exists\n },\n }\n const resolved = ts.resolveModuleName(specifier, file, options, resolutionHost).resolvedModule?.resolvedFileName\n if (!resolved || !resolved.endsWith('.json'))\n return fail(file, `cannot resolve JSON config \"${specifier}\" through tsconfig.json.`)\n const target = await resolveToolFile(root, slash(path.relative(root, resolved)))\n inputs.add(target)\n const real = realpathSync(target)\n if (destinations.has(real)) return fail(file, 'another tool already writes this config file.')\n destinations.add(real)\n const value = JSON.parse(readFileSync(target, 'utf8'))\n if (!value || typeof value !== 'object' || Array.isArray(value))\n return fail(file, 'config must be a JSON object.')\n resolvedTool.file = slash(path.relative(root, target))\n resolvedTool.initial = value\n dependencies.add(target)\n const key = `${tool.id}:${real}`\n const prior = previous?.seeds.get(key)\n const seed = prior && shape(prior) === shape(value) ? prior : value\n seeds.set(key, seed)\n typeImports.push(`import type config${index} from ${JSON.stringify(relativeImport(types, target))}`)\n mappings.push(` ${JSON.stringify(tool.id)}: typeof config${index}`)\n // JSON.parse preserves JSON keys such as __proto__ without JS object-literal semantics.\n values = `, file: ${JSON.stringify(slash(path.relative(root, target)))}, initial: JSON.parse(${JSON.stringify(JSON.stringify(seed))}) as DiscoveredToolConfigs[${JSON.stringify(tool.id)}]`\n } catch (cause) {\n throw new DiscoveryInputError(cause, new Set([...dependencies, ...inputs]))\n }\n }\n declarations.push(resolvedTool)\n definitions.push(\n ` { title: ${JSON.stringify(title)}, ...tool${index}, preview: ${JSON.stringify(preview)}${values} }`,\n )\n }\n const write = async () => {\n await mkdir(output, { recursive: true })\n await writeChanged(\n types,\n `${typeImports.join('\\n')}\\n\\ndeclare module '@joycostudio/studio' {\\n interface DiscoveredToolConfigs {\\n${mappings.join('\\n')}\\n }\\n}\\n`,\n )\n await writeChanged(\n registry,\n `${imports.join('\\n')}\\n\\nexport const tools = [\\n${definitions.join(',\\n')}\\n] satisfies readonly StudioTool[]\\n`,\n )\n }\n if (publish) await write()\n return { root, toolsDir, sources, dependencies, registry, seeds, declarations, write }\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { createJiti } from 'jiti'\nimport type { StudioConfig } from '../core/tool'\n\nconst CANDIDATES = ['studio.config.ts', 'studio.config.mts', 'studio.config.js', 'studio.config.mjs']\n\nexport function importer(root: string) {\n return createJiti(import.meta.url, {\n moduleCache: false,\n fsCache: false,\n tryNative: false,\n tsconfigPaths: existsSync(path.join(root, 'tsconfig.json')) ? path.join(root, 'tsconfig.json') : false,\n })\n}\n\nexport async function readSettings(cwd: string, explicit?: string) {\n const file = explicit ? path.resolve(cwd, explicit) : CANDIDATES.map((name) => path.join(cwd, name)).find(existsSync)\n if (explicit && !existsSync(file!)) throw new Error(`[studio] no ${explicit} found in ${cwd}`)\n const root = file ? path.dirname(file) : path.resolve(cwd)\n const config = file ? await importer(root).import<StudioConfig>(file, { default: true }) : {}\n if (!config || typeof config !== 'object' || (config.tools !== undefined && !Array.isArray(config.tools)))\n throw new Error('[studio] config must default-export defineConfig({ ... })')\n if (config.tools !== undefined && config.toolsDir !== undefined)\n throw new Error('[studio] Use either tools (manual registration) or toolsDir (discovery), not both.')\n return { config, root, file }\n}\n","import { generate, type Discovery } from '../discovery/generate'\nimport { importer, readSettings } from '../discovery/settings'\nimport type { StudioTool } from '../core/tool'\n\n/** Resolve discovery directly in Node; generated browser imports are published only when valid. */\nexport async function loadConfig(cwd: string, explicit?: string, publish = true, previous?: Discovery) {\n const { config, root } = await readSettings(cwd, explicit)\n const discovery = await generate(cwd, explicit, false, previous)\n const jiti = importer(root)\n const tools: readonly StudioTool[] =\n config.tools ??\n (await Promise.all(\n discovery!.declarations.map(async ({ source, title, preview, file, initial }) => {\n const tool = await jiti.import<StudioTool>(source, { default: true })\n return { title, ...tool, preview, ...(file ? { file, initial } : {}) } as StudioTool\n }),\n ))\n if (publish) await discovery?.write()\n return { config: { ...config, tools }, root, discovery }\n}\n","import { connect } from 'node:net'\nimport type { Runtime } from './runtime'\nimport { serveBridge, type Bridge, type BridgeOptions } from './server'\n\nconst ATTEMPTS = 20\n\n/** Serve on `port`, or on the next free one when another Studio (or anything else) already holds it. */\nexport async function serveBridgeNear(runtime: Runtime, options: BridgeOptions): Promise<Bridge> {\n for (let port = options.port; ; port++) {\n try {\n return await serveBridge(runtime, { ...options, port })\n } catch (cause) {\n const taken = (cause as NodeJS.ErrnoException).code === 'EADDRINUSE'\n if (!taken || options.port === 0 || port - options.port >= ATTEMPTS - 1) throw cause\n }\n }\n}\n\n/** Whether something already answers at `hostname:port`, on any address family `hostname` resolves to. */\nfunction answers(hostname: string, port: number) {\n return new Promise<boolean>((resolve) => {\n const socket = connect({ host: hostname.replace(/^\\[|\\]$/g, ''), port, timeout: 1000 })\n const done = (busy: boolean) => {\n socket.destroy()\n resolve(busy)\n }\n socket.once('connect', () => done(true))\n socket.once('timeout', () => done(true))\n socket.once('error', () => done(false))\n })\n}\n\n/** First port from `port` that nothing answers on, so a wrapped app server can claim it. */\nexport async function freeAppPort(hostname: string, port: number): Promise<number> {\n for (let candidate = port; candidate < port + ATTEMPTS; candidate++)\n if (!(await answers(hostname, candidate))) return candidate\n throw new Error(`[studio] ports ${port}-${port + ATTEMPTS - 1} on ${hostname} are all in use`)\n}\n","import { spawnSync } from 'node:child_process'\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmdirSync, rmSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { parseArgs } from 'node:util'\nimport packageInfo from '../package.json'\nimport { generate } from './discovery/generate'\nimport { nextConfigEdit } from './discovery/scaffold'\n\n/** Generate ordinary source files; never replace existing application code. */\nexport async function init(argv: string[]) {\n const { positionals, values } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: { 'no-install': { type: 'boolean' } },\n })\n if (positionals.length > 1) throw new Error('Usage: studio init [directory] [--no-install]')\n const root = path.resolve(positionals[0] ?? '.')\n const manifest = path.join(root, 'package.json')\n const pkg = JSON.parse(readFileSync(manifest, 'utf8'))\n if (!pkg.dependencies?.next && !pkg.devDependencies?.next)\n throw new Error('[studio] init supports existing Next.js App Router projects.')\n if (!existsSync(path.join(root, 'tsconfig.json')))\n throw new Error('[studio] init currently requires a TypeScript project (tsconfig.json).')\n const app = ['app', 'src/app'].find((dir) => existsSync(path.join(root, dir)))\n if (!app) throw new Error('[studio] No app/ or src/app/ directory found.')\n const src = app.startsWith('src/') ? 'src/' : ''\n const relative = (from: string, to: string) => {\n const result = path.relative(path.dirname(from), to).split(path.sep).join('/')\n return /^\\.\\.?\\//.test(result) ? result : `./${result}`\n }\n const client = `${src}studio.ts`\n const tool = `${app}/studio-preview/studio.tool.ts`\n const data = `${app}/studio-preview/config.json`\n const page = `${app}/studio/page.tsx`\n const preview = `${app}/studio-preview/page.tsx`\n const files: Record<string, string> = {\n [client]: `import { createStudio } from '@joycostudio/studio/next'\nimport { tools } from '${relative(client, '.studio/registry.generated')}'\n\nexport const studio = createStudio({ tools })\n`,\n [data]: '{ \"scale\": 1 }\\n',\n [tool]: `import { defineTool } from '@joycostudio/studio'\nimport { property, slider } from '@joycostudio/studio/controls'\n\nexport default defineTool({\n id: 'studio-example',\n title: 'Example',\n controls: (config) => ({ scale: slider(property(config, 'scale'), { min: 0.5, max: 2 }) }),\n})\n`,\n [page]: `'use client'\n\nimport '@joycostudio/studio/styles.css'\nimport { Studio } from '@joycostudio/studio/react'\nimport { studio } from '${relative(page, client.slice(0, -3))}'\n\nexport default function StudioPage() {\n return <Studio studio={studio} />\n}\n`,\n [preview]: `'use client'\n\nimport { useToolConfig } from '@joycostudio/studio/react'\nimport { studio } from '${relative(preview, client.slice(0, -3))}'\nimport example from './studio.tool'\n\nexport default function StudioPreview() {\n const config = useToolConfig(studio.tool(example))\n return (\n <main style={{ display: 'grid', placeItems: 'center', minHeight: '100vh' }}>\n <div style={{ width: 120, height: 120, background: '#ff5930', borderRadius: 24, transform: \\`scale(\\${config.scale})\\` }} />\n </main>\n )\n}\n`,\n }\n // Route groups do not contribute URL segments; handlers also reserve a URL.\n const checkRoute = (directory: string, segment: string | undefined, allowed: string) => {\n for (const entry of readdirSync(path.join(root, directory), { withFileTypes: true })) {\n const file = `${directory}/${entry.name}`\n if (entry.isDirectory()) {\n if (/^\\([^.)][^/]*\\)$/.test(entry.name)) checkRoute(file, segment, allowed)\n else if (entry.name === segment) checkRoute(file, undefined, allowed)\n } else if (!segment && /^(page|route)\\.[jt]sx?$/.test(entry.name) && file !== allowed) {\n throw new Error(`[studio] Route already exists: ${file}`)\n }\n }\n }\n checkRoute(app, 'studio', page)\n checkRoute(app, 'studio-preview', preview)\n // Check every destination before writing anything. Identical files make reruns safe.\n for (const [name, content] of Object.entries(files)) {\n const target = path.join(root, name)\n if (existsSync(target) && readFileSync(target, 'utf8') !== content)\n throw new Error(`[studio] Refusing to overwrite ${name}. Use the manual setup guide for existing integrations.`)\n }\n for (const ext of ['ts', 'mts', 'js', 'mjs']) {\n if (existsSync(path.join(root, `studio.config.${ext}`)))\n throw new Error(`[studio] Found studio.config.${ext}; use the manual setup guide for existing integrations.`)\n }\n const nextEdit = nextConfigEdit(root)\n const dev = pkg.scripts?.dev\n if (!dev || /[;&|\\n]/.test(dev) || (!/^studio dev(?:\\s|$)/.test(dev) && !/^next dev(?:\\s|$)/.test(dev)))\n throw new Error(\n '[studio] Expected a next dev script. Configure studio dev -- <command> manually for custom scripts.',\n )\n let manager = pkg.packageManager?.split('@')[0]\n if (!manager) {\n let dir = root\n while (true) {\n manager = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n ].find(([lock]) => existsSync(path.join(dir, lock!)))?.[1]\n if (manager || path.dirname(dir) === dir) break\n dir = path.dirname(dir)\n }\n }\n manager ??= 'npm'\n if (!['npm', 'pnpm', 'yarn', 'bun'].includes(manager))\n throw new Error(`[studio] Unsupported package manager: ${manager}`)\n if (pkg.dependencies?.['@joycostudio/studio'] || pkg.devDependencies?.['@joycostudio/studio']) {\n try {\n const require = createRequire(manifest)\n for (const entry of ['next', 'next/config', 'controls', 'react']) require.resolve(`@joycostudio/studio/${entry}`)\n } catch {\n throw new Error(\n '[studio] The declared Studio dependency is missing or lacks the required exports. Install the same version (or preview) as this initializer, then rerun init. No files were changed.',\n )\n }\n }\n const dependencies = {\n '@joycostudio/studio': `^${packageInfo.version}`,\n '@joycostudio/xyz': packageInfo.peerDependencies['@joycostudio/xyz'],\n tweakpane: packageInfo.peerDependencies.tweakpane,\n }\n pkg.dependencies ??= {}\n for (const [name, version] of Object.entries(dependencies)) {\n if (!pkg.dependencies[name] && !pkg.devDependencies?.[name]) pkg.dependencies[name] = version\n }\n if (!/^studio dev(?:\\s|$)/.test(dev)) pkg.scripts.dev = `studio dev -- ${dev}`\n const typecheck = pkg.scripts.typecheck ?? 'tsc --noEmit'\n if (!typecheck.startsWith('studio generate')) pkg.scripts.typecheck = `studio generate && ${typecheck}`\n const ignoreFile = path.join(root, '.gitignore')\n const targets = [\n ...Object.keys(files).map((name) => path.join(root, name)),\n nextEdit.file,\n ignoreFile,\n manifest,\n path.join(root, '.studio/types.generated.ts'),\n path.join(root, '.studio/registry.generated.ts'),\n ]\n const originals = new Map(targets.map((file) => [file, existsSync(file) ? readFileSync(file) : undefined]))\n const createdDirectories = new Set<string>()\n for (const file of targets) {\n for (let dir = path.dirname(file); !existsSync(dir); dir = path.dirname(dir)) createdDirectories.add(dir)\n }\n try {\n for (const [name, content] of Object.entries(files)) {\n const target = path.join(root, name)\n if (existsSync(target)) continue\n mkdirSync(path.dirname(target), { recursive: true })\n writeFileSync(target, content, { flag: 'wx' })\n }\n writeFileSync(nextEdit.file, nextEdit.content)\n const ignore = originals.get(ignoreFile)?.toString() ?? ''\n if (!ignore.split(/\\r?\\n/).some((line) => ['.studio', '.studio/', '/.studio/'].includes(line)))\n writeFileSync(ignoreFile, `${ignore}${ignore.endsWith('\\n') || !ignore ? '' : '\\n'}/.studio/\\n`)\n await generate(root)\n writeFileSync(manifest, `${JSON.stringify(pkg, null, 2)}\\n`)\n } catch (cause) {\n // A failed generation must leave the app as it was, including any prior generated output.\n for (const [file, original] of originals) {\n if (original === undefined) rmSync(file, { force: true })\n else if (!existsSync(file) || !readFileSync(file).equals(original)) writeFileSync(file, original)\n }\n for (const dir of [...createdDirectories].sort((a, b) => b.length - a.length)) {\n try {\n rmdirSync(dir)\n } catch (error) {\n // Preserve anything another process created while generation was running.\n if (!['ENOENT', 'ENOTEMPTY'].includes((error as NodeJS.ErrnoException).code ?? '')) throw error\n }\n }\n throw cause\n }\n if (!values['no-install']) {\n const result = spawnSync(manager, ['install'], { cwd: root, stdio: 'inherit', shell: process.platform === 'win32' })\n if (result.error || result.status !== 0)\n throw new Error(`[studio] Files created, but installation failed. Run ${manager} install in ${root} to retry.`)\n }\n console.log(`[studio] Ready. ${values['no-install'] ? `Run ${manager} install, then ` : 'Run '}${manager} run dev and open /studio.\nThe example at /studio-preview reacts to edits; Save writes ${data}.\nTo connect your app, read studio.tool(yourTool).config or useToolConfig(studio.tool(yourTool)).\nOptional: mount <StudioDebug studio={studio} /> or <StudioCommandMenu studio={studio} /> from @joycostudio/studio/react.\nFor MCP, use the endpoint printed by studio dev. Preview capture additionally requires appUrl and studio install-browser.`)\n}\n","{\n \"name\": \"@joycostudio/studio\",\n \"version\": \"0.1.6\",\n \"description\": \"Plug project-specific tools into a /studio route, a floating debug pane, and MCP agents.\",\n \"type\": \"module\",\n \"license\": \"ISC\",\n \"author\": \"joyco.studio\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/joyco-studio/studio.git\",\n \"directory\": \"packages/studio\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\"\n ],\n \"bin\": {\n \"studio\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./client\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react.d.ts\",\n \"default\": \"./dist/react.js\"\n },\n \"./runtime\": {\n \"types\": \"./dist/runtime.d.ts\",\n \"default\": \"./dist/runtime.js\"\n },\n \"./styles.css\": \"./dist/styles.css\",\n \"./command-menu.css\": \"./dist/command-menu.css\",\n \"./next\": {\n \"types\": \"./dist/next.d.ts\",\n \"default\": \"./dist/next.js\"\n },\n \"./controls\": {\n \"types\": \"./dist/controls.d.ts\",\n \"default\": \"./dist/controls.js\"\n },\n \"./next/config\": {\n \"types\": \"./dist/next-config.d.ts\",\n \"default\": \"./dist/next-config.js\"\n }\n },\n \"scripts\": {\n \"build\": \"pnpm build:shadow-css && tsup && tailwindcss -i src/react/styles.css -o dist/styles.css --minify && cp src/react/command-menu-export.css dist/command-menu.css\",\n \"dev\": \"pnpm build:shadow-css && pnpm run --parallel \\\"/^dev:/\\\"\",\n \"test\": \"vitest run\",\n \"test:browser\": \"STUDIO_TEST_BROWSER=1 vitest run test/browser-sync.test.ts\",\n \"test:capture\": \"STUDIO_TEST_CAPTURE=1 vitest run test/capture.test.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"dev:js\": \"tsup --watch\",\n \"dev:css\": \"tailwindcss -i src/react/styles.css -o dist/styles.css --watch=always\",\n \"build:shadow-css\": \"tailwindcss -i src/react/shadow.css -o src/react/generated/studio.css --minify\",\n \"dev:shadow-css\": \"tailwindcss -i src/react/shadow.css -o src/react/generated/studio.css --minify --watch=always\"\n },\n \"dependencies\": {\n \"@base-ui/react\": \"^1.9.0\",\n \"@modelcontextprotocol/node\": \"^2.1.1\",\n \"@modelcontextprotocol/server\": \"^2.3.1\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cmdk\": \"^1.1.1\",\n \"cn\": \"^0.4.0\",\n \"jiti\": \"^2.7.0\",\n \"lucide\": \"^1.55.0\",\n \"lucide-react\": \"^1.55.0\",\n \"playwright\": \"^1.64.0\",\n \"radix-ui\": \"^1.8.0\",\n \"tailwind-merge\": \"^3.7.0\",\n \"ws\": \"^8.22.0\",\n \"zod\": \"^4.6.6\",\n \"typescript\": \"^5.9.3\"\n },\n \"peerDependencies\": {\n \"@joycostudio/xyz\": \"^1.4.0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"tweakpane\": \"^4.0.5\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"tweakpane\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@joycostudio/xyz\": \"^1.4.0\",\n \"@modelcontextprotocol/client\": \"^2.3.1\",\n \"@tailwindcss/cli\": \"^4.3.3\",\n \"@tweakpane/core\": \"^2.0.5\",\n \"@types/node\": \"^24.19.2\",\n \"@types/react\": \"^19.3.0\",\n \"@types/react-dom\": \"^19.3.0\",\n \"@types/ws\": \"^8.18.2\",\n \"react\": \"^19.3.0\",\n \"react-dom\": \"^19.3.0\",\n \"tailwindcss\": \"^4.3.3\",\n \"tsup\": \"^8.5.1\",\n \"tw-animate-css\": \"^1.4.0\",\n \"tweakpane\": \"^4.0.5\",\n \"vitest\": \"^5.0.3\"\n },\n \"sideEffects\": [\n \"*.css\"\n ]\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\n\n/** Preserve existing Next options and function configs; wrap only their export expression. */\nexport function nextConfigEdit(root: string): { file: string; content: string } {\n const name = ['next.config.ts', 'next.config.mjs', 'next.config.js'].find((file) => existsSync(path.join(root, file)))\n if (!name)\n return {\n file: path.join(root, 'next.config.ts'),\n content: \"import { withStudio } from '@joycostudio/studio/next/config'\\n\\nexport default withStudio({})\\n\",\n }\n const file = path.join(root, name)\n const text = readFileSync(file, 'utf8')\n const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true)\n // Inspect calls so an unused import or commented example cannot disable generation.\n const wrapped = (node: ts.Node): boolean =>\n (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && /^withStudio\\w*$/.test(node.expression.text)) ||\n (ts.forEachChild(node, wrapped) ?? false)\n if (text.includes('@joycostudio/studio/next/config') && wrapped(source)) return { file, content: text }\n const exported = source.statements.find(ts.isExportAssignment)\n if (exported && !exported.isExportEquals) {\n const expression = exported.expression\n let local = 'withStudioSetup'\n while (new RegExp(`\\\\b${local}\\\\b`).test(text)) local += '_'\n return {\n file,\n content:\n `import { withStudio as ${local} } from '@joycostudio/studio/next/config'\\n` +\n text.slice(0, expression.getStart(source)) +\n `${local}(${expression.getText(source)})` +\n text.slice(expression.end),\n }\n }\n const assignment = source.statements.flatMap((statement) =>\n ts.isExpressionStatement(statement) &&\n ts.isBinaryExpression(statement.expression) &&\n statement.expression.left.getText(source) === 'module.exports' &&\n statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken\n ? [statement.expression.right]\n : [],\n )\n if (assignment.length === 1) {\n const expression = assignment[0]!\n return {\n file,\n content:\n text.slice(0, expression.getStart(source)) +\n `async (...args) => { const { withStudio } = await import('@joycostudio/studio/next/config'); return withStudio(${expression.getText(source)})(...args) }` +\n text.slice(expression.end),\n }\n }\n throw new Error(\n `[studio] Cannot wrap ${name} automatically. Export a config object/function or wrap it with withStudio manually.`,\n )\n}\n","import { existsSync, statSync, watch, type FSWatcher } from 'node:fs'\nimport path from 'node:path'\nimport { DiscoveryInputError, type Discovery } from './generate'\n\n/** Watch the selected tree, plus exact imported dependencies outside it. No page-content triggers. */\nexport function watchDiscovery(initial: Discovery, refresh: () => Promise<Discovery | undefined>) {\n let current = initial\n let retryInputs = new Set<string>()\n let watchers: FSWatcher[] = []\n let timer: NodeJS.Timeout | undefined\n let running = false\n let pending = false\n let closed = false\n const schedule = () => {\n if (closed) return\n pending = true\n clearTimeout(timer)\n timer = setTimeout(() => void run(), 80)\n }\n const run = async () => {\n if (running || closed) return\n pending = false\n running = true\n try {\n const next = await refresh()\n if (next && !closed) {\n current = next\n retryInputs.clear()\n bind()\n }\n } catch (cause) {\n if (cause instanceof DiscoveryInputError && !closed) {\n retryInputs = cause.inputs\n bind()\n }\n console.error('[studio] discovery update rejected:', cause instanceof Error ? cause.message : cause)\n } finally {\n running = false\n if (pending) schedule()\n }\n }\n const bind = () => {\n for (const watcher of watchers) watcher.close()\n watchers = []\n const pages = new Map(\n [...current.sources].flatMap((file) =>\n ['tsx', 'ts', 'jsx', 'js'].map((ext) => {\n const page = path.join(path.dirname(file), `page.${ext}`)\n return [page, existsSync(page)] as const\n }),\n ),\n )\n const add = (directory: string, recursive: boolean, listener: (event: string, filename: string | null) => void) => {\n if (!existsSync(directory)) return\n const watcher = watch(directory, { recursive }, listener)\n watcher.on('error', (cause) => console.error('[studio] discovery watcher:', cause.message))\n watcher.unref()\n watchers.push(watcher)\n }\n add(current.toolsDir, true, (event, filename) => {\n if (!filename) return schedule()\n const relative = filename.toString()\n if (relative.split(path.sep).some((part) => part.startsWith('.') || part === 'node_modules')) return\n const file = path.resolve(current.toolsDir, relative)\n if (path.basename(file) === 'studio.tool.ts' || current.dependencies.has(file)) return schedule()\n if (pages.has(file)) {\n if (pages.get(file) !== existsSync(file)) schedule()\n return\n }\n if (\n event === 'rename' &&\n (/^page\\.[jt]sx?$/.test(path.basename(file)) ||\n !path.extname(file) ||\n statSync(file, { throwIfNoEntry: false })?.isDirectory())\n )\n schedule()\n })\n const targets = new Set([\n ...current.dependencies,\n ...retryInputs,\n ...['studio.config.ts', 'studio.config.mts', 'studio.config.js', 'studio.config.mjs', 'tsconfig.json'].map(\n (file) => path.join(current.root, file),\n ),\n ])\n const byDirectory = new Map<string, Set<string>>()\n for (const file of targets) {\n let directory = path.dirname(file)\n // Watch the nearest existing parent until missing alias/relative-path directories appear.\n while (!existsSync(directory) && path.dirname(directory) !== directory) directory = path.dirname(directory)\n const names = byDirectory.get(directory) ?? new Set<string>()\n names.add(path.relative(directory, file).split(path.sep)[0]!)\n byDirectory.set(directory, names)\n }\n for (const [directory, names] of byDirectory) {\n add(directory, false, (_, filename) => {\n if (!filename || names.has(filename.toString())) schedule()\n })\n }\n const directoryId = statSync(current.toolsDir, { throwIfNoEntry: false })?.ino\n add(path.dirname(current.toolsDir), false, (_, filename) => {\n if (\n (!filename || filename.toString() === path.basename(current.toolsDir)) &&\n statSync(current.toolsDir, { throwIfNoEntry: false })?.ino !== directoryId\n )\n schedule()\n })\n }\n bind()\n return {\n retry: schedule,\n close() {\n closed = true\n clearTimeout(timer)\n for (const watcher of watchers) watcher.close()\n },\n }\n}\n"],"mappings":"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","names":["createRequire","path","parseArgs","tool","path","tool","path","fail","tool","path","revision","tool","revision","handle","existsSync","mkdir","readFile","path","path","path","inside","existsSync","error","readFile","tool","exists","mkdir","tool","existsSync","readFileSync","readdirSync","path","existsSync","readFileSync","path","ts","file","path","readFileSync","existsSync","tool","readdirSync","require","error","existsSync","watch","path","path","existsSync","watch","require","createRequire","path","child","parseArgs"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/core/tool.ts","../src/runtime/runtime.ts","../src/core/diff.ts","../src/core/result.ts","../src/core/validate.ts","../src/runtime/files.ts","../src/runtime/server.ts","../src/runtime/capture.ts","../src/runtime/mcp.ts","../src/discovery/generate.ts","../src/discovery/settings.ts","../src/runtime/load.ts","../src/runtime/ports.ts","../src/init.ts","../package.json","../src/discovery/scaffold.ts","../src/discovery/watch.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { DEFAULT_PORT } from './core/tool'\nimport { createRuntime, loadConfig } from './runtime'\nimport { freeAppPort, serveBridgeNear } from './runtime/ports'\nimport { init } from './init'\nimport { DiscoveryInputError, generate } from './discovery/generate'\nimport { watchDiscovery } from './discovery/watch'\n\nconst HELP = `Usage: studio dev [--config studio.config.ts] [--port ${DEFAULT_PORT}] [--app-url http://localhost:3000] [-- <command...>]\n studio generate [--config studio.config.ts]\n studio install-browser\n studio init [directory] [--ui tweakpane|dialkit] [--no-install]\n\nStarts the Studio runtime with a WebSocket bridge and an HTTP MCP endpoint at /mcp,\nmoving to the next free port when another project's Studio already uses it.\nAnything after \"--\" runs alongside it (e.g. \"next dev\") with STUDIO_PORT set to the runtime port,\nand the runtime stops when that command exits.\nSet appUrl in the config or pass --app-url to enable MCP preview capture. A configured local\nappUrl port is passed to the command as PORT, moved to the next free port when taken.\nRun \"studio install-browser\" once to install Chromium for captures.`\n\nasync function main(argv: string[]) {\n if (argv[0] === 'init') return init(argv.slice(1))\n if (argv[0] === 'install-browser') {\n const require = createRequire(import.meta.url)\n const cli = path.join(\n path.dirname(require.resolve('playwright/package.json')),\n require('playwright/package.json').bin.playwright,\n )\n const child = spawn(process.execPath, [cli, 'install', 'chromium'], { stdio: 'inherit' })\n child.once('error', (cause) => {\n console.error(cause.message)\n process.exit(1)\n })\n child.once('exit', (code) => process.exit(code ?? 1))\n return\n }\n const split = argv.indexOf('--')\n const own = split === -1 ? argv : argv.slice(0, split)\n const command = split === -1 ? [] : argv.slice(split + 1)\n const { positionals, values } = parseArgs({\n args: own,\n allowPositionals: true,\n options: {\n config: { type: 'string' },\n port: { type: 'string' },\n 'app-url': { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n })\n if (positionals[0] === 'generate') {\n await generate(process.cwd(), values.config)\n console.log('[studio] generated tool registry and types')\n return\n }\n if (values.help || positionals[0] !== 'dev') return console.log(HELP)\n\n const { config, root, discovery } = await loadConfig(process.cwd(), values.config)\n const [bin, ...args] = command\n const env = { ...process.env }\n let appUrl = values['app-url'] ?? config.appUrl\n // Projects share the default app port too: claim a free one for the wrapped app so captures follow it.\n const app = bin && !values['app-url'] && !env.PORT && appUrl && URL.canParse(appUrl) ? new URL(appUrl) : undefined\n if (app?.port && ['localhost', '127.0.0.1', '[::1]'].includes(app.hostname)) {\n const preferred = app.port\n app.port = env.PORT = String(await freeAppPort(app.hostname, Number(preferred)))\n if (app.port !== preferred) console.log(`[studio] port ${preferred} is in use, starting the app on ${app.origin}`)\n appUrl = app.href\n }\n\n const runtime = await createRuntime({ root, tools: config.tools })\n const port = Number(values.port ?? config.port ?? DEFAULT_PORT)\n const bridge = await serveBridgeNear(runtime, { port, origins: config.origins, appUrl })\n if (bridge.port !== port) console.log(`[studio] port ${port} is in use, probably by another project's Studio`)\n console.log(\n `[studio] runtime ready on ws://127.0.0.1:${bridge.port} — ${config.tools.length} tool(s) in ${path.relative(process.cwd(), root) || '.'}`,\n )\n console.log(`[studio] MCP ready on http://127.0.0.1:${bridge.port}/mcp`)\n\n let accepted = discovery\n const watcher =\n discovery &&\n watchDiscovery(discovery, async () => {\n const next = await loadConfig(process.cwd(), values.config, false, accepted)\n try {\n await runtime.replaceTools(next.config.tools)\n } catch (cause) {\n // E.g. a new tool's config is still invalid: watch it so fixing it retries.\n throw new DiscoveryInputError(cause, next.discovery?.dependencies ?? new Set())\n }\n await next.discovery?.write()\n accepted = next.discovery\n return next.discovery\n })\n const shutdown = async (code = 0) => {\n watcher?.close()\n runtime.close()\n await bridge.close()\n process.exit(code)\n }\n\n if (!bin) {\n process.once('SIGINT', () => void shutdown())\n process.once('SIGTERM', () => void shutdown())\n return\n }\n const child = spawn(bin, args, {\n stdio: 'inherit',\n env: {\n ...env,\n STUDIO_PORT: String(bridge.port),\n NEXT_PUBLIC_STUDIO_RUNTIME: `ws://127.0.0.1:${bridge.port}`,\n STUDIO_DISCOVERY_MANAGED: discovery ? '1' : '',\n ...(values.config ? { STUDIO_CONFIG: path.resolve(values.config) } : {}),\n },\n })\n child.once('exit', (code) => void shutdown(code ?? 0))\n for (const signal of ['SIGINT', 'SIGTERM'] as const) process.once(signal, () => child.kill(signal))\n}\n\nmain(process.argv.slice(2)).catch((cause) => {\n console.error(cause instanceof Error ? cause.message : cause)\n process.exit(1)\n})\n","import type { DebugHost, DebugSchema } from '@joycostudio/xyz/debug'\n\n/** Controls as an Xyz schema. Drawn with whichever UI the app picks (`createStudio({ ui })`), so `extend` gets an unknown folder. */\nexport type ToolControls = DebugSchema<DebugHost>\n\n/**\n * An SVG icon as data: `[tag, attributes]` children of a 24×24 stroke icon.\n * Lucide's core package (`import { Palette } from 'lucide'`) exports exactly this shape.\n */\nexport type ToolIcon = readonly (readonly [tag: string, attrs: Record<string, string | number | undefined>])[]\n\ntype ToolBase = {\n /** Unique, URL-safe identifier. */\n id: string\n title?: string\n /** Shown next to the tool in /studio. Data, not a component, so contracts stay loadable in Node. */\n icon?: ToolIcon\n /** App route that renders this tool's result, shown next to the controls in /studio. */\n preview?: string\n /** Use a bare iframe for tools that already own their canvas layout and headers. */\n previewLayout?: 'canvas' | 'custom'\n}\n\n/**\n * A tool's contract. Isomorphic on purpose: the runtime loads it in Node to\n * validate and persist, the app loads it in the browser to apply and debug.\n *\n * `TConfig` is the one type that is read, edited, applied, and persisted.\n */\nexport type ToolDefinition<TConfig extends object = object> = ToolBase & {\n /** Repo-relative JSON file the config persists to. Import that same file as `initial`. */\n file: string\n /** Config used before the runtime answers (and in production). */\n initial: TConfig\n /**\n * What can be tweaked, as an Xyz schema bound to `config`.\n * Doubles as the runtime validator: every control's bounds are enforced on write.\n */\n controls: (config: TConfig) => ToolControls\n}\n\n/** A tool with nothing to tune: a sidebar entry for its preview, without an inspector or config file. */\nexport type PreviewToolDefinition = ToolBase & {\n preview: string\n file?: never\n initial?: never\n controls?: never\n}\n\n/** A tool with a config. */\nexport type AnyTool = ToolDefinition<any>\n\n/** Anything `defineTool` returns: the kind follows from whether it declares a config. */\nexport type StudioTool = AnyTool | PreviewToolDefinition\n\nexport const hasConfig = (tool: StudioTool): tool is AnyTool => tool.controls !== undefined\n\n/** Filled by .studio/types.generated.ts in each consuming project. */\nexport interface DiscoveredToolConfigs {}\n\n/** A discovered declaration is resolved into a full definition by the generated registry. */\nexport type DiscoveredToolDefinition<TConfig extends object = object> = ToolBase & {\n /** JSON source relative to this tool file, or a tsconfig path alias. Defaults to ./config.json. */\n config?: string\n controls: (config: TConfig) => ToolControls\n file?: never\n initial?: never\n}\nexport type ToolReference<TConfig extends object> = Pick<ToolDefinition<TConfig>, 'id' | 'controls'>\nexport type ConfigOf<TTool> = TTool extends ToolReference<infer TConfig> ? TConfig : never\n\nconst ID = /^[a-z0-9][a-z0-9-]*$/\n\n/** Discovered tools infer their config from the generated ID-to-JSON type map. */\nexport function defineTool<K extends keyof DiscoveredToolConfigs & string>(\n tool: Omit<DiscoveredToolDefinition<Extract<DiscoveredToolConfigs[K], object>>, 'id'> & { id: K },\n): DiscoveredToolDefinition<Extract<DiscoveredToolConfigs[K], object>>\n/** Existing explicitly registered tools remain supported. */\nexport function defineTool<TConfig extends object>(tool: ToolDefinition<TConfig>): ToolDefinition<TConfig>\nexport function defineTool(tool: PreviewToolDefinition): PreviewToolDefinition\n/** A discovered preview-only tool may infer its preview from the adjacent page. */\nexport function defineTool(\n tool: ToolBase & { controls?: never; config?: never; file?: never; initial?: never },\n): ToolBase\nexport function defineTool(tool: StudioTool | DiscoveredToolDefinition<any> | ToolBase) {\n if (!ID.test(tool.id)) throw new Error(`[studio] tool id \"${tool.id}\" must be kebab-case`)\n const value = tool as Partial<AnyTool>\n if (value.file !== undefined || value.initial !== undefined) {\n if (value.file === undefined || value.initial === undefined || value.controls === undefined)\n throw new Error(`[studio] tool \"${tool.id}\" needs all of file, initial, and controls, or none of them`)\n }\n return tool\n}\n\nexport type StudioConfig = {\n /** Explicit registry; omit to enable convention-based discovery. */\n tools?: readonly StudioTool[]\n /**\n * Directory to scan and watch for `studio.tool.ts` files, relative to\n * the project root.\n *\n * Defaults to the active Next.js app directory: `app/` or `src/app/`.\n * Set a narrower directory to reduce scanning and discovery triggers.\n * This does not change preview URLs.\n *\n * @example 'src/app/experiments'\n */\n toolsDir?: string\n /** Runtime WebSocket and HTTP MCP port. Defaults to 5179. */\n port?: number\n /** Browser origins allowed on the bridge and MCP endpoint. Defaults to localhost origins. */\n origins?: readonly string[]\n /** Running app URL (e.g. http://localhost:3000), used for MCP preview captures. */\n appUrl?: string\n}\n\nexport const DEFAULT_PORT = 5179\n\nexport function defineConfig<T extends StudioConfig>(config: T): T {\n return config\n}\n","import { watch, type FSWatcher } from 'node:fs'\nimport path from 'node:path'\nimport type { Op, Operations, ToolState, ToolSummary } from '../core/protocol'\nimport { diff, writePath } from '../core/diff'\nimport { error, success, type Result } from '../core/result'\nimport { hasConfig, type AnyTool, type StudioTool } from '../core/tool'\nimport { validateConfig } from '../core/validate'\nimport { hashOf, readDisk, resolveToolFile, serialize, writeAtomic } from './files'\n\ntype Entry = {\n tool: AnyTool\n file: string\n state: ToolState\n /** Serializes disk work per tool so saves and external reloads never interleave. */\n queue: Promise<unknown>\n}\n\nexport type RuntimeListener = (state: ToolState, origin: unknown) => void\n\nexport type Runtime = {\n root: string\n run<TOp extends Op>(\n op: TOp,\n params: Operations[TOp]['params'],\n origin?: unknown,\n ): Promise<Result<Operations[TOp]['result']>>\n subscribe(listener: RuntimeListener): () => void\n /**\n * Atomically refresh definitions. Unsaved edits that still fit the new controls carry over; the rest are dropped\n * with a warning, so a schema change never leaves the runtime on stale definitions.\n */\n replaceTools(tools: readonly StudioTool[]): Promise<void>\n close(): void\n}\n\nconst equal = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n const keys = Object.keys(a)\n return (\n keys.length === Object.keys(b).length &&\n keys.every((key) => equal((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n )\n}\n\n/**\n * Replay the unsaved edits onto the new saved config. All together first, since one control's range can depend on\n * another field; failing that, one leaf at a time, keeping those the new controls accept.\n */\nfunction rebase(tool: AnyTool, old: ToolState, saved: unknown) {\n const changes = diff(old.saved.value, old.draft.value)\n const apply = (base: unknown, edits: typeof changes) => {\n const candidate = structuredClone(base) as Record<string, unknown>\n try {\n for (const { path, after } of edits) writePath(candidate, path, after)\n } catch (cause) {\n // The new shape can't hold the old path at all (e.g. an object's `length` onto what is now an array).\n return error('invalid_config', cause instanceof Error ? cause.message : String(cause))\n }\n return validateConfig(tool, candidate)\n }\n const all = apply(saved, changes)\n if (all.ok) return { value: all.data, dropped: [] }\n let value = saved\n const dropped: string[] = []\n for (const change of changes) {\n const parsed = apply(value, [change])\n if (parsed.ok) value = parsed.data\n else dropped.push(change.path.join('.'))\n }\n return { value, dropped }\n}\n\nasync function load(tool: AnyTool, file: string) {\n const disk = await readDisk(file)\n if (!disk) return { value: structuredClone(tool.initial), hash: null }\n const parsed = validateConfig(tool, JSON.parse(disk.content))\n if (!parsed.ok)\n throw new Error(`[studio] ${path.basename(file)} is not a valid \"${tool.id}\" config: ${parsed.message}`)\n return { value: parsed.data, hash: disk.hash }\n}\n\nasync function prepare(root: string, tools: readonly StudioTool[]) {\n const entries = new Map<string, Entry>()\n const files = new Set<string>()\n\n const ids = new Set<string>()\n for (const tool of tools) {\n if (ids.has(tool.id)) throw new Error(`[studio] duplicate tool id \"${tool.id}\"`)\n ids.add(tool.id)\n // Preview-only tools are listed, but have no config for the runtime to own.\n if (!hasConfig(tool)) continue\n const file = await resolveToolFile(root, tool.file)\n if (files.has(file)) throw new Error(`[studio] tool \"${tool.id}\" shares its file with another tool`)\n files.add(file)\n const saved = await load(tool, file)\n entries.set(tool.id, {\n tool,\n file,\n queue: Promise.resolve(),\n state: {\n tool: tool.id,\n draft: { value: structuredClone(saved.value), revision: 0 },\n saved,\n dirty: false,\n conflict: false,\n },\n })\n }\n\n return { entries, ids }\n}\n\n/**\n * The single authority over tool configs: validates every write, owns draft\n * revisions, and is the only thing that touches the persisted files.\n */\nexport async function createRuntime({ root, tools }: { root: string; tools: readonly StudioTool[] }): Promise<Runtime> {\n root = path.resolve(root)\n let { entries, ids } = await prepare(root, tools)\n let changing: Promise<void> = Promise.resolve()\n\n const listeners = new Set<RuntimeListener>()\n const commit = (entry: Entry, next: Partial<ToolState>, origin?: unknown) => {\n const state = { ...entry.state, ...next }\n state.dirty = !equal(state.draft.value, state.saved.value)\n if (!state.dirty) state.conflict = false\n entry.state = state\n for (const listener of listeners) listener(state, origin)\n return state\n }\n const serial = <T>(entry: Entry, task: () => Promise<T>) => {\n const run = entry.queue.then(task)\n entry.queue = run.catch(() => {})\n return run\n }\n\n const handlers: { [TOp in Op]: (params: any, origin: unknown) => Promise<Result<Operations[TOp]['result']>> } = {\n 'tools.list': async () =>\n success(\n tools.map((tool): ToolSummary => ({\n id: tool.id,\n title: tool.title ?? tool.id,\n file: tool.file,\n icon: tool.icon,\n preview: tool.preview,\n })),\n ),\n\n 'tool.get': async ({ tool }) => withEntry(tool, async (entry) => success(entry.state)),\n\n 'tool.update': async ({ tool, value, revision }, origin) =>\n withEntry(tool, async (entry) => {\n if (revision !== undefined && revision !== entry.state.draft.revision)\n return error('stale_revision', `draft is at revision ${entry.state.draft.revision}, not ${revision}`)\n const parsed = validateConfig(entry.tool, value)\n if (!parsed.ok) return parsed\n const draft = { value: parsed.data, revision: entry.state.draft.revision + 1 }\n return success(commit(entry, { draft }, origin))\n }),\n\n 'tool.save': async ({ tool, revision, force = false }, origin) =>\n withEntry(tool, (entry) =>\n serial(entry, async () => {\n const { draft, saved } = entry.state\n if (revision !== draft.revision)\n return error('stale_revision', `draft is at revision ${draft.revision}, not ${revision}`)\n const disk = await readDisk(entry.file)\n if (!force && (entry.state.conflict || (disk?.hash ?? null) !== saved.hash)) {\n commit(entry, { conflict: true })\n return error('conflict', `${entry.tool.file} changed on disk; discard to reload or save with force`)\n }\n const content = serialize(draft.value)\n await writeAtomic(entry.file, content)\n return success(\n commit(entry, { saved: { value: structuredClone(draft.value), hash: hashOf(content) } }, origin),\n )\n }),\n ),\n\n 'tool.discard': async ({ tool, revision }, origin) =>\n withEntry(tool, async (entry) => {\n const { saved, draft } = entry.state\n if (revision !== undefined && revision !== draft.revision)\n return error('stale_revision', `draft is at revision ${draft.revision}, not ${revision}`)\n return success(\n commit(entry, { draft: { value: structuredClone(saved.value), revision: draft.revision + 1 } }, origin),\n )\n }),\n }\n\n async function withEntry<T>(id: unknown, task: (entry: Entry) => Promise<Result<T>>): Promise<Result<T>> {\n const entry = typeof id === 'string' ? entries.get(id) : undefined\n if (entry) return task(entry)\n return ids.has(id as string)\n ? error('no_config', `tool \"${String(id)}\" is preview-only and has no config`)\n : error('unknown_tool', `no tool \"${String(id)}\"`)\n }\n\n /** Pick up edits made outside Studio (editor, git checkout, an agent). */\n const reload = (entry: Entry) =>\n serial(entry, async () => {\n const disk = await readDisk(entry.file)\n const { saved, draft, dirty } = entry.state\n if ((disk?.hash ?? null) === saved.hash) return\n if (!disk) return commit(entry, { saved: { ...saved, hash: null } })\n let value: unknown\n try {\n value = JSON.parse(disk.content)\n } catch {\n return console.warn(`[studio] ignoring unparsable ${entry.tool.file}`)\n }\n const parsed = validateConfig(entry.tool, value)\n if (!parsed.ok) return console.warn(`[studio] ignoring invalid ${entry.tool.file}: ${parsed.message}`)\n const next: Partial<ToolState> = { saved: { value: parsed.data, hash: disk.hash } }\n if (dirty) next.conflict = true\n else next.draft = { value: structuredClone(parsed.data), revision: draft.revision + 1 }\n commit(entry, next)\n })\n\n const timers = new Map<Entry, NodeJS.Timeout>()\n const watchers: FSWatcher[] = []\n const bindWatchers = () => {\n for (const watcher of watchers.splice(0)) watcher.close()\n for (const timer of timers.values()) clearTimeout(timer)\n timers.clear()\n const byDirectory = Map.groupBy(entries.values(), (entry) => path.dirname(entry.file))\n for (const [directory, group] of byDirectory) {\n try {\n const watcher = watch(directory, (_, filename) => {\n for (const entry of group) {\n if (filename && filename !== path.basename(entry.file)) continue\n clearTimeout(timers.get(entry))\n timers.set(\n entry,\n setTimeout(() => {\n void changing\n .then(async () => {\n if (entries.get(entry.tool.id) === entry) await reload(entry)\n })\n .catch((cause) => console.error('[studio] reload failed', cause))\n }, 50),\n )\n }\n })\n watchers.push(watcher)\n } catch {\n console.warn(`[studio] not watching ${path.relative(root, directory)} (it does not exist yet)`)\n }\n }\n }\n bindWatchers()\n\n const replaceTools = (nextTools: readonly StudioTool[]) => {\n const update = changing.then(async () => {\n await Promise.all([...entries.values()].map((entry) => entry.queue))\n const prepared = await prepare(root, nextTools)\n for (const [id, old] of entries) {\n const next = prepared.entries.get(id)\n if (!next || next.file !== old.file) {\n if (old.state.dirty)\n console.warn(`[studio] dropped unsaved \"${id}\" edits: the tool was removed or its config moved`)\n continue\n }\n next.state.draft.revision = old.state.draft.revision + 1\n if (!old.state.dirty) continue\n const { value, dropped } = rebase(next.tool, old.state, next.state.saved.value)\n if (dropped.length)\n console.warn(`[studio] dropped unsaved \"${id}\" edits that no longer fit its controls: ${dropped.join(', ')}`)\n next.state = {\n ...old.state,\n saved: next.state.saved,\n conflict: old.state.conflict || next.state.saved.hash !== old.state.saved.hash,\n draft: { value, revision: next.state.draft.revision },\n }\n }\n entries = prepared.entries\n ids = prepared.ids\n tools = nextTools\n bindWatchers()\n for (const entry of entries.values()) commit(entry, {})\n })\n changing = update.catch(() => {})\n return update\n }\n\n return {\n root,\n run: async (op, params, origin) => {\n await changing\n return handlers[op](params, origin) as never\n },\n replaceTools,\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n close() {\n for (const watcher of watchers) watcher.close()\n for (const timer of timers.values()) clearTimeout(timer)\n listeners.clear()\n },\n }\n}\n","export type Change = { path: string[]; before: unknown; after: unknown }\n\n/** Every leaf that differs between two configs of the same shape. Arrays count as leaves. */\nexport function diff(before: unknown, after: unknown, path: string[] = []): Change[] {\n const nested = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n if (nested(before) && nested(after)) {\n const keys = new Set([...Object.keys(before), ...Object.keys(after)])\n return [...keys].flatMap((key) => diff(before[key], after[key], [...path, key]))\n }\n return JSON.stringify(before) === JSON.stringify(after) ? [] : [{ path, before, after }]\n}\n\n/** Set an own data property, never an inherited setter such as `__proto__`. */\nconst define = (target: Record<string, unknown>, key: string, value: unknown) =>\n Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true })\n\n/**\n * Write `value` at `path` in place; undefined removes the key (it did not exist before the edit).\n * Walks own properties only, so a path through `__proto__` can't reach `Object.prototype`.\n */\nexport function writePath(target: Record<string, unknown>, path: string[], value: unknown) {\n const key = path.at(-1)!\n let parent = target\n for (const segment of path.slice(0, -1)) {\n const next = Object.hasOwn(parent, segment) ? parent[segment] : undefined\n if (typeof next !== 'object' || next === null) define(parent, segment, {})\n parent = parent[segment] as Record<string, unknown>\n }\n if (value === undefined) {\n if (Object.hasOwn(parent, key)) delete parent[key]\n } else define(parent, key, structuredClone(value))\n}\n","export type Success<T> = { ok: true; data: T }\n\nexport type Failure = {\n ok: false\n /** snake_case wire code, e.g. `invalid_config`. */\n error: string\n message?: string\n}\n\nexport type Result<T> = Success<T> | Failure\n\nexport const success = <T>(data: T): Success<T> => ({ ok: true, data })\n\nexport const error = (code: string, message?: string): Failure => ({\n ok: false,\n error: code,\n ...(message === undefined ? {} : { message }),\n})\n","import { error, success, type Result } from './result'\nimport type { ToolControls, ToolDefinition } from './tool'\n\n/**\n * Accept `candidate` as a config for `tool` only if it has the exact shape of\n * `tool.initial` and every control in `tool.controls` accepts its value.\n * Returns a detached copy, never the input.\n */\nexport function validateConfig<TConfig extends object>(\n tool: ToolDefinition<TConfig>,\n candidate: unknown,\n): Result<TConfig> {\n const mismatch = shapeMismatch(tool.initial, candidate, 'config')\n if (mismatch) return error('invalid_config', mismatch)\n const config = structuredClone(candidate) as TConfig\n const invalid = invalidControl(tool.controls(config))\n return invalid ? error('invalid_config', invalid) : success(config)\n}\n\nfunction kind(value: unknown) {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'array'\n return typeof value\n}\n\nfunction shapeMismatch(reference: unknown, value: unknown, path: string): string | null {\n const expected = kind(reference)\n if (kind(value) !== expected) return `${path}: expected ${expected}, got ${kind(value)}`\n if (expected === 'number' && !Number.isFinite(value)) return `${path}: expected a finite number`\n if (expected === 'array') {\n const [first] = reference as unknown[]\n if (first === undefined) return null\n for (const [index, item] of (value as unknown[]).entries()) {\n const nested = shapeMismatch(first, item, `${path}[${index}]`)\n if (nested) return nested\n }\n }\n if (expected === 'object') {\n const ref = reference as Record<string, unknown>\n const obj = value as Record<string, unknown>\n for (const key of Object.keys(obj)) if (!Object.hasOwn(ref, key)) return `${path}.${key}: unknown key`\n for (const key of Object.keys(ref)) {\n if (!Object.hasOwn(obj, key)) return `${path}.${key}: missing`\n const nested = shapeMismatch(ref[key], obj[key], `${path}.${key}`)\n if (nested) return nested\n }\n }\n return null\n}\n\nconst isRgb = (value: unknown) =>\n typeof value === 'object' &&\n value !== null &&\n ['r', 'g', 'b'].every((channel) => Number.isFinite((value as Record<string, unknown>)[channel]))\n\nfunction invalidControl(schema: ToolControls, path = ''): string | null {\n for (const [key, field] of Object.entries(schema)) {\n if (field.kind === 'button') continue\n const name = `${path}${field.label ?? key}`\n if (field.kind === 'folder') {\n const nested = invalidControl(field.definition.schema(), `${name}/`)\n if (nested) return nested\n continue\n }\n const value: unknown = field.read()\n if (field.kind === 'slider') {\n if (typeof value !== 'number' || value < field.min || value > field.max)\n return `${name}: expected a number in [${field.min}, ${field.max}], got ${JSON.stringify(value)}`\n } else if (field.kind === 'bool') {\n if (typeof value !== 'boolean') return `${name}: expected a boolean`\n } else if (field.kind === 'select') {\n const options = Object.values(field.options)\n if (!options.includes(value as string | number))\n return `${name}: expected one of ${JSON.stringify(options)}, got ${JSON.stringify(value)}`\n } else if (field.kind === 'color-string') {\n if (typeof value !== 'string') return `${name}: expected a color string`\n } else if (field.kind === 'color') {\n if (!isRgb(value)) return `${name}: expected an { r, g, b } color`\n }\n }\n return null\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { mkdir, readFile, realpath, rename, rm, stat } from 'node:fs/promises'\nimport { writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nconst inside = (root: string, target: string) => {\n const relative = path.relative(root, target)\n return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative)\n}\n\nconst exists = (target: string) =>\n stat(target).then(\n () => true,\n () => false,\n )\n\n/**\n * Resolve a tool's persistence target, refusing anything that is not a `.json`\n * file inside `root` — including paths that escape through a symlink.\n */\nexport async function resolveToolFile(root: string, file: string): Promise<string> {\n const fail = (reason: string) => new Error(`[studio] tool file \"${file}\" ${reason}`)\n if (path.isAbsolute(file)) throw fail('must be relative to the project root')\n if (path.extname(file) !== '.json') throw fail('must be a .json file')\n const absolute = path.resolve(root, file)\n if (!inside(root, absolute)) throw fail('escapes the project root')\n\n let probe = absolute\n while (!(await exists(probe))) probe = path.dirname(probe)\n if (probe !== root && !inside(await realpath(root), await realpath(probe))) throw fail('escapes the project root')\n return absolute\n}\n\nexport const hashOf = (content: string) => createHash('sha256').update(content).digest('hex').slice(0, 16)\n\nexport const serialize = (value: unknown) => `${JSON.stringify(value, null, 2)}\\n`\n\n/** The file's content and hash, or null when it does not exist. */\nexport async function readDisk(file: string): Promise<{ content: string; hash: string } | null> {\n try {\n const content = await readFile(file, 'utf8')\n return { content, hash: hashOf(content) }\n } catch (cause) {\n if ((cause as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw cause\n }\n}\n\n/** Write through a sibling temp file + rename so readers never see a half-written config. */\nexport async function writeAtomic(file: string, content: string) {\n await mkdir(path.dirname(file), { recursive: true })\n const temp = `${file}.${randomUUID()}.tmp`\n try {\n await writeFile(temp, content, 'utf8')\n await rename(temp, file)\n } catch (cause) {\n await rm(temp, { force: true })\n throw cause\n }\n}\n","import { createServer } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { localhostHostValidation, toNodeHandler } from '@modelcontextprotocol/node'\nimport { createMcpHandler } from '@modelcontextprotocol/server'\nimport { WebSocketServer, type WebSocket } from 'ws'\nimport type { Op, Request, ServerMessage } from '../core/protocol'\nimport { error } from '../core/result'\nimport { createPreviewCapture } from './capture'\nimport { createMcpServer } from './mcp'\nimport type { Runtime } from './runtime'\n\nconst LOCAL_ORIGIN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|\\[::1\\])(:\\d+)?$/\nconst OPS = new Set<string>(['tools.list', 'tool.get', 'tool.update', 'tool.save', 'tool.discard'] satisfies Op[])\n\nexport type BridgeOptions = {\n port: number\n host?: string\n /** Browser origins allowed to connect. Defaults to localhost. Non-browser clients send no origin. */\n origins?: readonly string[]\n /** Running app URL used to resolve registered preview routes for MCP capture. */\n appUrl?: string\n}\n\nexport type Bridge = { port: number; close(): Promise<void> }\n\nfunction parse(raw: string): Request | null {\n try {\n const message = JSON.parse(raw)\n if (typeof message?.id !== 'number' || !OPS.has(message.op)) return null\n return { id: message.id, op: message.op, params: message.params ?? {} }\n } catch {\n return null\n }\n}\n\n/** Share one runtime between the browser WebSocket bridge and the /mcp HTTP endpoint. */\nexport function serveBridge(\n runtime: Runtime,\n { port, host = '127.0.0.1', origins, appUrl }: BridgeOptions,\n): Promise<Bridge> {\n const allowed = (origin: string | undefined) =>\n origin === undefined || (origins ? origins.includes(origin) : LOCAL_ORIGIN.test(origin))\n\n const onerror = (cause: Error) => console.error('[studio] MCP request failed', cause)\n const previews = createPreviewCapture(runtime, { appUrl, runtimePort: () => (http.address() as AddressInfo).port })\n const mcp = createMcpHandler(() => createMcpServer(runtime, previews), { onerror })\n const handleMcp = toNodeHandler(mcp, { onerror })\n const validateHost = localhostHostValidation()\n const http = createServer((request, response) => {\n if (request.url?.split('?')[0] !== '/mcp') {\n response.writeHead(404).end()\n return\n }\n if (!validateHost(request, response)) return\n if (!allowed(request.headers.origin)) {\n response.writeHead(403).end('Origin not allowed')\n return\n }\n void handleMcp(request, response)\n })\n const server = new WebSocketServer({\n server: http,\n verifyClient: ({ origin }: { origin?: string }) => allowed(origin),\n })\n const send = (socket: WebSocket, message: ServerMessage) => {\n if (socket.readyState === socket.OPEN) socket.send(JSON.stringify(message))\n }\n\n server.on('connection', (socket) => {\n socket.on('message', async (raw) => {\n const request = parse(raw.toString())\n if (!request) return send(socket, { type: 'response', id: -1, result: error('bad_request') })\n const result = await runtime\n .run(request.op, request.params, socket)\n .catch((cause: unknown) => error('internal', cause instanceof Error ? cause.message : String(cause)))\n send(socket, { type: 'response', id: request.id, result })\n })\n })\n\n const unsubscribe = runtime.subscribe((state, origin) => {\n for (const client of server.clients) if (client !== origin) send(client, { type: 'state', state })\n })\n\n return new Promise((resolve, reject) => {\n server.once('error', (cause) => {\n unsubscribe()\n server.close()\n void mcp.close()\n void previews.close()\n reject(cause)\n })\n http.once('listening', () =>\n resolve({\n port: (http.address() as AddressInfo).port,\n close: async () => {\n unsubscribe()\n await previews.close()\n for (const client of server.clients) client.terminate()\n await mcp.close()\n await new Promise<void>((done) => server.close(() => done()))\n await new Promise<void>((done) => {\n http.close(() => done())\n http.closeAllConnections()\n })\n },\n }),\n )\n http.listen(port, host)\n })\n}\n","import type { Browser, BrowserContext } from 'playwright'\nimport type { Studio } from '../client/studio'\nimport { error, success, type Result } from '../core/result'\nimport type { Runtime } from './runtime'\n\nexport type CaptureParams = { tool: string; revision?: number; width?: number; height?: number }\ntype CaptureImage = {\n tool: string\n revision: number\n url: string\n width: number\n height: number\n settling: 'automatic'\n png: Buffer\n}\n\n/** Runs in the preview page. Reuse createStudio's HMR registry; tools need no capture integration. */\nfunction previewSnapshot({ port, tool, revision }: { port: number; tool: string; revision: number }) {\n const instances = (globalThis as { __joycoStudio?: Map<string, Studio> }).__joycoStudio\n for (const [address, studio] of instances ?? []) {\n const url = new URL(address)\n if (!['localhost', '127.0.0.1', '[::1]'].includes(url.hostname) || Number(url.port) !== port) continue\n const handle = studio.tools.find((handle) => handle.definition.id === tool)\n if (studio.connection.phase !== 'connected' || !handle?.state || handle.comparing) continue\n if (handle.state.draft.revision < revision) continue\n return { revision: handle.state.draft.revision, version: handle.version }\n }\n return null\n}\n\n/** One lazy browser per bridge, one isolated page per capture. Never writes a draft or a file. */\nexport function createPreviewCapture(\n runtime: Runtime,\n { appUrl, runtimePort, timeoutMs = 20_000 }: { appUrl?: string; runtimePort: () => number; timeoutMs?: number },\n) {\n let browser: Promise<Browser> | undefined\n let active = false\n let closed = false\n\n const capture = async ({\n tool,\n revision,\n width = 1200,\n height = 800,\n }: CaptureParams): Promise<Result<CaptureImage>> => {\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n if (active) return error('capture_busy', 'Another preview is being captured; retry when it finishes')\n const state = await runtime.run('tool.get', { tool })\n if (!state.ok) return state\n revision ??= state.data.draft.revision\n if (revision !== state.data.draft.revision) return error('stale_revision', 'Read the latest draft before capturing')\n const tools = await runtime.run('tools.list', {})\n if (!tools.ok) return tools\n const preview = tools.data.find((entry) => entry.id === tool)?.preview\n if (!preview) return error('preview_missing', `Tool \"${tool}\" has no preview route`)\n if (!appUrl) return error('app_url_missing', 'Set appUrl in studio.config.ts or pass studio dev --app-url <url>')\n let url: URL\n try {\n const base = new URL(appUrl)\n url = new URL(preview, base)\n if (!['http:', 'https:'].includes(base.protocol) || url.origin !== base.origin || url.username || url.password)\n return error('invalid_preview_url', 'The preview must be an HTTP(S) route on the configured app origin')\n } catch {\n return error('invalid_preview_url', 'appUrl must be an absolute HTTP(S) URL and preview must be a valid route')\n }\n\n // Recheck after the asynchronous runtime reads so concurrent MCP callers cannot race this lock.\n if (active) return error('capture_busy', 'Another preview is being captured; retry when it finishes')\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n active = true\n let context: BrowserContext | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n let timedOut = false\n let phase = 'starting the browser'\n try {\n browser ??= import('playwright').then(({ chromium }) => chromium.launch({ headless: true, timeout: 10_000 }))\n let instance: Browser\n try {\n instance = await browser\n } catch (cause) {\n browser = undefined\n return error('capture_unavailable', `Run \"studio install-browser\" to install Chromium. ${String(cause)}`)\n }\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n if (!instance.isConnected()) {\n browser = undefined\n return error('capture_unavailable', 'The capture browser disconnected; retry to start it again')\n }\n context = await instance.newContext({ viewport: { width, height }, deviceScaleFactor: 1 })\n timer = setTimeout(() => {\n timedOut = true\n void context?.close().catch(() => {})\n }, timeoutMs)\n const page = await context.newPage()\n page.setDefaultTimeout(timeoutMs)\n // Preview routes may load external assets, but must not navigate to a different app.\n await page.route('**/*', (route) => {\n const request = route.request()\n return request.isNavigationRequest() &&\n request.frame() === page.mainFrame() &&\n new URL(request.url()).origin !== url.origin\n ? route.abort()\n : route.continue()\n })\n phase = 'opening the preview'\n const response = await page.goto(url.href, { waitUntil: 'load' })\n if (!response?.ok()) return error('preview_failed', `Preview returned HTTP ${response?.status() ?? 'unknown'}`)\n\n phase = 'waiting for the preview to receive the draft'\n const target = { port: runtimePort(), tool, revision }\n const synced = await page.waitForFunction(previewSnapshot, target)\n const initial = await synced.jsonValue()\n await synced.dispose()\n if (initial?.revision !== revision) return error('stale_revision', 'The draft changed while opening the preview')\n\n phase = 'waiting for fonts, images, and animation frames'\n await page.evaluate(async () => {\n await document.fonts.ready\n await Promise.all(Array.from(document.images, (image) => image.decode().catch(() => {})))\n await new Promise<void>((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())))\n })\n const before = await page.evaluate(previewSnapshot, target)\n if (before?.revision !== revision) return error('stale_revision', 'The draft changed while settling the preview')\n\n phase = 'taking the screenshot'\n const png = await page.screenshot({ type: 'png', animations: 'disabled', timeout: timeoutMs })\n const after = await page.evaluate(previewSnapshot, target)\n const latest = await runtime.run('tool.get', { tool })\n if (!latest.ok) return latest\n if (latest.data.draft.revision !== revision || after?.revision !== revision || after.version !== before.version)\n return error('stale_revision', 'The preview changed during capture; read the latest draft and retry')\n return success({ tool, revision, url: page.url(), width, height, settling: 'automatic', png })\n } catch (cause) {\n if (closed) return error('capture_unavailable', 'Studio is shutting down')\n return error(\n timedOut || (cause instanceof Error && cause.name === 'TimeoutError') ? 'preview_not_ready' : 'capture_failed',\n `${phase}: ${String(cause)}`,\n )\n } finally {\n clearTimeout(timer)\n await context?.close().catch(() => {})\n active = false\n }\n }\n\n return {\n capture,\n async close() {\n closed = true\n await browser?.then((instance) => instance.close()).catch(() => {})\n browser = undefined\n },\n }\n}\n\nexport type PreviewCapture = ReturnType<typeof createPreviewCapture>\n","import { McpServer, type CallToolResult } from '@modelcontextprotocol/server'\nimport { z } from 'zod/v4'\nimport type { Op, Operations } from '../core/protocol'\nimport { success } from '../core/result'\nimport type { PreviewCapture } from './capture'\nimport type { Runtime } from './runtime'\n\nconst tool = z.string().min(1).describe('Registered Studio tool ID from studio_list_tools.')\nconst revision = z.number().int().nonnegative().describe('Draft revision returned by the latest read or update.')\n\n/** MCP is another caller of the live runtime; it never owns a second draft or writes files itself. */\nexport function createMcpServer(runtime: Runtime, previews: PreviewCapture) {\n const server = new McpServer(\n { name: 'joyco-studio', version: '0.0.0' },\n {\n instructions:\n 'List Studio tools, read the selected tool, then update its complete draft value. Updates appear live in the playground. Saving is a separate operation. If a revision is stale, read again and reconcile your changes before retrying.',\n },\n )\n const run = async <T extends Op>(op: T, params: Operations[T]['params']): Promise<CallToolResult> => {\n const result = await runtime.run(op, params)\n return {\n content: [{ type: 'text', text: JSON.stringify(result) }],\n structuredContent: result,\n isError: !result.ok,\n }\n }\n\n server.registerTool(\n 'studio_list_tools',\n {\n description:\n 'List registered Studio tools with their IDs, titles, config files, and preview routes. Tools without a file are preview-only: they have no config to read, edit, or capture.',\n inputSchema: z.object({}),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n },\n () => run('tools.list', {}),\n )\n server.registerTool(\n 'studio_get_tool',\n {\n description: 'Read a tool’s complete draft, revision, saved value, and dirty/conflict status before editing.',\n inputSchema: z.object({ tool }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n },\n (params) => run('tool.get', params),\n )\n server.registerTool(\n 'studio_update_tool',\n {\n description:\n 'Replace the complete draft config and update all connected previews. Read first and preserve fields you are not changing. The runtime validates types, slider bounds, and select options. Does not save to disk; rejects a stale revision.',\n inputSchema: z.object({ tool, revision, value: z.record(z.string(), z.unknown()) }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },\n },\n (params) => run('tool.update', params),\n )\n server.registerTool(\n 'studio_save_tool',\n {\n description:\n 'Persist a draft to its registered JSON file. Pass the latest draft revision. Rejects stale revisions and changes made on disk; force explicitly overwrites a disk conflict.',\n inputSchema: z.object({ tool, revision, force: z.boolean().optional() }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n },\n (params) => run('tool.save', params),\n )\n server.registerTool(\n 'studio_discard_tool',\n {\n description:\n 'Discard unsaved edits and restore the runtime’s latest saved value in every preview. Read first; rejects a stale revision.',\n inputSchema: z.object({ tool, revision }),\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },\n },\n (params) => run('tool.discard', params),\n )\n server.registerTool(\n 'studio_capture_preview',\n {\n description:\n 'Capture a registered preview as a PNG in a fresh browser page using the live draft. Requires appUrl and Chromium (studio install-browser). Defaults to the current revision and 1200×800. Waits for draft sync, fonts, images, and two animation frames; automatic settling does not guarantee arbitrary async scenes are finished. Rejects a draft change during capture. Does not share your open tab’s scroll, login, or interaction state.',\n inputSchema: z.object({\n tool,\n revision: revision.optional(),\n width: z.number().int().min(320).max(2560).optional(),\n height: z.number().int().min(240).max(1600).optional(),\n }),\n annotations: { readOnlyHint: true, idempotentHint: false, openWorldHint: true },\n },\n async (params): Promise<CallToolResult> => {\n const captured = await previews.capture(params)\n if (!captured.ok)\n return {\n content: [{ type: 'text', text: JSON.stringify(captured) }],\n structuredContent: captured,\n isError: true,\n }\n const { png, ...metadata } = captured.data\n const result = success(metadata)\n return {\n content: [\n { type: 'text', text: JSON.stringify(result) },\n { type: 'image', mimeType: 'image/png', data: png.toString('base64') },\n ],\n structuredContent: result,\n isError: false,\n }\n },\n )\n return server\n}\n","import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs'\nimport { mkdir, readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { resolveToolFile, writeAtomic } from '../runtime/files'\nimport { readSettings } from './settings'\n\nconst slash = (value: string) => value.split(path.sep).join('/')\nconst relativeImport = (from: string, to: string) => {\n const relative = slash(path.relative(path.dirname(from), to)).replace(/\\.(tsx?|jsx?|mts|mjs)$/, '')\n return /^\\.\\.?\\//.test(relative) ? relative : `./${relative}`\n}\nconst inside = (root: string, file: string) => {\n const relative = path.relative(root, file)\n return relative === '' || (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative))\n}\nconst fail = (file: string, message: string): never => {\n throw new Error(`[studio] ${file}: ${message}`)\n}\nconst HEADER = '// Generated by Studio. Do not edit.\\n'\n\n/** Inputs from a rejected update still need watching so finishing a tool can recover it. */\nexport class DiscoveryInputError extends Error {\n constructor(\n cause: unknown,\n readonly inputs: Set<string>,\n ) {\n super(cause instanceof Error ? cause.message : String(cause), { cause })\n }\n}\n\n// Value edits keep the browser seed stable; a different JSON shape needs a new module.\nfunction shape(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return `[${[...new Set(value.map(shape))].sort().join('|')}]`\n if (typeof value === 'object')\n return `{${Object.entries(value)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${shape(item)}`)\n .join(',')}}`\n return typeof value\n}\n\nexport type Discovery = {\n root: string\n toolsDir: string\n sources: Set<string>\n dependencies: Set<string>\n registry: string\n /** Browser bootstrap values retained across runtime-managed, value-only updates. */\n seeds: Map<string, object>\n declarations: { source: string; preview: string; title: string; file?: string; initial?: object }[]\n /** Publish validated output after the runtime has accepted a refresh. */\n write(): Promise<void>\n}\n\n/** Parse declarations before importing them: their contextual types do not exist on a clean checkout yet. */\nfunction declaration(file: string) {\n const source = ts.createSourceFile(file, readFileSync(file, 'utf8'), ts.ScriptTarget.Latest, true)\n const exported = source.statements.find(ts.isExportAssignment)\n const call = exported?.expression\n if (!call || !ts.isCallExpression(call) || !ts.isIdentifier(call.expression) || call.expression.text !== 'defineTool')\n return fail(file, 'default-export defineTool({ id, controls }) directly so discovery can inspect it.')\n const object = call.arguments[0]\n if (!object || !ts.isObjectLiteralExpression(object)) return fail(file, 'defineTool requires an object literal.')\n const properties = new Map<string, ts.ObjectLiteralElementLike>()\n for (const member of object.properties) {\n if (ts.isSpreadAssignment(member) || !member.name || ts.isComputedPropertyName(member.name))\n return fail(file, 'spread/computed tool options are not supported; put dynamic logic inside controls.')\n const key = member.name.getText(source).replace(/^['\"]|['\"]$/g, '')\n if (properties.has(key)) return fail(file, `duplicate option ${key}`)\n properties.set(key, member)\n }\n const literal = (key: string) => {\n const member = properties.get(key)\n if (!member) return undefined\n if (!ts.isPropertyAssignment(member) || !ts.isStringLiteral(member.initializer))\n return fail(file, `${key} must be a static string literal.`)\n return member.initializer.text\n }\n const id = literal('id')\n if (!id || !/^[a-z0-9][a-z0-9-]*$/.test(id)) return fail(file, 'id must be an explicit kebab-case string.')\n if (properties.has('file') || properties.has('initial'))\n return fail(file, 'discovered tools use config instead of file/initial; omit config for adjacent config.json.')\n const configurable = properties.has('controls')\n const config = literal('config')\n if (config !== undefined && !configurable) return fail(file, 'config requires controls.')\n return { id, config, configurable, preview: literal('preview'), source }\n}\n\nfunction pageRoute(app: string | undefined, file: string, explicit?: string) {\n if (explicit) return explicit\n const directory = path.dirname(file)\n if (!app || !inside(app, directory)) return fail(file, 'tools outside the app tree require an explicit preview URL.')\n if (!['tsx', 'ts', 'jsx', 'js'].some((ext) => existsSync(path.join(directory, `page.${ext}`))))\n return fail(file, 'add an adjacent page.tsx or specify preview explicitly.')\n const segments = slash(path.relative(app, directory)).split('/').filter(Boolean)\n if (segments.some((part) => part.includes('[') || part.startsWith('@') || /^\\(\\./.test(part) || part.startsWith('_')))\n return fail(file, 'dynamic, parallel, intercepted, and private routes require an explicit preview URL.')\n return '/' + segments.filter((part) => !/^\\(.+\\)$/.test(part)).join('/')\n}\n\nfunction walk(directory: string): string[] {\n return readdirSync(directory, { withFileTypes: true })\n .flatMap((entry) => {\n if (entry.name.startsWith('.') || entry.name === 'node_modules' || entry.isSymbolicLink()) return []\n const file = path.join(directory, entry.name)\n return entry.isDirectory() ? walk(file) : entry.name === 'studio.tool.ts' ? [file] : []\n })\n .sort()\n}\n\nfunction compilerConfig(root: string, dependencies: Set<string>) {\n const configFile = path.join(root, 'tsconfig.json')\n if (!existsSync(configFile)) return fail(root, 'discovery requires tsconfig.json.')\n const host: ts.ParseConfigFileHost = {\n ...ts.sys,\n readDirectory: () => [],\n readFile(file) {\n dependencies.add(path.resolve(file))\n return ts.sys.readFile(file)\n },\n onUnRecoverableConfigFileDiagnostic(error) {\n throw new Error(ts.flattenDiagnosticMessageText(error.messageText, '\\n'))\n },\n }\n const parsed = ts.getParsedCommandLineOfConfigFile(configFile, { resolveJsonModule: true }, host)\n if (!parsed) return fail(configFile, 'could not read TypeScript settings.')\n return parsed.options\n}\n\nasync function writeChanged(file: string, content: string) {\n if ((await readFile(file, 'utf8').catch(() => '')) === content) return\n await writeAtomic(file, content)\n}\n\n/** Generate only after all declarations and paths validate. Never loads preview components. */\nexport async function generate(\n cwd: string,\n explicit?: string,\n publish = true,\n previous?: Discovery,\n): Promise<Discovery | undefined> {\n const { root, config, file: settings } = await readSettings(cwd, explicit)\n if (config.tools !== undefined) return undefined\n const app = ['app', 'src/app'].map((dir) => path.join(root, dir)).find(existsSync)\n const toolsDir = config.toolsDir === undefined ? app : path.resolve(root, config.toolsDir)\n if (!toolsDir || !existsSync(toolsDir))\n return fail(root, 'no tools directory found; create app/ or configure toolsDir.')\n if (!inside(realpathSync(root), realpathSync(toolsDir)))\n return fail(toolsDir, 'toolsDir must stay inside the project.')\n const sources = new Set(walk(toolsDir))\n const dependencies = new Set<string>()\n if (settings) dependencies.add(settings)\n const options = compilerConfig(root, dependencies)\n const output = path.join(root, '.studio')\n const registry = path.join(output, 'registry.generated.ts')\n const types = path.join(output, 'types.generated.ts')\n const imports = [\n HEADER,\n '/// <reference path=\"./types.generated.ts\" />',\n \"import type { StudioTool, DiscoveredToolConfigs } from '@joycostudio/studio'\",\n ]\n const typeImports = [HEADER, \"import '@joycostudio/studio'\"]\n const declarations: Discovery['declarations'] = []\n const definitions: string[] = []\n const mappings: string[] = []\n const ids = new Set<string>()\n const destinations = new Set<string>()\n const seeds = new Map<string, object>()\n // Track local control helpers as well as the marker itself, without watching node_modules.\n const trackImports = (file: string) => {\n if (dependencies.has(file)) return\n dependencies.add(file)\n if (!/\\.[cm]?[jt]sx?$/.test(file)) return\n for (const imported of ts.preProcessFile(readFileSync(file, 'utf8')).importedFiles) {\n const resolved = ts.resolveModuleName(imported.fileName, file, options, ts.sys).resolvedModule?.resolvedFileName\n if (\n resolved &&\n inside(root, resolved) &&\n !resolved.includes(`${path.sep}node_modules${path.sep}`) &&\n !inside(output, resolved)\n )\n trackImports(resolved)\n }\n }\n for (const [index, file] of [...sources].entries()) {\n const tool = declaration(file)\n if (ids.has(tool.id)) return fail(file, `duplicate tool id \"${tool.id}\".`)\n ids.add(tool.id)\n trackImports(file)\n const preview = pageRoute(app, file, tool.preview)\n const title = (preview.split('/').filter(Boolean).at(-1) || tool.id)\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n imports.push(`import tool${index} from ${JSON.stringify(relativeImport(registry, file))}`)\n let values = ''\n const resolvedTool: Discovery['declarations'][number] = { source: file, title, preview }\n if (tool.configurable) {\n const inputs = new Set<string>()\n try {\n const specifier = tool.config ?? './config.json'\n const resolutionHost: ts.ModuleResolutionHost = {\n ...ts.sys,\n fileExists(candidate) {\n if (inside(root, candidate) && !candidate.includes(`${path.sep}node_modules${path.sep}`))\n inputs.add(candidate)\n return ts.sys.fileExists(candidate)\n },\n directoryExists(directory) {\n const exists = ts.sys.directoryExists(directory)\n if (!exists && inside(root, directory) && !directory.includes(`${path.sep}node_modules${path.sep}`))\n inputs.add(directory)\n return exists\n },\n }\n const resolved = ts.resolveModuleName(specifier, file, options, resolutionHost).resolvedModule?.resolvedFileName\n if (!resolved || !resolved.endsWith('.json'))\n return fail(file, `cannot resolve JSON config \"${specifier}\" through tsconfig.json.`)\n const target = await resolveToolFile(root, slash(path.relative(root, resolved)))\n inputs.add(target)\n const real = realpathSync(target)\n if (destinations.has(real)) return fail(file, 'another tool already writes this config file.')\n destinations.add(real)\n const value = JSON.parse(readFileSync(target, 'utf8'))\n if (!value || typeof value !== 'object' || Array.isArray(value))\n return fail(file, 'config must be a JSON object.')\n resolvedTool.file = slash(path.relative(root, target))\n resolvedTool.initial = value\n dependencies.add(target)\n const key = `${tool.id}:${real}`\n const prior = previous?.seeds.get(key)\n const seed = prior && shape(prior) === shape(value) ? prior : value\n seeds.set(key, seed)\n typeImports.push(`import type config${index} from ${JSON.stringify(relativeImport(types, target))}`)\n mappings.push(` ${JSON.stringify(tool.id)}: typeof config${index}`)\n // JSON.parse preserves JSON keys such as __proto__ without JS object-literal semantics.\n values = `, file: ${JSON.stringify(slash(path.relative(root, target)))}, initial: JSON.parse(${JSON.stringify(JSON.stringify(seed))}) as DiscoveredToolConfigs[${JSON.stringify(tool.id)}]`\n } catch (cause) {\n throw new DiscoveryInputError(cause, new Set([...dependencies, ...inputs]))\n }\n }\n declarations.push(resolvedTool)\n definitions.push(\n ` { title: ${JSON.stringify(title)}, ...tool${index}, preview: ${JSON.stringify(preview)}${values} }`,\n )\n }\n const write = async () => {\n await mkdir(output, { recursive: true })\n await writeChanged(\n types,\n `${typeImports.join('\\n')}\\n\\ndeclare module '@joycostudio/studio' {\\n interface DiscoveredToolConfigs {\\n${mappings.join('\\n')}\\n }\\n}\\n`,\n )\n await writeChanged(\n registry,\n `${imports.join('\\n')}\\n\\nexport const tools = [\\n${definitions.join(',\\n')}\\n] satisfies readonly StudioTool[]\\n`,\n )\n }\n if (publish) await write()\n return { root, toolsDir, sources, dependencies, registry, seeds, declarations, write }\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { createJiti } from 'jiti'\nimport type { StudioConfig } from '../core/tool'\n\nconst CANDIDATES = ['studio.config.ts', 'studio.config.mts', 'studio.config.js', 'studio.config.mjs']\n\nexport function importer(root: string) {\n return createJiti(import.meta.url, {\n moduleCache: false,\n fsCache: false,\n tryNative: false,\n tsconfigPaths: existsSync(path.join(root, 'tsconfig.json')) ? path.join(root, 'tsconfig.json') : false,\n })\n}\n\nexport async function readSettings(cwd: string, explicit?: string) {\n const file = explicit ? path.resolve(cwd, explicit) : CANDIDATES.map((name) => path.join(cwd, name)).find(existsSync)\n if (explicit && !existsSync(file!)) throw new Error(`[studio] no ${explicit} found in ${cwd}`)\n const root = file ? path.dirname(file) : path.resolve(cwd)\n const config = file ? await importer(root).import<StudioConfig>(file, { default: true }) : {}\n if (!config || typeof config !== 'object' || (config.tools !== undefined && !Array.isArray(config.tools)))\n throw new Error('[studio] config must default-export defineConfig({ ... })')\n if (config.tools !== undefined && config.toolsDir !== undefined)\n throw new Error('[studio] Use either tools (manual registration) or toolsDir (discovery), not both.')\n return { config, root, file }\n}\n","import { generate, type Discovery } from '../discovery/generate'\nimport { importer, readSettings } from '../discovery/settings'\nimport type { StudioTool } from '../core/tool'\n\n/** Resolve discovery directly in Node; generated browser imports are published only when valid. */\nexport async function loadConfig(cwd: string, explicit?: string, publish = true, previous?: Discovery) {\n const { config, root } = await readSettings(cwd, explicit)\n const discovery = await generate(cwd, explicit, false, previous)\n const jiti = importer(root)\n const tools: readonly StudioTool[] =\n config.tools ??\n (await Promise.all(\n discovery!.declarations.map(async ({ source, title, preview, file, initial }) => {\n const tool = await jiti.import<StudioTool>(source, { default: true })\n return { title, ...tool, preview, ...(file ? { file, initial } : {}) } as StudioTool\n }),\n ))\n if (publish) await discovery?.write()\n return { config: { ...config, tools }, root, discovery }\n}\n","import { connect } from 'node:net'\nimport type { Runtime } from './runtime'\nimport { serveBridge, type Bridge, type BridgeOptions } from './server'\n\nconst ATTEMPTS = 20\n\n/** Serve on `port`, or on the next free one when another Studio (or anything else) already holds it. */\nexport async function serveBridgeNear(runtime: Runtime, options: BridgeOptions): Promise<Bridge> {\n for (let port = options.port; ; port++) {\n try {\n return await serveBridge(runtime, { ...options, port })\n } catch (cause) {\n const taken = (cause as NodeJS.ErrnoException).code === 'EADDRINUSE'\n if (!taken || options.port === 0 || port - options.port >= ATTEMPTS - 1) throw cause\n }\n }\n}\n\n/** Whether something already answers at `hostname:port`, on any address family `hostname` resolves to. */\nfunction answers(hostname: string, port: number) {\n return new Promise<boolean>((resolve) => {\n const socket = connect({ host: hostname.replace(/^\\[|\\]$/g, ''), port, timeout: 1000 })\n const done = (busy: boolean) => {\n socket.destroy()\n resolve(busy)\n }\n socket.once('connect', () => done(true))\n socket.once('timeout', () => done(true))\n socket.once('error', () => done(false))\n })\n}\n\n/** First port from `port` that nothing answers on, so a wrapped app server can claim it. */\nexport async function freeAppPort(hostname: string, port: number): Promise<number> {\n for (let candidate = port; candidate < port + ATTEMPTS; candidate++)\n if (!(await answers(hostname, candidate))) return candidate\n throw new Error(`[studio] ports ${port}-${port + ATTEMPTS - 1} on ${hostname} are all in use`)\n}\n","import { spawnSync } from 'node:child_process'\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmdirSync, rmSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { parseArgs } from 'node:util'\nimport packageInfo from '../package.json'\nimport { generate } from './discovery/generate'\nimport { nextConfigEdit } from './discovery/scaffold'\n\n/** Generate ordinary source files; never replace existing application code. */\nexport async function init(argv: string[]) {\n const { positionals, values } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: { 'no-install': { type: 'boolean' }, ui: { type: 'string', default: 'tweakpane' } },\n })\n if (positionals.length > 1) throw new Error('Usage: studio init [directory] [--ui tweakpane|dialkit] [--no-install]')\n const ui = values.ui\n if (ui !== 'tweakpane' && ui !== 'dialkit') throw new Error(`[studio] --ui must be tweakpane or dialkit, got ${ui}.`)\n const root = path.resolve(positionals[0] ?? '.')\n const manifest = path.join(root, 'package.json')\n const pkg = JSON.parse(readFileSync(manifest, 'utf8'))\n if (!pkg.dependencies?.next && !pkg.devDependencies?.next)\n throw new Error('[studio] init supports existing Next.js App Router projects.')\n if (!existsSync(path.join(root, 'tsconfig.json')))\n throw new Error('[studio] init currently requires a TypeScript project (tsconfig.json).')\n const app = ['app', 'src/app'].find((dir) => existsSync(path.join(root, dir)))\n if (!app) throw new Error('[studio] No app/ or src/app/ directory found.')\n const src = app.startsWith('src/') ? 'src/' : ''\n const relative = (from: string, to: string) => {\n const result = path.relative(path.dirname(from), to).split(path.sep).join('/')\n return /^\\.\\.?\\//.test(result) ? result : `./${result}`\n }\n const client = `${src}studio.ts`\n const tool = `${app}/studio-preview/studio.tool.ts`\n const data = `${app}/studio-preview/config.json`\n const page = `${app}/studio/page.tsx`\n const preview = `${app}/studio-preview/page.tsx`\n const files: Record<string, string> = {\n [client]:\n ui === 'dialkit'\n ? `import 'dialkit/vanilla/styles.css'\nimport { createStudio } from '@joycostudio/studio/next'\nimport { dialkit } from '@joycostudio/studio/ui'\nimport { tools } from '${relative(client, '.studio/registry.generated')}'\n\nexport const studio = createStudio({ tools, ui: dialkit(() => import('dialkit/vanilla')) })\n`\n : `import { createStudio } from '@joycostudio/studio/next'\nimport { tweakpane } from '@joycostudio/studio/ui'\nimport { tools } from '${relative(client, '.studio/registry.generated')}'\n\nexport const studio = createStudio({ tools, ui: tweakpane(() => import('tweakpane')) })\n`,\n [data]: '{ \"scale\": 1 }\\n',\n [tool]: `import { defineTool } from '@joycostudio/studio'\nimport { property, slider } from '@joycostudio/studio/controls'\n\nexport default defineTool({\n id: 'studio-example',\n title: 'Example',\n controls: (config) => ({ scale: slider(property(config, 'scale'), { min: 0.5, max: 2 }) }),\n})\n`,\n [page]: `'use client'\n\nimport '@joycostudio/studio/styles.css'\nimport { Studio } from '@joycostudio/studio/react'\nimport { studio } from '${relative(page, client.slice(0, -3))}'\n\nexport default function StudioPage() {\n return <Studio studio={studio} />\n}\n`,\n [preview]: `'use client'\n\nimport { useToolConfig } from '@joycostudio/studio/react'\nimport { studio } from '${relative(preview, client.slice(0, -3))}'\nimport example from './studio.tool'\n\nexport default function StudioPreview() {\n const config = useToolConfig(studio.tool(example))\n return (\n <main style={{ display: 'grid', placeItems: 'center', minHeight: '100vh' }}>\n <div style={{ width: 120, height: 120, background: '#ff5930', borderRadius: 24, transform: \\`scale(\\${config.scale})\\` }} />\n </main>\n )\n}\n`,\n }\n // Route groups do not contribute URL segments; handlers also reserve a URL.\n const checkRoute = (directory: string, segment: string | undefined, allowed: string) => {\n for (const entry of readdirSync(path.join(root, directory), { withFileTypes: true })) {\n const file = `${directory}/${entry.name}`\n if (entry.isDirectory()) {\n if (/^\\([^.)][^/]*\\)$/.test(entry.name)) checkRoute(file, segment, allowed)\n else if (entry.name === segment) checkRoute(file, undefined, allowed)\n } else if (!segment && /^(page|route)\\.[jt]sx?$/.test(entry.name) && file !== allowed) {\n throw new Error(`[studio] Route already exists: ${file}`)\n }\n }\n }\n checkRoute(app, 'studio', page)\n checkRoute(app, 'studio-preview', preview)\n // Check every destination before writing anything. Identical files make reruns safe.\n for (const [name, content] of Object.entries(files)) {\n const target = path.join(root, name)\n if (existsSync(target) && readFileSync(target, 'utf8') !== content)\n throw new Error(`[studio] Refusing to overwrite ${name}. Use the manual setup guide for existing integrations.`)\n }\n for (const ext of ['ts', 'mts', 'js', 'mjs']) {\n if (existsSync(path.join(root, `studio.config.${ext}`)))\n throw new Error(`[studio] Found studio.config.${ext}; use the manual setup guide for existing integrations.`)\n }\n const nextEdit = nextConfigEdit(root)\n const dev = pkg.scripts?.dev\n if (!dev || /[;&|\\n]/.test(dev) || (!/^studio dev(?:\\s|$)/.test(dev) && !/^next dev(?:\\s|$)/.test(dev)))\n throw new Error(\n '[studio] Expected a next dev script. Configure studio dev -- <command> manually for custom scripts.',\n )\n let manager = pkg.packageManager?.split('@')[0]\n if (!manager) {\n let dir = root\n while (true) {\n manager = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n ].find(([lock]) => existsSync(path.join(dir, lock!)))?.[1]\n if (manager || path.dirname(dir) === dir) break\n dir = path.dirname(dir)\n }\n }\n manager ??= 'npm'\n if (!['npm', 'pnpm', 'yarn', 'bun'].includes(manager))\n throw new Error(`[studio] Unsupported package manager: ${manager}`)\n if (pkg.dependencies?.['@joycostudio/studio'] || pkg.devDependencies?.['@joycostudio/studio']) {\n try {\n const require = createRequire(manifest)\n for (const entry of ['next', 'next/config', 'controls', 'react', 'ui'])\n require.resolve(`@joycostudio/studio/${entry}`)\n } catch {\n throw new Error(\n '[studio] The declared Studio dependency is missing or lacks the required exports. Install the same version (or preview) as this initializer, then rerun init. No files were changed.',\n )\n }\n }\n const dependencies = {\n '@joycostudio/studio': `^${packageInfo.version}`,\n '@joycostudio/xyz': packageInfo.peerDependencies['@joycostudio/xyz'],\n [ui]: packageInfo.peerDependencies[ui],\n }\n pkg.dependencies ??= {}\n for (const [name, version] of Object.entries(dependencies)) {\n if (!pkg.dependencies[name] && !pkg.devDependencies?.[name]) pkg.dependencies[name] = version\n }\n if (!/^studio dev(?:\\s|$)/.test(dev)) pkg.scripts.dev = `studio dev -- ${dev}`\n const typecheck = pkg.scripts.typecheck ?? 'tsc --noEmit'\n if (!typecheck.startsWith('studio generate')) pkg.scripts.typecheck = `studio generate && ${typecheck}`\n const ignoreFile = path.join(root, '.gitignore')\n const targets = [\n ...Object.keys(files).map((name) => path.join(root, name)),\n nextEdit.file,\n ignoreFile,\n manifest,\n path.join(root, '.studio/types.generated.ts'),\n path.join(root, '.studio/registry.generated.ts'),\n ]\n const originals = new Map(targets.map((file) => [file, existsSync(file) ? readFileSync(file) : undefined]))\n const createdDirectories = new Set<string>()\n for (const file of targets) {\n for (let dir = path.dirname(file); !existsSync(dir); dir = path.dirname(dir)) createdDirectories.add(dir)\n }\n try {\n for (const [name, content] of Object.entries(files)) {\n const target = path.join(root, name)\n if (existsSync(target)) continue\n mkdirSync(path.dirname(target), { recursive: true })\n writeFileSync(target, content, { flag: 'wx' })\n }\n writeFileSync(nextEdit.file, nextEdit.content)\n const ignore = originals.get(ignoreFile)?.toString() ?? ''\n if (!ignore.split(/\\r?\\n/).some((line) => ['.studio', '.studio/', '/.studio/'].includes(line)))\n writeFileSync(ignoreFile, `${ignore}${ignore.endsWith('\\n') || !ignore ? '' : '\\n'}/.studio/\\n`)\n await generate(root)\n writeFileSync(manifest, `${JSON.stringify(pkg, null, 2)}\\n`)\n } catch (cause) {\n // A failed generation must leave the app as it was, including any prior generated output.\n for (const [file, original] of originals) {\n if (original === undefined) rmSync(file, { force: true })\n else if (!existsSync(file) || !readFileSync(file).equals(original)) writeFileSync(file, original)\n }\n for (const dir of [...createdDirectories].sort((a, b) => b.length - a.length)) {\n try {\n rmdirSync(dir)\n } catch (error) {\n // Preserve anything another process created while generation was running.\n if (!['ENOENT', 'ENOTEMPTY'].includes((error as NodeJS.ErrnoException).code ?? '')) throw error\n }\n }\n throw cause\n }\n if (!values['no-install']) {\n const result = spawnSync(manager, ['install'], { cwd: root, stdio: 'inherit', shell: process.platform === 'win32' })\n if (result.error || result.status !== 0)\n throw new Error(`[studio] Files created, but installation failed. Run ${manager} install in ${root} to retry.`)\n }\n console.log(`[studio] Ready. ${values['no-install'] ? `Run ${manager} install, then ` : 'Run '}${manager} run dev and open /studio.\nThe example at /studio-preview reacts to edits; Save writes ${data}.\nTo connect your app, read studio.tool(yourTool).config or useToolConfig(studio.tool(yourTool)).\nOptional: mount <StudioDebug studio={studio} /> or <StudioCommandMenu studio={studio} /> from @joycostudio/studio/react.\nFor MCP, use the endpoint printed by studio dev. Preview capture additionally requires appUrl and studio install-browser.`)\n}\n","{\n \"name\": \"@joycostudio/studio\",\n \"version\": \"0.2.1\",\n \"description\": \"Plug project-specific tools into a /studio route, a floating debug pane, and MCP agents.\",\n \"type\": \"module\",\n \"license\": \"ISC\",\n \"author\": \"joyco.studio\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/joyco-studio/studio.git\",\n \"directory\": \"packages/studio\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\"\n ],\n \"bin\": {\n \"studio\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./client\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react.d.ts\",\n \"default\": \"./dist/react.js\"\n },\n \"./runtime\": {\n \"types\": \"./dist/runtime.d.ts\",\n \"default\": \"./dist/runtime.js\"\n },\n \"./styles.css\": \"./dist/styles.css\",\n \"./command-menu.css\": \"./dist/command-menu.css\",\n \"./next\": {\n \"types\": \"./dist/next.d.ts\",\n \"default\": \"./dist/next.js\"\n },\n \"./controls\": {\n \"types\": \"./dist/controls.d.ts\",\n \"default\": \"./dist/controls.js\"\n },\n \"./ui\": {\n \"types\": \"./dist/ui.d.ts\",\n \"default\": \"./dist/ui.js\"\n },\n \"./next/config\": {\n \"types\": \"./dist/next-config.d.ts\",\n \"default\": \"./dist/next-config.js\"\n }\n },\n \"scripts\": {\n \"build\": \"pnpm build:shadow-css && tsup && tailwindcss -i src/react/styles.css -o dist/styles.css --minify && cp src/react/command-menu-export.css dist/command-menu.css\",\n \"dev\": \"pnpm build:shadow-css && pnpm run --parallel \\\"/^dev:/\\\"\",\n \"test\": \"vitest run\",\n \"test:browser\": \"STUDIO_TEST_BROWSER=1 vitest run test/browser-sync.test.ts test/ui.test.ts\",\n \"test:capture\": \"STUDIO_TEST_CAPTURE=1 vitest run test/capture.test.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"dev:js\": \"tsup --watch\",\n \"dev:css\": \"tailwindcss -i src/react/styles.css -o dist/styles.css --watch=always\",\n \"build:shadow-css\": \"tailwindcss -i src/react/shadow.css -o src/react/generated/studio.css --minify\",\n \"dev:shadow-css\": \"tailwindcss -i src/react/shadow.css -o src/react/generated/studio.css --minify --watch=always\"\n },\n \"dependencies\": {\n \"@base-ui/react\": \"^1.9.0\",\n \"@modelcontextprotocol/node\": \"^2.1.1\",\n \"@modelcontextprotocol/server\": \"^2.3.1\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cmdk\": \"^1.1.1\",\n \"cn\": \"^0.4.0\",\n \"jiti\": \"^2.7.0\",\n \"lucide\": \"^1.55.0\",\n \"lucide-react\": \"^1.55.0\",\n \"playwright\": \"^1.64.0\",\n \"radix-ui\": \"^1.8.0\",\n \"tailwind-merge\": \"^3.7.0\",\n \"ws\": \"^8.22.0\",\n \"zod\": \"^4.6.6\",\n \"typescript\": \"^5.9.3\"\n },\n \"peerDependencies\": {\n \"@joycostudio/xyz\": \"^1.5.0\",\n \"dialkit\": \"^2.2.0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"tweakpane\": \"^4.0.5\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"tweakpane\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"dialkit\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@joycostudio/xyz\": \"^1.5.0\",\n \"@modelcontextprotocol/client\": \"^2.3.1\",\n \"@tailwindcss/cli\": \"^4.3.3\",\n \"@tweakpane/core\": \"^2.0.5\",\n \"@types/node\": \"^24.19.2\",\n \"@types/react\": \"^19.3.0\",\n \"@types/react-dom\": \"^19.3.0\",\n \"@types/ws\": \"^8.18.2\",\n \"dialkit\": \"^2.2.0\",\n \"react\": \"^19.3.0\",\n \"react-dom\": \"^19.3.0\",\n \"tailwindcss\": \"^4.3.3\",\n \"tsup\": \"^8.5.1\",\n \"tw-animate-css\": \"^1.4.0\",\n \"tweakpane\": \"^4.0.5\",\n \"vitest\": \"^5.0.3\"\n },\n \"sideEffects\": [\n \"*.css\"\n ]\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\n\n/** Preserve existing Next options and function configs; wrap only their export expression. */\nexport function nextConfigEdit(root: string): { file: string; content: string } {\n const name = ['next.config.ts', 'next.config.mjs', 'next.config.js'].find((file) => existsSync(path.join(root, file)))\n if (!name)\n return {\n file: path.join(root, 'next.config.ts'),\n content: \"import { withStudio } from '@joycostudio/studio/next/config'\\n\\nexport default withStudio({})\\n\",\n }\n const file = path.join(root, name)\n const text = readFileSync(file, 'utf8')\n const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true)\n // Inspect calls so an unused import or commented example cannot disable generation.\n const wrapped = (node: ts.Node): boolean =>\n (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && /^withStudio\\w*$/.test(node.expression.text)) ||\n (ts.forEachChild(node, wrapped) ?? false)\n if (text.includes('@joycostudio/studio/next/config') && wrapped(source)) return { file, content: text }\n const exported = source.statements.find(ts.isExportAssignment)\n if (exported && !exported.isExportEquals) {\n const expression = exported.expression\n let local = 'withStudioSetup'\n while (new RegExp(`\\\\b${local}\\\\b`).test(text)) local += '_'\n return {\n file,\n content:\n `import { withStudio as ${local} } from '@joycostudio/studio/next/config'\\n` +\n text.slice(0, expression.getStart(source)) +\n `${local}(${expression.getText(source)})` +\n text.slice(expression.end),\n }\n }\n const assignment = source.statements.flatMap((statement) =>\n ts.isExpressionStatement(statement) &&\n ts.isBinaryExpression(statement.expression) &&\n statement.expression.left.getText(source) === 'module.exports' &&\n statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken\n ? [statement.expression.right]\n : [],\n )\n if (assignment.length === 1) {\n const expression = assignment[0]!\n return {\n file,\n content:\n text.slice(0, expression.getStart(source)) +\n `async (...args) => { const { withStudio } = await import('@joycostudio/studio/next/config'); return withStudio(${expression.getText(source)})(...args) }` +\n text.slice(expression.end),\n }\n }\n throw new Error(\n `[studio] Cannot wrap ${name} automatically. Export a config object/function or wrap it with withStudio manually.`,\n )\n}\n","import { existsSync, statSync, watch, type FSWatcher } from 'node:fs'\nimport path from 'node:path'\nimport { DiscoveryInputError, type Discovery } from './generate'\n\n/** Watch the selected tree, plus exact imported dependencies outside it. No page-content triggers. */\nexport function watchDiscovery(initial: Discovery, refresh: () => Promise<Discovery | undefined>) {\n let current = initial\n let retryInputs = new Set<string>()\n let watchers: FSWatcher[] = []\n let timer: NodeJS.Timeout | undefined\n let running = false\n let pending = false\n let closed = false\n const schedule = () => {\n if (closed) return\n pending = true\n clearTimeout(timer)\n timer = setTimeout(() => void run(), 80)\n }\n const run = async () => {\n if (running || closed) return\n pending = false\n running = true\n try {\n const next = await refresh()\n if (next && !closed) {\n current = next\n retryInputs.clear()\n bind()\n }\n } catch (cause) {\n if (cause instanceof DiscoveryInputError && !closed) {\n retryInputs = cause.inputs\n bind()\n }\n console.error('[studio] discovery update rejected:', cause instanceof Error ? cause.message : cause)\n } finally {\n running = false\n if (pending) schedule()\n }\n }\n const bind = () => {\n for (const watcher of watchers) watcher.close()\n watchers = []\n const pages = new Map(\n [...current.sources].flatMap((file) =>\n ['tsx', 'ts', 'jsx', 'js'].map((ext) => {\n const page = path.join(path.dirname(file), `page.${ext}`)\n return [page, existsSync(page)] as const\n }),\n ),\n )\n const add = (directory: string, recursive: boolean, listener: (event: string, filename: string | null) => void) => {\n if (!existsSync(directory)) return\n const watcher = watch(directory, { recursive }, listener)\n watcher.on('error', (cause) => console.error('[studio] discovery watcher:', cause.message))\n watcher.unref()\n watchers.push(watcher)\n }\n add(current.toolsDir, true, (event, filename) => {\n if (!filename) return schedule()\n const relative = filename.toString()\n if (relative.split(path.sep).some((part) => part.startsWith('.') || part === 'node_modules')) return\n const file = path.resolve(current.toolsDir, relative)\n if (path.basename(file) === 'studio.tool.ts' || current.dependencies.has(file)) return schedule()\n if (pages.has(file)) {\n if (pages.get(file) !== existsSync(file)) schedule()\n return\n }\n if (\n event === 'rename' &&\n (/^page\\.[jt]sx?$/.test(path.basename(file)) ||\n !path.extname(file) ||\n statSync(file, { throwIfNoEntry: false })?.isDirectory())\n )\n schedule()\n })\n const targets = new Set([\n ...current.dependencies,\n ...retryInputs,\n ...['studio.config.ts', 'studio.config.mts', 'studio.config.js', 'studio.config.mjs', 'tsconfig.json'].map(\n (file) => path.join(current.root, file),\n ),\n ])\n const byDirectory = new Map<string, Set<string>>()\n for (const file of targets) {\n let directory = path.dirname(file)\n // Watch the nearest existing parent until missing alias/relative-path directories appear.\n while (!existsSync(directory) && path.dirname(directory) !== directory) directory = path.dirname(directory)\n const names = byDirectory.get(directory) ?? new Set<string>()\n names.add(path.relative(directory, file).split(path.sep)[0]!)\n byDirectory.set(directory, names)\n }\n for (const [directory, names] of byDirectory) {\n add(directory, false, (_, filename) => {\n if (!filename || names.has(filename.toString())) schedule()\n })\n }\n const directoryId = statSync(current.toolsDir, { throwIfNoEntry: false })?.ino\n add(path.dirname(current.toolsDir), false, (_, filename) => {\n if (\n (!filename || filename.toString() === path.basename(current.toolsDir)) &&\n statSync(current.toolsDir, { throwIfNoEntry: false })?.ino !== directoryId\n )\n schedule()\n })\n }\n bind()\n return {\n retry: schedule,\n close() {\n closed = true\n clearTimeout(timer)\n for (const watcher of watchers) watcher.close()\n },\n }\n}\n"],"mappings":"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","names":["createRequire","path","parseArgs","tool","path","path","tool","path","fail","tool","path","revision","tool","revision","handle","existsSync","mkdir","readFile","path","path","path","inside","existsSync","error","readFile","tool","exists","mkdir","tool","existsSync","readFileSync","readdirSync","path","existsSync","readFileSync","path","ts","file","path","readFileSync","existsSync","tool","readdirSync","require","error","existsSync","watch","path","path","existsSync","watch","require","createRequire","path","child","parseArgs"]}