@donut-games/cli 0.1.0
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/donut-mcp.js +2654 -0
- package/dist/donut-mcp.js.map +1 -0
- package/dist/donut.js +1724 -0
- package/dist/donut.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1722 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../mcp/src/index.ts","../../mcp/src/tools/component-system/components.ts","../../mcp/src/tools/component-system/naming.ts","../../mcp/src/tools/component-system/path-guard.ts","../../mcp/src/tools/component-system/systems.ts","../../mcp/src/tools/component-system/index.ts","../../mcp/src/tools/entity-scene/assets.ts","../../mcp/src/tools/entity-scene/entities.ts","../../mcp/src/tools/entity-scene/scene-file.ts","../../mcp/src/tools/entity-scene/project.ts","../../mcp/src/tools/entity-scene/scenes.ts","../../mcp/src/tools/entity-scene/index.ts","../../mcp/src/tools/quality/type-check.ts","../../mcp/src/tools/quality/lint.ts","../../mcp/src/tools/quality/imports-world.ts","../../cli/src/commands/validate.ts","../../mcp/src/tools/quality/index.ts","../../mcp/src/tools/runtime/tools.ts","../../mcp/src/tools/runtime/runtime-session.ts","../../mcp/src/tools/runtime/index.ts","../src/donut-mcp.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from 'node:path';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport type { ToolContext, ToolDefinition } from './tool-context.js';\nimport { registerComponentSystemTools } from './tools/component-system/index.js';\nimport { registerEntitySceneTools } from './tools/entity-scene/index.js';\nimport { registerQualityTools } from './tools/quality/index.js';\nimport { registerRuntimeTools } from './tools/runtime/index.js';\n\n/**\n * Entry point for the `donut-mcp` executable. Boots an MCP stdio server that\n * exposes Donut-engine authoring tools (component/system/entity/scene CRUD,\n * quality checks, and runtime control) to AI clients.\n *\n * Project root is controlled by the `DONUT_PROJECT_DIRECTORY` environment\n * variable and defaults to the process's current working directory.\n */\nexport async function startMcpServer(): Promise<void> {\n const projectDirectory = path.resolve(\n process.env['DONUT_PROJECT_DIRECTORY'] ?? process.cwd(),\n );\n\n const registeredTools: ToolDefinition[] = [];\n\n const toolContext: ToolContext = {\n projectDirectory,\n registerTool(definition: ToolDefinition): void {\n const alreadyRegistered = registeredTools.some(\n (existing) => existing.name === definition.name,\n );\n if (alreadyRegistered) {\n throw new Error(`Duplicate MCP tool registration: ${definition.name}`);\n }\n registeredTools.push(definition);\n },\n };\n\n const server = new Server(\n { name: 'donut-mcp', version: '0.0.1' },\n { capabilities: { tools: {} } },\n );\n\n registerComponentSystemTools(server, toolContext);\n registerEntitySceneTools(server, toolContext);\n registerQualityTools(server, toolContext);\n registerRuntimeTools(server, toolContext);\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: registeredTools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n })),\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const toolName = request.params.name;\n const tool = registeredTools.find((candidate) => candidate.name === toolName);\n if (tool === undefined) {\n throw new Error(`Unknown tool: ${toolName}`);\n }\n return tool.handler(request.params.arguments ?? {});\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nconst isRunningAsMain =\n import.meta.url === `file://${process.argv[1]}` ||\n process.argv[1]?.endsWith('/donut-mcp') === true ||\n process.argv[1]?.endsWith('\\\\donut-mcp') === true ||\n process.argv[1]?.endsWith('mcp/src/index.ts') === true ||\n process.argv[1]?.endsWith('mcp/dist/index.js') === true;\n\nif (isRunningAsMain) {\n startMcpServer().catch((error) => {\n console.error(error);\n process.exit(1);\n });\n}\n","import path from 'node:path';\nimport fileSystemExtra from 'fs-extra';\nimport typescript from 'typescript';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport { stripSuffix, toKebabCase, toPascalCase } from './naming.js';\nimport { resolveWithinProject } from './path-guard.js';\n\n/**\n * Supported state-field primitive types for scaffolded components.\n * Keep this list aligned with the `@donut/math` re-exports used in templates.\n */\nconst stateFieldTypeSchema = z.enum(['number', 'string', 'boolean', 'Vector2', 'Vector3']);\n\nconst stateFieldSchema = z.object({\n name: z.string().min(1),\n type: stateFieldTypeSchema,\n defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional(),\n});\n\nconst lifecycleHookSchema = z.enum(['onAdd', 'onRemove']);\n\nconst createComponentInputSchema = z.object({\n name: z.string().min(1),\n stateFields: z.array(stateFieldSchema).default([]),\n lifecycleHooks: z.array(lifecycleHookSchema).optional(),\n});\n\nconst readComponentInputSchema = z.object({ name: z.string().min(1) });\n\nconst updateComponentInputSchema = z.object({\n name: z.string().min(1),\n changes: z\n .object({\n addFields: z.array(stateFieldSchema).optional(),\n removeFields: z.array(z.string()).optional(),\n renameFields: z\n .array(z.object({ from: z.string(), to: z.string() }))\n .optional(),\n addHook: lifecycleHookSchema.optional(),\n removeHook: lifecycleHookSchema.optional(),\n })\n .default({}),\n});\n\nconst deleteComponentInputSchema = z.object({ name: z.string().min(1) });\n\nconst listComponentsInputSchema = z.object({}).default({});\n\n/** State field on a parsed component class. */\ninterface ParsedStateField {\n name: string;\n type: string;\n defaultText?: string;\n}\n\n/** Result returned by {@link parseComponentSource}. */\ninterface ParsedComponent {\n className: string;\n stateFields: ParsedStateField[];\n dependencies: string[];\n}\n\n/**\n * Convert a state-field default value to its TypeScript literal representation.\n */\nfunction renderDefaultLiteral(field: z.infer<typeof stateFieldSchema>): string {\n if (field.defaultValue !== undefined) {\n if (field.type === 'string') {\n return JSON.stringify(String(field.defaultValue));\n }\n return String(field.defaultValue);\n }\n switch (field.type) {\n case 'number':\n return '0';\n case 'string':\n return \"''\";\n case 'boolean':\n return 'false';\n case 'Vector2':\n return 'new Vector2(0, 0)';\n case 'Vector3':\n return 'new Vector3(0, 0, 0)';\n }\n}\n\n/**\n * Render the source text for a scaffolded component file.\n */\nfunction renderComponentSource(\n className: string,\n stateFields: Array<z.infer<typeof stateFieldSchema>>,\n lifecycleHooks: ReadonlyArray<'onAdd' | 'onRemove'>,\n): string {\n const needsVector2 = stateFields.some((field) => field.type === 'Vector2');\n const needsVector3 = stateFields.some((field) => field.type === 'Vector3');\n const mathImports: string[] = [];\n if (needsVector2) {\n mathImports.push('Vector2');\n }\n if (needsVector3) {\n mathImports.push('Vector3');\n }\n\n const lines: string[] = [];\n lines.push(`import { Component, type Entity } from '@donut/core';`);\n if (mathImports.length > 0) {\n lines.push(`import { ${mathImports.join(', ')} } from '@donut/math';`);\n }\n lines.push('');\n lines.push('/**');\n lines.push(` * ${className} — generated by the Donut MCP \\`create_component\\` tool.`);\n lines.push(' *');\n lines.push(' * Holds authored state for entities that participate in the related system.');\n lines.push(' */');\n lines.push(`export class ${className} extends Component {`);\n\n for (const field of stateFields) {\n lines.push(` /** Authored state field. */`);\n lines.push(\n ` ${field.name}: ${field.type} = ${renderDefaultLiteral(field)};`,\n );\n }\n\n if (lifecycleHooks.includes('onAdd')) {\n lines.push('');\n lines.push(' /** Lifecycle hook fired when this component is attached to an entity. */');\n lines.push(' onAdd(owner: Entity): void {');\n lines.push(' void owner;');\n lines.push(' }');\n }\n if (lifecycleHooks.includes('onRemove')) {\n lines.push('');\n lines.push(' /** Lifecycle hook fired when this component is detached from an entity. */');\n lines.push(' onRemove(previousOwner: Entity): void {');\n lines.push(' void previousOwner;');\n lines.push(' }');\n }\n\n // clone\n lines.push('');\n lines.push(' /** Deep-copy this component for entity duplication. */');\n lines.push(` clone(): ${className} {`);\n lines.push(` const copy = new ${className}();`);\n for (const field of stateFields) {\n if (field.type === 'Vector2' || field.type === 'Vector3') {\n lines.push(` copy.${field.name} = this.${field.name}.clone();`);\n } else {\n lines.push(` copy.${field.name} = this.${field.name};`);\n }\n }\n lines.push(' return copy;');\n lines.push(' }');\n\n // serialize\n lines.push('');\n lines.push(' /** Convert this component to a plain-object snapshot. */');\n lines.push(' serialize(): Record<string, unknown> {');\n lines.push(' return {');\n for (const field of stateFields) {\n if (field.type === 'Vector2' || field.type === 'Vector3') {\n lines.push(` ${field.name}: this.${field.name}.serialize(),`);\n } else {\n lines.push(` ${field.name}: this.${field.name},`);\n }\n }\n lines.push(' };');\n lines.push(' }');\n\n // deserialize\n lines.push('');\n lines.push(' /** Restore this component\\'s state from a plain-object snapshot. */');\n lines.push(' deserialize(data: Record<string, unknown>): void {');\n for (const field of stateFields) {\n lines.push(` if (data['${field.name}'] !== undefined) {`);\n if (field.type === 'Vector2') {\n lines.push(\n ` this.${field.name} = Vector2.deserialize(data['${field.name}'] as Record<string, unknown>);`,\n );\n } else if (field.type === 'Vector3') {\n lines.push(\n ` this.${field.name} = Vector3.deserialize(data['${field.name}'] as Record<string, unknown>);`,\n );\n } else {\n lines.push(` this.${field.name} = data['${field.name}'] as ${field.type};`);\n }\n lines.push(' }');\n }\n lines.push(' }');\n\n lines.push('}');\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Parse a component source file and extract the class name, declared state\n * fields, and any component constructors in the `dependencies` property.\n */\nfunction parseComponentSource(sourceText: string, filePath: string): ParsedComponent {\n const sourceFile = typescript.createSourceFile(\n filePath,\n sourceText,\n typescript.ScriptTarget.ES2022,\n true,\n );\n\n let className: string | undefined;\n const stateFields: ParsedStateField[] = [];\n const dependencies: string[] = [];\n\n typescript.forEachChild(sourceFile, (node) => {\n if (!typescript.isClassDeclaration(node) || node.name === undefined) {\n return;\n }\n className = node.name.text;\n for (const member of node.members) {\n if (\n typescript.isPropertyDeclaration(member) &&\n typescript.isIdentifier(member.name)\n ) {\n const propertyName = member.name.text;\n if (propertyName === 'dependencies' && member.initializer !== undefined) {\n if (typescript.isArrayLiteralExpression(member.initializer)) {\n for (const element of member.initializer.elements) {\n if (typescript.isIdentifier(element)) {\n dependencies.push(element.text);\n }\n }\n }\n continue;\n }\n if (propertyName === 'owner') {\n continue;\n }\n const typeText = member.type !== undefined ? member.type.getText(sourceFile) : 'unknown';\n const defaultText =\n member.initializer !== undefined ? member.initializer.getText(sourceFile) : undefined;\n stateFields.push({\n name: propertyName,\n type: typeText,\n ...(defaultText !== undefined ? { defaultText } : {}),\n });\n }\n }\n });\n\n if (className === undefined) {\n throw new Error(`No class declaration found in ${filePath}`);\n }\n return { className, stateFields, dependencies };\n}\n\n/**\n * Compute `{ absoluteFilePath, className, kebabName }` for a given component name.\n */\nfunction resolveComponentPaths(\n projectDirectory: string,\n rawName: string,\n): { absoluteFilePath: string; className: string; kebabName: string } {\n const pascal = toPascalCase(rawName);\n const baseName = stripSuffix(pascal, 'Component');\n const className = `${baseName}Component`;\n const kebabName = toKebabCase(baseName);\n const relativePath = path.posix.join('src', 'components', `${kebabName}-component.ts`);\n const absoluteFilePath = resolveWithinProject(projectDirectory, relativePath);\n return { absoluteFilePath, className, kebabName };\n}\n\n/**\n * Format a successful tool handler response.\n */\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Recursively collect `.ts` files under a directory, skipping test files.\n * Returns an empty array if the directory does not exist.\n */\nasync function collectTypeScriptFiles(directory: string): Promise<string[]> {\n if (!(await fileSystemExtra.pathExists(directory))) {\n return [];\n }\n const collected: string[] = [];\n const walk = async (current: string): Promise<void> => {\n const entries = await fileSystemExtra.readdir(current, { withFileTypes: true });\n for (const entry of entries) {\n const entryAbsolute = path.join(current, entry.name);\n if (entry.isDirectory()) {\n await walk(entryAbsolute);\n continue;\n }\n if (\n entry.isFile() &&\n entry.name.endsWith('.ts') &&\n !entry.name.endsWith('.test.ts')\n ) {\n collected.push(entryAbsolute);\n }\n }\n };\n await walk(directory);\n return collected;\n}\n\n/**\n * Register all component CRUD tools on the given context.\n */\nexport function registerComponentTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const createComponentTool: ToolDefinition = {\n name: 'create_component',\n description:\n 'Scaffold a new Donut component file under src/components/. State fields ' +\n 'generate typed properties with sane defaults plus clone/serialize/deserialize. ' +\n 'Fails if the file already exists.',\n inputSchema: zodToJsonSchema(createComponentInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = createComponentInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveComponentPaths(\n projectDirectory,\n parsed.name,\n );\n if (await fileSystemExtra.pathExists(absoluteFilePath)) {\n throw new Error(`Component file already exists: ${absoluteFilePath}`);\n }\n const lifecycleHooks = parsed.lifecycleHooks ?? [];\n const source = renderComponentSource(className, parsed.stateFields, lifecycleHooks);\n await fileSystemExtra.ensureDir(path.dirname(absoluteFilePath));\n await fileSystemExtra.writeFile(absoluteFilePath, source, 'utf8');\n return formatToolResult({ className, filePath: absoluteFilePath });\n },\n };\n\n const readComponentTool: ToolDefinition = {\n name: 'read_component',\n description: 'Return the source text of an existing component file.',\n inputSchema: zodToJsonSchema(readComponentInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = readComponentInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveComponentPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`Component file not found: ${absoluteFilePath}`);\n }\n const source = await fileSystemExtra.readFile(absoluteFilePath, 'utf8');\n return formatToolResult({ className, filePath: absoluteFilePath, source });\n },\n };\n\n const updateComponentTool: ToolDefinition = {\n name: 'update_component',\n description:\n 'Apply structural changes to an existing component: add/remove/rename state ' +\n 'fields and add/remove onAdd/onRemove lifecycle hooks. File is re-rendered ' +\n 'from the merged field list to keep clone/serialize/deserialize in sync.',\n inputSchema: zodToJsonSchema(updateComponentInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = updateComponentInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveComponentPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`Component file not found: ${absoluteFilePath}`);\n }\n const existingSource = await fileSystemExtra.readFile(absoluteFilePath, 'utf8');\n const existing = parseComponentSource(existingSource, absoluteFilePath);\n\n /**\n * Merge parsed fields + requested changes into a normalized field list\n * suitable for re-rendering. Unknown-type existing fields are preserved\n * if they map to supported primitive/vector types.\n */\n const supportedTypes = ['number', 'string', 'boolean', 'Vector2', 'Vector3'] as const;\n type SupportedType = (typeof supportedTypes)[number];\n const isSupportedType = (value: string): value is SupportedType =>\n (supportedTypes as readonly string[]).includes(value);\n\n const currentFields: Array<z.infer<typeof stateFieldSchema>> = existing.stateFields\n .filter((field) => isSupportedType(field.type))\n .map((field) => ({\n name: field.name,\n type: field.type as SupportedType,\n }));\n\n const changes = parsed.changes;\n const removeFields = new Set(changes.removeFields ?? []);\n const renameMap = new Map((changes.renameFields ?? []).map((rename) => [rename.from, rename.to]));\n\n const rebuiltFields: Array<z.infer<typeof stateFieldSchema>> = [];\n for (const field of currentFields) {\n if (removeFields.has(field.name)) {\n continue;\n }\n const renamedTo = renameMap.get(field.name);\n rebuiltFields.push({\n name: renamedTo ?? field.name,\n type: field.type,\n });\n }\n for (const added of changes.addFields ?? []) {\n rebuiltFields.push(added);\n }\n\n // Detect existing lifecycle hooks from source text (simple regex is sufficient\n // because the template renders them in a consistent shape).\n const hadOnAdd = /\\bonAdd\\s*\\(/.test(existingSource);\n const hadOnRemove = /\\bonRemove\\s*\\(/.test(existingSource);\n const lifecycleHooksSet = new Set<'onAdd' | 'onRemove'>();\n if (hadOnAdd) {\n lifecycleHooksSet.add('onAdd');\n }\n if (hadOnRemove) {\n lifecycleHooksSet.add('onRemove');\n }\n if (changes.addHook !== undefined) {\n lifecycleHooksSet.add(changes.addHook);\n }\n if (changes.removeHook !== undefined) {\n lifecycleHooksSet.delete(changes.removeHook);\n }\n\n const nextSource = renderComponentSource(\n className,\n rebuiltFields,\n Array.from(lifecycleHooksSet),\n );\n await fileSystemExtra.writeFile(absoluteFilePath, nextSource, 'utf8');\n return formatToolResult({\n className,\n filePath: absoluteFilePath,\n stateFields: rebuiltFields,\n lifecycleHooks: Array.from(lifecycleHooksSet),\n });\n },\n };\n\n const deleteComponentTool: ToolDefinition = {\n name: 'delete_component',\n description:\n 'Delete a component file and report warnings for any references to the ' +\n 'class name found under src/systems/ or src/scenes/.',\n inputSchema: zodToJsonSchema(deleteComponentInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = deleteComponentInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveComponentPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`Component file not found: ${absoluteFilePath}`);\n }\n\n const warnings: Array<{ filePath: string; line: number; text: string }> = [];\n const scanRoots = [\n resolveWithinProject(projectDirectory, 'src/systems'),\n resolveWithinProject(projectDirectory, 'src/scenes'),\n ];\n for (const root of scanRoots) {\n const files = await collectTypeScriptFiles(root);\n for (const filePath of files) {\n const content = await fileSystemExtra.readFile(filePath, 'utf8');\n const lines = content.split('\\n');\n lines.forEach((lineText, lineIndex) => {\n const pattern = new RegExp(`\\\\b${className}\\\\b`);\n if (pattern.test(lineText)) {\n warnings.push({\n filePath,\n line: lineIndex + 1,\n text: lineText.trim(),\n });\n }\n });\n }\n }\n\n await fileSystemExtra.remove(absoluteFilePath);\n return formatToolResult({ deleted: absoluteFilePath, className, warnings });\n },\n };\n\n const listComponentsTool: ToolDefinition = {\n name: 'list_components',\n description:\n 'List all component files under src/components/ with their class names, ' +\n 'state fields, and declared dependencies.',\n inputSchema: zodToJsonSchema(listComponentsInputSchema) as object,\n handler: async (input: unknown) => {\n listComponentsInputSchema.parse(input ?? {});\n const componentsDirectory = resolveWithinProject(\n projectDirectory,\n 'src/components',\n );\n const files = await collectTypeScriptFiles(componentsDirectory);\n const components: Array<{\n name: string;\n filePath: string;\n stateFields: Array<{ name: string; type: string }>;\n dependencies: string[];\n }> = [];\n for (const filePath of files) {\n const content = await fileSystemExtra.readFile(filePath, 'utf8');\n try {\n const parsedFile = parseComponentSource(content, filePath);\n components.push({\n name: parsedFile.className,\n filePath,\n stateFields: parsedFile.stateFields.map((field) => ({\n name: field.name,\n type: field.type,\n })),\n dependencies: parsedFile.dependencies,\n });\n } catch {\n // Skip files that do not contain a parseable class declaration.\n }\n }\n return formatToolResult({ components });\n },\n };\n\n context.registerTool(createComponentTool);\n context.registerTool(readComponentTool);\n context.registerTool(updateComponentTool);\n context.registerTool(deleteComponentTool);\n context.registerTool(listComponentsTool);\n}\n","/**\n * Naming helpers shared by component and system tool implementations.\n * Enforces the donut-engine convention: PascalCase class names, kebab-case file\n * names, and full-descriptive identifiers (no abbreviations).\n */\n\n/**\n * Convert an input identifier (PascalCase, camelCase, kebab-case, or snake_case)\n * to PascalCase. Throws if the input is empty.\n */\nexport function toPascalCase(rawName: string): string {\n const trimmed = rawName.trim();\n if (trimmed.length === 0) {\n throw new Error('Name must not be empty');\n }\n const parts = trimmed\n .replace(/[_\\-\\s]+/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(' ')\n .filter((part) => part.length > 0);\n return parts\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\n/**\n * Convert an input identifier to kebab-case for use in file names.\n */\nexport function toKebabCase(rawName: string): string {\n const pascal = toPascalCase(rawName);\n return pascal\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase();\n}\n\n/**\n * Strip a trailing \"Component\" or \"System\" suffix from a PascalCase name,\n * so callers can pass either `\"Health\"` or `\"HealthComponent\"`.\n */\nexport function stripSuffix(pascalName: string, suffix: string): string {\n return pascalName.endsWith(suffix)\n ? pascalName.slice(0, pascalName.length - suffix.length)\n : pascalName;\n}\n","import path from 'node:path';\n\n/**\n * Resolve `relativePath` under `projectDirectory` and assert the result does\n * not escape the project root (defence against `..` traversal in tool input).\n */\nexport function resolveWithinProject(\n projectDirectory: string,\n relativePath: string,\n): string {\n const absoluteProjectDirectory = path.resolve(projectDirectory);\n const absoluteResolved = path.resolve(absoluteProjectDirectory, relativePath);\n const projectDirectoryWithSeparator = absoluteProjectDirectory.endsWith(path.sep)\n ? absoluteProjectDirectory\n : absoluteProjectDirectory + path.sep;\n if (\n absoluteResolved !== absoluteProjectDirectory &&\n !absoluteResolved.startsWith(projectDirectoryWithSeparator)\n ) {\n throw new Error(\n `Path \"${relativePath}\" escapes project directory \"${absoluteProjectDirectory}\"`,\n );\n }\n return absoluteResolved;\n}\n","import path from 'node:path';\nimport fileSystemExtra from 'fs-extra';\nimport typescript from 'typescript';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport { stripSuffix, toKebabCase, toPascalCase } from './naming.js';\nimport { resolveWithinProject } from './path-guard.js';\n\nconst priorityEnum = z.enum(['Highest', 'Higher', 'Average', 'Lower', 'Lowest']);\nconst systemTypeEnum = z.enum(['Update', 'Draw']);\n\nconst createSystemInputSchema = z.object({\n name: z.string().min(1),\n queryComponents: z.array(z.string().min(1)).default([]),\n priority: priorityEnum.optional(),\n systemType: systemTypeEnum.optional(),\n});\n\nconst readSystemInputSchema = z.object({ name: z.string().min(1) });\n\nconst updateSystemInputSchema = z.object({\n name: z.string().min(1),\n changes: z\n .object({\n setQueryComponents: z.array(z.string().min(1)).optional(),\n setPriority: priorityEnum.optional(),\n setSystemType: systemTypeEnum.optional(),\n })\n .default({}),\n});\n\nconst deleteSystemInputSchema = z.object({ name: z.string().min(1) });\nconst listSystemsInputSchema = z.object({}).default({});\n\n/**\n * Render the source text for a scaffolded system file.\n */\nfunction renderSystemSource(\n className: string,\n queryComponents: readonly string[],\n priority: z.infer<typeof priorityEnum>,\n systemType: z.infer<typeof systemTypeEnum>,\n): string {\n const queryComponentList = queryComponents.join(', ');\n const coreImports = [\n 'System',\n 'SystemPriority',\n 'SystemType',\n 'Query',\n 'type World',\n ];\n for (const componentName of queryComponents) {\n if (!coreImports.includes(componentName)) {\n coreImports.push(componentName);\n }\n }\n\n const lines: string[] = [];\n lines.push(`import {`);\n for (const importName of coreImports) {\n lines.push(` ${importName},`);\n }\n lines.push(`} from '@donut/core';`);\n lines.push('');\n lines.push('/**');\n lines.push(` * ${className} — generated by the Donut MCP \\`create_system\\` tool.`);\n lines.push(' *');\n lines.push(' * Processes entities matching its declared component query each frame.');\n lines.push(' */');\n lines.push(`export class ${className} extends System {`);\n lines.push(` /** Indicates whether this system runs in the update or draw phase. */`);\n lines.push(` readonly systemType = SystemType.${systemType};`);\n lines.push('');\n lines.push(` /** Execution priority relative to sibling systems. */`);\n lines.push(` static priority = SystemPriority.${priority};`);\n lines.push('');\n lines.push(` /** Reactive query matching entities this system operates on. */`);\n lines.push(\n ` private readonly entityQuery: Query<${queryComponents.length > 0 ? `typeof ${queryComponents.join(', typeof ')}` : 'never'}>;`,\n );\n lines.push('');\n lines.push(' /** Build the query once the world is available. */');\n lines.push(' constructor(world: World) {');\n lines.push(' super();');\n lines.push(\n ` this.entityQuery = world.query([${queryComponentList}]) as Query<${queryComponents.length > 0 ? `typeof ${queryComponents.join(', typeof ')}` : 'never'}>;`,\n );\n lines.push(' }');\n lines.push('');\n lines.push(' /**');\n lines.push(' * Frame update. Iterates matching entities and applies system logic.');\n lines.push(' * @param elapsedMilliseconds time since previous frame, in milliseconds');\n lines.push(' */');\n lines.push(' update(elapsedMilliseconds: number): void {');\n lines.push(' void elapsedMilliseconds;');\n lines.push(' for (const entity of this.entityQuery.entities) {');\n lines.push(' void entity;');\n lines.push(' }');\n lines.push(' }');\n lines.push('}');\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Parse a system source file and extract class name, query component names,\n * declared priority, and system-type.\n */\nfunction parseSystemSource(\n sourceText: string,\n filePath: string,\n): {\n className: string;\n queryComponents: string[];\n priority: string;\n systemType: string;\n} {\n const sourceFile = typescript.createSourceFile(\n filePath,\n sourceText,\n typescript.ScriptTarget.ES2022,\n true,\n );\n\n let className: string | undefined;\n let priority = 'Average';\n let systemType = 'Update';\n const queryComponents: string[] = [];\n\n typescript.forEachChild(sourceFile, (node) => {\n if (!typescript.isClassDeclaration(node) || node.name === undefined) {\n return;\n }\n className = node.name.text;\n for (const member of node.members) {\n if (\n typescript.isPropertyDeclaration(member) &&\n typescript.isIdentifier(member.name)\n ) {\n const propertyName = member.name.text;\n if (propertyName === 'systemType' && member.initializer !== undefined) {\n const text = member.initializer.getText(sourceFile);\n const match = /SystemType\\.(\\w+)/.exec(text);\n if (match) {\n systemType = match[1] as string;\n }\n }\n if (propertyName === 'priority' && member.initializer !== undefined) {\n const text = member.initializer.getText(sourceFile);\n const match = /SystemPriority\\.(\\w+)/.exec(text);\n if (match) {\n priority = match[1] as string;\n }\n }\n }\n if (typescript.isConstructorDeclaration(member) && member.body !== undefined) {\n const bodyText = member.body.getText(sourceFile);\n const queryMatch = /world\\.query\\(\\s*\\[([^\\]]*)\\]/m.exec(bodyText);\n if (queryMatch) {\n const inside = (queryMatch[1] as string).trim();\n if (inside.length > 0) {\n for (const part of inside.split(',')) {\n const trimmed = part.trim();\n if (trimmed.length > 0) {\n queryComponents.push(trimmed);\n }\n }\n }\n }\n }\n }\n });\n\n if (className === undefined) {\n throw new Error(`No class declaration found in ${filePath}`);\n }\n return { className, queryComponents, priority, systemType };\n}\n\nfunction resolveSystemPaths(\n projectDirectory: string,\n rawName: string,\n): { absoluteFilePath: string; className: string; kebabName: string } {\n const pascal = toPascalCase(rawName);\n const baseName = stripSuffix(pascal, 'System');\n const className = `${baseName}System`;\n const kebabName = toKebabCase(baseName);\n const relativePath = path.posix.join('src', 'systems', `${kebabName}-system.ts`);\n const absoluteFilePath = resolveWithinProject(projectDirectory, relativePath);\n return { absoluteFilePath, className, kebabName };\n}\n\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\nasync function collectTypeScriptFiles(directory: string): Promise<string[]> {\n if (!(await fileSystemExtra.pathExists(directory))) {\n return [];\n }\n const collected: string[] = [];\n const walk = async (current: string): Promise<void> => {\n const entries = await fileSystemExtra.readdir(current, { withFileTypes: true });\n for (const entry of entries) {\n const entryAbsolute = path.join(current, entry.name);\n if (entry.isDirectory()) {\n await walk(entryAbsolute);\n continue;\n }\n if (\n entry.isFile() &&\n entry.name.endsWith('.ts') &&\n !entry.name.endsWith('.test.ts')\n ) {\n collected.push(entryAbsolute);\n }\n }\n };\n await walk(directory);\n return collected;\n}\n\n/**\n * Register all system CRUD tools on the given context.\n */\nexport function registerSystemTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const createSystemTool: ToolDefinition = {\n name: 'create_system',\n description:\n 'Scaffold a new Donut system file under src/systems/. Declares a reactive ' +\n 'query over the named components and an empty update loop. Imports only ' +\n 'from @donut/core to preserve the portability guarantee for game logic.',\n inputSchema: zodToJsonSchema(createSystemInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = createSystemInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveSystemPaths(\n projectDirectory,\n parsed.name,\n );\n if (await fileSystemExtra.pathExists(absoluteFilePath)) {\n throw new Error(`System file already exists: ${absoluteFilePath}`);\n }\n const priority = parsed.priority ?? 'Average';\n const systemType = parsed.systemType ?? 'Update';\n const source = renderSystemSource(\n className,\n parsed.queryComponents,\n priority,\n systemType,\n );\n await fileSystemExtra.ensureDir(path.dirname(absoluteFilePath));\n await fileSystemExtra.writeFile(absoluteFilePath, source, 'utf8');\n return formatToolResult({ className, filePath: absoluteFilePath });\n },\n };\n\n const readSystemTool: ToolDefinition = {\n name: 'read_system',\n description: 'Return the source text of an existing system file.',\n inputSchema: zodToJsonSchema(readSystemInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = readSystemInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveSystemPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`System file not found: ${absoluteFilePath}`);\n }\n const source = await fileSystemExtra.readFile(absoluteFilePath, 'utf8');\n return formatToolResult({ className, filePath: absoluteFilePath, source });\n },\n };\n\n const updateSystemTool: ToolDefinition = {\n name: 'update_system',\n description:\n 'Apply structural changes to an existing system: replace the query ' +\n 'component list, priority, or system-type. File is re-rendered from the ' +\n 'merged configuration.',\n inputSchema: zodToJsonSchema(updateSystemInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = updateSystemInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveSystemPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`System file not found: ${absoluteFilePath}`);\n }\n const existingSource = await fileSystemExtra.readFile(absoluteFilePath, 'utf8');\n const existing = parseSystemSource(existingSource, absoluteFilePath);\n\n const nextQueryComponents = parsed.changes.setQueryComponents ?? existing.queryComponents;\n const nextPriority =\n parsed.changes.setPriority ?? (existing.priority as z.infer<typeof priorityEnum>);\n const nextSystemType =\n parsed.changes.setSystemType ?? (existing.systemType as z.infer<typeof systemTypeEnum>);\n\n const nextSource = renderSystemSource(\n className,\n nextQueryComponents,\n nextPriority,\n nextSystemType,\n );\n await fileSystemExtra.writeFile(absoluteFilePath, nextSource, 'utf8');\n return formatToolResult({\n className,\n filePath: absoluteFilePath,\n queryComponents: nextQueryComponents,\n priority: nextPriority,\n systemType: nextSystemType,\n });\n },\n };\n\n const deleteSystemTool: ToolDefinition = {\n name: 'delete_system',\n description:\n 'Delete a system file and report warnings for any references to the ' +\n 'class name found under src/scenes/.',\n inputSchema: zodToJsonSchema(deleteSystemInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = deleteSystemInputSchema.parse(input);\n const { absoluteFilePath, className } = resolveSystemPaths(\n projectDirectory,\n parsed.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`System file not found: ${absoluteFilePath}`);\n }\n\n const warnings: Array<{ filePath: string; line: number; text: string }> = [];\n const scenesDirectory = resolveWithinProject(projectDirectory, 'src/scenes');\n const files = await collectTypeScriptFiles(scenesDirectory);\n for (const filePath of files) {\n const content = await fileSystemExtra.readFile(filePath, 'utf8');\n const lines = content.split('\\n');\n lines.forEach((lineText, lineIndex) => {\n const pattern = new RegExp(`\\\\b${className}\\\\b`);\n if (pattern.test(lineText)) {\n warnings.push({ filePath, line: lineIndex + 1, text: lineText.trim() });\n }\n });\n }\n\n await fileSystemExtra.remove(absoluteFilePath);\n return formatToolResult({ deleted: absoluteFilePath, className, warnings });\n },\n };\n\n const listSystemsTool: ToolDefinition = {\n name: 'list_systems',\n description:\n 'List all system files under src/systems/ with their class names, query ' +\n 'components, priority, and system-type.',\n inputSchema: zodToJsonSchema(listSystemsInputSchema) as object,\n handler: async (input: unknown) => {\n listSystemsInputSchema.parse(input ?? {});\n const systemsDirectory = resolveWithinProject(projectDirectory, 'src/systems');\n const files = await collectTypeScriptFiles(systemsDirectory);\n const systems: Array<{\n name: string;\n filePath: string;\n queryComponents: string[];\n priority: string;\n systemType: string;\n }> = [];\n for (const filePath of files) {\n const content = await fileSystemExtra.readFile(filePath, 'utf8');\n try {\n const parsedFile = parseSystemSource(content, filePath);\n systems.push({\n name: parsedFile.className,\n filePath,\n queryComponents: parsedFile.queryComponents,\n priority: parsedFile.priority,\n systemType: parsedFile.systemType,\n });\n } catch {\n // Skip unparseable files.\n }\n }\n return formatToolResult({ systems });\n },\n };\n\n context.registerTool(createSystemTool);\n context.registerTool(readSystemTool);\n context.registerTool(updateSystemTool);\n context.registerTool(deleteSystemTool);\n context.registerTool(listSystemsTool);\n}\n","import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { ToolContext } from '../../tool-context.js';\nimport { registerComponentTools } from './components.js';\nimport { registerSystemTools } from './systems.js';\n\n/**\n * Register component and system CRUD tools (teammate 1 deliverable).\n * Exposes: create_component, read_component, update_component, delete_component,\n * list_components, and the matching _system tools.\n */\nexport function registerComponentSystemTools(\n _server: Server,\n context: ToolContext,\n): void {\n registerComponentTools(context);\n registerSystemTools(context);\n}\n","import path from 'node:path';\nimport fileSystemExtra from 'fs-extra';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport { resolveWithinProject } from '../component-system/path-guard.js';\n\nconst assetTypeSchema = z.enum(['texture', 'audio', 'font', 'other']);\n\nconst addAssetInputSchema = z.object({\n type: assetTypeSchema,\n sourcePath: z.string().min(1),\n name: z.string().min(1).optional(),\n});\n\nconst getAssetInputSchema = z.object({ name: z.string().min(1) });\n\nconst replaceAssetInputSchema = z.object({\n name: z.string().min(1),\n newSourcePath: z.string().min(1),\n});\n\nconst deleteAssetInputSchema = z.object({ name: z.string().min(1) });\n\nconst listAssetsInputSchema = z\n .object({ type: assetTypeSchema.optional() })\n .default({});\n\n/**\n * Folder name (under `assets/`) used for each asset type.\n */\nconst ASSET_TYPE_DIRECTORIES: Readonly<Record<z.infer<typeof assetTypeSchema>, string>> =\n Object.freeze({\n texture: 'textures',\n audio: 'audio',\n font: 'fonts',\n other: 'other',\n });\n\n/**\n * Wrap a JSON-serializable value as a successful MCP tool response.\n */\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Determine whether `sourcePath` looks like an http(s) URL.\n */\nfunction isHttpUrl(sourcePath: string): boolean {\n return /^https?:\\/\\//i.test(sourcePath);\n}\n\n/**\n * Copy or download `sourcePath` to `destinationAbsolute`.\n */\nasync function copyOrDownload(sourcePath: string, destinationAbsolute: string): Promise<void> {\n await fileSystemExtra.ensureDir(path.dirname(destinationAbsolute));\n if (isHttpUrl(sourcePath)) {\n const response = await fetch(sourcePath);\n if (!response.ok) {\n throw new Error(`Failed to download asset from ${sourcePath}: ${response.status}`);\n }\n const buffer = Buffer.from(await response.arrayBuffer());\n await fileSystemExtra.writeFile(destinationAbsolute, buffer);\n return;\n }\n if (!(await fileSystemExtra.pathExists(sourcePath))) {\n throw new Error(`Asset source file not found: ${sourcePath}`);\n }\n await fileSystemExtra.copy(sourcePath, destinationAbsolute, { overwrite: true });\n}\n\n/**\n * Located asset record after scanning the assets/ tree.\n */\ninterface LocatedAsset {\n readonly name: string;\n readonly type: z.infer<typeof assetTypeSchema>;\n readonly absolutePath: string;\n readonly relativePath: string;\n}\n\n/**\n * Walk the assets/ directory and return every file grouped by type.\n */\nasync function scanAssets(projectDirectory: string): Promise<LocatedAsset[]> {\n const assetsRoot = resolveWithinProject(projectDirectory, 'assets');\n if (!(await fileSystemExtra.pathExists(assetsRoot))) {\n return [];\n }\n const located: LocatedAsset[] = [];\n for (const [typeKey, typeDirectory] of Object.entries(ASSET_TYPE_DIRECTORIES) as Array<\n [z.infer<typeof assetTypeSchema>, string]\n >) {\n const absoluteTypeDirectory = path.join(assetsRoot, typeDirectory);\n if (!(await fileSystemExtra.pathExists(absoluteTypeDirectory))) {\n continue;\n }\n const entries = await fileSystemExtra.readdir(absoluteTypeDirectory);\n for (const entryName of entries) {\n const absolutePath = path.join(absoluteTypeDirectory, entryName);\n const stats = await fileSystemExtra.stat(absolutePath);\n if (!stats.isFile()) {\n continue;\n }\n located.push({\n name: entryName,\n type: typeKey,\n absolutePath,\n relativePath: path.posix.join('assets', typeDirectory, entryName),\n });\n }\n }\n return located;\n}\n\n/**\n * Locate a single asset by filename (across all type folders). Throws when\n * not found.\n */\nasync function findAssetByName(\n projectDirectory: string,\n assetName: string,\n): Promise<LocatedAsset> {\n const assets = await scanAssets(projectDirectory);\n const match = assets.find((candidate) => candidate.name === assetName);\n if (match === undefined) {\n throw new Error(`Asset not found: ${assetName}`);\n }\n return match;\n}\n\n/**\n * Recursively scan a directory for occurrences of `searchText` and return\n * reference lines. Returns an empty array when the directory does not exist.\n */\nasync function findReferencesInSource(\n projectDirectory: string,\n searchText: string,\n): Promise<Array<{ filePath: string; line: number; text: string }>> {\n const sourceRoot = resolveWithinProject(projectDirectory, 'src');\n const references: Array<{ filePath: string; line: number; text: string }> = [];\n if (!(await fileSystemExtra.pathExists(sourceRoot))) {\n return references;\n }\n const walk = async (current: string): Promise<void> => {\n const entries = await fileSystemExtra.readdir(current, { withFileTypes: true });\n for (const entry of entries) {\n const entryAbsolute = path.join(current, entry.name);\n if (entry.isDirectory()) {\n await walk(entryAbsolute);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.ts')) {\n continue;\n }\n const content = await fileSystemExtra.readFile(entryAbsolute, 'utf8');\n const lines = content.split('\\n');\n lines.forEach((lineText, lineIndex) => {\n if (lineText.includes(searchText)) {\n references.push({\n filePath: entryAbsolute,\n line: lineIndex + 1,\n text: lineText.trim(),\n });\n }\n });\n }\n };\n await walk(sourceRoot);\n return references;\n}\n\n/**\n * Register the five asset management tools.\n */\nexport function registerAssetTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const addAssetTool: ToolDefinition = {\n name: 'add_asset',\n description:\n 'Copy (or download, if sourcePath is http(s)) a file into assets/<type>/. ' +\n 'If `name` is provided it is used as the destination filename; otherwise ' +\n 'the source basename is used.',\n inputSchema: zodToJsonSchema(addAssetInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = addAssetInputSchema.parse(input);\n const destinationFilename =\n parsedInput.name ?? path.basename(parsedInput.sourcePath.split('?')[0]!);\n const relativePath = path.posix.join(\n 'assets',\n ASSET_TYPE_DIRECTORIES[parsedInput.type],\n destinationFilename,\n );\n const destinationAbsolute = resolveWithinProject(projectDirectory, relativePath);\n await copyOrDownload(parsedInput.sourcePath, destinationAbsolute);\n const stats = await fileSystemExtra.stat(destinationAbsolute);\n return formatToolResult({\n name: destinationFilename,\n type: parsedInput.type,\n path: relativePath,\n absolutePath: destinationAbsolute,\n sizeBytes: stats.size,\n });\n },\n };\n\n const getAssetTool: ToolDefinition = {\n name: 'get_asset',\n description:\n 'Return metadata (name, type, relative path, size in bytes) for an asset ' +\n 'by filename. Dimensions are omitted because they would require a native ' +\n 'image decoder.',\n inputSchema: zodToJsonSchema(getAssetInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = getAssetInputSchema.parse(input);\n const located = await findAssetByName(projectDirectory, parsedInput.name);\n const stats = await fileSystemExtra.stat(located.absolutePath);\n return formatToolResult({\n name: located.name,\n type: located.type,\n path: located.relativePath,\n absolutePath: located.absolutePath,\n sizeBytes: stats.size,\n });\n },\n };\n\n const replaceAssetTool: ToolDefinition = {\n name: 'replace_asset',\n description:\n 'Overwrite an existing asset file with a new source (local path or http(s) URL). ' +\n 'The destination filename and type folder are preserved.',\n inputSchema: zodToJsonSchema(replaceAssetInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = replaceAssetInputSchema.parse(input);\n const located = await findAssetByName(projectDirectory, parsedInput.name);\n await copyOrDownload(parsedInput.newSourcePath, located.absolutePath);\n const stats = await fileSystemExtra.stat(located.absolutePath);\n return formatToolResult({\n name: located.name,\n type: located.type,\n path: located.relativePath,\n sizeBytes: stats.size,\n });\n },\n };\n\n const deleteAssetTool: ToolDefinition = {\n name: 'delete_asset',\n description:\n 'Delete an asset file. Before deletion, scans src/ for string references ' +\n 'to the asset filename and returns them as warnings.',\n inputSchema: zodToJsonSchema(deleteAssetInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = deleteAssetInputSchema.parse(input);\n const located = await findAssetByName(projectDirectory, parsedInput.name);\n const warnings = await findReferencesInSource(projectDirectory, located.name);\n await fileSystemExtra.remove(located.absolutePath);\n return formatToolResult({\n deleted: located.absolutePath,\n name: located.name,\n warnings,\n });\n },\n };\n\n const listAssetsTool: ToolDefinition = {\n name: 'list_assets',\n description: 'List all assets, optionally filtered by type.',\n inputSchema: zodToJsonSchema(listAssetsInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = listAssetsInputSchema.parse(input ?? {});\n const assets = await scanAssets(projectDirectory);\n const filtered =\n parsedInput.type === undefined\n ? assets\n : assets.filter((asset) => asset.type === parsedInput.type);\n return formatToolResult({\n assets: filtered.map((asset) => ({\n name: asset.name,\n type: asset.type,\n path: asset.relativePath,\n })),\n });\n },\n };\n\n context.registerTool(addAssetTool);\n context.registerTool(getAssetTool);\n context.registerTool(replaceAssetTool);\n context.registerTool(deleteAssetTool);\n context.registerTool(listAssetsTool);\n}\n","import { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport {\n listSceneFiles,\n readSceneFile,\n writeSceneFile,\n type EntityComponentDescriptor,\n type EntityDescriptor,\n} from './scene-file.js';\n\nconst createEntityInputSchema = z.object({\n sceneName: z.string().min(1),\n entityName: z.string().min(1),\n components: z.array(z.string().min(1)).default([]),\n tags: z.array(z.string().min(1)).optional(),\n componentConfigs: z.record(z.record(z.unknown())).optional(),\n});\n\nconst getEntityInputSchema = z.object({\n sceneName: z.string().min(1),\n entityName: z.string().min(1),\n});\n\nconst updateEntityInputSchema = z.object({\n sceneName: z.string().min(1),\n entityName: z.string().min(1),\n addComponents: z.array(z.string().min(1)).optional(),\n removeComponents: z.array(z.string().min(1)).optional(),\n setConfig: z.record(z.record(z.unknown())).optional(),\n addTags: z.array(z.string().min(1)).optional(),\n removeTags: z.array(z.string().min(1)).optional(),\n});\n\nconst deleteEntityInputSchema = z.object({\n sceneName: z.string().min(1),\n entityName: z.string().min(1),\n});\n\nconst listEntitiesInputSchema = z\n .object({ sceneName: z.string().min(1).optional() })\n .default({});\n\nconst cloneEntityInputSchema = z.object({\n sceneName: z.string().min(1),\n sourceEntityName: z.string().min(1),\n newEntityName: z.string().min(1),\n overrides: z\n .object({\n tags: z.array(z.string().min(1)).optional(),\n componentConfigs: z.record(z.record(z.unknown())).optional(),\n })\n .optional(),\n});\n\n/**\n * Wrap a JSON-serializable value as a successful MCP tool response.\n */\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Deep-clone a JSON-compatible value. Used when cloning entity descriptors.\n */\nfunction deepCloneJson<TValue>(value: TValue): TValue {\n return JSON.parse(JSON.stringify(value)) as TValue;\n}\n\n/**\n * Register the six entity CRUD tools.\n */\nexport function registerEntityTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const createEntityTool: ToolDefinition = {\n name: 'create_entity',\n description:\n 'Append a new entity to the @donut-entities marker block of a scene file. ' +\n 'The scene body is regenerated. Fails if the entity name is already used ' +\n 'in that scene or the scene file does not exist.',\n inputSchema: zodToJsonSchema(createEntityInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = createEntityInputSchema.parse(input);\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n if (parsedScene.entities.some((entity) => entity.name === parsedInput.entityName)) {\n throw new Error(\n `Entity \"${parsedInput.entityName}\" already exists in scene \"${parsedInput.sceneName}\"`,\n );\n }\n const components: EntityComponentDescriptor[] = parsedInput.components.map(\n (componentType) => {\n const descriptor: EntityComponentDescriptor = { type: componentType };\n const config = parsedInput.componentConfigs?.[componentType];\n if (config !== undefined) {\n descriptor.config = config;\n }\n return descriptor;\n },\n );\n const newEntity: EntityDescriptor = { name: parsedInput.entityName, components };\n if (parsedInput.tags !== undefined && parsedInput.tags.length > 0) {\n newEntity.tags = parsedInput.tags;\n }\n parsedScene.entities.push(newEntity);\n const absoluteFilePath = await writeSceneFile(projectDirectory, parsedScene);\n return formatToolResult({\n sceneName: parsedScene.sceneBaseName,\n entity: newEntity,\n filePath: absoluteFilePath,\n });\n },\n };\n\n const getEntityTool: ToolDefinition = {\n name: 'get_entity',\n description: 'Return the declarative record for a single entity in a scene.',\n inputSchema: zodToJsonSchema(getEntityInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = getEntityInputSchema.parse(input);\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n const entity = parsedScene.entities.find(\n (candidate) => candidate.name === parsedInput.entityName,\n );\n if (entity === undefined) {\n throw new Error(\n `Entity \"${parsedInput.entityName}\" not found in scene \"${parsedInput.sceneName}\"`,\n );\n }\n return formatToolResult({ sceneName: parsedScene.sceneBaseName, entity });\n },\n };\n\n const updateEntityTool: ToolDefinition = {\n name: 'update_entity',\n description:\n 'Add/remove components, replace component config, and add/remove tags ' +\n 'on an existing entity. The scene body is regenerated on every call.',\n inputSchema: zodToJsonSchema(updateEntityInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = updateEntityInputSchema.parse(input);\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n const entity = parsedScene.entities.find(\n (candidate) => candidate.name === parsedInput.entityName,\n );\n if (entity === undefined) {\n throw new Error(\n `Entity \"${parsedInput.entityName}\" not found in scene \"${parsedInput.sceneName}\"`,\n );\n }\n\n if (parsedInput.removeComponents !== undefined) {\n const toRemove = new Set(parsedInput.removeComponents);\n entity.components = entity.components.filter(\n (component) => !toRemove.has(component.type),\n );\n }\n if (parsedInput.addComponents !== undefined) {\n for (const componentType of parsedInput.addComponents) {\n if (!entity.components.some((component) => component.type === componentType)) {\n entity.components.push({ type: componentType });\n }\n }\n }\n if (parsedInput.setConfig !== undefined) {\n for (const [componentType, config] of Object.entries(parsedInput.setConfig)) {\n let component = entity.components.find(\n (candidate) => candidate.type === componentType,\n );\n if (component === undefined) {\n component = { type: componentType };\n entity.components.push(component);\n }\n component.config = { ...(component.config ?? {}), ...config };\n }\n }\n if (parsedInput.addTags !== undefined) {\n const nextTags = new Set<string>(entity.tags ?? []);\n for (const tag of parsedInput.addTags) {\n nextTags.add(tag);\n }\n entity.tags = Array.from(nextTags);\n }\n if (parsedInput.removeTags !== undefined) {\n const removalSet = new Set(parsedInput.removeTags);\n entity.tags = (entity.tags ?? []).filter((tag) => !removalSet.has(tag));\n if (entity.tags.length === 0) {\n delete entity.tags;\n }\n }\n\n const absoluteFilePath = await writeSceneFile(projectDirectory, parsedScene);\n return formatToolResult({\n sceneName: parsedScene.sceneBaseName,\n entity,\n filePath: absoluteFilePath,\n });\n },\n };\n\n const deleteEntityTool: ToolDefinition = {\n name: 'delete_entity',\n description: 'Remove an entity from a scene and regenerate the scene body.',\n inputSchema: zodToJsonSchema(deleteEntityInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = deleteEntityInputSchema.parse(input);\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n const entityIndex = parsedScene.entities.findIndex(\n (candidate) => candidate.name === parsedInput.entityName,\n );\n if (entityIndex === -1) {\n throw new Error(\n `Entity \"${parsedInput.entityName}\" not found in scene \"${parsedInput.sceneName}\"`,\n );\n }\n parsedScene.entities.splice(entityIndex, 1);\n const absoluteFilePath = await writeSceneFile(projectDirectory, parsedScene);\n return formatToolResult({\n sceneName: parsedScene.sceneBaseName,\n deletedEntityName: parsedInput.entityName,\n filePath: absoluteFilePath,\n });\n },\n };\n\n const listEntitiesTool: ToolDefinition = {\n name: 'list_entities',\n description:\n 'List all entities in a single scene, or across every scene under src/scenes/ ' +\n 'when sceneName is omitted.',\n inputSchema: zodToJsonSchema(listEntitiesInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = listEntitiesInputSchema.parse(input ?? {});\n if (parsedInput.sceneName !== undefined) {\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n return formatToolResult({\n entities: parsedScene.entities.map((entity) => ({\n sceneName: parsedScene.sceneBaseName,\n ...entity,\n })),\n });\n }\n const scenes = await listSceneFiles(projectDirectory);\n const entities = scenes.flatMap((scene) =>\n scene.entities.map((entity) => ({\n sceneName: scene.sceneBaseName,\n ...entity,\n })),\n );\n return formatToolResult({ entities });\n },\n };\n\n const cloneEntityTool: ToolDefinition = {\n name: 'clone_entity',\n description:\n 'Deep-clone an entity within the same scene under a new name. Overrides ' +\n 'can replace tags and merge component configs on the clone.',\n inputSchema: zodToJsonSchema(cloneEntityInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = cloneEntityInputSchema.parse(input);\n const { parsed: parsedScene } = await readSceneFile(\n projectDirectory,\n parsedInput.sceneName,\n );\n const sourceEntity = parsedScene.entities.find(\n (candidate) => candidate.name === parsedInput.sourceEntityName,\n );\n if (sourceEntity === undefined) {\n throw new Error(\n `Source entity \"${parsedInput.sourceEntityName}\" not found in scene \"${parsedInput.sceneName}\"`,\n );\n }\n if (parsedScene.entities.some((candidate) => candidate.name === parsedInput.newEntityName)) {\n throw new Error(\n `Entity \"${parsedInput.newEntityName}\" already exists in scene \"${parsedInput.sceneName}\"`,\n );\n }\n const clone: EntityDescriptor = deepCloneJson(sourceEntity);\n clone.name = parsedInput.newEntityName;\n if (parsedInput.overrides?.tags !== undefined) {\n clone.tags = parsedInput.overrides.tags;\n }\n if (parsedInput.overrides?.componentConfigs !== undefined) {\n for (const [componentType, config] of Object.entries(\n parsedInput.overrides.componentConfigs,\n )) {\n let component = clone.components.find((candidate) => candidate.type === componentType);\n if (component === undefined) {\n component = { type: componentType };\n clone.components.push(component);\n }\n component.config = { ...(component.config ?? {}), ...config };\n }\n }\n parsedScene.entities.push(clone);\n const absoluteFilePath = await writeSceneFile(projectDirectory, parsedScene);\n return formatToolResult({\n sceneName: parsedScene.sceneBaseName,\n entity: clone,\n filePath: absoluteFilePath,\n });\n },\n };\n\n context.registerTool(createEntityTool);\n context.registerTool(getEntityTool);\n context.registerTool(updateEntityTool);\n context.registerTool(deleteEntityTool);\n context.registerTool(listEntitiesTool);\n context.registerTool(cloneEntityTool);\n}\n","import path from 'node:path';\nimport fileSystemExtra from 'fs-extra';\n\nimport { resolveWithinProject } from '../component-system/path-guard.js';\nimport { stripSuffix, toKebabCase, toPascalCase } from '../component-system/naming.js';\n\n/**\n * Declarative component entry inside a scene's `@donut-entities` marker block.\n */\nexport interface EntityComponentDescriptor {\n /** Component class name, e.g. \"TransformComponent\". */\n type: string;\n /** Optional field-name-to-value map applied after construction. */\n config?: Record<string, unknown>;\n}\n\n/**\n * Declarative entity entry inside a scene's `@donut-entities` marker block.\n */\nexport interface EntityDescriptor {\n /** Unique (within the scene) entity name. */\n name: string;\n /** Optional entity tags applied via Entity#addTag. */\n tags?: string[];\n /** Components attached to this entity, in order. */\n components: EntityComponentDescriptor[];\n}\n\n/**\n * Parsed view of a scene source file — the declarative marker blocks plus\n * the scene's PascalCase and kebab-case names.\n */\nexport interface ParsedScene {\n /** Scene base name without the \"Scene\" suffix, PascalCase. */\n sceneBaseName: string;\n /** PascalCase class name ending in \"Scene\". */\n sceneClassName: string;\n /** kebab-case file base ending in \"-scene\". */\n sceneKebabName: string;\n /** All entities declared in this scene. */\n entities: EntityDescriptor[];\n /** System class names registered on this scene (order preserved). */\n systems: string[];\n}\n\n/**\n * Known engine component → package mapping used to generate scene-file imports\n * for components that do not live under src/components/.\n */\nconst ENGINE_COMPONENT_PACKAGE: Readonly<Record<string, string>> = Object.freeze({\n TransformComponent: '@donut/core',\n SpriteComponent: '@donut/pixi',\n AnimatedSpriteComponent: '@donut/pixi',\n TilemapComponent: '@donut/pixi',\n Camera2dComponent: '@donut/pixi',\n CtrllrInputComponent: '@donut/ctrllr',\n});\n\nconst MARKER_ENTITIES_OPEN = '@donut-entities';\nconst MARKER_SYSTEMS_OPEN = '@donut-systems';\n\n/**\n * Resolve absolute filesystem path to the scene file for `sceneName`.\n */\nexport function resolveScenePaths(\n projectDirectory: string,\n rawName: string,\n): { absoluteFilePath: string; sceneBaseName: string; sceneClassName: string; sceneKebabName: string; relativePath: string } {\n const pascal = toPascalCase(rawName);\n const sceneBaseName = stripSuffix(pascal, 'Scene');\n const sceneClassName = `${sceneBaseName}Scene`;\n const sceneKebabName = `${toKebabCase(sceneBaseName)}-scene`;\n const relativePath = path.posix.join('src', 'scenes', `${sceneKebabName}.ts`);\n const absoluteFilePath = resolveWithinProject(projectDirectory, relativePath);\n return { absoluteFilePath, sceneBaseName, sceneClassName, sceneKebabName, relativePath };\n}\n\n/**\n * Extract the JSON payload nested inside a JSDoc-style marker block whose\n * opener line contains `markerTag`. Returns `undefined` if the marker is\n * absent; throws if the JSON inside is malformed.\n */\nfunction extractMarkerJson(source: string, markerTag: string): string | undefined {\n const markerIndex = source.indexOf(markerTag);\n if (markerIndex === -1) {\n return undefined;\n }\n // Walk forward to the containing block's closing `*/`.\n const closingIndex = source.indexOf('*/', markerIndex);\n if (closingIndex === -1) {\n throw new Error(`Marker ${markerTag} has no closing */`);\n }\n const rawBlock = source.slice(markerIndex + markerTag.length, closingIndex);\n // Strip leading `*` from each line, trim, then return the first `[` or `{`\n // through the matching close.\n const stripped = rawBlock\n .split('\\n')\n .map((line) => line.replace(/^\\s*\\*\\s?/, ''))\n .join('\\n')\n .trim();\n return stripped;\n}\n\n/**\n * Parse a scene source string into the declarative representation stored in\n * its marker blocks.\n */\nexport function parseSceneSource(\n source: string,\n sceneBaseName: string,\n sceneKebabName: string,\n): ParsedScene {\n const sceneClassName = `${sceneBaseName}Scene`;\n const entitiesJson = extractMarkerJson(source, MARKER_ENTITIES_OPEN);\n const systemsJson = extractMarkerJson(source, MARKER_SYSTEMS_OPEN);\n const entities: EntityDescriptor[] = entitiesJson !== undefined && entitiesJson.length > 0\n ? (JSON.parse(entitiesJson) as EntityDescriptor[])\n : [];\n const systems: string[] = systemsJson !== undefined && systemsJson.length > 0\n ? (JSON.parse(systemsJson) as string[])\n : [];\n return { sceneBaseName, sceneClassName, sceneKebabName, entities, systems };\n}\n\n/**\n * Render a TypeScript literal for a config value supported inside\n * `EntityComponentDescriptor.config`.\n */\nfunction renderConfigLiteral(value: unknown): string {\n if (Array.isArray(value) && value.every((element) => typeof element === 'number')) {\n if (value.length === 2) {\n return `new Vector2(${value[0]}, ${value[1]})`;\n }\n if (value.length === 3) {\n return `new Vector3(${value[0]}, ${value[1]}, ${value[2]})`;\n }\n if (value.length === 4) {\n return `new Quaternion(${value[0]}, ${value[1]}, ${value[2]}, ${value[3]})`;\n }\n }\n return JSON.stringify(value);\n}\n\n/**\n * Resolve the import source (module specifier) for a component class name\n * given the project directory. Returns `undefined` when no known source\n * exists — callers should then emit a TODO comment rather than a broken\n * import.\n */\nasync function resolveComponentImportSource(\n projectDirectory: string,\n componentType: string,\n): Promise<string | undefined> {\n const baseName = stripSuffix(componentType, 'Component');\n const kebabName = toKebabCase(baseName);\n const localRelative = path.posix.join('src', 'components', `${kebabName}-component.ts`);\n const localAbsolute = resolveWithinProject(projectDirectory, localRelative);\n if (await fileSystemExtra.pathExists(localAbsolute)) {\n return `../components/${kebabName}-component.js`;\n }\n const enginePackage = ENGINE_COMPONENT_PACKAGE[componentType];\n if (enginePackage !== undefined) {\n return enginePackage;\n }\n return undefined;\n}\n\n/**\n * Resolve the import source for a system class name. Only local\n * `src/systems/` files are supported; returns `undefined` otherwise.\n */\nasync function resolveSystemImportSource(\n projectDirectory: string,\n systemType: string,\n): Promise<string | undefined> {\n const baseName = stripSuffix(systemType, 'System');\n const kebabName = toKebabCase(baseName);\n const localRelative = path.posix.join('src', 'systems', `${kebabName}-system.ts`);\n const localAbsolute = resolveWithinProject(projectDirectory, localRelative);\n if (await fileSystemExtra.pathExists(localAbsolute)) {\n return `../systems/${kebabName}-system.js`;\n }\n return undefined;\n}\n\n/**\n * Serialize a `ParsedScene` back into a complete scene source file.\n * The body is fully regenerated from the declarative blocks on every write.\n */\nexport async function renderSceneSource(\n projectDirectory: string,\n parsedScene: ParsedScene,\n): Promise<string> {\n // Collect component imports.\n const componentImports = new Map<string, Set<string>>(); // module -> set of names\n componentImports.set('@donut/core', new Set<string>(['Entity', 'type World']));\n const todoComments: string[] = [];\n const usedMathTypes = new Set<string>();\n\n for (const entity of parsedScene.entities) {\n for (const componentDescriptor of entity.components) {\n const importSource = await resolveComponentImportSource(\n projectDirectory,\n componentDescriptor.type,\n );\n if (importSource === undefined) {\n todoComments.push(\n `// TODO: resolve import for unknown component \"${componentDescriptor.type}\"`,\n );\n continue;\n }\n const existing = componentImports.get(importSource) ?? new Set<string>();\n existing.add(componentDescriptor.type);\n componentImports.set(importSource, existing);\n // Detect math type usage in configs.\n if (componentDescriptor.config !== undefined) {\n for (const configValue of Object.values(componentDescriptor.config)) {\n if (Array.isArray(configValue) && configValue.every((element) => typeof element === 'number')) {\n if (configValue.length === 2) {\n usedMathTypes.add('Vector2');\n } else if (configValue.length === 3) {\n usedMathTypes.add('Vector3');\n } else if (configValue.length === 4) {\n usedMathTypes.add('Quaternion');\n }\n }\n }\n }\n }\n }\n\n const systemImports = new Map<string, Set<string>>();\n for (const systemType of parsedScene.systems) {\n const importSource = await resolveSystemImportSource(projectDirectory, systemType);\n if (importSource === undefined) {\n todoComments.push(`// TODO: resolve import for unknown system \"${systemType}\"`);\n continue;\n }\n const existing = systemImports.get(importSource) ?? new Set<string>();\n existing.add(systemType);\n systemImports.set(importSource, existing);\n }\n\n const lines: string[] = [];\n\n // External/package imports first (alphabetical), then local (relative).\n const externalModules: string[] = [];\n const relativeModules: string[] = [];\n for (const moduleSpecifier of componentImports.keys()) {\n if (moduleSpecifier.startsWith('.')) {\n relativeModules.push(moduleSpecifier);\n } else {\n externalModules.push(moduleSpecifier);\n }\n }\n for (const moduleSpecifier of systemImports.keys()) {\n if (moduleSpecifier.startsWith('.')) {\n relativeModules.push(moduleSpecifier);\n } else {\n externalModules.push(moduleSpecifier);\n }\n }\n externalModules.sort();\n relativeModules.sort();\n\n for (const moduleSpecifier of externalModules) {\n const names = new Set<string>([\n ...(componentImports.get(moduleSpecifier) ?? new Set<string>()),\n ...(systemImports.get(moduleSpecifier) ?? new Set<string>()),\n ]);\n lines.push(`import { ${Array.from(names).sort().join(', ')} } from '${moduleSpecifier}';`);\n }\n if (usedMathTypes.size > 0) {\n lines.push(`import { ${Array.from(usedMathTypes).sort().join(', ')} } from '@donut/math';`);\n }\n for (const moduleSpecifier of relativeModules) {\n const names = new Set<string>([\n ...(componentImports.get(moduleSpecifier) ?? new Set<string>()),\n ...(systemImports.get(moduleSpecifier) ?? new Set<string>()),\n ]);\n lines.push(`import { ${Array.from(names).sort().join(', ')} } from '${moduleSpecifier}';`);\n }\n lines.push('');\n\n // Marker blocks.\n const entitiesJsonPayload = JSON.stringify(parsedScene.entities, null, 2);\n const systemsJsonPayload = JSON.stringify(parsedScene.systems, null, 2);\n lines.push('/**');\n lines.push(` * ${MARKER_ENTITIES_OPEN}`);\n for (const jsonLine of entitiesJsonPayload.split('\\n')) {\n lines.push(` * ${jsonLine}`);\n }\n lines.push(' */');\n lines.push('/**');\n lines.push(` * ${MARKER_SYSTEMS_OPEN}`);\n for (const jsonLine of systemsJsonPayload.split('\\n')) {\n lines.push(` * ${jsonLine}`);\n }\n lines.push(' */');\n lines.push('');\n for (const todoComment of todoComments) {\n lines.push(todoComment);\n }\n if (todoComments.length > 0) {\n lines.push('');\n }\n\n // Scene factory function body.\n lines.push('/**');\n lines.push(` * Construct the ${parsedScene.sceneClassName} entities and register its systems on`);\n lines.push(' * the provided world. Generated by the Donut MCP scene tools — do not edit the');\n lines.push(' * body directly; edit the declarative marker blocks above instead.');\n lines.push(' */');\n lines.push(`export function create${parsedScene.sceneClassName}(world: World): Entity[] {`);\n lines.push(' const createdEntities: Entity[] = [];');\n for (let entityIndex = 0; entityIndex < parsedScene.entities.length; entityIndex += 1) {\n const entity = parsedScene.entities[entityIndex]!;\n const entityVariable = `entity${entityIndex}`;\n lines.push('');\n lines.push(` const ${entityVariable} = new Entity({ name: ${JSON.stringify(entity.name)} });`);\n for (const tagName of entity.tags ?? []) {\n lines.push(` ${entityVariable}.addTag(${JSON.stringify(tagName)});`);\n }\n for (let componentIndex = 0; componentIndex < entity.components.length; componentIndex += 1) {\n const componentDescriptor = entity.components[componentIndex]!;\n const componentVariable = `${entityVariable}Component${componentIndex}`;\n lines.push(` const ${componentVariable} = new ${componentDescriptor.type}();`);\n for (const [fieldName, fieldValue] of Object.entries(componentDescriptor.config ?? {})) {\n lines.push(` ${componentVariable}.${fieldName} = ${renderConfigLiteral(fieldValue)};`);\n }\n lines.push(` ${entityVariable}.addComponent(${componentVariable});`);\n }\n lines.push(` world.add(${entityVariable});`);\n lines.push(` createdEntities.push(${entityVariable});`);\n }\n if (parsedScene.systems.length > 0) {\n lines.push('');\n for (const systemType of parsedScene.systems) {\n lines.push(` world.addSystem(new ${systemType}(world));`);\n }\n }\n lines.push('');\n lines.push(' return createdEntities;');\n lines.push('}');\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Read (or synthesize) a scene file's parsed representation. Throws when the\n * file is missing.\n */\nexport async function readSceneFile(\n projectDirectory: string,\n rawName: string,\n): Promise<{ parsed: ParsedScene; absoluteFilePath: string; source: string }> {\n const { absoluteFilePath, sceneBaseName, sceneKebabName } = resolveScenePaths(\n projectDirectory,\n rawName,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`Scene file not found: ${absoluteFilePath}`);\n }\n const source = await fileSystemExtra.readFile(absoluteFilePath, 'utf8');\n const parsed = parseSceneSource(source, sceneBaseName, sceneKebabName);\n return { parsed, absoluteFilePath, source };\n}\n\n/**\n * Write a parsed scene to disk, regenerating the full file body from its\n * declarative marker blocks.\n */\nexport async function writeSceneFile(\n projectDirectory: string,\n parsedScene: ParsedScene,\n): Promise<string> {\n const { absoluteFilePath } = resolveScenePaths(projectDirectory, parsedScene.sceneBaseName);\n const source = await renderSceneSource(projectDirectory, parsedScene);\n await fileSystemExtra.ensureDir(path.dirname(absoluteFilePath));\n await fileSystemExtra.writeFile(absoluteFilePath, source, 'utf8');\n return absoluteFilePath;\n}\n\n/**\n * List all scene files under `src/scenes/` as `ParsedScene` records.\n */\nexport async function listSceneFiles(projectDirectory: string): Promise<ParsedScene[]> {\n const scenesDirectory = resolveWithinProject(projectDirectory, 'src/scenes');\n if (!(await fileSystemExtra.pathExists(scenesDirectory))) {\n return [];\n }\n const entries = await fileSystemExtra.readdir(scenesDirectory);\n const scenes: ParsedScene[] = [];\n for (const entryName of entries) {\n if (!entryName.endsWith('-scene.ts') || entryName.endsWith('.test.ts')) {\n continue;\n }\n const sceneKebabName = entryName.slice(0, entryName.length - '.ts'.length);\n const sceneBaseName = toPascalCase(sceneKebabName.slice(0, sceneKebabName.length - '-scene'.length));\n try {\n const source = await fileSystemExtra.readFile(\n path.join(scenesDirectory, entryName),\n 'utf8',\n );\n scenes.push(parseSceneSource(source, sceneBaseName, sceneKebabName));\n } catch {\n // Skip unreadable / unparseable scene files.\n }\n }\n return scenes;\n}\n","import fileSystemExtra from 'fs-extra';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport { resolveWithinProject } from '../component-system/path-guard.js';\n\nconst readProjectConfigInputSchema = z.object({}).default({});\n\nconst updateProjectConfigInputSchema = z.object({\n changes: z.record(z.unknown()),\n});\n\n/**\n * Wrap a JSON-serializable value as a successful MCP tool response.\n */\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Register the two donut.json project-config tools.\n */\nexport function registerProjectTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const readProjectConfigTool: ToolDefinition = {\n name: 'read_project_config',\n description: 'Return the parsed contents of donut.json.',\n inputSchema: zodToJsonSchema(readProjectConfigInputSchema) as object,\n handler: async (input: unknown) => {\n readProjectConfigInputSchema.parse(input ?? {});\n const manifestPath = resolveWithinProject(projectDirectory, 'donut.json');\n if (!(await fileSystemExtra.pathExists(manifestPath))) {\n throw new Error(`donut.json not found at ${manifestPath}`);\n }\n const raw = await fileSystemExtra.readFile(manifestPath, 'utf8');\n const config = JSON.parse(raw) as Record<string, unknown>;\n return formatToolResult({ filePath: manifestPath, config });\n },\n };\n\n const updateProjectConfigTool: ToolDefinition = {\n name: 'update_project_config',\n description:\n 'Shallow-merge `changes` into donut.json and write back the result. ' +\n 'Top-level keys in `changes` overwrite existing values.',\n inputSchema: zodToJsonSchema(updateProjectConfigInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = updateProjectConfigInputSchema.parse(input);\n const manifestPath = resolveWithinProject(projectDirectory, 'donut.json');\n if (!(await fileSystemExtra.pathExists(manifestPath))) {\n throw new Error(`donut.json not found at ${manifestPath}`);\n }\n const raw = await fileSystemExtra.readFile(manifestPath, 'utf8');\n const existing = JSON.parse(raw) as Record<string, unknown>;\n const merged: Record<string, unknown> = { ...existing, ...parsedInput.changes };\n await fileSystemExtra.writeFile(\n manifestPath,\n JSON.stringify(merged, null, 2) + '\\n',\n 'utf8',\n );\n return formatToolResult({ filePath: manifestPath, config: merged });\n },\n };\n\n context.registerTool(readProjectConfigTool);\n context.registerTool(updateProjectConfigTool);\n}\n","import fileSystemExtra from 'fs-extra';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport { resolveWithinProject } from '../component-system/path-guard.js';\nimport {\n listSceneFiles,\n readSceneFile,\n resolveScenePaths,\n writeSceneFile,\n type ParsedScene,\n} from './scene-file.js';\n\nconst createSceneInputSchema = z.object({\n name: z.string().min(1),\n systems: z.array(z.string().min(1)).optional(),\n});\n\nconst readSceneInputSchema = z.object({ name: z.string().min(1) });\n\nconst updateSceneInputSchema = z.object({\n name: z.string().min(1),\n setSystems: z.array(z.string().min(1)).optional(),\n});\n\nconst deleteSceneInputSchema = z.object({ name: z.string().min(1) });\n\nconst listScenesInputSchema = z.object({}).default({});\n\nconst setActiveSceneInputSchema = z.object({ name: z.string().min(1) });\n\n/**\n * Wrap a JSON-serializable value as a successful MCP tool response.\n */\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Register the six scene CRUD tools.\n */\nexport function registerSceneTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const createSceneTool: ToolDefinition = {\n name: 'create_scene',\n description:\n 'Create a new scene file under src/scenes/ with empty @donut-entities and ' +\n '@donut-systems marker blocks. Fails if the file already exists.',\n inputSchema: zodToJsonSchema(createSceneInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = createSceneInputSchema.parse(input);\n const { absoluteFilePath, sceneBaseName, sceneClassName, sceneKebabName } =\n resolveScenePaths(projectDirectory, parsedInput.name);\n if (await fileSystemExtra.pathExists(absoluteFilePath)) {\n throw new Error(`Scene file already exists: ${absoluteFilePath}`);\n }\n const parsedScene: ParsedScene = {\n sceneBaseName,\n sceneClassName,\n sceneKebabName,\n entities: [],\n systems: parsedInput.systems ?? [],\n };\n const written = await writeSceneFile(projectDirectory, parsedScene);\n return formatToolResult({\n sceneName: sceneBaseName,\n className: sceneClassName,\n filePath: written,\n });\n },\n };\n\n const readSceneTool: ToolDefinition = {\n name: 'read_scene',\n description: 'Return the current source text of a scene file plus its parsed data.',\n inputSchema: zodToJsonSchema(readSceneInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = readSceneInputSchema.parse(input);\n const { parsed, absoluteFilePath, source } = await readSceneFile(\n projectDirectory,\n parsedInput.name,\n );\n return formatToolResult({\n sceneName: parsed.sceneBaseName,\n className: parsed.sceneClassName,\n filePath: absoluteFilePath,\n source,\n entities: parsed.entities,\n systems: parsed.systems,\n });\n },\n };\n\n const updateSceneTool: ToolDefinition = {\n name: 'update_scene',\n description:\n 'Replace the list of systems registered by this scene. Marker block and ' +\n 'generated body are both regenerated.',\n inputSchema: zodToJsonSchema(updateSceneInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = updateSceneInputSchema.parse(input);\n const { parsed } = await readSceneFile(projectDirectory, parsedInput.name);\n if (parsedInput.setSystems !== undefined) {\n parsed.systems = parsedInput.setSystems;\n }\n const written = await writeSceneFile(projectDirectory, parsed);\n return formatToolResult({\n sceneName: parsed.sceneBaseName,\n systems: parsed.systems,\n filePath: written,\n });\n },\n };\n\n const deleteSceneTool: ToolDefinition = {\n name: 'delete_scene',\n description: 'Delete a scene file from src/scenes/.',\n inputSchema: zodToJsonSchema(deleteSceneInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = deleteSceneInputSchema.parse(input);\n const { absoluteFilePath, sceneBaseName } = resolveScenePaths(\n projectDirectory,\n parsedInput.name,\n );\n if (!(await fileSystemExtra.pathExists(absoluteFilePath))) {\n throw new Error(`Scene file not found: ${absoluteFilePath}`);\n }\n await fileSystemExtra.remove(absoluteFilePath);\n return formatToolResult({ sceneName: sceneBaseName, deleted: absoluteFilePath });\n },\n };\n\n const listScenesTool: ToolDefinition = {\n name: 'list_scenes',\n description: 'List all scene files found under src/scenes/.',\n inputSchema: zodToJsonSchema(listScenesInputSchema) as object,\n handler: async (input: unknown) => {\n listScenesInputSchema.parse(input ?? {});\n const scenes = await listSceneFiles(projectDirectory);\n return formatToolResult({\n scenes: scenes.map((scene) => ({\n name: scene.sceneBaseName,\n className: scene.sceneClassName,\n entityCount: scene.entities.length,\n systems: scene.systems,\n })),\n });\n },\n };\n\n const setActiveSceneTool: ToolDefinition = {\n name: 'set_active_scene',\n description:\n 'Set the activeScene field in donut.json to the given scene name. Creates ' +\n 'the field if missing.',\n inputSchema: zodToJsonSchema(setActiveSceneInputSchema) as object,\n handler: async (input: unknown) => {\n const parsedInput = setActiveSceneInputSchema.parse(input);\n const { sceneBaseName } = resolveScenePaths(projectDirectory, parsedInput.name);\n const manifestPath = resolveWithinProject(projectDirectory, 'donut.json');\n if (!(await fileSystemExtra.pathExists(manifestPath))) {\n throw new Error(`donut.json not found at ${manifestPath}`);\n }\n const raw = await fileSystemExtra.readFile(manifestPath, 'utf8');\n const manifest = JSON.parse(raw) as Record<string, unknown>;\n manifest['activeScene'] = sceneBaseName;\n await fileSystemExtra.writeFile(\n manifestPath,\n JSON.stringify(manifest, null, 2) + '\\n',\n 'utf8',\n );\n return formatToolResult({ activeScene: sceneBaseName, filePath: manifestPath });\n },\n };\n\n context.registerTool(createSceneTool);\n context.registerTool(readSceneTool);\n context.registerTool(updateSceneTool);\n context.registerTool(deleteSceneTool);\n context.registerTool(listScenesTool);\n context.registerTool(setActiveSceneTool);\n}\n","import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\n\nimport type { ToolContext } from '../../tool-context.js';\nimport { registerAssetTools } from './assets.js';\nimport { registerEntityTools } from './entities.js';\nimport { registerProjectTools } from './project.js';\nimport { registerSceneTools } from './scenes.js';\n\n/**\n * Register the full entity/scene/asset/project tool suite on the MCP context.\n * The `server` parameter is accepted for parity with the other registrars but\n * is not needed here — all tools register through `context.registerTool`.\n */\nexport function registerEntitySceneTools(\n _server: Server,\n context: ToolContext,\n): void {\n registerEntityTools(context);\n registerSceneTools(context);\n registerAssetTools(context);\n registerProjectTools(context);\n}\n","import path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport fileSystemExtra from 'fs-extra';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\n\n/**\n * Structured TypeScript diagnostic returned by the type-check tools.\n */\nexport interface TypeCheckDiagnostic {\n readonly filePath: string;\n readonly line: number;\n readonly column: number;\n readonly message: string;\n readonly code: string;\n}\n\n/**\n * Hook for tests — when set, `runTypeScriptCompiler` returns the injected\n * diagnostic output instead of spawning `tsc`.\n */\nlet compilerOutputOverride: string | undefined;\n\n/**\n * Test-only hook: replace the tsc invocation with a fixed string of output.\n * Pass `undefined` to reset.\n */\nexport function setTypeScriptCompilerOutputOverride(\n output: string | undefined,\n): void {\n compilerOutputOverride = output;\n}\n\nfunction resolveTypeScriptCompiler(projectDirectory: string): string | undefined {\n const projectLocal = path.join(\n projectDirectory,\n 'node_modules',\n 'typescript',\n 'bin',\n 'tsc',\n );\n if (fileSystemExtra.existsSync(projectLocal)) {\n return projectLocal;\n }\n try {\n const requireFromHere = createRequire(import.meta.url);\n const typeScriptPackageJsonPath = requireFromHere.resolve('typescript/package.json');\n const typeScriptPackageDirectory = path.dirname(typeScriptPackageJsonPath);\n const fallback = path.join(typeScriptPackageDirectory, 'bin', 'tsc');\n if (fileSystemExtra.existsSync(fallback)) {\n return fallback;\n }\n } catch {\n // ignore\n }\n return undefined;\n}\n\nfunction runProcess(\n command: string,\n argumentList: string[],\n workingDirectory: string,\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, argumentList, {\n cwd: workingDirectory,\n env: process.env,\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('close', () => {\n resolve({ stdout, stderr });\n });\n child.on('error', () => {\n resolve({ stdout, stderr });\n });\n });\n}\n\n/**\n * Run tsc --noEmit against the project's tsconfig.json and return captured\n * output. When the test override is set, return that output instead.\n */\nexport async function runTypeScriptCompiler(\n projectDirectory: string,\n): Promise<{ output: string; skippedReason?: string }> {\n if (compilerOutputOverride !== undefined) {\n return { output: compilerOutputOverride };\n }\n const tsconfigPath = path.join(projectDirectory, 'tsconfig.json');\n if (!(await fileSystemExtra.pathExists(tsconfigPath))) {\n return { output: '', skippedReason: 'tsconfig.json not found' };\n }\n const compilerPath = resolveTypeScriptCompiler(projectDirectory);\n if (compilerPath === undefined) {\n return { output: '', skippedReason: 'unable to locate the TypeScript compiler' };\n }\n const { stdout, stderr } = await runProcess(\n process.execPath,\n [compilerPath, '--noEmit', '-p', tsconfigPath],\n projectDirectory,\n );\n return { output: `${stdout}\\n${stderr}` };\n}\n\n/**\n * Parse tsc diagnostic output into structured records.\n */\nexport function parseTypeScriptDiagnostics(\n output: string,\n projectDirectory: string,\n): TypeCheckDiagnostic[] {\n const diagnosticLineRegex =\n /^([^\\s(][^(]*?)\\((\\d+),(\\d+)\\):\\s+error\\s+(TS\\d+):\\s+(.+)$/gm;\n const diagnostics: TypeCheckDiagnostic[] = [];\n let match: RegExpExecArray | null;\n while ((match = diagnosticLineRegex.exec(output)) !== null) {\n const [, rawFilePath, lineText, columnText, typeScriptCode, messageText] = match;\n const absoluteFilePath = path.isAbsolute(rawFilePath)\n ? rawFilePath\n : path.join(projectDirectory, rawFilePath);\n diagnostics.push({\n filePath: absoluteFilePath,\n line: Number.parseInt(lineText, 10),\n column: Number.parseInt(columnText, 10),\n message: `${typeScriptCode}: ${messageText.trim()}`,\n code: typeScriptCode,\n });\n }\n return diagnostics;\n}\n\nconst checkTypesFileInputSchema = z.object({ filePath: z.string().min(1) });\nconst emptyInputSchema = z.object({}).default({});\n\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Register MCP tools that surface TypeScript compiler diagnostics.\n */\nexport function registerTypeCheckTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const checkTypesTool: ToolDefinition = {\n name: 'check_types',\n description:\n 'Run `tsc --noEmit` against the project and return structured diagnostics ' +\n 'for every type error discovered.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async (input: unknown) => {\n emptyInputSchema.parse(input ?? {});\n const { output, skippedReason } = await runTypeScriptCompiler(projectDirectory);\n const errors = parseTypeScriptDiagnostics(output, projectDirectory);\n return formatToolResult({\n errors,\n errorCount: errors.length,\n ...(skippedReason !== undefined ? { skippedReason } : {}),\n });\n },\n };\n\n const checkTypesFileTool: ToolDefinition = {\n name: 'check_types_file',\n description:\n 'Run a project-wide type-check and filter diagnostics down to a single ' +\n 'file (preserves tsconfig.json settings for accurate results).',\n inputSchema: zodToJsonSchema(checkTypesFileInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = checkTypesFileInputSchema.parse(input);\n const absoluteTargetPath = path.isAbsolute(parsed.filePath)\n ? parsed.filePath\n : path.resolve(projectDirectory, parsed.filePath);\n const { output, skippedReason } = await runTypeScriptCompiler(projectDirectory);\n const allDiagnostics = parseTypeScriptDiagnostics(output, projectDirectory);\n const errors = allDiagnostics.filter(\n (diagnostic) =>\n path.resolve(diagnostic.filePath) === path.resolve(absoluteTargetPath),\n );\n return formatToolResult({\n filePath: absoluteTargetPath,\n errors,\n errorCount: errors.length,\n ...(skippedReason !== undefined ? { skippedReason } : {}),\n });\n },\n };\n\n context.registerTool(checkTypesTool);\n context.registerTool(checkTypesFileTool);\n}\n","import path from 'node:path';\nimport fileSystemExtra from 'fs-extra';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\n\nconst lintInputSchema = z\n .object({ filePath: z.string().min(1).optional() })\n .default({});\n\n/**\n * A single lint message normalized from ESLint's native result shape.\n */\nexport interface LintMessage {\n readonly filePath: string;\n readonly line: number;\n readonly column: number;\n readonly ruleId: string | null;\n readonly message: string;\n readonly severity: 'error' | 'warning';\n}\n\nconst CONFIG_FILE_NAMES = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n '.eslintrc',\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.json',\n '.eslintrc.yaml',\n '.eslintrc.yml',\n];\n\nasync function hasEslintConfig(projectDirectory: string): Promise<boolean> {\n for (const fileName of CONFIG_FILE_NAMES) {\n if (await fileSystemExtra.pathExists(path.join(projectDirectory, fileName))) {\n return true;\n }\n }\n const packageJsonPath = path.join(projectDirectory, 'package.json');\n if (await fileSystemExtra.pathExists(packageJsonPath)) {\n try {\n const packageJson = await fileSystemExtra.readJson(packageJsonPath);\n if (packageJson && typeof packageJson === 'object' && 'eslintConfig' in packageJson) {\n return true;\n }\n } catch {\n // ignore parse errors\n }\n }\n return false;\n}\n\ninterface EslintModule {\n ESLint: new (options: Record<string, unknown>) => {\n lintFiles: (patterns: string[]) => Promise<unknown[]>;\n };\n}\n\nasync function tryLoadEslint(): Promise<EslintModule | undefined> {\n try {\n const moduleName = 'eslint';\n const mod = (await import(moduleName)) as unknown as EslintModule;\n return mod;\n } catch {\n return undefined;\n }\n}\n\ninterface RawEslintResult {\n filePath: string;\n messages: Array<{\n ruleId: string | null;\n severity: number;\n message: string;\n line?: number;\n column?: number;\n }>;\n errorCount: number;\n warningCount: number;\n output?: string;\n}\n\nfunction normalizeResults(rawResults: unknown[]): {\n errors: LintMessage[];\n warnings: LintMessage[];\n results: Array<{\n filePath: string;\n errorCount: number;\n warningCount: number;\n }>;\n} {\n const errors: LintMessage[] = [];\n const warnings: LintMessage[] = [];\n const results: Array<{\n filePath: string;\n errorCount: number;\n warningCount: number;\n }> = [];\n for (const entry of rawResults as RawEslintResult[]) {\n results.push({\n filePath: entry.filePath,\n errorCount: entry.errorCount,\n warningCount: entry.warningCount,\n });\n for (const message of entry.messages) {\n const normalized: LintMessage = {\n filePath: entry.filePath,\n line: message.line ?? 1,\n column: message.column ?? 1,\n ruleId: message.ruleId,\n message: message.message,\n severity: message.severity === 2 ? 'error' : 'warning',\n };\n if (normalized.severity === 'error') {\n errors.push(normalized);\n } else {\n warnings.push(normalized);\n }\n }\n }\n return { errors, warnings, results };\n}\n\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\nfunction resolveLintTargets(\n projectDirectory: string,\n filePath: string | undefined,\n): string[] {\n if (filePath === undefined) {\n return [path.join(projectDirectory, 'src')];\n }\n const absolute = path.isAbsolute(filePath)\n ? filePath\n : path.resolve(projectDirectory, filePath);\n return [absolute];\n}\n\n/**\n * Register the `lint` and `lint_fix` tools on the given context.\n */\nexport function registerLintTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const lintTool: ToolDefinition = {\n name: 'lint',\n description:\n 'Run ESLint programmatically against the project (or a single file). ' +\n 'Returns structured errors and warnings. If the project has no ESLint ' +\n 'configuration or ESLint is not installed, the tool returns a skip warning.',\n inputSchema: zodToJsonSchema(lintInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = lintInputSchema.parse(input ?? {});\n if (!(await hasEslintConfig(projectDirectory))) {\n return formatToolResult({\n skipped: true,\n reason: 'No ESLint configuration found at the project root',\n errors: [],\n warnings: [],\n results: [],\n });\n }\n const eslintModule = await tryLoadEslint();\n if (eslintModule === undefined) {\n return formatToolResult({\n skipped: true,\n reason: 'ESLint package is not installed',\n errors: [],\n warnings: [],\n results: [],\n });\n }\n const eslintInstance = new eslintModule.ESLint({ cwd: projectDirectory });\n const rawResults = await eslintInstance.lintFiles(\n resolveLintTargets(projectDirectory, parsed.filePath),\n );\n const normalized = normalizeResults(rawResults);\n return formatToolResult(normalized);\n },\n };\n\n const lintFixTool: ToolDefinition = {\n name: 'lint_fix',\n description:\n 'Run ESLint with auto-fix enabled. Writes fixes to disk and returns the ' +\n 'number of auto-fixed messages plus any remaining errors and warnings.',\n inputSchema: zodToJsonSchema(lintInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = lintInputSchema.parse(input ?? {});\n if (!(await hasEslintConfig(projectDirectory))) {\n return formatToolResult({\n skipped: true,\n reason: 'No ESLint configuration found at the project root',\n fixed: 0,\n remainingErrors: [],\n remainingWarnings: [],\n });\n }\n const eslintModule = await tryLoadEslint();\n if (eslintModule === undefined) {\n return formatToolResult({\n skipped: true,\n reason: 'ESLint package is not installed',\n fixed: 0,\n remainingErrors: [],\n remainingWarnings: [],\n });\n }\n const eslintInstance = new eslintModule.ESLint({\n cwd: projectDirectory,\n fix: true,\n });\n const rawResults = (await eslintInstance.lintFiles(\n resolveLintTargets(projectDirectory, parsed.filePath),\n )) as RawEslintResult[];\n\n let fixed = 0;\n for (const result of rawResults) {\n if (typeof result.output === 'string') {\n await fileSystemExtra.writeFile(result.filePath, result.output, 'utf8');\n fixed += 1;\n }\n }\n const normalized = normalizeResults(rawResults);\n return formatToolResult({\n fixed,\n remainingErrors: normalized.errors,\n remainingWarnings: normalized.warnings,\n });\n },\n };\n\n context.registerTool(lintTool);\n context.registerTool(lintFixTool);\n}\n","import { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport { runValidation } from '@donut/cli/src/commands/validate.js';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\n\nconst emptyInputSchema = z.object({}).default({});\n\nfunction formatToolResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Register the `check_imports` and `validate_world` tools. Both delegate to\n * `@donut/cli`'s {@link runValidation} to avoid duplicating validation logic.\n */\nexport function registerImportsAndWorldTools(context: ToolContext): void {\n const projectDirectory = context.projectDirectory;\n\n const checkImportsTool: ToolDefinition = {\n name: 'check_imports',\n description:\n 'Scan src/components and src/systems for renderer imports that break the ' +\n 'game-logic portability contract. Returns findings with the ' +\n 'RENDERER_IMPORT_IN_GAME_LOGIC code.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async (input: unknown) => {\n emptyInputSchema.parse(input ?? {});\n const report = await runValidation({\n projectDirectory,\n skipTypeCheck: true,\n });\n const findings = report.errors.filter(\n (error) => error.code === 'RENDERER_IMPORT_IN_GAME_LOGIC',\n );\n return formatToolResult({\n findings,\n findingCount: findings.length,\n });\n },\n };\n\n const validateWorldTool: ToolDefinition = {\n name: 'validate_world',\n description:\n 'Run the full project validation pipeline (manifest, types, imports, ' +\n 'asset references) via @donut/cli and return the complete report grouped ' +\n 'by error code.',\n inputSchema: zodToJsonSchema(\n z\n .object({ skipTypeCheck: z.boolean().optional() })\n .default({}),\n ) as object,\n handler: async (input: unknown) => {\n const parsed = z\n .object({ skipTypeCheck: z.boolean().optional() })\n .default({})\n .parse(input ?? {});\n const report = await runValidation({\n projectDirectory,\n ...(parsed.skipTypeCheck !== undefined\n ? { skipTypeCheck: parsed.skipTypeCheck }\n : {}),\n });\n const groupByCode = (\n findings: ReadonlyArray<{ code: string }>,\n ): Record<string, unknown[]> => {\n const grouped: Record<string, unknown[]> = {};\n for (const finding of findings) {\n const bucket = grouped[finding.code] ?? [];\n bucket.push(finding);\n grouped[finding.code] = bucket;\n }\n return grouped;\n };\n return formatToolResult({\n errors: report.errors,\n warnings: report.warnings,\n errorsByCode: groupByCode(report.errors),\n warningsByCode: groupByCode(report.warnings),\n errorCount: report.errors.length,\n warningCount: report.warnings.length,\n });\n },\n };\n\n context.registerTool(checkImportsTool);\n context.registerTool(validateWorldTool);\n}\n","import path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport fileSystemExtra from 'fs-extra';\n\n/**\n * A single validation finding emitted by {@link runValidation}.\n */\nexport interface ValidationError {\n /** Absolute or project-relative path of the offending file. */\n readonly filePath: string;\n /** 1-based line number when known. */\n readonly line?: number;\n /** 1-based column number when known. */\n readonly column?: number;\n /** Human-readable explanation of the problem. */\n readonly message: string;\n /** Stable machine-readable identifier (e.g. \"MANIFEST_INVALID\"). */\n readonly code: string;\n}\n\n/**\n * Aggregate report returned by {@link runValidation}.\n */\nexport interface ValidationReport {\n readonly errors: ValidationError[];\n readonly warnings: ValidationError[];\n}\n\n/**\n * Options accepted by {@link runValidation}.\n */\nexport interface RunValidationOptions {\n /** Absolute path to the project root to validate. */\n readonly projectDirectory: string;\n /** When true, skip the (slow) `tsc --noEmit` pass. Useful for tests. */\n readonly skipTypeCheck?: boolean;\n}\n\n/**\n * Parsed representation of the subset of `donut.json` fields that the\n * validator needs to route subsequent checks. Returned by\n * {@link validateManifest} when the manifest itself is structurally valid.\n */\nexport interface ParsedManifest {\n readonly name: string;\n readonly version: string;\n readonly rendererTarget: string;\n readonly donutEngineVersion: string;\n}\n\nconst REQUIRED_MANIFEST_FIELDS = ['name', 'version', 'rendererTarget', 'donutEngineVersion'] as const;\nconst ALLOWED_RENDERER_TARGETS = new Set(['pixi-2d', 'three-3d']);\n\n/**\n * Forbidden import prefixes inside `src/components/**` and `src/systems/**`.\n * Game logic must stay renderer-agnostic. The legacy `@donut/pixi` and\n * `@donut/three` entries remain during the transition to the published\n * `@donut-games/engine` surface so that in-monorepo projects keep failing\n * as expected.\n */\nconst GAME_LOGIC_FORBIDDEN_RENDERER_IMPORT_PREFIXES = [\n '@donut-games/engine/pixi',\n '@donut-games/engine/three',\n '@donut/pixi',\n '@donut/three',\n] as const;\n\n/**\n * Mapping from a project's `rendererTarget` to the renderer subpath that is\n * disallowed anywhere under `src/**` for that project. The other subpath is\n * the \"correct\" renderer for the target and remains allowed in scene files.\n */\nconst WRONG_RENDERER_FORBIDDEN_IMPORT_BY_TARGET: Record<string, string> = {\n 'pixi-2d': '@donut-games/engine/three',\n 'three-3d': '@donut-games/engine/pixi',\n};\n\n/**\n * Mapping from a project's `rendererTarget` to the renderer subpath that is\n * permitted for renderer-specific code in that project. Used only for\n * error-message construction.\n */\nconst WRONG_RENDERER_ALLOWED_IMPORT_BY_TARGET: Record<string, string> = {\n 'pixi-2d': '@donut-games/engine/pixi',\n 'three-3d': '@donut-games/engine/three',\n};\n\n/**\n * Run all validation checks against a Donut project directory and return a\n * structured {@link ValidationReport}. Never throws for validation problems;\n * only throws for unexpected I/O failures.\n */\nexport async function runValidation(\n options: RunValidationOptions,\n): Promise<ValidationReport> {\n const { projectDirectory } = options;\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n const parsedManifest = await validateManifest(projectDirectory, errors);\n\n if (options.skipTypeCheck !== true) {\n await validateTypes(projectDirectory, errors);\n }\n\n const rendererTarget = parsedManifest?.rendererTarget;\n await validateImportGraph(projectDirectory, rendererTarget, errors);\n await validateAssetReferences(projectDirectory, errors);\n\n return { errors, warnings };\n}\n\nasync function validateManifest(\n projectDirectory: string,\n errors: ValidationError[],\n): Promise<ParsedManifest | null> {\n const manifestPath = path.join(projectDirectory, 'donut.json');\n if (!(await fileSystemExtra.pathExists(manifestPath))) {\n errors.push({\n filePath: manifestPath,\n message: 'donut.json is missing at the project root',\n code: 'MANIFEST_INVALID',\n });\n return null;\n }\n let raw: string;\n try {\n raw = await fileSystemExtra.readFile(manifestPath, 'utf8');\n } catch (readError) {\n errors.push({\n filePath: manifestPath,\n message: `Unable to read donut.json: ${(readError as Error).message}`,\n code: 'MANIFEST_INVALID',\n });\n return null;\n }\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch (parseError) {\n errors.push({\n filePath: manifestPath,\n message: `donut.json is not valid JSON: ${(parseError as Error).message}`,\n code: 'MANIFEST_INVALID',\n });\n return null;\n }\n let hasRequiredFieldError = false;\n for (const fieldName of REQUIRED_MANIFEST_FIELDS) {\n const value = parsed[fieldName];\n if (typeof value !== 'string' || value.trim().length === 0) {\n errors.push({\n filePath: manifestPath,\n message: `donut.json missing required string field \"${fieldName}\"`,\n code: 'MANIFEST_INVALID',\n });\n hasRequiredFieldError = true;\n }\n }\n const rendererTargetValue = parsed.rendererTarget;\n if (\n typeof rendererTargetValue === 'string' &&\n !ALLOWED_RENDERER_TARGETS.has(rendererTargetValue)\n ) {\n errors.push({\n filePath: manifestPath,\n message: `donut.json \"rendererTarget\" must be one of pixi-2d, three-3d (got \"${rendererTargetValue}\")`,\n code: 'MANIFEST_INVALID',\n });\n }\n if (hasRequiredFieldError) {\n return null;\n }\n return {\n name: parsed.name as string,\n version: parsed.version as string,\n rendererTarget: parsed.rendererTarget as string,\n donutEngineVersion: parsed.donutEngineVersion as string,\n };\n}\n\nasync function validateTypes(\n projectDirectory: string,\n errors: ValidationError[],\n): Promise<void> {\n const tsconfigPath = path.join(projectDirectory, 'tsconfig.json');\n if (!(await fileSystemExtra.pathExists(tsconfigPath))) {\n return;\n }\n const typeScriptCompilerPath = resolveTypeScriptCompiler(projectDirectory);\n if (typeScriptCompilerPath === undefined) {\n errors.push({\n filePath: tsconfigPath,\n message: 'Unable to locate a TypeScript compiler (tsc) to run the type-check',\n code: 'TYPE_ERROR',\n });\n return;\n }\n\n const { stdout, stderr } = await runProcess(\n process.execPath,\n [typeScriptCompilerPath, '--noEmit', '-p', tsconfigPath],\n projectDirectory,\n );\n const combined = `${stdout}\\n${stderr}`;\n const diagnosticLineRegex =\n /^([^\\s(][^(]*?)\\((\\d+),(\\d+)\\):\\s+error\\s+(TS\\d+):\\s+(.+)$/gm;\n let match: RegExpExecArray | null;\n while ((match = diagnosticLineRegex.exec(combined)) !== null) {\n const [, rawFilePath, lineText, columnText, typeScriptCode, messageText] = match;\n const absoluteFilePath = path.isAbsolute(rawFilePath)\n ? rawFilePath\n : path.join(projectDirectory, rawFilePath);\n errors.push({\n filePath: absoluteFilePath,\n line: Number.parseInt(lineText, 10),\n column: Number.parseInt(columnText, 10),\n message: `${typeScriptCode}: ${messageText.trim()}`,\n code: 'TYPE_ERROR',\n });\n }\n}\n\nfunction resolveTypeScriptCompiler(projectDirectory: string): string | undefined {\n const projectLocal = path.join(\n projectDirectory,\n 'node_modules',\n 'typescript',\n 'bin',\n 'tsc',\n );\n if (fileSystemExtra.existsSync(projectLocal)) {\n return projectLocal;\n }\n try {\n const requireFromHere = createRequire(import.meta.url);\n const typeScriptPackageJsonPath = requireFromHere.resolve('typescript/package.json');\n const typeScriptPackageDirectory = path.dirname(typeScriptPackageJsonPath);\n const fallback = path.join(typeScriptPackageDirectory, 'bin', 'tsc');\n if (fileSystemExtra.existsSync(fallback)) {\n return fallback;\n }\n } catch {\n // ignore\n }\n return undefined;\n}\n\nfunction runProcess(\n command: string,\n argumentList: string[],\n workingDirectory: string,\n): Promise<{ stdout: string; stderr: string; exitCode: number | null }> {\n return new Promise((resolve) => {\n const child = spawn(command, argumentList, {\n cwd: workingDirectory,\n env: process.env,\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('close', (exitCode) => {\n resolve({ stdout, stderr, exitCode });\n });\n child.on('error', () => {\n resolve({ stdout, stderr, exitCode: null });\n });\n });\n}\n\nasync function validateImportGraph(\n projectDirectory: string,\n rendererTarget: string | undefined,\n errors: ValidationError[],\n): Promise<void> {\n await validateGameLogicImports(projectDirectory, errors);\n await validateWrongRendererImports(projectDirectory, rendererTarget, errors);\n}\n\n/**\n * Game-logic rule: scan `src/components/**` and `src/systems/**` and flag any\n * renderer-specific import regardless of the project's `rendererTarget`.\n * Game logic must remain renderer-agnostic so components and systems are\n * portable across 2D and 3D projects.\n */\nasync function validateGameLogicImports(\n projectDirectory: string,\n errors: ValidationError[],\n): Promise<void> {\n const gameLogicDirectories = [\n path.join(projectDirectory, 'src', 'components'),\n path.join(projectDirectory, 'src', 'systems'),\n ];\n const importLineRegex = /^\\s*import\\s+[^;]*?from\\s+['\"]([^'\"]+)['\"]/;\n for (const directoryPath of gameLogicDirectories) {\n if (!(await fileSystemExtra.pathExists(directoryPath))) {\n continue;\n }\n const typeScriptFiles = await collectTypeScriptFiles(directoryPath);\n for (const filePath of typeScriptFiles) {\n const contents = await fileSystemExtra.readFile(filePath, 'utf8');\n const lines = contents.split(/\\r?\\n/);\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {\n const lineText = lines[lineIndex];\n const matched = importLineRegex.exec(lineText);\n if (matched === null) {\n continue;\n }\n const importedSpecifier = matched[1];\n if (\n GAME_LOGIC_FORBIDDEN_RENDERER_IMPORT_PREFIXES.some(\n (disallowedPrefix) =>\n importedSpecifier === disallowedPrefix ||\n importedSpecifier.startsWith(`${disallowedPrefix}/`),\n )\n ) {\n errors.push({\n filePath,\n line: lineIndex + 1,\n message: `Renderer import \"${importedSpecifier}\" is not allowed in game logic (components/systems must only import @donut-games/engine/core, @donut-games/engine/math, or relative paths)`,\n code: 'RENDERER_IMPORT_IN_GAME_LOGIC',\n });\n }\n }\n }\n }\n}\n\n/**\n * Wrong-renderer rule: scan the entire `src/**` tree and flag any import of\n * the renderer subpath that does not match the project's `rendererTarget`.\n * A `pixi-2d` project may not import `@donut-games/engine/three`, and a\n * `three-3d` project may not import `@donut-games/engine/pixi`.\n */\nasync function validateWrongRendererImports(\n projectDirectory: string,\n rendererTarget: string | undefined,\n errors: ValidationError[],\n): Promise<void> {\n if (rendererTarget === undefined) {\n return;\n }\n const wrongRendererImportSpecifierPrefix =\n WRONG_RENDERER_FORBIDDEN_IMPORT_BY_TARGET[rendererTarget];\n const allowedRendererImportSpecifierPrefix =\n WRONG_RENDERER_ALLOWED_IMPORT_BY_TARGET[rendererTarget];\n if (\n wrongRendererImportSpecifierPrefix === undefined ||\n allowedRendererImportSpecifierPrefix === undefined\n ) {\n return;\n }\n const sourceRoot = path.join(projectDirectory, 'src');\n if (!(await fileSystemExtra.pathExists(sourceRoot))) {\n return;\n }\n const importLineRegex = /^\\s*import\\s+[^;]*?from\\s+['\"]([^'\"]+)['\"]/;\n const typeScriptFiles = await collectTypeScriptFiles(sourceRoot);\n for (const filePath of typeScriptFiles) {\n const contents = await fileSystemExtra.readFile(filePath, 'utf8');\n const lines = contents.split(/\\r?\\n/);\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {\n const lineText = lines[lineIndex];\n const matched = importLineRegex.exec(lineText);\n if (matched === null) {\n continue;\n }\n const importedSpecifier = matched[1];\n if (\n importedSpecifier === wrongRendererImportSpecifierPrefix ||\n importedSpecifier.startsWith(`${wrongRendererImportSpecifierPrefix}/`)\n ) {\n errors.push({\n filePath,\n line: lineIndex + 1,\n message: `Renderer import \"${importedSpecifier}\" is not allowed in a \"${rendererTarget}\" project. This project's donut.json specifies rendererTarget: \"${rendererTarget}\", which only permits ${allowedRendererImportSpecifierPrefix} for renderer-specific code.`,\n code: 'WRONG_RENDERER_IMPORT',\n });\n }\n }\n }\n}\n\nasync function collectTypeScriptFiles(directoryPath: string): Promise<string[]> {\n const collected: string[] = [];\n const entries = await fileSystemExtra.readdir(directoryPath, { withFileTypes: true });\n for (const entry of entries) {\n const entryPath = path.join(directoryPath, entry.name);\n if (entry.isDirectory()) {\n collected.push(...(await collectTypeScriptFiles(entryPath)));\n } else if (entry.isFile() && entry.name.endsWith('.ts')) {\n collected.push(entryPath);\n }\n }\n return collected;\n}\n\nasync function validateAssetReferences(\n projectDirectory: string,\n errors: ValidationError[],\n): Promise<void> {\n const sourceRoot = path.join(projectDirectory, 'src');\n const assetsRoot = path.join(projectDirectory, 'assets');\n if (!(await fileSystemExtra.pathExists(sourceRoot))) {\n return;\n }\n const typeScriptFiles = await collectTypeScriptFiles(sourceRoot);\n const texturePathRegex = /texturePath\\s*(?::[^='\"]*)?=?\\s*['\"]([^'\"]*)['\"]/g;\n const assetsLiteralRegex = /['\"]assets\\/([^'\"]+)['\"]/g;\n\n for (const filePath of typeScriptFiles) {\n const contents = await fileSystemExtra.readFile(filePath, 'utf8');\n const lines = contents.split(/\\r?\\n/);\n const referencedAssets: { relativePath: string; line: number }[] = [];\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {\n const lineText = lines[lineIndex];\n texturePathRegex.lastIndex = 0;\n let textureMatch: RegExpExecArray | null;\n while ((textureMatch = texturePathRegex.exec(lineText)) !== null) {\n const referenced = textureMatch[1];\n if (referenced.length === 0) {\n continue;\n }\n referencedAssets.push({ relativePath: referenced, line: lineIndex + 1 });\n }\n assetsLiteralRegex.lastIndex = 0;\n let assetsMatch: RegExpExecArray | null;\n while ((assetsMatch = assetsLiteralRegex.exec(lineText)) !== null) {\n referencedAssets.push({\n relativePath: assetsMatch[1],\n line: lineIndex + 1,\n });\n }\n }\n\n for (const { relativePath, line } of referencedAssets) {\n const normalized = relativePath.startsWith('assets/')\n ? relativePath.slice('assets/'.length)\n : relativePath;\n const absoluteAssetPath = path.join(assetsRoot, normalized);\n if (!(await fileSystemExtra.pathExists(absoluteAssetPath))) {\n errors.push({\n filePath,\n line,\n message: `Referenced asset \"${relativePath}\" not found under assets/`,\n code: 'MISSING_ASSET',\n });\n }\n }\n }\n}\n\n/**\n * Resolve the directory where this module lives; useful for callers that\n * want to look up bundled assets relative to the compiled output.\n */\nexport function getValidateCommandDirectory(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n","import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { ToolContext } from '../../tool-context.js';\n\nimport { registerTypeCheckTools } from './type-check.js';\nimport { registerLintTools } from './lint.js';\nimport { registerImportsAndWorldTools } from './imports-world.js';\n\n/**\n * Register all quality-focused MCP tools: TypeScript type checking, ESLint\n * linting, renderer-import auditing, and full-project validation.\n */\nexport function registerQualityTools(\n _server: Server,\n context: ToolContext,\n): void {\n registerTypeCheckTools(context);\n registerLintTools(context);\n registerImportsAndWorldTools(context);\n}\n","import { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport type { ToolContext, ToolDefinition } from '../../tool-context.js';\nimport {\n getCurrentRuntimeSession,\n requireRuntimeSession,\n startRuntimeSession,\n stopRuntimeSession,\n} from './runtime-session.js';\n\n/** Input schema for {@link buildStartGameTool}. */\nconst startGameInputSchema = z.object({\n port: z.number().int().positive().max(65_535).default(5173),\n});\n\n/** Input schema for {@link buildRestartGameTool}. */\nconst restartGameInputSchema = z.object({\n port: z.number().int().positive().max(65_535).default(5173),\n});\n\n/** Empty-object input, accepted as either `{}` or undefined. */\nconst emptyInputSchema = z.object({}).default({});\n\n/** Input schema for {@link buildTakeScreenshotAfterTool}. */\nconst takeScreenshotAfterInputSchema = z.object({\n delayMilliseconds: z.number().int().nonnegative().max(60_000),\n});\n\n/** Input schema for {@link buildReadConsoleLogsTool}. */\nconst readConsoleLogsInputSchema = z.object({\n count: z.number().int().positive().max(200).default(50),\n level: z.enum(['log', 'warn', 'error']).optional(),\n});\n\n/** Input schema for {@link buildSendInputActionTool}. Supports two shapes. */\nconst sendInputActionInputSchema = z.union([\n z.object({\n actionName: z.string().min(1),\n value: z.number().default(1),\n }),\n z.object({\n actionName: z.string().min(1),\n phase: z.enum(['start', 'end']),\n value: z.number().default(1),\n }),\n]);\n\n/** Input schema for {@link buildGetEntityStateTool}. */\nconst getEntityStateInputSchema = z.object({ entityName: z.string().min(1) });\n\n/**\n * Format a JSON-ish payload into the standard MCP text response envelope used\n * across the Donut MCP tools.\n */\nfunction formatTextResult(payload: unknown): {\n content: Array<{ type: 'text'; text: string }>;\n} {\n return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };\n}\n\n/**\n * Sleep helper used by `take_screenshot_after`.\n */\nfunction delay(milliseconds: number): Promise<void> {\n return new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds));\n}\n\n/** Build the `start_game` tool definition. */\nfunction buildStartGameTool(context: ToolContext): ToolDefinition {\n return {\n name: 'start_game',\n description:\n 'Spawn the Donut dev server as a child process and open a headless ' +\n 'browser pointed at it. Fails if a session is already running.',\n inputSchema: zodToJsonSchema(startGameInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = startGameInputSchema.parse(input ?? {});\n const session = await startRuntimeSession({\n projectDirectory: context.projectDirectory,\n port: parsed.port,\n });\n return formatTextResult({ url: session.url, pid: session.pid });\n },\n };\n}\n\n/** Build the `stop_game` tool definition. */\nfunction buildStopGameTool(): ToolDefinition {\n return {\n name: 'stop_game',\n description: 'Close the headless browser and terminate the dev server process.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async () => {\n const stopped = await stopRuntimeSession();\n return formatTextResult({ stopped });\n },\n };\n}\n\n/** Build the `restart_game` tool definition. */\nfunction buildRestartGameTool(context: ToolContext): ToolDefinition {\n return {\n name: 'restart_game',\n description: 'Stop any running dev session, then start a fresh one.',\n inputSchema: zodToJsonSchema(restartGameInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = restartGameInputSchema.parse(input ?? {});\n await stopRuntimeSession();\n const session = await startRuntimeSession({\n projectDirectory: context.projectDirectory,\n port: parsed.port,\n });\n return formatTextResult({ url: session.url, pid: session.pid });\n },\n };\n}\n\n/** Build the `take_screenshot` tool definition. */\nfunction buildTakeScreenshotTool(): ToolDefinition {\n return {\n name: 'take_screenshot',\n description:\n 'Capture the contents of the #game-canvas element as a base64 PNG. ' +\n 'Requires a running runtime session.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async () => {\n const session = requireRuntimeSession();\n const buffer = await session.page.locator('#game-canvas').screenshot();\n const base64 = buffer.toString('base64');\n return {\n content: [{ type: 'image' as const, data: base64, mimeType: 'image/png' }],\n } as unknown as { content: Array<{ type: 'text'; text: string }> };\n },\n };\n}\n\n/** Build the `take_screenshot_after` tool definition. */\nfunction buildTakeScreenshotAfterTool(): ToolDefinition {\n return {\n name: 'take_screenshot_after',\n description:\n 'Wait `delayMilliseconds`, then capture a screenshot of #game-canvas.',\n inputSchema: zodToJsonSchema(takeScreenshotAfterInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = takeScreenshotAfterInputSchema.parse(input);\n const session = requireRuntimeSession();\n await delay(parsed.delayMilliseconds);\n const buffer = await session.page.locator('#game-canvas').screenshot();\n const base64 = buffer.toString('base64');\n return {\n content: [{ type: 'image' as const, data: base64, mimeType: 'image/png' }],\n } as unknown as { content: Array<{ type: 'text'; text: string }> };\n },\n };\n}\n\n/** Build the `read_console_logs` tool definition. */\nfunction buildReadConsoleLogsTool(): ToolDefinition {\n return {\n name: 'read_console_logs',\n description:\n 'Return the most recent console entries captured by the runtime bridge, ' +\n 'optionally filtered by level.',\n inputSchema: zodToJsonSchema(readConsoleLogsInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = readConsoleLogsInputSchema.parse(input ?? {});\n const session = requireRuntimeSession();\n const buffer = await session.page.evaluate<\n Array<{ level: 'log' | 'warn' | 'error'; timestamp: number; message: string }>\n >(\n (() => {\n const runtime = (window as unknown as {\n __donutRuntime?: {\n consoleBuffer: Array<{\n level: 'log' | 'warn' | 'error';\n timestamp: number;\n message: string;\n }>;\n };\n }).__donutRuntime;\n return runtime?.consoleBuffer ?? [];\n }) as () => Array<{\n level: 'log' | 'warn' | 'error';\n timestamp: number;\n message: string;\n }>,\n );\n const filtered =\n parsed.level === undefined\n ? buffer\n : buffer.filter((entry) => entry.level === parsed.level);\n const tail = filtered.slice(Math.max(0, filtered.length - parsed.count));\n return formatTextResult({ entries: tail });\n },\n };\n}\n\n/** Build the `read_performance_metrics` tool definition. */\nfunction buildReadPerformanceMetricsTool(): ToolDefinition {\n return {\n name: 'read_performance_metrics',\n description:\n 'Return live FPS, last-frame duration, entity count, and per-system ' +\n 'update timings captured by the runtime bridge.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async () => {\n const session = requireRuntimeSession();\n const metrics = await session.page.evaluate<{\n fps: number;\n frameTimeMilliseconds: number;\n entityCount: number;\n systemTimings: Record<string, number>;\n }>(\n (() => {\n const runtime = (window as unknown as {\n __donutRuntime?: {\n getMetrics(): {\n fps: number;\n frameTimeMilliseconds: number;\n entityCount: number;\n systemTimings: Record<string, number>;\n };\n };\n }).__donutRuntime;\n if (runtime === undefined) {\n return {\n fps: 0,\n frameTimeMilliseconds: 0,\n entityCount: 0,\n systemTimings: {},\n };\n }\n return runtime.getMetrics();\n }) as () => {\n fps: number;\n frameTimeMilliseconds: number;\n entityCount: number;\n systemTimings: Record<string, number>;\n },\n );\n return formatTextResult(metrics);\n },\n };\n}\n\n/** Build the `send_input_action` tool definition. */\nfunction buildSendInputActionTool(): ToolDefinition {\n return {\n name: 'send_input_action',\n description:\n 'Dispatch a synthetic CTRLLR action to the running game. Without a ' +\n '`phase`, sends a start event and an end event one frame later. With a ' +\n '`phase`, dispatches just that single event.',\n inputSchema: zodToJsonSchema(sendInputActionInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = sendInputActionInputSchema.parse(input);\n const session = requireRuntimeSession();\n await session.page.evaluate<\n void,\n { actionName: string; value: number; phase: 'start' | 'end' | undefined }\n >(\n ((argument) => {\n const runtime = (window as unknown as {\n __donutRuntime?: {\n triggerAction(\n actionName: string,\n value?: number,\n phase?: 'start' | 'end',\n ): void;\n };\n }).__donutRuntime;\n runtime?.triggerAction(argument.actionName, argument.value, argument.phase);\n }) as (argument: {\n actionName: string;\n value: number;\n phase: 'start' | 'end' | undefined;\n }) => void,\n {\n actionName: parsed.actionName,\n value: parsed.value,\n phase: 'phase' in parsed ? parsed.phase : undefined,\n },\n );\n return formatTextResult({ dispatched: parsed.actionName });\n },\n };\n}\n\n/** Build the `get_entity_state` tool definition. */\nfunction buildGetEntityStateTool(): ToolDefinition {\n return {\n name: 'get_entity_state',\n description:\n 'Look up an entity by name and return its tags plus each component ' +\n 'serialized via `Component.serialize()`.',\n inputSchema: zodToJsonSchema(getEntityStateInputSchema) as object,\n handler: async (input: unknown) => {\n const parsed = getEntityStateInputSchema.parse(input);\n const session = requireRuntimeSession();\n const state = await session.page.evaluate<unknown, string>(\n ((entityName: string) => {\n const runtime = (window as unknown as {\n __donutRuntime?: { getEntityState(entityName: string): unknown };\n }).__donutRuntime;\n return runtime?.getEntityState(entityName);\n }) as (entityName: string) => unknown,\n parsed.entityName,\n );\n if (state === undefined || state === null) {\n throw new Error(`Entity not found: ${parsed.entityName}`);\n }\n return formatTextResult(state);\n },\n };\n}\n\n/** Build the `list_active_entities` tool definition. */\nfunction buildListActiveEntitiesTool(): ToolDefinition {\n return {\n name: 'list_active_entities',\n description:\n 'List every entity currently in the world, with identifier, name, ' +\n 'tags, and component type names.',\n inputSchema: zodToJsonSchema(emptyInputSchema) as object,\n handler: async () => {\n const session = requireRuntimeSession();\n const entities = await session.page.evaluate<\n Array<{\n identifier: number;\n name: string;\n tags: string[];\n componentTypes: string[];\n }>\n >(\n (() => {\n const runtime = (window as unknown as {\n __donutRuntime?: {\n getEntities(): Array<{\n identifier: number;\n name: string;\n tags: string[];\n componentTypes: string[];\n }>;\n };\n }).__donutRuntime;\n return runtime?.getEntities() ?? [];\n }) as () => Array<{\n identifier: number;\n name: string;\n tags: string[];\n componentTypes: string[];\n }>,\n );\n return formatTextResult({ entities });\n },\n };\n}\n\n// Re-export the session singleton accessor so tests can check tool behaviour.\nexport { getCurrentRuntimeSession };\n\n/**\n * Register every runtime control tool with the MCP server context.\n */\nexport function registerRuntimeControlTools(context: ToolContext): void {\n context.registerTool(buildStartGameTool(context));\n context.registerTool(buildStopGameTool());\n context.registerTool(buildRestartGameTool(context));\n context.registerTool(buildTakeScreenshotTool());\n context.registerTool(buildTakeScreenshotAfterTool());\n context.registerTool(buildReadConsoleLogsTool());\n context.registerTool(buildReadPerformanceMetricsTool());\n context.registerTool(buildSendInputActionTool());\n context.registerTool(buildGetEntityStateTool());\n context.registerTool(buildListActiveEntitiesTool());\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport fileSystem from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Subset of Playwright's `Page` interface used by the runtime tools. The tools\n * only exercise `evaluate`, `locator`, and `close`, so we keep the structural\n * type narrow — this is what enables unit tests to stub the session without\n * pulling in a real browser.\n */\nexport interface RuntimePage {\n evaluate<TResult>(script: string | (() => TResult | Promise<TResult>)): Promise<TResult>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n evaluate<TResult, TArgument>(\n script: ((argument: TArgument) => TResult | Promise<TResult>),\n argument: TArgument,\n ): Promise<TResult>;\n locator(selector: string): {\n screenshot(): Promise<Buffer>;\n };\n close(): Promise<void>;\n}\n\n/**\n * Subset of Playwright's `Browser` interface used by the runtime tools.\n */\nexport interface RuntimeBrowser {\n close(): Promise<void>;\n}\n\n/**\n * Handle to a running dev server + headless browser session. One session at a\n * time is supported; the module-level singleton {@link getCurrentRuntimeSession}\n * holds it.\n */\nexport interface RuntimeSession {\n readonly url: string;\n readonly pid: number;\n readonly process: ChildProcess;\n readonly browser: RuntimeBrowser;\n readonly page: RuntimePage;\n}\n\nlet currentSession: RuntimeSession | undefined;\n\n/** Returns the active runtime session, or `undefined` if none is running. */\nexport function getCurrentRuntimeSession(): RuntimeSession | undefined {\n return currentSession;\n}\n\n/**\n * Test-only: forcibly inject a {@link RuntimeSession} (usually a mock) so the\n * tool handlers can be exercised without spinning up a real dev server.\n */\nexport function setCurrentRuntimeSessionForTesting(\n session: RuntimeSession | undefined,\n): void {\n currentSession = session;\n}\n\n/**\n * Options for {@link startRuntimeSession}.\n */\nexport interface StartRuntimeSessionOptions {\n readonly projectDirectory: string;\n readonly port: number;\n /** Overridable Playwright import, injected for tests. */\n readonly launchBrowser?: () => Promise<{\n browser: RuntimeBrowser;\n page: RuntimePage;\n }>;\n}\n\n/**\n * Default browser launcher — dynamically imports Playwright at call time so\n * MCP clients that never touch the runtime tools do not pay the import cost.\n * Extracted so tests can skip it entirely via dependency injection.\n */\nasync function defaultLaunchBrowser(): Promise<{\n browser: RuntimeBrowser;\n page: RuntimePage;\n}> {\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n const playwright = (await import('playwright')) as unknown as {\n chromium: {\n launch(options?: { headless?: boolean }): Promise<RuntimeBrowser & {\n newPage(): Promise<RuntimePage>;\n }>;\n };\n };\n const browser = await playwright.chromium.launch({ headless: true });\n const page = await browser.newPage();\n return { browser, page };\n}\n\n/**\n * Locate the monorepo root by walking parents of `startDirectory` until a\n * `pnpm-workspace.yaml` is found. Returns `undefined` if not in a workspace.\n */\nfunction detectMonorepoRoot(startDirectory: string): string | undefined {\n let currentDirectory = path.resolve(startDirectory);\n for (let depth = 0; depth < 8; depth++) {\n if (fileSystem.existsSync(path.join(currentDirectory, 'pnpm-workspace.yaml'))) {\n return currentDirectory;\n }\n const parentDirectory = path.dirname(currentDirectory);\n if (parentDirectory === currentDirectory) {\n return undefined;\n }\n currentDirectory = parentDirectory;\n }\n return undefined;\n}\n\n/**\n * Spawn the Donut CLI dev server, wait for its \"Dev server ready\" line,\n * launch Playwright chromium, navigate to the server URL, and store the\n * resulting session in the singleton.\n *\n * @throws if a session is already running, or if the dev server fails to\n * announce its URL within the configured timeout.\n */\nexport async function startRuntimeSession(\n options: StartRuntimeSessionOptions,\n): Promise<RuntimeSession> {\n if (currentSession !== undefined) {\n throw new Error('Runtime session is already running; call stop_game first.');\n }\n\n const monorepoRoot = detectMonorepoRoot(options.projectDirectory);\n const cliDistEntry =\n monorepoRoot !== undefined\n ? path.join(monorepoRoot, 'packages', 'cli', 'dist', 'index.js')\n : undefined;\n const cliSourceEntry =\n monorepoRoot !== undefined\n ? path.join(monorepoRoot, 'packages', 'cli', 'src', 'index.ts')\n : undefined;\n\n let childProcess: ChildProcess;\n if (cliDistEntry !== undefined && fileSystem.existsSync(cliDistEntry)) {\n // Prefer the compiled CLI — no tsx dependency, works from any cwd.\n childProcess = spawn(\n 'node',\n [cliDistEntry, 'dev', '--no-open', '--port', String(options.port)],\n { cwd: options.projectDirectory, stdio: ['ignore', 'pipe', 'pipe'] },\n );\n } else if (cliSourceEntry !== undefined) {\n // Fall back to the TypeScript source via tsx. Requires tsx to be\n // resolvable from the monorepo root.\n childProcess = spawn(\n 'node',\n [\n '--import',\n 'tsx',\n cliSourceEntry,\n 'dev',\n '--no-open',\n '--port',\n String(options.port),\n ],\n { cwd: monorepoRoot, stdio: ['ignore', 'pipe', 'pipe'] },\n );\n } else {\n childProcess = spawn(\n 'donut',\n ['dev', '--no-open', '--port', String(options.port)],\n { cwd: options.projectDirectory, stdio: ['ignore', 'pipe', 'pipe'] },\n );\n }\n\n const url = await new Promise<string>((resolvePromise, rejectPromise) => {\n const timeoutHandle = setTimeout(() => {\n rejectPromise(new Error('Timed out waiting for dev server to start (20s).'));\n }, 20_000);\n\n const handleData = (chunk: Buffer): void => {\n const text = chunk.toString();\n const match = text.match(/Dev server ready at (https?:\\/\\/[^\\s]+)/);\n if (match !== null && match[1] !== undefined) {\n clearTimeout(timeoutHandle);\n resolvePromise(match[1].replace(/\\/$/, ''));\n }\n };\n\n childProcess.stdout?.on('data', handleData);\n childProcess.stderr?.on('data', handleData);\n childProcess.on('error', (error) => {\n clearTimeout(timeoutHandle);\n rejectPromise(error);\n });\n childProcess.on('exit', (code) => {\n clearTimeout(timeoutHandle);\n rejectPromise(new Error(`Dev server exited before becoming ready (code ${code}).`));\n });\n });\n\n const launchBrowser = options.launchBrowser ?? defaultLaunchBrowser;\n const { browser, page } = await launchBrowser();\n await (page as unknown as { goto(destination: string): Promise<unknown> }).goto(url);\n\n const session: RuntimeSession = {\n url,\n pid: childProcess.pid ?? -1,\n process: childProcess,\n browser,\n page,\n };\n currentSession = session;\n return session;\n}\n\n/**\n * Tear down the active session. No-op if nothing is running.\n */\nexport async function stopRuntimeSession(): Promise<boolean> {\n const session = currentSession;\n if (session === undefined) {\n return false;\n }\n currentSession = undefined;\n try {\n await session.browser.close();\n } catch {\n // Swallow — the browser may already be closed.\n }\n if (!session.process.killed) {\n session.process.kill('SIGTERM');\n }\n return true;\n}\n\n/**\n * Retrieve the active session or throw a descriptive error if no session is\n * running. Used by every runtime tool that requires a live browser.\n */\nexport function requireRuntimeSession(): RuntimeSession {\n const session = currentSession;\n if (session === undefined) {\n throw new Error('No runtime session is running. Call start_game first.');\n }\n return session;\n}\n","import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { ToolContext } from '../../tool-context.js';\nimport { registerRuntimeControlTools } from './tools.js';\n\n/**\n * Register the runtime-control MCP tools (teammate 4 deliverable):\n * start_game, stop_game, restart_game, take_screenshot,\n * take_screenshot_after, read_console_logs, read_performance_metrics,\n * send_input_action, get_entity_state, list_active_entities.\n */\nexport function registerRuntimeTools(\n _server: Server,\n context: ToolContext,\n): void {\n registerRuntimeControlTools(context);\n}\n","// The real `#!/usr/bin/env node` shebang is injected at build time by the\n// `tsup` banner configuration — do not add one here as a string, or it will\n// appear mid-file after bundling.\n\n/**\n * `donut-mcp` bin entry. Forwards to the stdio MCP server defined in the\n * internal `@donut/mcp` workspace package.\n */\nimport { startMcpServer } from '@donut/mcp';\n\nstartMcpServer().catch((error: unknown) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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","names":["path","path","path","path","fileSystemExtra","typescript","z","zodToJsonSchema","z","typescript","path","formatToolResult","collectTypeScriptFiles","fileSystemExtra","zodToJsonSchema","path","fileSystemExtra","z","zodToJsonSchema","z","formatToolResult","fileSystemExtra","path","zodToJsonSchema","z","zodToJsonSchema","path","fileSystemExtra","path","fileSystemExtra","z","formatToolResult","zodToJsonSchema","fileSystemExtra","z","zodToJsonSchema","z","formatToolResult","zodToJsonSchema","fileSystemExtra","fileSystemExtra","z","zodToJsonSchema","z","formatToolResult","zodToJsonSchema","fileSystemExtra","path","fileSystemExtra","z","zodToJsonSchema","path","fileSystemExtra","z","formatToolResult","zodToJsonSchema","path","fileSystemExtra","z","zodToJsonSchema","formatToolResult","z","zodToJsonSchema","path","spawn","createRequire","fileSystemExtra","resolveTypeScriptCompiler","runProcess","collectTypeScriptFiles","emptyInputSchema","z","formatToolResult","zodToJsonSchema","z","zodToJsonSchema","spawn","path","path","spawn","z","emptyInputSchema","zodToJsonSchema","path"]}
|