dominus-cli 0.5.9 → 0.6.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/mcp.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transport/protocol.ts","../src/transport/ws-server.ts","../src/transport/ws-client.ts","../src/config/config.ts","../src/memory/store.ts","../src/agent/internal-memory.ts","../src/mcp/server.ts","../src/mcp/index.ts"],"names":["EventEmitter","WebSocket","fs","result","path"],"mappings":"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","file":"mcp.js","sourcesContent":["import { nanoid } from 'nanoid';\r\n\r\nexport interface WsMessage<T = unknown> {\r\n id: string;\r\n type: string;\r\n payload: T;\r\n ts: number;\r\n}\r\n\r\nexport const StudioMsg = {\r\n CONNECTED: 'studio:connected',\r\n DISCONNECTED: 'studio:disconnected',\r\n EXPLORER: 'studio:explorer',\r\n OUTPUT: 'studio:output',\r\n ERROR: 'studio:error',\r\n SELECTION: 'studio:selection',\r\n SCRIPT_CONTENT: 'studio:script:content',\r\n SCRIPT_CHANGED: 'studio:script:changed',\r\n RESPONSE: 'studio:response',\r\n REFLECTION: 'studio:reflection',\r\n TEST_RESULTS: 'studio:test:results',\r\n} as const;\r\n\r\nexport const CliMsg = {\r\n GET_EXPLORER: 'cli:get:explorer',\r\n GET_SCRIPT: 'cli:get:script',\r\n SET_SCRIPT: 'cli:set:script',\r\n RUN_CODE: 'cli:run',\r\n GET_PROPERTIES: 'cli:get:properties',\r\n GET_DESCENDANTS_PROPERTIES: 'cli:get:descendants:properties',\r\n SET_PROPERTIES: 'cli:set:properties',\r\n INSERT_INSTANCE: 'cli:insert',\r\n DELETE_INSTANCE: 'cli:delete',\r\n GET_SELECTION: 'cli:get:selection',\r\n SELECT: 'cli:select',\r\n SEARCH_SCRIPTS: 'cli:search:scripts',\r\n GET_OUTPUT: 'cli:get:output',\r\n RUN_TESTS: 'cli:run:tests',\r\n EXECUTE_RUN_TEST: 'cli:test:run',\r\n EXECUTE_PLAY_TEST: 'cli:test:play',\r\n END_TEST: 'cli:test:end',\r\n BUILD_UI: 'cli:build:ui',\r\n GET_REFLECTION: 'cli:get:reflection',\r\n UPLOAD_ASSET: 'cli:upload:asset',\r\n SERIALIZE_UI: 'cli:serialize:ui',\r\n MOVE_INSTANCE: 'cli:move:instance',\r\n UNDO: 'cli:undo',\r\n REDO: 'cli:redo',\r\n BULK_SET_PROPERTIES: 'cli:bulk:set:properties',\r\n FIND_REPLACE_SCRIPTS: 'cli:find:replace:scripts',\r\n} as const;\r\n\r\nexport type StudioMsgType = (typeof StudioMsg)[keyof typeof StudioMsg];\r\nexport type CliMsgType = (typeof CliMsg)[keyof typeof CliMsg];\r\n\r\nexport interface ExplorerNode {\r\n name: string;\r\n className: string;\r\n path: string;\r\n children?: ExplorerNode[];\r\n}\r\n\r\nexport interface StudioConnectedPayload {\r\n studioVersion: string;\r\n placeId?: number;\r\n placeName?: string;\r\n engineVersion?: string;\r\n}\r\n\r\nexport interface ScriptContentPayload {\r\n path: string;\r\n className: 'Script' | 'LocalScript' | 'ModuleScript';\r\n source: string;\r\n lineCount: number;\r\n}\r\n\r\nexport interface ScriptChangedPayload {\r\n path: string;\r\n source: string;\r\n}\r\n\r\nexport interface OutputPayload {\r\n message: string;\r\n level: 'info' | 'warn' | 'error';\r\n timestamp: number;\r\n source?: string;\r\n}\r\n\r\nexport interface SelectionPayload {\r\n paths: string[];\r\n classNames: string[];\r\n}\r\n\r\nexport interface PropertyEntry {\r\n name: string;\r\n value: string;\r\n type: string;\r\n category?: string;\r\n}\r\n\r\nexport interface TestResultPayload {\r\n name: string;\r\n passed: boolean;\r\n duration: number;\r\n error?: string;\r\n}\r\n\r\nexport interface StudioTestPayload {\r\n args?: unknown;\r\n}\r\n\r\nexport interface StudioTestResultPayload {\r\n success: boolean;\r\n result?: unknown;\r\n error?: string;\r\n duration?: number;\r\n}\r\n\r\nexport interface ReflectionPayload {\r\n className: string;\r\n properties: { name: string; type: string; category: string }[];\r\n methods: { name: string; parameters: string[] }[];\r\n events: { name: string; parameters: string[] }[];\r\n}\r\n\r\nexport interface RunCodePayload {\r\n code: string;\r\n}\r\n\r\nexport interface RunCodeResponsePayload {\r\n output: string;\r\n error?: string;\r\n duration: number;\r\n}\r\n\r\nexport interface SearchScriptsPayload {\r\n query: string;\r\n maxResults?: number;\r\n}\r\n\r\nexport interface SearchResultPayload {\r\n results: {\r\n path: string;\r\n className: string;\r\n matches: { line: number; text: string }[];\r\n }[];\r\n}\r\n\r\nexport interface InsertInstancePayload {\r\n className: string;\r\n parentPath: string;\r\n name: string;\r\n properties?: Record<string, unknown>;\r\n}\r\n\r\nexport interface SetPropertiesPayload {\r\n path: string;\r\n properties: Record<string, unknown>;\r\n}\r\n\r\nexport function createMessage<T>(type: string, payload: T): WsMessage<T> {\r\n return { id: nanoid(), type, payload, ts: Date.now() };\r\n}\r\n\r\nexport function createRequest<T>(type: string, payload: T): WsMessage<T> {\r\n return createMessage(type, payload);\r\n}\r\n\r\nexport function parseMessage(raw: string): WsMessage {\r\n try {\r\n return JSON.parse(raw) as WsMessage;\r\n } catch {\r\n throw new Error(`Failed to parse WebSocket message: ${raw.slice(0, 100)}`);\r\n }\r\n}\r\n\r\nexport function serializeMessage(msg: WsMessage): string {\r\n return JSON.stringify(msg);\r\n}\r\n","import { WebSocketServer, WebSocket } from 'ws';\nimport { EventEmitter } from 'node:events';\nimport {\n parseMessage,\n serializeMessage,\n createMessage,\n StudioMsg,\n type WsMessage,\n type StudioConnectedPayload,\n} from './protocol.js';\n\nexport interface StudioConnection {\n ws: WebSocket;\n studioVersion?: string;\n placeId?: number;\n placeName?: string;\n connectedAt: number;\n}\n\nexport interface StudioBridge extends EventEmitter {\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs?: number): Promise<WsMessage<T>>;\n sendNotification(type: string, payload: unknown): void;\n isConnected(): boolean;\n getConnectionInfo(): StudioConnection | null;\n getPort(): number;\n stop(): Promise<void>;\n}\n\nexport class DominusServer extends EventEmitter implements StudioBridge {\n private wss: WebSocketServer | null = null;\n private studioClient: StudioConnection | null = null;\n private controllers = new Set<WebSocket>();\n private pendingRequests = new Map<\n string,\n { resolve: (msg: WsMessage) => void; reject: (err: Error) => void; timer: ReturnType<typeof setTimeout> }\n >();\n private relayRequests = new Map<string, WebSocket>();\n private port: number;\n\n constructor(port = 18088) {\n super();\n this.port = port;\n }\n\n start(maxRetries = 0): Promise<void> {\n return new Promise((resolve, reject) => {\n const tryPort = (port: number, attempt: number) => {\n const wss = new WebSocketServer({ port });\n\n wss.on('listening', () => {\n this.wss = wss;\n this.port = port;\n this.wss.on('connection', (ws) => this.handleConnection(ws));\n this.emit('server:started', { port });\n resolve();\n });\n\n wss.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE' && attempt < maxRetries) {\n wss.close();\n tryPort(port + 1, attempt + 1);\n } else {\n this.emit('server:error', err);\n reject(err);\n }\n });\n };\n\n tryPort(this.port, 0);\n });\n }\n\n private handleConnection(ws: WebSocket): void {\n let identified = false;\n\n ws.on('message', (raw) => {\n try {\n const msg = parseMessage(raw.toString());\n\n if (!identified) {\n if (msg.type === StudioMsg.CONNECTED) {\n identified = true;\n this.setStudioClient(ws, msg);\n return;\n }\n if (msg.type === 'controller:connect') {\n identified = true;\n this.addController(ws);\n ws.send(serializeMessage(createMessage('controller:welcome', {\n studioConnected: this.isConnected(),\n port: this.port,\n })));\n return;\n }\n }\n\n if (this.controllers.has(ws)) {\n this.handleControllerMessage(ws, msg);\n } else {\n this.handleStudioMessage(msg);\n }\n } catch (err) {\n this.emit('server:error', err);\n }\n });\n\n ws.on('close', () => {\n if (this.controllers.has(ws)) {\n this.controllers.delete(ws);\n for (const [id, controllerWs] of this.relayRequests) {\n if (controllerWs === ws) this.relayRequests.delete(id);\n }\n } else if (this.studioClient?.ws === ws) {\n this.studioClient = null;\n this.emit('studio:disconnected');\n this.broadcastToControllers('studio:disconnected', {});\n for (const [id, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error('Studio disconnected'));\n this.pendingRequests.delete(id);\n }\n }\n });\n\n ws.on('error', (err) => {\n this.emit('server:error', err);\n });\n }\n\n private setStudioClient(ws: WebSocket, msg: WsMessage): void {\n if (this.studioClient) {\n this.studioClient.ws.close();\n }\n\n const payload = msg.payload as StudioConnectedPayload;\n this.studioClient = {\n ws,\n connectedAt: Date.now(),\n studioVersion: payload.studioVersion,\n placeId: payload.placeId,\n placeName: payload.placeName,\n };\n\n this.emit('studio:connected', payload);\n this.broadcastToControllers('studio:connected', payload);\n }\n\n private addController(ws: WebSocket): void {\n this.controllers.add(ws);\n this.emit('controller:connected');\n }\n\n private broadcastToControllers(type: string, payload: unknown): void {\n const msg = serializeMessage(createMessage(type, payload));\n for (const ws of this.controllers) {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(msg);\n }\n }\n }\n\n private handleControllerMessage(controllerWs: WebSocket, msg: WsMessage): void {\n if (!this.studioClient || this.studioClient.ws.readyState !== WebSocket.OPEN) {\n controllerWs.send(serializeMessage({\n id: msg.id,\n type: StudioMsg.RESPONSE,\n payload: { error: 'Studio not connected' },\n ts: Date.now(),\n }));\n return;\n }\n\n this.relayRequests.set(msg.id, controllerWs);\n this.studioClient.ws.send(serializeMessage(msg));\n }\n\n private handleStudioMessage(msg: WsMessage): void {\n if (msg.type === StudioMsg.CONNECTED) {\n const payload = msg.payload as StudioConnectedPayload;\n if (this.studioClient) {\n this.studioClient.studioVersion = payload.studioVersion;\n this.studioClient.placeId = payload.placeId;\n this.studioClient.placeName = payload.placeName;\n }\n this.emit('studio:connected', payload);\n this.broadcastToControllers('studio:connected', payload);\n return;\n }\n\n if (msg.type === StudioMsg.RESPONSE) {\n // Check if this is a relayed request from a controller\n const controllerWs = this.relayRequests.get(msg.id);\n if (controllerWs && controllerWs.readyState === WebSocket.OPEN) {\n controllerWs.send(serializeMessage(msg));\n this.relayRequests.delete(msg.id);\n return;\n }\n\n // Otherwise handle locally (MCP or direct)\n const pending = this.pendingRequests.get(msg.id);\n if (pending) {\n clearTimeout(pending.timer);\n pending.resolve(msg);\n this.pendingRequests.delete(msg.id);\n }\n return;\n }\n\n // Forward events to controllers and local listeners\n this.emit(msg.type, msg.payload);\n this.emit('message', msg);\n this.broadcastToControllers(msg.type, msg.payload);\n }\n\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs = 10000): Promise<WsMessage<T>> {\n return new Promise((resolve, reject) => {\n if (!this.studioClient || this.studioClient.ws.readyState !== WebSocket.OPEN) {\n reject(new Error('No Studio connection'));\n return;\n }\n\n const msg = createMessage(type, payload);\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(msg.id);\n reject(new Error(`Request timed out: ${type}`));\n }, timeoutMs);\n\n this.pendingRequests.set(msg.id, {\n resolve: resolve as (msg: WsMessage) => void,\n reject,\n timer,\n });\n\n this.studioClient.ws.send(serializeMessage(msg));\n });\n }\n\n sendNotification(type: string, payload: unknown): void {\n if (!this.studioClient || this.studioClient.ws.readyState !== WebSocket.OPEN) {\n return;\n }\n const msg = createMessage(type, payload);\n this.studioClient.ws.send(serializeMessage(msg));\n }\n\n isConnected(): boolean {\n return this.studioClient !== null && this.studioClient.ws.readyState === WebSocket.OPEN;\n }\n\n getConnectionInfo(): StudioConnection | null {\n return this.studioClient;\n }\n\n getPort(): number {\n return this.port;\n }\n\n stop(): Promise<void> {\n return new Promise((resolve) => {\n if (this.studioClient) {\n this.studioClient.ws.close();\n this.studioClient = null;\n }\n for (const ws of this.controllers) {\n ws.close();\n }\n this.controllers.clear();\n for (const [, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error('Server shutting down'));\n }\n this.pendingRequests.clear();\n this.relayRequests.clear();\n\n if (this.wss) {\n this.wss.close(() => resolve());\n } else {\n resolve();\n }\n });\n }\n}\n","import { WebSocket } from 'ws';\r\nimport { EventEmitter } from 'node:events';\r\nimport {\r\n parseMessage,\r\n serializeMessage,\r\n createMessage,\r\n StudioMsg,\r\n type WsMessage,\r\n type StudioConnectedPayload,\r\n} from './protocol.js';\r\nimport type { StudioBridge, StudioConnection } from './ws-server.js';\r\n\r\n/**\r\n * Connects as a relay client to an existing DominusServer.\r\n * Has the same interface as DominusServer so the TUI/Agent\r\n * can use either transparently.\r\n */\r\nexport class DominusClient extends EventEmitter implements StudioBridge {\r\n private ws: WebSocket | null = null;\r\n private port: number;\r\n private studioConnected = false;\r\n private connectionInfo: Omit<StudioConnection, 'ws'> | null = null;\r\n private pendingRequests = new Map<\r\n string,\r\n { resolve: (msg: WsMessage) => void; reject: (err: Error) => void; timer: ReturnType<typeof setTimeout> }\r\n >();\r\n\r\n constructor(port = 18088) {\r\n super();\r\n this.port = port;\r\n }\r\n\r\n connect(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const url = `ws://localhost:${this.port}`;\r\n const ws = new WebSocket(url);\r\n\r\n ws.on('open', () => {\r\n this.ws = ws;\r\n ws.send(serializeMessage(createMessage('controller:connect', {})));\r\n this.emit('server:started', { port: this.port, relay: true });\r\n resolve();\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const msg = parseMessage(raw.toString());\r\n this.handleMessage(msg);\r\n } catch (err) {\r\n this.emit('server:error', err);\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.ws = null;\r\n this.studioConnected = false;\r\n this.emit('studio:disconnected');\r\n for (const [id, pending] of this.pendingRequests) {\r\n clearTimeout(pending.timer);\r\n pending.reject(new Error('Relay connection lost'));\r\n this.pendingRequests.delete(id);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n if (!this.ws) reject(err);\r\n this.emit('server:error', err);\r\n });\r\n });\r\n }\r\n\r\n private handleMessage(msg: WsMessage): void {\r\n if (msg.type === 'controller:welcome') {\r\n const p = msg.payload as { studioConnected: boolean };\r\n this.studioConnected = p.studioConnected;\r\n if (this.studioConnected) {\r\n this.emit('studio:connected', {});\r\n }\r\n return;\r\n }\r\n\r\n if (msg.type === 'studio:connected') {\r\n this.studioConnected = true;\r\n const payload = msg.payload as StudioConnectedPayload;\r\n this.connectionInfo = {\r\n connectedAt: Date.now(),\r\n studioVersion: payload.studioVersion,\r\n placeId: payload.placeId,\r\n placeName: payload.placeName,\r\n };\r\n this.emit('studio:connected', payload);\r\n return;\r\n }\r\n\r\n if (msg.type === 'studio:disconnected') {\r\n this.studioConnected = false;\r\n this.connectionInfo = null;\r\n this.emit('studio:disconnected');\r\n return;\r\n }\r\n\r\n if (msg.type === StudioMsg.RESPONSE) {\r\n const pending = this.pendingRequests.get(msg.id);\r\n if (pending) {\r\n clearTimeout(pending.timer);\r\n pending.resolve(msg);\r\n this.pendingRequests.delete(msg.id);\r\n }\r\n return;\r\n }\r\n\r\n this.emit(msg.type, msg.payload);\r\n this.emit('message', msg);\r\n }\r\n\r\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs = 10000): Promise<WsMessage<T>> {\r\n return new Promise((resolve, reject) => {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n reject(new Error('Not connected to Dominus server'));\r\n return;\r\n }\r\n if (!this.studioConnected) {\r\n reject(new Error('Studio not connected'));\r\n return;\r\n }\r\n\r\n const msg = createMessage(type, payload);\r\n\r\n const timer = setTimeout(() => {\r\n this.pendingRequests.delete(msg.id);\r\n reject(new Error(`Request timed out: ${type}`));\r\n }, timeoutMs);\r\n\r\n this.pendingRequests.set(msg.id, {\r\n resolve: resolve as (msg: WsMessage) => void,\r\n reject,\r\n timer,\r\n });\r\n\r\n this.ws.send(serializeMessage(msg));\r\n });\r\n }\r\n\r\n sendNotification(type: string, payload: unknown): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\r\n const msg = createMessage(type, payload);\r\n this.ws.send(serializeMessage(msg));\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.studioConnected;\r\n }\r\n\r\n getConnectionInfo(): StudioConnection | null {\r\n if (!this.connectionInfo) return null;\r\n return { ...this.connectionInfo, ws: this.ws! } as StudioConnection;\r\n }\r\n\r\n getPort(): number {\r\n return this.port;\r\n }\r\n\r\n stop(): Promise<void> {\r\n return new Promise((resolve) => {\r\n for (const [, pending] of this.pendingRequests) {\r\n clearTimeout(pending.timer);\r\n pending.reject(new Error('Client shutting down'));\r\n }\r\n this.pendingRequests.clear();\r\n if (this.ws) {\r\n this.ws.close();\r\n this.ws = null;\r\n }\r\n resolve();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Check if a Dominus server is already running on the given port.\r\n */\r\nexport async function isPortInUse(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const ws = new WebSocket(`ws://localhost:${port}`);\r\n const timer = setTimeout(() => {\r\n ws.close();\r\n resolve(false);\r\n }, 1000);\r\n\r\n ws.on('open', () => {\r\n clearTimeout(timer);\r\n ws.close();\r\n resolve(true);\r\n });\r\n\r\n ws.on('error', () => {\r\n clearTimeout(timer);\r\n resolve(false);\r\n });\r\n });\r\n}\r\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type { ConfigAccess } from '../tools/types.js';\n\nconst DOMINUS_DIR = path.join(os.homedir(), '.dominus');\nconst CONFIG_PATH = path.join(DOMINUS_DIR, 'config.json');\nconst DB_PATH = path.join(DOMINUS_DIR, 'dominus.db');\nconst RULES_PATH = path.join(DOMINUS_DIR, 'rules.json');\n\nexport type AIProviderType =\n | 'openai'\n | 'anthropic'\n | 'gemini'\n | 'xai'\n | 'openrouter'\n | 'custom';\n\nexport interface ProviderConfig {\n name: string;\n baseUrl: string;\n envVar: string;\n defaultModel: string;\n}\n\nexport const PROVIDERS: Record<AIProviderType, ProviderConfig> = {\n openai: {\n name: 'OpenAI',\n baseUrl: 'https://api.openai.com/v1',\n envVar: 'OPENAI_API_KEY',\n defaultModel: 'gpt-5.3-codex',\n },\n anthropic: {\n name: 'Anthropic',\n baseUrl: 'https://api.anthropic.com/v1/',\n envVar: 'ANTHROPIC_API_KEY',\n defaultModel: 'claude-sonnet-4-6',\n },\n gemini: {\n name: 'Google Gemini',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai',\n envVar: 'GEMINI_API_KEY',\n defaultModel: 'gemini-3.1-pro',\n },\n xai: {\n name: 'xAI (Grok)',\n baseUrl: 'https://api.x.ai/v1',\n envVar: 'XAI_API_KEY',\n defaultModel: 'grok-4.2',\n },\n openrouter: {\n name: 'OpenRouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n envVar: 'OPENROUTER_API_KEY',\n defaultModel: 'anthropic/claude-sonnet-4-6',\n },\n custom: {\n name: 'Custom',\n baseUrl: '',\n envVar: '',\n defaultModel: '',\n },\n};\n\nexport interface DominusConfig {\n provider: AIProviderType;\n apiKey?: string;\n apiBaseUrl: string;\n model: string;\n port: number;\n maxToolIterations: number;\n maxVerifyRetries: number;\n tokenBudget: number;\n autoIndex: boolean;\n autoLearn: boolean;\n userName: string;\n openCloudApiKey?: string;\n}\n\nconst DEFAULTS: DominusConfig = {\n provider: 'openai',\n apiBaseUrl: '',\n model: '',\n port: 18088,\n maxToolIterations: 25,\n maxVerifyRetries: 3,\n tokenBudget: 128000,\n autoIndex: true,\n autoLearn: true,\n userName: 'Developer',\n};\n\n/**\n * Auto-detect provider from environment variables.\n * Returns the first provider whose env var is set, or null.\n */\nexport function detectProviderFromEnv(): { provider: AIProviderType; apiKey: string } | null {\n const priority: AIProviderType[] = ['openai', 'anthropic', 'gemini', 'xai', 'openrouter'];\n for (const p of priority) {\n const key = process.env[PROVIDERS[p].envVar];\n if (key) return { provider: p, apiKey: key };\n }\n return null;\n}\n\n/**\n * Resolve the effective base URL and model for a provider config.\n */\nexport function resolveProviderSettings(config: DominusConfig): {\n baseUrl: string;\n model: string;\n} {\n const providerInfo = PROVIDERS[config.provider];\n return {\n baseUrl: config.apiBaseUrl || providerInfo?.baseUrl || PROVIDERS.openrouter.baseUrl,\n model: config.model || providerInfo?.defaultModel || 'gpt-4o',\n };\n}\n\nexport interface DominusRules {\n do: string[];\n dont: string[];\n conventions: string[];\n context: string;\n}\n\nconst DEFAULT_RULES: DominusRules = {\n do: [],\n dont: [],\n conventions: [],\n context: '',\n};\n\nfunction ensureDir(): void {\n if (!fs.existsSync(DOMINUS_DIR)) {\n fs.mkdirSync(DOMINUS_DIR, { recursive: true });\n }\n}\n\nfunction readJson<T>(filePath: string, defaults: T): T {\n try {\n if (fs.existsSync(filePath)) {\n const raw = fs.readFileSync(filePath, 'utf-8');\n return { ...defaults, ...JSON.parse(raw) };\n }\n } catch {\n // Corrupted file; reset to defaults\n }\n return { ...defaults };\n}\n\nfunction writeJson(filePath: string, data: unknown): void {\n ensureDir();\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\nexport function loadConfig(): DominusConfig {\n ensureDir();\n return readJson(CONFIG_PATH, DEFAULTS);\n}\n\nexport function saveConfig(config: DominusConfig): void {\n writeJson(CONFIG_PATH, config);\n}\n\nexport function getConfigValue<K extends keyof DominusConfig>(key: K): DominusConfig[K] {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue<K extends keyof DominusConfig>(\n key: K,\n value: DominusConfig[K],\n): void {\n const config = loadConfig();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (config as any)[key] = value;\n saveConfig(config);\n}\n\nexport function loadRules(): DominusRules {\n ensureDir();\n return readJson(RULES_PATH, DEFAULT_RULES);\n}\n\nexport function saveRules(rules: DominusRules): void {\n writeJson(RULES_PATH, rules);\n}\n\nexport function getDominusDir(): string {\n ensureDir();\n return DOMINUS_DIR;\n}\n\nexport function getDbPath(): string {\n ensureDir();\n return DB_PATH;\n}\n\nexport function createConfigAccess(): ConfigAccess {\n return {\n get<T>(key: string): T | undefined {\n const config = loadConfig() as unknown as Record<string, unknown>;\n return config[key] as T | undefined;\n },\n set(key: string, value: unknown): void {\n const config = loadConfig() as unknown as Record<string, unknown>;\n config[key] = value;\n saveConfig(config as unknown as DominusConfig);\n },\n getAll(): Record<string, unknown> {\n return loadConfig() as unknown as Record<string, unknown>;\n },\n };\n}\n","import fs from 'node:fs';\r\nimport initSqlJs from 'sql.js';\r\nimport type { Database, QueryExecResult } from 'sql.js';\r\nimport { getDbPath } from '../config/config.js';\r\nimport type { Fact, FactCategory, SessionSummary, ChatMessage, ScriptEntry } from './types.js';\r\n\r\nlet db: Database | null = null;\r\nlet dbPath: string;\r\n\r\nconst SCHEMA = `\r\nCREATE TABLE IF NOT EXISTS facts (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n content TEXT NOT NULL,\r\n category TEXT NOT NULL,\r\n source TEXT,\r\n relevance REAL DEFAULT 1.0,\r\n created_at INTEGER NOT NULL,\r\n accessed_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS summaries (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n session_id TEXT NOT NULL,\r\n summary TEXT NOT NULL,\r\n created_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS messages (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n session_id TEXT NOT NULL,\r\n role TEXT NOT NULL,\r\n content TEXT NOT NULL,\r\n tool_name TEXT,\r\n created_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS script_index (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n path TEXT NOT NULL,\r\n class_name TEXT NOT NULL,\r\n summary TEXT,\r\n line_count INTEGER,\r\n last_hash TEXT,\r\n updated_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_facts_project ON facts(project_id);\r\nCREATE INDEX IF NOT EXISTS idx_facts_category ON facts(project_id, category);\r\nCREATE INDEX IF NOT EXISTS idx_scripts_project ON script_index(project_id);\r\nCREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\r\nCREATE INDEX IF NOT EXISTS idx_summaries_project ON summaries(project_id);\r\n`;\r\n\r\nfunction persist(): void {\r\n if (!db) return;\r\n const data = db.export();\r\n fs.writeFileSync(dbPath, Buffer.from(data));\r\n}\r\n\r\nexport async function initMemoryStore(): Promise<void> {\r\n if (db) return;\r\n dbPath = getDbPath();\r\n const SQL = await initSqlJs();\r\n\r\n if (fs.existsSync(dbPath)) {\r\n const buffer = fs.readFileSync(dbPath);\r\n db = new SQL.Database(buffer);\r\n } else {\r\n db = new SQL.Database();\r\n }\r\n\r\n db.run(SCHEMA);\r\n persist();\r\n}\r\n\r\nexport function getDb(): Database {\r\n if (!db) throw new Error('Memory store not initialized. Call initMemoryStore() first.');\r\n return db;\r\n}\r\n\r\nexport function closeMemoryStore(): void {\r\n if (db) {\r\n persist();\r\n db.close();\r\n db = null;\r\n }\r\n}\r\n\r\n// --- Facts ---\r\n\r\nexport function storeFact(fact: Omit<Fact, 'id'>): number {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO facts (project_id, content, category, source, relevance, created_at, accessed_at)\r\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\r\n [\r\n fact.projectId,\r\n fact.content,\r\n fact.category,\r\n fact.source ?? null,\r\n fact.relevance,\r\n fact.createdAt,\r\n fact.accessedAt,\r\n ],\r\n );\r\n persist();\r\n const stmt = d.prepare('SELECT last_insert_rowid()');\r\n stmt.step();\r\n const row = stmt.get();\r\n stmt.free();\r\n return (row?.[0] as number) ?? 0;\r\n}\r\n\r\nexport function recallFacts(projectId: string, query: string, limit = 10): Fact[] {\r\n const d = getDb();\r\n const keywords = query\r\n .toLowerCase()\r\n .split(/\\s+/)\r\n .filter((w) => w.length > 2);\r\n\r\n if (keywords.length === 0) {\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? ORDER BY relevance DESC, accessed_at DESC LIMIT ?`,\r\n [projectId, limit],\r\n );\r\n return rowsToFacts(result);\r\n }\r\n\r\n const likeClauses = keywords.map(() => `LOWER(content) LIKE ?`).join(' OR ');\r\n const likeParams = keywords.map((k) => `%${k}%`);\r\n\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? AND (${likeClauses})\r\n ORDER BY relevance DESC, accessed_at DESC LIMIT ?`,\r\n [projectId, ...likeParams, limit],\r\n );\r\n\r\n const facts = rowsToFacts(result);\r\n\r\n // Update accessed_at for recalled facts\r\n for (const fact of facts) {\r\n if (fact.id) {\r\n d.run(`UPDATE facts SET accessed_at = ? WHERE id = ?`, [Date.now(), fact.id]);\r\n }\r\n }\r\n if (facts.length > 0) persist();\r\n\r\n return facts;\r\n}\r\n\r\nexport function getAllFacts(projectId: string): Fact[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? ORDER BY relevance DESC`,\r\n [projectId],\r\n );\r\n return rowsToFacts(result);\r\n}\r\n\r\nfunction rowsToFacts(result: QueryExecResult[]): Fact[] {\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n content: row[2] as string,\r\n category: row[3] as FactCategory,\r\n source: row[4] as string | undefined,\r\n relevance: row[5] as number,\r\n createdAt: row[6] as number,\r\n accessedAt: row[7] as number,\r\n }));\r\n}\r\n\r\n// --- Messages ---\r\n\r\nexport function storeMessage(msg: Omit<ChatMessage, 'id'>): void {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO messages (session_id, role, content, tool_name, created_at)\r\n VALUES (?, ?, ?, ?, ?)`,\r\n [msg.sessionId, msg.role, msg.content, msg.toolName ?? null, msg.createdAt],\r\n );\r\n persist();\r\n}\r\n\r\nexport function getSessionMessages(sessionId: string, limit = 100): ChatMessage[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM messages WHERE session_id = ? ORDER BY created_at ASC LIMIT ?`,\r\n [sessionId, limit],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n sessionId: row[1] as string,\r\n role: row[2] as ChatMessage['role'],\r\n content: row[3] as string,\r\n toolName: (row[4] as string) || undefined,\r\n createdAt: row[5] as number,\r\n }));\r\n}\r\n\r\n// --- Summaries ---\r\n\r\nexport function storeSummary(summary: Omit<SessionSummary, 'id'>): void {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO summaries (project_id, session_id, summary, created_at)\r\n VALUES (?, ?, ?, ?)`,\r\n [summary.projectId, summary.sessionId, summary.summary, summary.createdAt],\r\n );\r\n persist();\r\n}\r\n\r\nexport function getProjectSummaries(projectId: string, limit = 20): SessionSummary[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM summaries WHERE project_id = ? ORDER BY created_at DESC LIMIT ?`,\r\n [projectId, limit],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n sessionId: row[2] as string,\r\n summary: row[3] as string,\r\n createdAt: row[4] as number,\r\n }));\r\n}\r\n\r\n// --- Script Index ---\r\n\r\nexport function upsertScript(entry: Omit<ScriptEntry, 'id'>): void {\r\n const d = getDb();\r\n const existing = d.exec(\r\n `SELECT id FROM script_index WHERE project_id = ? AND path = ?`,\r\n [entry.projectId, entry.path],\r\n );\r\n\r\n if (existing[0]?.values.length) {\r\n d.run(\r\n `UPDATE script_index SET class_name = ?, summary = ?, line_count = ?, last_hash = ?, updated_at = ?\r\n WHERE project_id = ? AND path = ?`,\r\n [\r\n entry.className,\r\n entry.summary ?? null,\r\n entry.lineCount ?? null,\r\n entry.lastHash ?? null,\r\n entry.updatedAt,\r\n entry.projectId,\r\n entry.path,\r\n ],\r\n );\r\n } else {\r\n d.run(\r\n `INSERT INTO script_index (project_id, path, class_name, summary, line_count, last_hash, updated_at)\r\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\r\n [\r\n entry.projectId,\r\n entry.path,\r\n entry.className,\r\n entry.summary ?? null,\r\n entry.lineCount ?? null,\r\n entry.lastHash ?? null,\r\n entry.updatedAt,\r\n ],\r\n );\r\n }\r\n persist();\r\n}\r\n\r\nexport function getScriptIndex(\r\n projectId: string,\r\n): { path: string; summary?: string; className: string }[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT path, summary, class_name FROM script_index WHERE project_id = ? ORDER BY path`,\r\n [projectId],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n path: row[0] as string,\r\n summary: (row[1] as string) || undefined,\r\n className: row[2] as string,\r\n }));\r\n}\r\n\r\nexport function getScriptEntry(projectId: string, scriptPath: string): ScriptEntry | null {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM script_index WHERE project_id = ? AND path = ?`,\r\n [projectId, scriptPath],\r\n );\r\n if (!result[0]?.values.length) return null;\r\n const row = result[0].values[0];\r\n return {\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n path: row[2] as string,\r\n className: row[3] as string,\r\n summary: (row[4] as string) || undefined,\r\n lineCount: (row[5] as number) || undefined,\r\n lastHash: (row[6] as string) || undefined,\r\n updatedAt: row[7] as number,\r\n };\r\n}\r\n\r\n// --- Decay ---\r\n\r\nexport function decayRelevance(projectId: string, factor = 0.95): void {\r\n const d = getDb();\r\n d.run(`UPDATE facts SET relevance = relevance * ? WHERE project_id = ?`, [factor, projectId]);\r\n persist();\r\n}\r\n","/**\r\n * INTERNAL_MEMORY — lessons learned and quirks that ship with Dominus.\r\n *\r\n * These are baked into every system prompt so the agent doesn't repeat\r\n * known mistakes. Add entries here when you discover a pattern that caused\r\n * a failure, an unintuitive API, or a workaround that should be remembered.\r\n *\r\n * Keep entries short, specific, and actionable. Prefer bullet points over prose.\r\n */\r\n\r\nexport const INTERNAL_MEMORY = `## Internal Memory — Known Quirks & Lessons\r\n\r\nThese are built-in lessons that ship with Dominus. Follow them exactly.\r\n\r\n### create_ui — property format\r\n- Each node accepts properties in **either** of two shapes:\r\n - **Flattened (preferred)**: props as top-level keys next to \\`ClassName\\`, \\`Name\\`, \\`Children\\`.\r\n \\`\\`\\`json\r\n { \"ClassName\": \"TextButton\", \"Name\": \"Btn\", \"Text\": \"OK\", \"Size\": [0, 100, 0, 40] }\r\n \\`\\`\\`\r\n - **Nested bag**: props grouped under \\`properties\\` / \\`Properties\\` / \\`props\\` / \\`Props\\`.\r\n \\`\\`\\`json\r\n { \"ClassName\": \"TextButton\", \"Name\": \"Btn\",\r\n \"properties\": { \"Text\": \"OK\", \"Size\": [0, 100, 0, 40] } }\r\n \\`\\`\\`\r\n- Do NOT mix a nested \\`properties\\` bag with flattened props of the same name — the bag wins.\r\n- Reserved keys (never treated as instance properties): \\`ClassName\\`, \\`className\\`, \\`Name\\`, \\`name\\`, \\`Children\\`, \\`children\\`, \\`properties\\`, \\`Properties\\`, \\`props\\`, \\`Props\\`.\r\n\r\n### build_multiple — schema is strict\r\n- Top-level keys only: \\`name\\`, \\`className\\`, \\`position\\`, \\`size\\`, \\`color\\`, \\`material\\`, \\`anchored\\`, \\`shape\\`, \\`transparency\\`, \\`parent\\`, \\`canCollide\\`.\r\n- Does NOT accept a nested \\`properties\\` bag. For anything outside those fields use \\`insert_instance\\` + \\`set_properties\\`.\r\n- \\`shape\\` values: \\`Block\\`, \\`Ball\\`, \\`Cylinder\\`, \\`Wedge\\`.\r\n\r\n### Color formats (accepted everywhere)\r\n- Hex: \\`\"#RRGGBB\"\\`\r\n- RGB string: \\`\"rgb(255, 128, 0)\"\\`\r\n- BrickColor name: \\`\"Bright red\"\\`, \\`\"Institutional white\"\\`, \\`\"Really black\"\\`, etc.\r\n- Array: \\`[r, g, b]\\` (0–1 floats) or \\`[255, 128, 0]\\` (auto-detected if any value > 1)\r\n\r\n### UDim2 / UDim / Vector2 / Color3 coercion (create_ui)\r\n- UDim2: \\`[xScale, xOffset, yScale, yOffset]\\` or \\`{XScale, XOffset, YScale, YOffset}\\`.\r\n- UDim: \\`[scale, offset]\\` or a plain number (treated as pixels).\r\n- Vector2 (e.g. \\`AnchorPoint\\`): \\`[x, y]\\` or \\`{x, y}\\`.\r\n- 2-element arrays are auto-disambiguated by property name (\\`AnchorPoint\\` → Vector2, \\`CornerRadius\\` → UDim).\r\n\r\n### Common GUI property names\r\n- GUI uses \\`Size\\`/\\`Position\\` as **UDim2** — never Vector3.\r\n- \\`BackgroundColor3\\`, \\`TextColor3\\`, \\`BorderColor3\\`, \\`ImageColor3\\` → Color3.\r\n- \\`Font\\` accepts a string enum name like \\`\"GothamBold\"\\`, \\`\"SourceSans\"\\`.\r\n- Enum properties take the string name: \\`\"Center\"\\`, \\`\"Left\"\\`, \\`\"Fit\"\\`.\r\n\r\n### Tool selection cheat-sheet\r\n- Single 3D part → \\`create_part\\`\r\n- Many 3D parts (tree, building, vehicle) → \\`build_multiple\\` with \\`groupName\\`\r\n- Full UI tree → \\`create_ui\\` (one call, never loop \\`insert_instance\\` for UI)\r\n- **Convert/export existing UI → \\`serialize_ui\\`** (NOT get_descendants_properties)\r\n- Adjusting an existing instance → \\`set_properties\\` (not \\`run_code\\`)\r\n- **Inspecting user's selection → \\`get_selection\\`, then \\`get_properties\\` or \\`serialize_ui\\`**\r\n- **Reading properties → \\`get_properties\\` (NEVER \\`run_code\\` with dump scripts)**\r\n- **Browsing the tree → \\`get_explorer\\`**\r\n- Anything exotic or procedural → \\`run_code\\` as last resort\r\n\r\n### NEVER use run_code for:\r\n- Getting properties of an instance → use \\`get_properties\\` or \\`serialize_ui\\`\r\n- Dumping selection info → use \\`inspect_selection\\` (ONE call does it all)\r\n- Inspecting an instance + its children → use \\`inspect_instance\\`\r\n- Converting UI to Roact/React → use \\`convert_ui_to_code\\`\r\n- Creating instances → use \\`create_part\\`, \\`create_ui\\`, \\`insert_instance\\`, \\`build_multiple\\`\r\n- Modifying properties → use \\`set_properties\\` or \\`bulk_set_properties\\`\r\n- Reading scripts → use \\`read_script\\`\r\n- Browsing the explorer → use \\`get_explorer\\`\r\n\\`run_code\\` is ONLY for procedural logic, terrain generation, raycasts, physics queries, or custom algorithms with no tool equivalent.\r\n\r\n### Composite skill tools (prefer these over chaining)\r\n- \\`inspect_selection\\` — Returns paths + compact properties for all selected instances in ONE call. Use when user says \"my selection\" or \"what I selected\".\r\n- \\`inspect_instance\\` — Returns compact properties + children tree for a single instance in ONE call. Combines get_properties + get_explorer.\r\n- \\`convert_ui_to_code\\` — Serializes a UI tree and generates a Roact/React component. Use when user says \"turn this into a component\" or \"convert to React\".\r\n\r\n### Verification habits\r\n- After a build, call \\`get_explorer\\` or \\`get_selection\\` to confirm the tree looks right.\r\n- After editing a script, read it back.\r\n- After \\`run_code\\`, check \\`get_output\\` for errors.\r\n\r\n### serialize_ui — the RIGHT tool for UI conversion\r\n- **Use \\`serialize_ui\\` when converting existing UI to Roact/React/Fusion components.** It returns a minimal JSON tree with only non-default properties, already in JSON-friendly formats.\r\n- **Do NOT use \\`get_descendants_properties\\` for UI conversion** — it returns a flat list with ~50+ properties per instance (including read-only, deprecated, nil, and default values), which bloats context and confuses conversion.\r\n- \\`serialize_ui\\` output maps 1:1 to \\`create_ui\\` input — you can round-trip UI through it.\r\n- The tree structure preserves parent-child hierarchy, so Roact/React children mapping is direct.\r\n\r\n### UI → Roact/React conversion cheat-sheet\r\n- \\`serialize_ui\\` path → JSON tree → map each node to \\`Roact.createElement(ClassName, props, childrenDict)\\`\r\n- UDim2 arrays \\`[xS, xO, yS, yO]\\` → \\`UDim2.new(xS, xO, yS, yO)\\`\r\n- Color3 hex strings → \\`Color3.fromHex(\"#RRGGBB\")\\`\r\n- Vector2 arrays → \\`Vector2.new(x, y)\\`\r\n- UDim arrays → \\`UDim.new(s, o)\\`\r\n- Enum strings like \\`\"Center\"\\` → \\`Enum.TextXAlignment.Center\\`\r\n- FontFace → \\`Font.new(family, weight, style)\\`\r\n- UI modifiers (UICorner, UIStroke, UIGradient, UIListLayout, UIPadding) are CHILDREN not props\r\n- Use instance Name as dictionary key in children table\r\n`;\r\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { z } from 'zod';\r\nimport { DominusServer, type StudioBridge } from '../transport/ws-server.js';\r\nimport { DominusClient, isPortInUse } from '../transport/ws-client.js';\r\nimport { CliMsg, type ExplorerNode, type ScriptContentPayload, type RunCodeResponsePayload, type SearchResultPayload, type OutputPayload, type SelectionPayload, type PropertyEntry, type TestResultPayload, type StudioTestResultPayload } from '../transport/protocol.js';\r\nimport { initMemoryStore, recallFacts, storeFact, getScriptIndex } from '../memory/store.js';\r\nimport { loadConfig } from '../config/config.js';\r\nimport { INTERNAL_MEMORY } from '../agent/internal-memory.js';\r\n\r\nlet bridge: StudioBridge;\r\n\r\nexport async function startMcpServer(): Promise<void> {\r\n const config = loadConfig();\r\n await initMemoryStore();\r\n\r\n const portTaken = await isPortInUse(config.port);\r\n if (portTaken) {\r\n const client = new DominusClient(config.port);\r\n await client.connect();\r\n bridge = client;\r\n } else {\r\n const server = new DominusServer(config.port);\r\n await server.start();\r\n bridge = server;\r\n }\r\n\r\n const mcp = new McpServer({\r\n name: 'dominus',\r\n version: '0.5.8',\r\n }, {\r\n instructions: INTERNAL_MEMORY,\r\n });\r\n\r\n // --- Helpers: safe Lua string generation ---\r\n /** Escape a string for safe embedding in Lua code */\r\n function luaStr(s: string): string {\r\n return `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r')}\"`;\r\n }\r\n /** Convert a dot-path like \"Workspace.Folder.Part\" to game[\"Workspace\"][\"Folder\"][\"Part\"] */\r\n function resolvePath(dotPath: string): string {\r\n const parts = dotPath.split('.');\r\n let r = 'game';\r\n for (const p of parts) r += `[${luaStr(p)}]`;\r\n return r;\r\n }\r\n\r\n // --- Code Generation Helpers ---\r\n\r\n /** Round a number to 3 decimal places, drop trailing zeros. Integers stay as-is. */\r\n function cleanNum(n: number): string {\r\n if (Number.isInteger(n)) return String(n);\r\n // Round to 3 decimals, strip trailing zeros\r\n const rounded = Math.round(n * 1000) / 1000;\r\n return String(rounded);\r\n }\r\n\r\n /** Convert a serialized UI tree node into a Roact/React createElement call */\r\n function generateComponentCode(\r\n tree: Record<string, unknown>,\r\n componentName: string,\r\n framework: string,\r\n ): string {\r\n const isReact = framework === 'react';\r\n const lib = isReact ? 'React' : 'Roact';\r\n\r\n const lines: string[] = [];\r\n lines.push(`local ${lib} = require(game.ReplicatedStorage.Packages.${isReact ? 'React' : 'Roact'})`);\r\n if (isReact) {\r\n lines.push(`local e = React.createElement`);\r\n } else {\r\n lines.push(`local e = Roact.createElement`);\r\n }\r\n lines.push('');\r\n\r\n // Collect all ClassName types used so we can note them\r\n lines.push(`local function ${componentName}()`);\r\n lines.push(`\\treturn ${renderNode(tree, 1)}`);\r\n lines.push('end');\r\n lines.push('');\r\n lines.push(`return ${componentName}`);\r\n\r\n return lines.join('\\n');\r\n }\r\n\r\n function renderNode(node: Record<string, unknown>, depth: number): string {\r\n const indent = '\\t'.repeat(depth);\r\n const indent2 = '\\t'.repeat(depth + 1);\r\n const className = (node.ClassName as string) || 'Frame';\r\n const children = (node.Children as Record<string, unknown>[]) || [];\r\n const name = node.Name as string | undefined;\r\n\r\n // Build props table\r\n const props: string[] = [];\r\n const skipKeys = new Set(['ClassName', 'Name', 'Children', 'className', 'name', 'children']);\r\n for (const [key, val] of Object.entries(node)) {\r\n if (skipKeys.has(key)) continue;\r\n props.push(`${indent2}${key} = ${luaValue(val, depth + 1)},`);\r\n }\r\n\r\n // Build children table\r\n const childEntries: string[] = [];\r\n for (const child of children) {\r\n const childName = (child.Name as string) || (child.ClassName as string) || 'Child';\r\n childEntries.push(`${indent2}${childName} = ${renderNode(child, depth + 1)},`);\r\n }\r\n\r\n // Combine\r\n const hasProps = props.length > 0;\r\n const hasChildren = childEntries.length > 0;\r\n\r\n if (!hasProps && !hasChildren) {\r\n return `e(\"${className}\", {})`;\r\n }\r\n\r\n const parts: string[] = [];\r\n parts.push(`e(\"${className}\", {`);\r\n if (hasProps) {\r\n parts.push(...props);\r\n }\r\n if (hasChildren) {\r\n parts.push(`${indent2}}, {`);\r\n parts.push(...childEntries);\r\n parts.push(`${indent}})`);\r\n } else {\r\n parts.push(`${indent}})`);\r\n }\r\n\r\n return parts.join('\\n');\r\n }\r\n\r\n function luaValue(val: unknown, _depth: number): string {\r\n if (val === null || val === undefined) return 'nil';\r\n if (typeof val === 'boolean') return String(val);\r\n if (typeof val === 'number') return cleanNum(val);\r\n if (typeof val === 'string') {\r\n // Detect special Roblox types from serialize_ui output\r\n if (val.startsWith('#') && val.length === 7) {\r\n return `Color3.fromHex(\"${val}\")`;\r\n }\r\n // Enum-like strings (single word, PascalCase)\r\n if (/^[A-Z][a-zA-Z]+$/.test(val)) {\r\n return `\"${val}\"`; // keep as string, Roact handles enum coercion\r\n }\r\n return `\"${val.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`;\r\n }\r\n if (Array.isArray(val)) {\r\n // UDim2: [xS, xO, yS, yO]\r\n if (val.length === 4 && val.every(v => typeof v === 'number')) {\r\n return `UDim2.new(${val.map(cleanNum).join(', ')})`;\r\n }\r\n // Vector2 / UDim: [x, y]\r\n if (val.length === 2 && val.every(v => typeof v === 'number')) {\r\n return `Vector2.new(${val.map(cleanNum).join(', ')})`;\r\n }\r\n // Color3: [r, g, b]\r\n if (val.length === 3 && val.every(v => typeof v === 'number')) {\r\n const allSmall = val.every(v => (v as number) <= 1);\r\n if (allSmall) return `Color3.new(${val.map(cleanNum).join(', ')})`;\r\n return `Color3.fromRGB(${val.map(v => String(Math.round(v as number))).join(', ')})`;\r\n }\r\n return `{${val.map(v => luaValue(v, _depth)).join(', ')}}`;\r\n }\r\n if (typeof val === 'object') {\r\n const entries = Object.entries(val as Record<string, unknown>);\r\n if (entries.length === 0) return '{}';\r\n return `{\\n${entries.map(([k, v]) => `${'\\t'.repeat(_depth + 1)}${k} = ${luaValue(v, _depth + 1)}`).join(',\\n')}\\n${'\\t'.repeat(_depth)}}`;\r\n }\r\n return String(val);\r\n }\r\n\r\n // --- Studio Tools ---\r\n\r\n mcp.tool(\r\n 'read_script',\r\n 'Read the source code of a script in Roblox Studio',\r\n { path: z.string().describe('Full instance path, e.g. \"ServerScriptService.GameManager\"') },\r\n async ({ path }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<ScriptContentPayload>(CliMsg.GET_SCRIPT, { path });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'edit_script',\r\n 'Replace the entire source code of a script in Roblox Studio',\r\n {\r\n path: z.string().describe('Full instance path'),\r\n source: z.string().describe('New complete source code'),\r\n },\r\n async ({ path, source }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.SET_SCRIPT, { path, source });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'run_code',\r\n 'Execute arbitrary Luau code in Roblox Studio. LAST RESORT — only use when no dedicated tool exists. ' +\r\n 'Do NOT use for: reading properties (use get_properties/inspect_selection/serialize_ui), creating instances (use create_part/create_ui/insert_instance/build_multiple), ' +\r\n 'modifying properties (use set_properties/bulk_set_properties), or inspecting the tree (use get_explorer). ' +\r\n 'Valid uses: complex procedural generation, terrain algorithms, raycasting, physics queries, custom logic with no tool equivalent.',\r\n { code: z.string().describe('Luau code to execute') },\r\n async ({ code }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_explorer',\r\n 'Get the DataModel explorer tree from Roblox Studio',\r\n {\r\n rootPath: z.string().optional().describe('Root path to start from. Omit for entire tree.'),\r\n maxDepth: z.number().optional().default(3).describe('Maximum tree depth'),\r\n },\r\n async ({ rootPath, maxDepth }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ tree: ExplorerNode[] }>(CliMsg.GET_EXPLORER, {\r\n rootPath: rootPath ?? null,\r\n maxDepth,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_properties',\r\n 'Get all properties of a single instance in Roblox Studio. Returns property name, value, type, and category. For inspecting UI trees, prefer serialize_ui (structured tree) or get_descendants_properties (flat list with compact filtering).',\r\n {\r\n path: z.string().describe('Full instance path (e.g. \"Workspace.Part\", \"StarterGui.MyUI.Frame\")'),\r\n compact: z.boolean().optional().default(true).describe('Strip read-only, nil, deprecated, and default-valued properties (default true). Set false for full dump.'),\r\n },\r\n async ({ path, compact }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ properties: PropertyEntry[] }>(CliMsg.GET_PROPERTIES, { path, compact });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_descendants_properties',\r\n 'Easily get all descendants of a UI instance (or any instance) and all of their properties. By default uses compact mode which strips read-only, nil, deprecated, and default-valued properties to keep responses small.',\r\n { \r\n path: z.string().describe('Full instance path (e.g., \"Workspace.Part\", \"StarterGui.ScreenGui\")'),\r\n compact: z.boolean().optional().default(true).describe('Strip noisy/default properties (default true). Set false for full dump.'),\r\n outputFile: z.string().optional().describe('Optional file path to write to prevent limit errors/timeouts'),\r\n },\r\n async ({ path, compact, outputFile }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<unknown>(CliMsg.GET_DESCENDANTS_PROPERTIES, { path, compact, outputFile }, 1000 * 60 * 5);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'set_properties',\r\n 'Set properties on an instance in Roblox Studio',\r\n {\r\n path: z.string().describe('Full instance path'),\r\n properties: z.record(z.unknown()).describe('Key-value pairs of properties to set'),\r\n },\r\n async ({ path, properties }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.SET_PROPERTIES, { path, properties });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'insert_instance',\r\n 'Create a new instance in the Roblox Studio DataModel',\r\n {\r\n className: z.string().describe('Class name (e.g. \"Part\", \"Script\")'),\r\n parentPath: z.string().describe('Parent instance path'),\r\n name: z.string().describe('Name for the new instance'),\r\n properties: z.record(z.unknown()).optional().describe('Optional properties to set'),\r\n },\r\n async ({ className, parentPath, name, properties }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.INSERT_INSTANCE, {\r\n className, parentPath, name, properties: properties ?? {},\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'delete_instance',\r\n 'Delete an instance from the Roblox Studio DataModel',\r\n { path: z.string().describe('Full instance path to delete') },\r\n async ({ path }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.DELETE_INSTANCE, { path });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_selection',\r\n 'Get the currently selected instances in Roblox Studio. Returns paths and class names of all selected objects. ' +\r\n 'Use this FIRST when the user says \"my selection\" or \"what I have selected\". ' +\r\n 'Then use get_properties or serialize_ui on the returned paths to inspect details.',\r\n {},\r\n async () => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<SelectionPayload>(CliMsg.GET_SELECTION, {});\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'search_scripts',\r\n 'Search all scripts in Roblox Studio for a text pattern',\r\n {\r\n query: z.string().describe('Text to search for'),\r\n maxResults: z.number().optional().default(20).describe('Max results'),\r\n },\r\n async ({ query, maxResults }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<SearchResultPayload>(CliMsg.SEARCH_SCRIPTS, { query, maxResults });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_output',\r\n 'Get recent output log from Roblox Studio',\r\n {\r\n limit: z.number().optional().default(50).describe('Max entries'),\r\n level: z.enum(['info', 'warn', 'error']).optional().describe('Filter by level'),\r\n },\r\n async ({ limit, level }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ entries: OutputPayload[] }>(CliMsg.GET_OUTPUT, {\r\n limit, level: level ?? null,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_class_info',\r\n 'Look up the schema of any Roblox class using ReflectionService. Returns all properties (with types), methods (with parameters), and events. ' +\r\n 'ALWAYS use this before creating or modifying GUI elements to know correct property names and types.',\r\n { className: z.string().describe('Roblox class name, e.g. \"Frame\", \"TextLabel\", \"Part\", \"MeshPart\"') },\r\n async ({ className }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<unknown>(CliMsg.GET_REFLECTION, { className });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'create_ui',\r\n 'Create an entire UI tree in one call. Pass a declarative JSON tree — ClassName, Name, properties, Children. ' +\r\n 'All types auto-coerced in Luau (UDim2, Color3, Font, enums). 10x faster than run_code. ' +\r\n 'UDim2: [xScale, xOffset, yScale, yOffset]. Color3: \"#hex\" or \"rgb(r,g,b)\". Font: \"GothamBold\". Enums: string names.',\r\n {\r\n parent: z.string().optional().describe('Parent: \"StarterGui\", \"PlayerGui\", or path. Default: StarterGui'),\r\n tree: z.record(z.unknown()).describe(\r\n 'Root UI node: {ClassName, Name, properties..., Children: [{...}, ...]}. ' +\r\n 'UDim2 as [xScale, xOffset, yScale, yOffset], Color3 as \"#hex\", Font as \"GothamBold\"',\r\n ),\r\n animate: z.boolean().optional().describe('If true, task.wait() will be injected between creation of nodes so that the UI writes out dynamically.'),\r\n },\r\n async ({ parent, tree, animate }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ success: boolean; path?: string; instanceCount?: number; error?: string }>(\r\n CliMsg.BUILD_UI, { parent: parent ?? 'StarterGui', tree, animate },\r\n );\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'run_tests',\r\n 'Run tests by requiring ModuleScripts matching test naming conventions (*.test, *.spec, *Test, *Spec). Lightweight — does not enter Run/Play mode.',\r\n { testName: z.string().optional().describe('Specific test name, or omit to run all') },\r\n async ({ testName }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ results: TestResultPayload[] }>(CliMsg.RUN_TESTS, {\r\n testName: testName ?? null,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'execute_run_test',\r\n 'Start a Run mode test session using StudioTestService:ExecuteRunModeAsync(). ' +\r\n 'This actually enters Run mode in Studio. Pass args that server scripts can retrieve via GetTestArgs(). ' +\r\n 'Yields until EndTest() is called or the session stops. Returns the value from EndTest(). ' +\r\n 'Use for headless automated tests — no player, just server scripts.',\r\n { args: z.unknown().optional().describe('Arguments passed to the test session. Server scripts get this via StudioTestService:GetTestArgs()') },\r\n async ({ args }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<StudioTestResultPayload>(CliMsg.EXECUTE_RUN_TEST, { args: args ?? null }, 120_000);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'execute_play_test',\r\n 'Start a solo Play mode test session using StudioTestService:ExecutePlayModeAsync(). ' +\r\n 'This enters Play mode with a player character. Pass args that server scripts can retrieve via GetTestArgs(). ' +\r\n 'Yields until EndTest() is called or the session stops. Returns the value from EndTest(). ' +\r\n 'Use for tests needing a player character and full client-server simulation.',\r\n { args: z.unknown().optional().describe('Arguments passed to the test session. Server scripts get this via StudioTestService:GetTestArgs()') },\r\n async ({ args }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<StudioTestResultPayload>(CliMsg.EXECUTE_PLAY_TEST, { args: args ?? null }, 120_000);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- Builder Tools ---\r\n\r\n mcp.tool(\r\n 'create_part',\r\n 'Create a Part with position, size, color, material — all in one call. Faster than insert_instance + set_properties.',\r\n {\r\n name: z.string().describe('Name for the part'),\r\n parent: z.string().optional().describe('Parent path (default: Workspace)'),\r\n shape: z.enum(['Block', 'Ball', 'Cylinder', 'Wedge', 'CornerWedge']).optional().describe('Part shape'),\r\n position: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('World position'),\r\n size: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('Size in studs'),\r\n color: z.string().optional().describe('Hex \"#00FF00\", BrickColor name, or \"rgb(0,255,0)\"'),\r\n material: z.string().optional().describe('Plastic, Wood, Grass, Neon, Metal, etc.'),\r\n transparency: z.number().optional().describe('0=opaque, 1=invisible'),\r\n anchored: z.boolean().optional().describe('Anchored (default: true)'),\r\n canCollide: z.boolean().optional().describe('Has collision'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const properties: Record<string, unknown> = {};\r\n if (params.position) properties.Position = { X: params.position.x, Y: params.position.y, Z: params.position.z };\r\n if (params.size) properties.Size = { X: params.size.x, Y: params.size.y, Z: params.size.z };\r\n if (params.color) {\r\n const c = params.color;\r\n if (c.startsWith('#')) properties.Color = c;\r\n else if (c.startsWith('rgb')) {\r\n const m = c.match(/(\\d+)/g);\r\n if (m && m.length >= 3) properties.Color = { red: parseInt(m[0]), green: parseInt(m[1]), blue: parseInt(m[2]) };\r\n } else properties.BrickColor = c;\r\n }\r\n if (params.material) properties.Material = params.material;\r\n if (params.transparency !== undefined) properties.Transparency = params.transparency;\r\n if (params.anchored !== undefined) properties.Anchored = params.anchored;\r\n else properties.Anchored = true;\r\n if (params.canCollide !== undefined) properties.CanCollide = params.canCollide;\r\n if (params.shape && params.shape !== 'Block') properties.Shape = params.shape;\r\n\r\n const className = params.shape === 'Wedge' ? 'WedgePart' : params.shape === 'CornerWedge' ? 'CornerWedgePart' : 'Part';\r\n\r\n const res = await bridge.sendRequest<{ success: boolean; path?: string; error?: string }>(CliMsg.INSERT_INSTANCE, {\r\n className,\r\n parentPath: params.parent ?? 'Workspace',\r\n name: params.name,\r\n properties,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'clone_instance',\r\n 'Clone an existing instance, optionally rename it, move it, or offset its position',\r\n {\r\n path: z.string().describe('Path of instance to clone'),\r\n newName: z.string().optional().describe('Name for the clone'),\r\n newParent: z.string().optional().describe('Parent path for the clone'),\r\n offset: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('Position offset from original'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const lines = [`local orig = ${resolvePath(params.path)}`, `local clone = orig:Clone()`];\r\n if (params.newName) lines.push(`clone.Name = ${luaStr(params.newName)}`);\r\n if (params.newParent) {\r\n lines.push(`clone.Parent = ${resolvePath(params.newParent)}`);\r\n } else {\r\n lines.push(`clone.Parent = orig.Parent`);\r\n }\r\n if (params.offset) {\r\n lines.push(`if clone:IsA(\"BasePart\") then`);\r\n lines.push(` clone.Position = clone.Position + Vector3.new(${params.offset.x}, ${params.offset.y}, ${params.offset.z})`);\r\n lines.push(`end`);\r\n }\r\n lines.push(`print(\"Cloned: \" .. clone:GetFullName())`);\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code: lines.join('\\n') });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'group_instances',\r\n 'Group multiple instances into a Model or Folder. All listed instances become children of the new group.',\r\n {\r\n paths: z.array(z.string()).describe('Array of instance paths to group'),\r\n groupName: z.string().describe('Name for the group'),\r\n groupClass: z.enum(['Model', 'Folder']).optional().describe('Container class (default: Model)'),\r\n parent: z.string().optional().describe('Parent path (default: Workspace)'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const gc = params.groupClass ?? 'Model';\r\n const parent = params.parent ?? 'Workspace';\r\n\r\n const code = [\r\n `local group = Instance.new(${luaStr(gc)})`,\r\n `group.Name = ${luaStr(params.groupName)}`,\r\n `group.Parent = ${resolvePath(parent)}`,\r\n ...params.paths.map((p) => `${resolvePath(p)}.Parent = group`),\r\n `print(\"Grouped ${params.paths.length} instances into: \" .. group:GetFullName())`,\r\n ].join('\\n');\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'build_multiple',\r\n 'Create many parts/instances in one batch. Send an array of specs — all created in a single round-trip. Ideal for building trees, houses, vehicles. Supports hex colors, rgb() colors, and BrickColor names.',\r\n {\r\n parts: z.array(z.object({\r\n name: z.string(),\r\n className: z.string().optional(),\r\n parent: z.string().optional(),\r\n position: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional(),\r\n size: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional(),\r\n color: z.string().optional().describe('Hex \"#RRGGBB\", \"rgb(r,g,b)\", or BrickColor name'),\r\n material: z.string().optional().describe('Enum.Material name: Plastic, Wood, Neon, Glass, etc.'),\r\n transparency: z.number().optional(),\r\n anchored: z.boolean().optional(),\r\n canCollide: z.boolean().optional(),\r\n shape: z.enum(['Block', 'Ball', 'Cylinder', 'Wedge']).optional(),\r\n })).describe('Array of part specifications'),\r\n groupName: z.string().optional().describe('Group all parts into a Model with this name'),\r\n groupParent: z.string().optional().describe('Parent for the group (default: Workspace)'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const parts = params.parts;\r\n const groupName = params.groupName;\r\n const groupParent = params.groupParent ?? 'Workspace';\r\n\r\n const lines: string[] = [];\r\n if (groupName) {\r\n lines.push(`local _group = Instance.new(\"Model\")`);\r\n lines.push(`_group.Name = ${luaStr(groupName)}`);\r\n lines.push(`_group.Parent = ${resolvePath(groupParent)}`);\r\n }\r\n for (let i = 0; i < parts.length; i++) {\r\n const p = parts[i];\r\n const v = `_p${i}`;\r\n const cn = p.className ?? (p.shape === 'Wedge' ? 'WedgePart' : 'Part');\r\n lines.push(`local ${v} = Instance.new(${luaStr(cn)})`);\r\n lines.push(`${v}.Name = ${luaStr(p.name)}`);\r\n if (p.position) lines.push(`${v}.Position = Vector3.new(${p.position.x}, ${p.position.y}, ${p.position.z})`);\r\n if (p.size) lines.push(`${v}.Size = Vector3.new(${p.size.x}, ${p.size.y}, ${p.size.z})`);\r\n if (p.color) {\r\n if (p.color.startsWith('#')) {\r\n lines.push(`${v}.Color = Color3.fromHex(${luaStr(p.color)})`);\r\n } else if (p.color.startsWith('rgb(')) {\r\n const m = p.color.match(/rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/);\r\n if (m) lines.push(`${v}.Color = Color3.fromRGB(${m[1]}, ${m[2]}, ${m[3]})`);\r\n } else {\r\n lines.push(`${v}.BrickColor = BrickColor.new(${luaStr(p.color)})`);\r\n }\r\n }\r\n if (p.material) lines.push(`${v}.Material = Enum.Material.${p.material}`);\r\n if (p.transparency !== undefined) lines.push(`${v}.Transparency = ${p.transparency}`);\r\n lines.push(`${v}.Anchored = ${p.anchored ?? true}`);\r\n if (p.canCollide !== undefined) lines.push(`${v}.CanCollide = ${p.canCollide}`);\r\n if (p.shape && p.shape !== 'Block' && cn === 'Part') lines.push(`${v}.Shape = Enum.PartType.${p.shape}`);\r\n lines.push(`${v}.Parent = ${groupName ? '_group' : resolvePath(p.parent ?? 'Workspace')}`);\r\n }\r\n lines.push(`print(\"Built ${parts.length} parts${groupName ? ` in ${groupName}` : ''}\")`);\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code: lines.join('\\n') });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- UI Serialization ---\r\n\r\n mcp.tool(\r\n 'serialize_ui',\r\n 'Serialize an existing Roblox UI tree into a compact, create_ui-compatible JSON tree. ' +\r\n 'This is the reverse of create_ui — reads any GUI instance and returns a declarative JSON tree ' +\r\n 'with ClassName, Name, non-default properties (Color3 as hex, UDim2 as arrays, etc.), and Children. ' +\r\n 'Perfect for: converting existing UI to Roact/React components, cloning/templating, understanding UI structure, ' +\r\n 'or refactoring. Use this INSTEAD of get_descendants_properties when you need to recreate or convert UI.',\r\n {\r\n path: z.string().describe('Instance path to serialize (e.g. \"StarterGui.MyScreenGui\")'),\r\n maxDepth: z.number().optional().default(50).describe('Maximum tree depth (default 50)'),\r\n },\r\n async ({ path, maxDepth }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ success: boolean; tree?: unknown; error?: string }>(\r\n CliMsg.SERIALIZE_UI, { path, maxDepth }, 1000 * 60 * 2,\r\n );\r\n if (!res.payload.success) {\r\n return { content: [{ type: 'text' as const, text: `Error: ${res.payload.error ?? 'Serialization failed'}` }] };\r\n }\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload.tree, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- Composite Skill Tools ---\r\n // Higher-level tools that combine multiple operations into a single call.\r\n // These prevent LLMs from falling back to run_code for common workflows.\r\n\r\n mcp.tool(\r\n 'inspect_selection',\r\n 'Inspect the user\\'s current selection in Roblox Studio. Returns the selected instance paths AND their properties (compact) in a single call. ' +\r\n 'Use this FIRST when the user says \"my selection\", \"what I selected\", or \"the selected thing\". ' +\r\n 'Much better than calling get_selection + get_properties separately.',\r\n {},\r\n async () => {\r\n assertConnected();\r\n // Step 1: get selection\r\n const selRes = await bridge.sendRequest<SelectionPayload>(CliMsg.GET_SELECTION, {});\r\n const paths: string[] = selRes.payload?.paths ?? [];\r\n if (paths.length === 0) {\r\n return { content: [{ type: 'text' as const, text: 'No instances selected in Studio.' }] };\r\n }\r\n\r\n // Step 2: get compact properties for each selected instance\r\n const results: Record<string, unknown> = {};\r\n for (const p of paths.slice(0, 10)) { // cap at 10 to avoid huge payloads\r\n try {\r\n const propRes = await bridge.sendRequest<{ properties?: PropertyEntry[]; error?: string }>(\r\n CliMsg.GET_PROPERTIES, { path: p, compact: true },\r\n );\r\n results[p] = propRes.payload.properties ?? propRes.payload;\r\n } catch {\r\n results[p] = { error: 'Failed to read properties' };\r\n }\r\n }\r\n if (paths.length > 10) {\r\n results['_truncated'] = `${paths.length - 10} more instances not shown`;\r\n }\r\n\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(results, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'inspect_instance',\r\n 'Inspect a single instance: returns its compact properties AND its children tree in one call. ' +\r\n 'Combines get_properties + get_explorer into a single round-trip. ' +\r\n 'Use when you need to understand an instance and its subtree.',\r\n {\r\n path: z.string().describe('Full instance path (e.g. \"Workspace.MyModel\")'),\r\n childDepth: z.number().optional().default(2).describe('How deep to show the children tree (default 2)'),\r\n },\r\n async ({ path, childDepth }) => {\r\n assertConnected();\r\n // Parallel: get properties + get children tree\r\n const [propRes, treeRes] = await Promise.all([\r\n bridge.sendRequest<{ properties?: PropertyEntry[]; error?: string }>(\r\n CliMsg.GET_PROPERTIES, { path, compact: true },\r\n ),\r\n bridge.sendRequest<{ tree?: ExplorerNode; error?: string }>(\r\n CliMsg.GET_EXPLORER, { rootPath: path, maxDepth: childDepth ?? 2 },\r\n ),\r\n ]);\r\n\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({\r\n properties: propRes.payload.properties ?? propRes.payload,\r\n children: treeRes.payload.tree ?? treeRes.payload,\r\n }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'convert_ui_to_code',\r\n 'Convert an existing Roblox UI tree into Roact/React-lua component code. ' +\r\n 'Serializes the UI at the given path, then generates a ready-to-use Luau component. ' +\r\n 'Use when the user asks to \"turn this into a component\", \"convert to React\", or \"make a Roact version\".',\r\n {\r\n path: z.string().describe('Path to the UI instance to convert (e.g. \"StarterGui.MyScreenGui.MainFrame\")'),\r\n framework: z.enum(['roact', 'react']).optional().default('react').describe('Target framework: \"roact\" (legacy) or \"react\" (react-lua, default)'),\r\n componentName: z.string().optional().describe('Name for the generated component (defaults to instance Name)'),\r\n },\r\n async ({ path, framework, componentName }) => {\r\n assertConnected();\r\n // Step 1: serialize the UI tree\r\n const res = await bridge.sendRequest<{ success: boolean; tree?: Record<string, unknown>; error?: string }>(\r\n CliMsg.SERIALIZE_UI, { path, maxDepth: 50 }, 1000 * 60 * 2,\r\n );\r\n if (!res.payload.success || !res.payload.tree) {\r\n return { content: [{ type: 'text' as const, text: `Error serializing UI: ${res.payload.error ?? 'Unknown error'}` }] };\r\n }\r\n\r\n const tree = res.payload.tree;\r\n const name = componentName || (tree.Name as string) || 'GeneratedComponent';\r\n const fw = framework || 'react';\r\n\r\n // Step 2: generate code from the serialized tree\r\n const code = generateComponentCode(tree, name, fw);\r\n return { content: [{ type: 'text' as const, text: code }] };\r\n },\r\n );\r\n\r\n // --- Memory Tools ---\r\n\r\n mcp.tool(\r\n 'recall_memory',\r\n 'Search persistent memory for facts about the current Roblox project',\r\n { query: z.string().describe('What to search for') },\r\n async ({ query }) => {\r\n const facts = recallFacts('current', query, 15);\r\n const scripts = getScriptIndex('current');\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({ facts: facts.map(f => f.content), scriptIndex: scripts }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'remember',\r\n 'Store a fact about the project in persistent memory for future sessions',\r\n {\r\n fact: z.string().describe('The fact to remember'),\r\n category: z.enum(['architecture', 'pattern', 'preference', 'bug', 'api', 'general']).describe('Category'),\r\n },\r\n async ({ fact, category }) => {\r\n const now = Date.now();\r\n storeFact({ projectId: 'current', content: fact, category, source: 'mcp', relevance: 1.0, createdAt: now, accessedAt: now });\r\n return { content: [{ type: 'text' as const, text: `Remembered: ${fact}` }] };\r\n },\r\n );\r\n\r\n // --- Resources ---\r\n\r\n mcp.resource(\r\n 'studio://status',\r\n 'studio://status',\r\n async () => {\r\n const info = bridge.getConnectionInfo();\r\n return {\r\n contents: [{\r\n uri: 'studio://status',\r\n text: JSON.stringify({\r\n connected: bridge.isConnected(),\r\n placeName: info?.placeName,\r\n placeId: info?.placeId,\r\n studioVersion: info?.studioVersion,\r\n port: bridge.getPort(),\r\n }, null, 2),\r\n mimeType: 'application/json',\r\n }],\r\n };\r\n },\r\n );\r\n\r\n // Start the MCP server on stdio\r\n const transport = new StdioServerTransport();\r\n await mcp.connect(transport);\r\n}\r\n\r\nfunction assertConnected(): void {\r\n if (!bridge.isConnected()) {\r\n throw new Error(\r\n 'Roblox Studio is not connected. Open Studio and click the Dominus plugin Connect button.',\r\n );\r\n }\r\n}\r\n","import { startMcpServer } from './server.js';\r\n\r\nstartMcpServer().catch((err) => {\r\n console.error('Failed to start Dominus MCP server:', err);\r\n process.exit(1);\r\n});\r\n"]}
1
+ {"version":3,"sources":["../src/transport/protocol.ts","../src/transport/ws-server.ts","../src/transport/ws-client.ts","../src/config/config.ts","../src/memory/store.ts","../src/agent/internal-memory.ts","../src/mcp/server.ts","../src/mcp/index.ts"],"names":["EventEmitter","WebSocket","fs","result","path"],"mappings":"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","file":"mcp.js","sourcesContent":["import { nanoid } from 'nanoid';\r\n\r\nexport interface WsMessage<T = unknown> {\r\n id: string;\r\n type: string;\r\n payload: T;\r\n ts: number;\r\n}\r\n\r\nexport const StudioMsg = {\r\n CONNECTED: 'studio:connected',\r\n DISCONNECTED: 'studio:disconnected',\r\n EXPLORER: 'studio:explorer',\r\n OUTPUT: 'studio:output',\r\n ERROR: 'studio:error',\r\n SELECTION: 'studio:selection',\r\n SCRIPT_CONTENT: 'studio:script:content',\r\n SCRIPT_CHANGED: 'studio:script:changed',\r\n RESPONSE: 'studio:response',\r\n REFLECTION: 'studio:reflection',\r\n TEST_RESULTS: 'studio:test:results',\r\n} as const;\r\n\r\nexport const CliMsg = {\r\n GET_EXPLORER: 'cli:get:explorer',\r\n GET_SCRIPT: 'cli:get:script',\r\n SET_SCRIPT: 'cli:set:script',\r\n RUN_CODE: 'cli:run',\r\n GET_PROPERTIES: 'cli:get:properties',\r\n GET_DESCENDANTS_PROPERTIES: 'cli:get:descendants:properties',\r\n SET_PROPERTIES: 'cli:set:properties',\r\n INSERT_INSTANCE: 'cli:insert',\r\n DELETE_INSTANCE: 'cli:delete',\r\n GET_SELECTION: 'cli:get:selection',\r\n SELECT: 'cli:select',\r\n SEARCH_SCRIPTS: 'cli:search:scripts',\r\n GET_OUTPUT: 'cli:get:output',\r\n RUN_TESTS: 'cli:run:tests',\r\n EXECUTE_RUN_TEST: 'cli:test:run',\r\n EXECUTE_PLAY_TEST: 'cli:test:play',\r\n END_TEST: 'cli:test:end',\r\n BUILD_UI: 'cli:build:ui',\r\n GET_REFLECTION: 'cli:get:reflection',\r\n UPLOAD_ASSET: 'cli:upload:asset',\r\n SERIALIZE_UI: 'cli:serialize:ui',\r\n MOVE_INSTANCE: 'cli:move:instance',\r\n UNDO: 'cli:undo',\r\n REDO: 'cli:redo',\r\n BULK_SET_PROPERTIES: 'cli:bulk:set:properties',\r\n FIND_REPLACE_SCRIPTS: 'cli:find:replace:scripts',\r\n} as const;\r\n\r\nexport type StudioMsgType = (typeof StudioMsg)[keyof typeof StudioMsg];\r\nexport type CliMsgType = (typeof CliMsg)[keyof typeof CliMsg];\r\n\r\nexport interface ExplorerNode {\r\n name: string;\r\n className: string;\r\n path: string;\r\n children?: ExplorerNode[];\r\n}\r\n\r\nexport interface StudioConnectedPayload {\r\n studioVersion: string;\r\n placeId?: number;\r\n placeName?: string;\r\n engineVersion?: string;\r\n}\r\n\r\nexport interface ScriptContentPayload {\r\n path: string;\r\n className: 'Script' | 'LocalScript' | 'ModuleScript';\r\n source: string;\r\n lineCount: number;\r\n}\r\n\r\nexport interface ScriptChangedPayload {\r\n path: string;\r\n source: string;\r\n}\r\n\r\nexport interface OutputPayload {\r\n message: string;\r\n level: 'info' | 'warn' | 'error';\r\n timestamp: number;\r\n source?: string;\r\n}\r\n\r\nexport interface SelectionPayload {\r\n paths: string[];\r\n classNames: string[];\r\n}\r\n\r\nexport interface PropertyEntry {\r\n name: string;\r\n value: string;\r\n type: string;\r\n category?: string;\r\n}\r\n\r\nexport interface TestResultPayload {\r\n name: string;\r\n passed: boolean;\r\n duration: number;\r\n error?: string;\r\n}\r\n\r\nexport interface StudioTestPayload {\r\n args?: unknown;\r\n}\r\n\r\nexport interface StudioTestResultPayload {\r\n success: boolean;\r\n result?: unknown;\r\n error?: string;\r\n duration?: number;\r\n}\r\n\r\nexport interface ReflectionPayload {\r\n className: string;\r\n properties: { name: string; type: string; category: string }[];\r\n methods: { name: string; parameters: string[] }[];\r\n events: { name: string; parameters: string[] }[];\r\n}\r\n\r\nexport interface RunCodePayload {\r\n code: string;\r\n}\r\n\r\nexport interface RunCodeResponsePayload {\r\n output: string;\r\n error?: string;\r\n duration: number;\r\n}\r\n\r\nexport interface SearchScriptsPayload {\r\n query: string;\r\n maxResults?: number;\r\n}\r\n\r\nexport interface SearchResultPayload {\r\n results: {\r\n path: string;\r\n className: string;\r\n matches: { line: number; text: string }[];\r\n }[];\r\n}\r\n\r\nexport interface InsertInstancePayload {\r\n className: string;\r\n parentPath: string;\r\n name: string;\r\n properties?: Record<string, unknown>;\r\n}\r\n\r\nexport interface SetPropertiesPayload {\r\n path: string;\r\n properties: Record<string, unknown>;\r\n}\r\n\r\nexport function createMessage<T>(type: string, payload: T): WsMessage<T> {\r\n return { id: nanoid(), type, payload, ts: Date.now() };\r\n}\r\n\r\nexport function createRequest<T>(type: string, payload: T): WsMessage<T> {\r\n return createMessage(type, payload);\r\n}\r\n\r\nexport function parseMessage(raw: string): WsMessage {\r\n try {\r\n return JSON.parse(raw) as WsMessage;\r\n } catch {\r\n throw new Error(`Failed to parse WebSocket message: ${raw.slice(0, 100)}`);\r\n }\r\n}\r\n\r\nexport function serializeMessage(msg: WsMessage): string {\r\n return JSON.stringify(msg);\r\n}\r\n","import { WebSocketServer, WebSocket } from 'ws';\nimport { EventEmitter } from 'node:events';\nimport {\n parseMessage,\n serializeMessage,\n createMessage,\n StudioMsg,\n type WsMessage,\n type StudioConnectedPayload,\n} from './protocol.js';\n\nexport interface StudioConnection {\n ws: WebSocket;\n studioVersion?: string;\n placeId?: number;\n placeName?: string;\n connectedAt: number;\n}\n\nexport interface PlaceInfo {\n placeId: number;\n placeName?: string;\n studioVersion?: string;\n connectedAt: number;\n}\n\nexport interface StudioBridge extends EventEmitter {\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs?: number): Promise<WsMessage<T>>;\n sendNotification(type: string, payload: unknown): void;\n isConnected(): boolean;\n getConnectionInfo(): StudioConnection | null;\n getPort(): number;\n stop(): Promise<void>;\n /** List all connected Studio instances */\n listConnections(): PlaceInfo[];\n /** Get/set which placeId is the active target. 0 = auto (single connection). */\n getActivePlaceId(): number;\n setActivePlaceId(placeId: number): void;\n}\n\nexport class DominusServer extends EventEmitter implements StudioBridge {\n private wss: WebSocketServer | null = null;\n /** All connected Studio instances, keyed by placeId (0 for unknown) */\n private studioClients = new Map<number, StudioConnection>();\n /** Reverse lookup: ws → placeId */\n private wsToPlaceId = new Map<WebSocket, number>();\n /** Which placeId to target. 0 = auto-select if only one is connected. */\n private activePlaceId = 0;\n private controllers = new Set<WebSocket>();\n private pendingRequests = new Map<\n string,\n { resolve: (msg: WsMessage) => void; reject: (err: Error) => void; timer: ReturnType<typeof setTimeout> }\n >();\n private relayRequests = new Map<string, WebSocket>();\n private port: number;\n\n constructor(port = 18088) {\n super();\n this.port = port;\n }\n\n start(maxRetries = 0): Promise<void> {\n return new Promise((resolve, reject) => {\n const tryPort = (port: number, attempt: number) => {\n const wss = new WebSocketServer({ port });\n\n wss.on('listening', () => {\n this.wss = wss;\n this.port = port;\n this.wss.on('connection', (ws) => this.handleConnection(ws));\n this.emit('server:started', { port });\n resolve();\n });\n\n wss.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE' && attempt < maxRetries) {\n wss.close();\n tryPort(port + 1, attempt + 1);\n } else {\n this.emit('server:error', err);\n reject(err);\n }\n });\n };\n\n tryPort(this.port, 0);\n });\n }\n\n private handleConnection(ws: WebSocket): void {\n let identified = false;\n\n ws.on('message', (raw) => {\n try {\n const msg = parseMessage(raw.toString());\n\n if (!identified) {\n if (msg.type === StudioMsg.CONNECTED) {\n identified = true;\n this.setStudioClient(ws, msg);\n return;\n }\n if (msg.type === 'controller:connect') {\n identified = true;\n this.addController(ws);\n ws.send(serializeMessage(createMessage('controller:welcome', {\n studioConnected: this.isConnected(),\n port: this.port,\n connections: this.listConnections(),\n activePlaceId: this.activePlaceId,\n })));\n return;\n }\n }\n\n if (this.controllers.has(ws)) {\n this.handleControllerMessage(ws, msg);\n } else {\n this.handleStudioMessage(ws, msg);\n }\n } catch (err) {\n this.emit('server:error', err);\n }\n });\n\n ws.on('close', () => {\n if (this.controllers.has(ws)) {\n this.controllers.delete(ws);\n for (const [id, controllerWs] of this.relayRequests) {\n if (controllerWs === ws) this.relayRequests.delete(id);\n }\n } else {\n const placeId = this.wsToPlaceId.get(ws);\n if (placeId !== undefined) {\n const conn = this.studioClients.get(placeId);\n this.studioClients.delete(placeId);\n this.wsToPlaceId.delete(ws);\n this.emit('studio:disconnected', { placeId, placeName: conn?.placeName });\n this.broadcastToControllers('studio:disconnected', { placeId, placeName: conn?.placeName });\n // Reject pending requests that were targeting this ws\n for (const [id, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(`Studio disconnected (place ${placeId})`));\n this.pendingRequests.delete(id);\n }\n // If the active place disconnected, reset to auto\n if (this.activePlaceId === placeId) {\n this.activePlaceId = 0;\n }\n }\n }\n });\n\n ws.on('error', (err) => {\n this.emit('server:error', err);\n });\n }\n\n private setStudioClient(ws: WebSocket, msg: WsMessage): void {\n const payload = msg.payload as StudioConnectedPayload;\n const placeId = payload.placeId ?? 0;\n\n // If same placeId reconnects, close the old one\n const existing = this.studioClients.get(placeId);\n if (existing && existing.ws !== ws) {\n existing.ws.close();\n this.wsToPlaceId.delete(existing.ws);\n }\n\n const conn: StudioConnection = {\n ws,\n connectedAt: Date.now(),\n studioVersion: payload.studioVersion,\n placeId,\n placeName: payload.placeName,\n };\n this.studioClients.set(placeId, conn);\n this.wsToPlaceId.set(ws, placeId);\n\n this.emit('studio:connected', { ...payload, placeId });\n this.broadcastToControllers('studio:connected', { ...payload, placeId });\n }\n\n private addController(ws: WebSocket): void {\n this.controllers.add(ws);\n this.emit('controller:connected');\n }\n\n private broadcastToControllers(type: string, payload: unknown): void {\n const msg = serializeMessage(createMessage(type, payload));\n for (const ws of this.controllers) {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(msg);\n }\n }\n }\n\n private handleControllerMessage(controllerWs: WebSocket, msg: WsMessage): void {\n const target = this.resolveTarget();\n if (!target || target.ws.readyState !== WebSocket.OPEN) {\n controllerWs.send(serializeMessage({\n id: msg.id,\n type: StudioMsg.RESPONSE,\n payload: { error: this.getTargetError() },\n ts: Date.now(),\n }));\n return;\n }\n\n this.relayRequests.set(msg.id, controllerWs);\n target.ws.send(serializeMessage(msg));\n }\n\n private handleStudioMessage(ws: WebSocket, msg: WsMessage): void {\n if (msg.type === StudioMsg.CONNECTED) {\n // Re-handshake — update existing connection info\n const payload = msg.payload as StudioConnectedPayload;\n const placeId = this.wsToPlaceId.get(ws);\n if (placeId !== undefined) {\n const conn = this.studioClients.get(placeId);\n if (conn) {\n conn.studioVersion = payload.studioVersion;\n conn.placeId = payload.placeId;\n conn.placeName = payload.placeName;\n }\n }\n this.emit('studio:connected', payload);\n this.broadcastToControllers('studio:connected', payload);\n return;\n }\n\n if (msg.type === StudioMsg.RESPONSE) {\n // Check if this is a relayed request from a controller\n const controllerWs = this.relayRequests.get(msg.id);\n if (controllerWs && controllerWs.readyState === WebSocket.OPEN) {\n controllerWs.send(serializeMessage(msg));\n this.relayRequests.delete(msg.id);\n return;\n }\n\n // Otherwise handle locally (MCP or direct)\n const pending = this.pendingRequests.get(msg.id);\n if (pending) {\n clearTimeout(pending.timer);\n pending.resolve(msg);\n this.pendingRequests.delete(msg.id);\n }\n return;\n }\n\n // Forward events to controllers and local listeners\n this.emit(msg.type, msg.payload);\n this.emit('message', msg);\n this.broadcastToControllers(msg.type, msg.payload);\n }\n\n /** Resolve which Studio connection to target */\n private resolveTarget(): StudioConnection | null {\n if (this.studioClients.size === 0) return null;\n\n // Explicit active place\n if (this.activePlaceId !== 0) {\n const conn = this.studioClients.get(this.activePlaceId);\n if (conn && conn.ws.readyState === WebSocket.OPEN) return conn;\n return null;\n }\n\n // Auto: if exactly one connection, use it\n if (this.studioClients.size === 1) {\n const conn = this.studioClients.values().next().value!;\n if (conn.ws.readyState === WebSocket.OPEN) return conn;\n return null;\n }\n\n // Multiple connections, no active set — return null (ambiguous)\n return null;\n }\n\n /** Generate an appropriate error message when no target found */\n private getTargetError(): string {\n if (this.studioClients.size === 0) return 'No Studio connection';\n if (this.activePlaceId !== 0) {\n return `Active place ${this.activePlaceId} is not connected. Use set_active_place or list_connections.`;\n }\n const places = [...this.studioClients.values()].map(c => `${c.placeName ?? 'Unknown'} (${c.placeId})`);\n return `Multiple Studio instances connected: ${places.join(', ')}. Use set_active_place to choose one.`;\n }\n\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs = 10000): Promise<WsMessage<T>> {\n return new Promise((resolve, reject) => {\n const target = this.resolveTarget();\n if (!target || target.ws.readyState !== WebSocket.OPEN) {\n reject(new Error(this.getTargetError()));\n return;\n }\n\n const msg = createMessage(type, payload);\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(msg.id);\n reject(new Error(`Request timed out: ${type}`));\n }, timeoutMs);\n\n this.pendingRequests.set(msg.id, {\n resolve: resolve as (msg: WsMessage) => void,\n reject,\n timer,\n });\n\n target.ws.send(serializeMessage(msg));\n });\n }\n\n sendNotification(type: string, payload: unknown): void {\n const target = this.resolveTarget();\n if (!target || target.ws.readyState !== WebSocket.OPEN) return;\n const msg = createMessage(type, payload);\n target.ws.send(serializeMessage(msg));\n }\n\n isConnected(): boolean {\n return this.resolveTarget() !== null;\n }\n\n getConnectionInfo(): StudioConnection | null {\n return this.resolveTarget();\n }\n\n listConnections(): PlaceInfo[] {\n return [...this.studioClients.values()]\n .filter(c => c.ws.readyState === WebSocket.OPEN)\n .map(c => ({\n placeId: c.placeId ?? 0,\n placeName: c.placeName,\n studioVersion: c.studioVersion,\n connectedAt: c.connectedAt,\n }));\n }\n\n getActivePlaceId(): number {\n return this.activePlaceId;\n }\n\n setActivePlaceId(placeId: number): void {\n this.activePlaceId = placeId;\n }\n\n getPort(): number {\n return this.port;\n }\n\n stop(): Promise<void> {\n return new Promise((resolve) => {\n for (const conn of this.studioClients.values()) {\n conn.ws.close();\n }\n this.studioClients.clear();\n this.wsToPlaceId.clear();\n for (const ws of this.controllers) {\n ws.close();\n }\n this.controllers.clear();\n for (const [, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error('Server shutting down'));\n }\n this.pendingRequests.clear();\n this.relayRequests.clear();\n\n if (this.wss) {\n this.wss.close(() => resolve());\n } else {\n resolve();\n }\n });\n }\n}\n","import { WebSocket } from 'ws';\r\nimport { EventEmitter } from 'node:events';\r\nimport {\r\n parseMessage,\r\n serializeMessage,\r\n createMessage,\r\n StudioMsg,\r\n type WsMessage,\r\n type StudioConnectedPayload,\r\n} from './protocol.js';\r\nimport type { StudioBridge, StudioConnection, PlaceInfo } from './ws-server.js';\r\n\r\n/**\r\n * Connects as a relay client to an existing DominusServer.\r\n * Has the same interface as DominusServer so the TUI/Agent\r\n * can use either transparently.\r\n */\r\nexport class DominusClient extends EventEmitter implements StudioBridge {\r\n private ws: WebSocket | null = null;\r\n private port: number;\r\n private studioConnected = false;\r\n private connections = new Map<number, Omit<StudioConnection, 'ws'>>();\r\n private activePlaceId = 0;\r\n private pendingRequests = new Map<\r\n string,\r\n { resolve: (msg: WsMessage) => void; reject: (err: Error) => void; timer: ReturnType<typeof setTimeout> }\r\n >();\r\n\r\n constructor(port = 18088) {\r\n super();\r\n this.port = port;\r\n }\r\n\r\n connect(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const url = `ws://localhost:${this.port}`;\r\n const ws = new WebSocket(url);\r\n\r\n ws.on('open', () => {\r\n this.ws = ws;\r\n ws.send(serializeMessage(createMessage('controller:connect', {})));\r\n this.emit('server:started', { port: this.port, relay: true });\r\n resolve();\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const msg = parseMessage(raw.toString());\r\n this.handleMessage(msg);\r\n } catch (err) {\r\n this.emit('server:error', err);\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.ws = null;\r\n this.studioConnected = false;\r\n this.emit('studio:disconnected');\r\n for (const [id, pending] of this.pendingRequests) {\r\n clearTimeout(pending.timer);\r\n pending.reject(new Error('Relay connection lost'));\r\n this.pendingRequests.delete(id);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n if (!this.ws) reject(err);\r\n this.emit('server:error', err);\r\n });\r\n });\r\n }\r\n\r\n private handleMessage(msg: WsMessage): void {\r\n if (msg.type === 'controller:welcome') {\r\n const p = msg.payload as {\r\n studioConnected: boolean;\r\n connections?: PlaceInfo[];\r\n activePlaceId?: number;\r\n };\r\n this.studioConnected = p.studioConnected;\r\n if (p.connections) {\r\n this.connections.clear();\r\n for (const c of p.connections) {\r\n this.connections.set(c.placeId, {\r\n connectedAt: c.connectedAt,\r\n studioVersion: c.studioVersion,\r\n placeId: c.placeId,\r\n placeName: c.placeName,\r\n });\r\n }\r\n }\r\n if (p.activePlaceId !== undefined) {\r\n this.activePlaceId = p.activePlaceId;\r\n }\r\n if (this.studioConnected) {\r\n this.emit('studio:connected', {});\r\n }\r\n return;\r\n }\r\n\r\n if (msg.type === 'studio:connected') {\r\n this.studioConnected = true;\r\n const payload = msg.payload as StudioConnectedPayload & { placeId?: number };\r\n const placeId = payload.placeId ?? 0;\r\n this.connections.set(placeId, {\r\n connectedAt: Date.now(),\r\n studioVersion: payload.studioVersion,\r\n placeId,\r\n placeName: payload.placeName,\r\n });\r\n this.emit('studio:connected', payload);\r\n return;\r\n }\r\n\r\n if (msg.type === 'studio:disconnected') {\r\n const payload = msg.payload as { placeId?: number };\r\n const placeId = payload.placeId ?? 0;\r\n this.connections.delete(placeId);\r\n if (this.connections.size === 0) {\r\n this.studioConnected = false;\r\n }\r\n if (this.activePlaceId === placeId) {\r\n this.activePlaceId = 0;\r\n }\r\n this.emit('studio:disconnected', payload);\r\n return;\r\n }\r\n\r\n if (msg.type === StudioMsg.RESPONSE) {\r\n const pending = this.pendingRequests.get(msg.id);\r\n if (pending) {\r\n clearTimeout(pending.timer);\r\n pending.resolve(msg);\r\n this.pendingRequests.delete(msg.id);\r\n }\r\n return;\r\n }\r\n\r\n this.emit(msg.type, msg.payload);\r\n this.emit('message', msg);\r\n }\r\n\r\n sendRequest<T = unknown>(type: string, payload: unknown, timeoutMs = 10000): Promise<WsMessage<T>> {\r\n return new Promise((resolve, reject) => {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n reject(new Error('Not connected to Dominus server'));\r\n return;\r\n }\r\n if (!this.studioConnected) {\r\n reject(new Error('Studio not connected'));\r\n return;\r\n }\r\n\r\n const msg = createMessage(type, payload);\r\n\r\n const timer = setTimeout(() => {\r\n this.pendingRequests.delete(msg.id);\r\n reject(new Error(`Request timed out: ${type}`));\r\n }, timeoutMs);\r\n\r\n this.pendingRequests.set(msg.id, {\r\n resolve: resolve as (msg: WsMessage) => void,\r\n reject,\r\n timer,\r\n });\r\n\r\n this.ws.send(serializeMessage(msg));\r\n });\r\n }\r\n\r\n sendNotification(type: string, payload: unknown): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\r\n const msg = createMessage(type, payload);\r\n this.ws.send(serializeMessage(msg));\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.studioConnected && this.connections.size > 0;\r\n }\r\n\r\n getConnectionInfo(): StudioConnection | null {\r\n if (this.connections.size === 0) return null;\r\n // Return active or first connection\r\n const target = this.activePlaceId !== 0\r\n ? this.connections.get(this.activePlaceId)\r\n : this.connections.values().next().value;\r\n if (!target) return null;\r\n return { ...target, ws: this.ws! } as StudioConnection;\r\n }\r\n\r\n listConnections(): PlaceInfo[] {\r\n return [...this.connections.values()].map(c => ({\r\n placeId: c.placeId ?? 0,\r\n placeName: c.placeName,\r\n studioVersion: c.studioVersion,\r\n connectedAt: c.connectedAt,\r\n }));\r\n }\r\n\r\n getActivePlaceId(): number {\r\n return this.activePlaceId;\r\n }\r\n\r\n setActivePlaceId(placeId: number): void {\r\n this.activePlaceId = placeId;\r\n }\r\n\r\n getPort(): number {\r\n return this.port;\r\n }\r\n\r\n stop(): Promise<void> {\r\n return new Promise((resolve) => {\r\n for (const [, pending] of this.pendingRequests) {\r\n clearTimeout(pending.timer);\r\n pending.reject(new Error('Client shutting down'));\r\n }\r\n this.pendingRequests.clear();\r\n if (this.ws) {\r\n this.ws.close();\r\n this.ws = null;\r\n }\r\n resolve();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Check if a Dominus server is already running on the given port.\r\n */\r\nexport async function isPortInUse(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const ws = new WebSocket(`ws://localhost:${port}`);\r\n const timer = setTimeout(() => {\r\n ws.close();\r\n resolve(false);\r\n }, 1000);\r\n\r\n ws.on('open', () => {\r\n clearTimeout(timer);\r\n ws.close();\r\n resolve(true);\r\n });\r\n\r\n ws.on('error', () => {\r\n clearTimeout(timer);\r\n resolve(false);\r\n });\r\n });\r\n}\r\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type { ConfigAccess } from '../tools/types.js';\n\nconst DOMINUS_DIR = path.join(os.homedir(), '.dominus');\nconst CONFIG_PATH = path.join(DOMINUS_DIR, 'config.json');\nconst DB_PATH = path.join(DOMINUS_DIR, 'dominus.db');\nconst RULES_PATH = path.join(DOMINUS_DIR, 'rules.json');\n\nexport type AIProviderType =\n | 'openai'\n | 'anthropic'\n | 'gemini'\n | 'xai'\n | 'openrouter'\n | 'custom';\n\nexport interface ProviderConfig {\n name: string;\n baseUrl: string;\n envVar: string;\n defaultModel: string;\n}\n\nexport const PROVIDERS: Record<AIProviderType, ProviderConfig> = {\n openai: {\n name: 'OpenAI',\n baseUrl: 'https://api.openai.com/v1',\n envVar: 'OPENAI_API_KEY',\n defaultModel: 'gpt-5.3-codex',\n },\n anthropic: {\n name: 'Anthropic',\n baseUrl: 'https://api.anthropic.com/v1/',\n envVar: 'ANTHROPIC_API_KEY',\n defaultModel: 'claude-sonnet-4-6',\n },\n gemini: {\n name: 'Google Gemini',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai',\n envVar: 'GEMINI_API_KEY',\n defaultModel: 'gemini-3.1-pro',\n },\n xai: {\n name: 'xAI (Grok)',\n baseUrl: 'https://api.x.ai/v1',\n envVar: 'XAI_API_KEY',\n defaultModel: 'grok-4.2',\n },\n openrouter: {\n name: 'OpenRouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n envVar: 'OPENROUTER_API_KEY',\n defaultModel: 'anthropic/claude-sonnet-4-6',\n },\n custom: {\n name: 'Custom',\n baseUrl: '',\n envVar: '',\n defaultModel: '',\n },\n};\n\nexport interface DominusConfig {\n provider: AIProviderType;\n apiKey?: string;\n apiBaseUrl: string;\n model: string;\n port: number;\n maxToolIterations: number;\n maxVerifyRetries: number;\n tokenBudget: number;\n autoIndex: boolean;\n autoLearn: boolean;\n userName: string;\n openCloudApiKey?: string;\n}\n\nconst DEFAULTS: DominusConfig = {\n provider: 'openai',\n apiBaseUrl: '',\n model: '',\n port: 18088,\n maxToolIterations: 25,\n maxVerifyRetries: 3,\n tokenBudget: 128000,\n autoIndex: true,\n autoLearn: true,\n userName: 'Developer',\n};\n\n/**\n * Auto-detect provider from environment variables.\n * Returns the first provider whose env var is set, or null.\n */\nexport function detectProviderFromEnv(): { provider: AIProviderType; apiKey: string } | null {\n const priority: AIProviderType[] = ['openai', 'anthropic', 'gemini', 'xai', 'openrouter'];\n for (const p of priority) {\n const key = process.env[PROVIDERS[p].envVar];\n if (key) return { provider: p, apiKey: key };\n }\n return null;\n}\n\n/**\n * Resolve the effective base URL and model for a provider config.\n */\nexport function resolveProviderSettings(config: DominusConfig): {\n baseUrl: string;\n model: string;\n} {\n const providerInfo = PROVIDERS[config.provider];\n return {\n baseUrl: config.apiBaseUrl || providerInfo?.baseUrl || PROVIDERS.openrouter.baseUrl,\n model: config.model || providerInfo?.defaultModel || 'gpt-4o',\n };\n}\n\nexport interface DominusRules {\n do: string[];\n dont: string[];\n conventions: string[];\n context: string;\n}\n\nconst DEFAULT_RULES: DominusRules = {\n do: [],\n dont: [],\n conventions: [],\n context: '',\n};\n\nfunction ensureDir(): void {\n if (!fs.existsSync(DOMINUS_DIR)) {\n fs.mkdirSync(DOMINUS_DIR, { recursive: true });\n }\n}\n\nfunction readJson<T>(filePath: string, defaults: T): T {\n try {\n if (fs.existsSync(filePath)) {\n const raw = fs.readFileSync(filePath, 'utf-8');\n return { ...defaults, ...JSON.parse(raw) };\n }\n } catch {\n // Corrupted file; reset to defaults\n }\n return { ...defaults };\n}\n\nfunction writeJson(filePath: string, data: unknown): void {\n ensureDir();\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\nexport function loadConfig(): DominusConfig {\n ensureDir();\n return readJson(CONFIG_PATH, DEFAULTS);\n}\n\nexport function saveConfig(config: DominusConfig): void {\n writeJson(CONFIG_PATH, config);\n}\n\nexport function getConfigValue<K extends keyof DominusConfig>(key: K): DominusConfig[K] {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue<K extends keyof DominusConfig>(\n key: K,\n value: DominusConfig[K],\n): void {\n const config = loadConfig();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (config as any)[key] = value;\n saveConfig(config);\n}\n\nexport function loadRules(): DominusRules {\n ensureDir();\n return readJson(RULES_PATH, DEFAULT_RULES);\n}\n\nexport function saveRules(rules: DominusRules): void {\n writeJson(RULES_PATH, rules);\n}\n\nexport function getDominusDir(): string {\n ensureDir();\n return DOMINUS_DIR;\n}\n\nexport function getDbPath(): string {\n ensureDir();\n return DB_PATH;\n}\n\nexport function createConfigAccess(): ConfigAccess {\n return {\n get<T>(key: string): T | undefined {\n const config = loadConfig() as unknown as Record<string, unknown>;\n return config[key] as T | undefined;\n },\n set(key: string, value: unknown): void {\n const config = loadConfig() as unknown as Record<string, unknown>;\n config[key] = value;\n saveConfig(config as unknown as DominusConfig);\n },\n getAll(): Record<string, unknown> {\n return loadConfig() as unknown as Record<string, unknown>;\n },\n };\n}\n","import fs from 'node:fs';\r\nimport initSqlJs from 'sql.js';\r\nimport type { Database, QueryExecResult } from 'sql.js';\r\nimport { getDbPath } from '../config/config.js';\r\nimport type { Fact, FactCategory, SessionSummary, ChatMessage, ScriptEntry } from './types.js';\r\n\r\nlet db: Database | null = null;\r\nlet dbPath: string;\r\n\r\nconst SCHEMA = `\r\nCREATE TABLE IF NOT EXISTS facts (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n content TEXT NOT NULL,\r\n category TEXT NOT NULL,\r\n source TEXT,\r\n relevance REAL DEFAULT 1.0,\r\n created_at INTEGER NOT NULL,\r\n accessed_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS summaries (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n session_id TEXT NOT NULL,\r\n summary TEXT NOT NULL,\r\n created_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS messages (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n session_id TEXT NOT NULL,\r\n role TEXT NOT NULL,\r\n content TEXT NOT NULL,\r\n tool_name TEXT,\r\n created_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE TABLE IF NOT EXISTS script_index (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n project_id TEXT NOT NULL,\r\n path TEXT NOT NULL,\r\n class_name TEXT NOT NULL,\r\n summary TEXT,\r\n line_count INTEGER,\r\n last_hash TEXT,\r\n updated_at INTEGER NOT NULL\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_facts_project ON facts(project_id);\r\nCREATE INDEX IF NOT EXISTS idx_facts_category ON facts(project_id, category);\r\nCREATE INDEX IF NOT EXISTS idx_scripts_project ON script_index(project_id);\r\nCREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\r\nCREATE INDEX IF NOT EXISTS idx_summaries_project ON summaries(project_id);\r\n`;\r\n\r\nfunction persist(): void {\r\n if (!db) return;\r\n const data = db.export();\r\n fs.writeFileSync(dbPath, Buffer.from(data));\r\n}\r\n\r\nexport async function initMemoryStore(): Promise<void> {\r\n if (db) return;\r\n dbPath = getDbPath();\r\n const SQL = await initSqlJs();\r\n\r\n if (fs.existsSync(dbPath)) {\r\n const buffer = fs.readFileSync(dbPath);\r\n db = new SQL.Database(buffer);\r\n } else {\r\n db = new SQL.Database();\r\n }\r\n\r\n db.run(SCHEMA);\r\n persist();\r\n}\r\n\r\nexport function getDb(): Database {\r\n if (!db) throw new Error('Memory store not initialized. Call initMemoryStore() first.');\r\n return db;\r\n}\r\n\r\nexport function closeMemoryStore(): void {\r\n if (db) {\r\n persist();\r\n db.close();\r\n db = null;\r\n }\r\n}\r\n\r\n// --- Facts ---\r\n\r\nexport function storeFact(fact: Omit<Fact, 'id'>): number {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO facts (project_id, content, category, source, relevance, created_at, accessed_at)\r\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\r\n [\r\n fact.projectId,\r\n fact.content,\r\n fact.category,\r\n fact.source ?? null,\r\n fact.relevance,\r\n fact.createdAt,\r\n fact.accessedAt,\r\n ],\r\n );\r\n persist();\r\n const stmt = d.prepare('SELECT last_insert_rowid()');\r\n stmt.step();\r\n const row = stmt.get();\r\n stmt.free();\r\n return (row?.[0] as number) ?? 0;\r\n}\r\n\r\nexport function recallFacts(projectId: string, query: string, limit = 10): Fact[] {\r\n const d = getDb();\r\n const keywords = query\r\n .toLowerCase()\r\n .split(/\\s+/)\r\n .filter((w) => w.length > 2);\r\n\r\n if (keywords.length === 0) {\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? ORDER BY relevance DESC, accessed_at DESC LIMIT ?`,\r\n [projectId, limit],\r\n );\r\n return rowsToFacts(result);\r\n }\r\n\r\n const likeClauses = keywords.map(() => `LOWER(content) LIKE ?`).join(' OR ');\r\n const likeParams = keywords.map((k) => `%${k}%`);\r\n\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? AND (${likeClauses})\r\n ORDER BY relevance DESC, accessed_at DESC LIMIT ?`,\r\n [projectId, ...likeParams, limit],\r\n );\r\n\r\n const facts = rowsToFacts(result);\r\n\r\n // Update accessed_at for recalled facts\r\n for (const fact of facts) {\r\n if (fact.id) {\r\n d.run(`UPDATE facts SET accessed_at = ? WHERE id = ?`, [Date.now(), fact.id]);\r\n }\r\n }\r\n if (facts.length > 0) persist();\r\n\r\n return facts;\r\n}\r\n\r\nexport function getAllFacts(projectId: string): Fact[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM facts WHERE project_id = ? ORDER BY relevance DESC`,\r\n [projectId],\r\n );\r\n return rowsToFacts(result);\r\n}\r\n\r\nfunction rowsToFacts(result: QueryExecResult[]): Fact[] {\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n content: row[2] as string,\r\n category: row[3] as FactCategory,\r\n source: row[4] as string | undefined,\r\n relevance: row[5] as number,\r\n createdAt: row[6] as number,\r\n accessedAt: row[7] as number,\r\n }));\r\n}\r\n\r\n// --- Messages ---\r\n\r\nexport function storeMessage(msg: Omit<ChatMessage, 'id'>): void {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO messages (session_id, role, content, tool_name, created_at)\r\n VALUES (?, ?, ?, ?, ?)`,\r\n [msg.sessionId, msg.role, msg.content, msg.toolName ?? null, msg.createdAt],\r\n );\r\n persist();\r\n}\r\n\r\nexport function getSessionMessages(sessionId: string, limit = 100): ChatMessage[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM messages WHERE session_id = ? ORDER BY created_at ASC LIMIT ?`,\r\n [sessionId, limit],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n sessionId: row[1] as string,\r\n role: row[2] as ChatMessage['role'],\r\n content: row[3] as string,\r\n toolName: (row[4] as string) || undefined,\r\n createdAt: row[5] as number,\r\n }));\r\n}\r\n\r\n// --- Summaries ---\r\n\r\nexport function storeSummary(summary: Omit<SessionSummary, 'id'>): void {\r\n const d = getDb();\r\n d.run(\r\n `INSERT INTO summaries (project_id, session_id, summary, created_at)\r\n VALUES (?, ?, ?, ?)`,\r\n [summary.projectId, summary.sessionId, summary.summary, summary.createdAt],\r\n );\r\n persist();\r\n}\r\n\r\nexport function getProjectSummaries(projectId: string, limit = 20): SessionSummary[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM summaries WHERE project_id = ? ORDER BY created_at DESC LIMIT ?`,\r\n [projectId, limit],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n sessionId: row[2] as string,\r\n summary: row[3] as string,\r\n createdAt: row[4] as number,\r\n }));\r\n}\r\n\r\n// --- Script Index ---\r\n\r\nexport function upsertScript(entry: Omit<ScriptEntry, 'id'>): void {\r\n const d = getDb();\r\n const existing = d.exec(\r\n `SELECT id FROM script_index WHERE project_id = ? AND path = ?`,\r\n [entry.projectId, entry.path],\r\n );\r\n\r\n if (existing[0]?.values.length) {\r\n d.run(\r\n `UPDATE script_index SET class_name = ?, summary = ?, line_count = ?, last_hash = ?, updated_at = ?\r\n WHERE project_id = ? AND path = ?`,\r\n [\r\n entry.className,\r\n entry.summary ?? null,\r\n entry.lineCount ?? null,\r\n entry.lastHash ?? null,\r\n entry.updatedAt,\r\n entry.projectId,\r\n entry.path,\r\n ],\r\n );\r\n } else {\r\n d.run(\r\n `INSERT INTO script_index (project_id, path, class_name, summary, line_count, last_hash, updated_at)\r\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\r\n [\r\n entry.projectId,\r\n entry.path,\r\n entry.className,\r\n entry.summary ?? null,\r\n entry.lineCount ?? null,\r\n entry.lastHash ?? null,\r\n entry.updatedAt,\r\n ],\r\n );\r\n }\r\n persist();\r\n}\r\n\r\nexport function getScriptIndex(\r\n projectId: string,\r\n): { path: string; summary?: string; className: string }[] {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT path, summary, class_name FROM script_index WHERE project_id = ? ORDER BY path`,\r\n [projectId],\r\n );\r\n if (!result[0]) return [];\r\n return result[0].values.map((row) => ({\r\n path: row[0] as string,\r\n summary: (row[1] as string) || undefined,\r\n className: row[2] as string,\r\n }));\r\n}\r\n\r\nexport function getScriptEntry(projectId: string, scriptPath: string): ScriptEntry | null {\r\n const d = getDb();\r\n const result = d.exec(\r\n `SELECT * FROM script_index WHERE project_id = ? AND path = ?`,\r\n [projectId, scriptPath],\r\n );\r\n if (!result[0]?.values.length) return null;\r\n const row = result[0].values[0];\r\n return {\r\n id: row[0] as number,\r\n projectId: row[1] as string,\r\n path: row[2] as string,\r\n className: row[3] as string,\r\n summary: (row[4] as string) || undefined,\r\n lineCount: (row[5] as number) || undefined,\r\n lastHash: (row[6] as string) || undefined,\r\n updatedAt: row[7] as number,\r\n };\r\n}\r\n\r\n// --- Decay ---\r\n\r\nexport function decayRelevance(projectId: string, factor = 0.95): void {\r\n const d = getDb();\r\n d.run(`UPDATE facts SET relevance = relevance * ? WHERE project_id = ?`, [factor, projectId]);\r\n persist();\r\n}\r\n","/**\r\n * INTERNAL_MEMORY — lessons learned and quirks that ship with Dominus.\r\n *\r\n * These are baked into every system prompt so the agent doesn't repeat\r\n * known mistakes. Add entries here when you discover a pattern that caused\r\n * a failure, an unintuitive API, or a workaround that should be remembered.\r\n *\r\n * Keep entries short, specific, and actionable. Prefer bullet points over prose.\r\n */\r\n\r\nexport const INTERNAL_MEMORY = `## Internal Memory — Known Quirks & Lessons\r\n\r\nThese are built-in lessons that ship with Dominus. Follow them exactly.\r\n\r\n### create_ui — property format\r\n- Each node accepts properties in **either** of two shapes:\r\n - **Flattened (preferred)**: props as top-level keys next to \\`ClassName\\`, \\`Name\\`, \\`Children\\`.\r\n \\`\\`\\`json\r\n { \"ClassName\": \"TextButton\", \"Name\": \"Btn\", \"Text\": \"OK\", \"Size\": [0, 100, 0, 40] }\r\n \\`\\`\\`\r\n - **Nested bag**: props grouped under \\`properties\\` / \\`Properties\\` / \\`props\\` / \\`Props\\`.\r\n \\`\\`\\`json\r\n { \"ClassName\": \"TextButton\", \"Name\": \"Btn\",\r\n \"properties\": { \"Text\": \"OK\", \"Size\": [0, 100, 0, 40] } }\r\n \\`\\`\\`\r\n- Do NOT mix a nested \\`properties\\` bag with flattened props of the same name — the bag wins.\r\n- Reserved keys (never treated as instance properties): \\`ClassName\\`, \\`className\\`, \\`Name\\`, \\`name\\`, \\`Children\\`, \\`children\\`, \\`properties\\`, \\`Properties\\`, \\`props\\`, \\`Props\\`.\r\n\r\n### build_multiple — schema is strict\r\n- Top-level keys only: \\`name\\`, \\`className\\`, \\`position\\`, \\`size\\`, \\`color\\`, \\`material\\`, \\`anchored\\`, \\`shape\\`, \\`transparency\\`, \\`parent\\`, \\`canCollide\\`.\r\n- Does NOT accept a nested \\`properties\\` bag. For anything outside those fields use \\`insert_instance\\` + \\`set_properties\\`.\r\n- \\`shape\\` values: \\`Block\\`, \\`Ball\\`, \\`Cylinder\\`, \\`Wedge\\`.\r\n\r\n### Color formats (accepted everywhere)\r\n- Hex: \\`\"#RRGGBB\"\\`\r\n- RGB string: \\`\"rgb(255, 128, 0)\"\\`\r\n- BrickColor name: \\`\"Bright red\"\\`, \\`\"Institutional white\"\\`, \\`\"Really black\"\\`, etc.\r\n- Array: \\`[r, g, b]\\` (0–1 floats) or \\`[255, 128, 0]\\` (auto-detected if any value > 1)\r\n\r\n### UDim2 / UDim / Vector2 / Color3 coercion (create_ui)\r\n- UDim2: \\`[xScale, xOffset, yScale, yOffset]\\` or \\`{XScale, XOffset, YScale, YOffset}\\`.\r\n- UDim: \\`[scale, offset]\\` or a plain number (treated as pixels).\r\n- Vector2 (e.g. \\`AnchorPoint\\`): \\`[x, y]\\` or \\`{x, y}\\`.\r\n- 2-element arrays are auto-disambiguated by property name (\\`AnchorPoint\\` → Vector2, \\`CornerRadius\\` → UDim).\r\n\r\n### Common GUI property names\r\n- GUI uses \\`Size\\`/\\`Position\\` as **UDim2** — never Vector3.\r\n- \\`BackgroundColor3\\`, \\`TextColor3\\`, \\`BorderColor3\\`, \\`ImageColor3\\` → Color3.\r\n- \\`Font\\` accepts a string enum name like \\`\"GothamBold\"\\`, \\`\"SourceSans\"\\`.\r\n- Enum properties take the string name: \\`\"Center\"\\`, \\`\"Left\"\\`, \\`\"Fit\"\\`.\r\n\r\n### Tool selection cheat-sheet\r\n- Single 3D part → \\`create_part\\`\r\n- Many 3D parts (tree, building, vehicle) → \\`build_multiple\\` with \\`groupName\\`\r\n- Full UI tree → \\`create_ui\\` (one call, never loop \\`insert_instance\\` for UI)\r\n- **Convert/export existing UI → \\`serialize_ui\\`** (NOT get_descendants_properties)\r\n- Adjusting an existing instance → \\`set_properties\\` (not \\`run_code\\`)\r\n- **Inspecting user's selection → \\`get_selection\\`, then \\`get_properties\\` or \\`serialize_ui\\`**\r\n- **Reading properties → \\`get_properties\\` (NEVER \\`run_code\\` with dump scripts)**\r\n- **Browsing the tree → \\`get_explorer\\`**\r\n- **Multiple Studios open → \\`list_connections\\` to see all, \\`set_active_place\\` to target one**\r\n- Anything exotic or procedural → \\`run_code\\` as last resort\r\n\r\n### NEVER use run_code for:\r\n- Getting properties of an instance → use \\`get_properties\\` or \\`serialize_ui\\`\r\n- Dumping selection info → use \\`inspect_selection\\` (ONE call does it all)\r\n- Inspecting an instance + its children → use \\`inspect_instance\\`\r\n- Converting UI to Roact/React → use \\`convert_ui_to_code\\`\r\n- Creating instances → use \\`create_part\\`, \\`create_ui\\`, \\`insert_instance\\`, \\`build_multiple\\`\r\n- Modifying properties → use \\`set_properties\\` or \\`bulk_set_properties\\`\r\n- Reading scripts → use \\`read_script\\`\r\n- Browsing the explorer → use \\`get_explorer\\`\r\n\\`run_code\\` is ONLY for procedural logic, terrain generation, raycasts, physics queries, or custom algorithms with no tool equivalent.\r\n\r\n### Composite skill tools (prefer these over chaining)\r\n- \\`inspect_selection\\` — Returns paths + compact properties for all selected instances in ONE call. Use when user says \"my selection\" or \"what I selected\".\r\n- \\`inspect_instance\\` — Returns compact properties + children tree for a single instance in ONE call. Combines get_properties + get_explorer.\r\n- \\`convert_ui_to_code\\` — Serializes a UI tree and generates a Roact/React component. Use when user says \"turn this into a component\" or \"convert to React\".\r\n\r\n### Verification habits\r\n- After a build, call \\`get_explorer\\` or \\`get_selection\\` to confirm the tree looks right.\r\n- After editing a script, read it back.\r\n- After \\`run_code\\`, check \\`get_output\\` for errors.\r\n\r\n### serialize_ui — the RIGHT tool for UI conversion\r\n- **Use \\`serialize_ui\\` when converting existing UI to Roact/React/Fusion components.** It returns a minimal JSON tree with only non-default properties, already in JSON-friendly formats.\r\n- **Do NOT use \\`get_descendants_properties\\` for UI conversion** — it returns a flat list with ~50+ properties per instance (including read-only, deprecated, nil, and default values), which bloats context and confuses conversion.\r\n- \\`serialize_ui\\` output maps 1:1 to \\`create_ui\\` input — you can round-trip UI through it.\r\n- The tree structure preserves parent-child hierarchy, so Roact/React children mapping is direct.\r\n\r\n### UI → Roact/React conversion cheat-sheet\r\n- \\`serialize_ui\\` path → JSON tree → map each node to \\`Roact.createElement(ClassName, props, childrenDict)\\`\r\n- UDim2 arrays \\`[xS, xO, yS, yO]\\` → \\`UDim2.new(xS, xO, yS, yO)\\`\r\n- Color3 hex strings → \\`Color3.fromHex(\"#RRGGBB\")\\`\r\n- Vector2 arrays → \\`Vector2.new(x, y)\\`\r\n- UDim arrays → \\`UDim.new(s, o)\\`\r\n- Enum strings like \\`\"Center\"\\` → \\`Enum.TextXAlignment.Center\\`\r\n- FontFace → \\`Font.new(family, weight, style)\\`\r\n- UI modifiers (UICorner, UIStroke, UIGradient, UIListLayout, UIPadding) are CHILDREN not props\r\n- Use instance Name as dictionary key in children table\r\n`;\r\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { z } from 'zod';\r\nimport { DominusServer, type StudioBridge } from '../transport/ws-server.js';\r\nimport { DominusClient, isPortInUse } from '../transport/ws-client.js';\r\nimport { CliMsg, type ExplorerNode, type ScriptContentPayload, type RunCodeResponsePayload, type SearchResultPayload, type OutputPayload, type SelectionPayload, type PropertyEntry, type TestResultPayload, type StudioTestResultPayload } from '../transport/protocol.js';\r\nimport { initMemoryStore, recallFacts, storeFact, getScriptIndex } from '../memory/store.js';\r\nimport { loadConfig } from '../config/config.js';\r\nimport { INTERNAL_MEMORY } from '../agent/internal-memory.js';\r\n\r\nlet bridge: StudioBridge;\r\n\r\nexport async function startMcpServer(): Promise<void> {\r\n const config = loadConfig();\r\n await initMemoryStore();\r\n\r\n const portTaken = await isPortInUse(config.port);\r\n if (portTaken) {\r\n const client = new DominusClient(config.port);\r\n await client.connect();\r\n bridge = client;\r\n } else {\r\n const server = new DominusServer(config.port);\r\n await server.start();\r\n bridge = server;\r\n }\r\n\r\n const mcp = new McpServer({\r\n name: 'dominus',\r\n version: '0.6.0',\r\n }, {\r\n instructions: INTERNAL_MEMORY,\r\n });\r\n\r\n // --- Helpers: safe Lua string generation ---\r\n /** Escape a string for safe embedding in Lua code */\r\n function luaStr(s: string): string {\r\n return `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r')}\"`;\r\n }\r\n /** Convert a dot-path like \"Workspace.Folder.Part\" to game[\"Workspace\"][\"Folder\"][\"Part\"] */\r\n function resolvePath(dotPath: string): string {\r\n const parts = dotPath.split('.');\r\n let r = 'game';\r\n for (const p of parts) r += `[${luaStr(p)}]`;\r\n return r;\r\n }\r\n\r\n // --- Code Generation Helpers ---\r\n\r\n /** Round a number to 3 decimal places, drop trailing zeros. Integers stay as-is. */\r\n function cleanNum(n: number): string {\r\n if (Number.isInteger(n)) return String(n);\r\n // Round to 3 decimals, strip trailing zeros\r\n const rounded = Math.round(n * 1000) / 1000;\r\n return String(rounded);\r\n }\r\n\r\n /** Convert a serialized UI tree node into a Roact/React createElement call */\r\n function generateComponentCode(\r\n tree: Record<string, unknown>,\r\n componentName: string,\r\n framework: string,\r\n ): string {\r\n const isReact = framework === 'react';\r\n const lib = isReact ? 'React' : 'Roact';\r\n\r\n const lines: string[] = [];\r\n lines.push(`local ${lib} = require(game.ReplicatedStorage.Packages.${isReact ? 'React' : 'Roact'})`);\r\n if (isReact) {\r\n lines.push(`local e = React.createElement`);\r\n } else {\r\n lines.push(`local e = Roact.createElement`);\r\n }\r\n lines.push('');\r\n\r\n // Collect all ClassName types used so we can note them\r\n lines.push(`local function ${componentName}()`);\r\n lines.push(`\\treturn ${renderNode(tree, 1)}`);\r\n lines.push('end');\r\n lines.push('');\r\n lines.push(`return ${componentName}`);\r\n\r\n return lines.join('\\n');\r\n }\r\n\r\n function renderNode(node: Record<string, unknown>, depth: number): string {\r\n const indent = '\\t'.repeat(depth);\r\n const indent2 = '\\t'.repeat(depth + 1);\r\n const className = (node.ClassName as string) || 'Frame';\r\n const children = (node.Children as Record<string, unknown>[]) || [];\r\n const name = node.Name as string | undefined;\r\n\r\n // Build props table\r\n const props: string[] = [];\r\n const skipKeys = new Set(['ClassName', 'Name', 'Children', 'className', 'name', 'children']);\r\n for (const [key, val] of Object.entries(node)) {\r\n if (skipKeys.has(key)) continue;\r\n props.push(`${indent2}${key} = ${luaValue(val, depth + 1)},`);\r\n }\r\n\r\n // Build children table\r\n const childEntries: string[] = [];\r\n for (const child of children) {\r\n const childName = (child.Name as string) || (child.ClassName as string) || 'Child';\r\n childEntries.push(`${indent2}${childName} = ${renderNode(child, depth + 1)},`);\r\n }\r\n\r\n // Combine\r\n const hasProps = props.length > 0;\r\n const hasChildren = childEntries.length > 0;\r\n\r\n if (!hasProps && !hasChildren) {\r\n return `e(\"${className}\", {})`;\r\n }\r\n\r\n const parts: string[] = [];\r\n parts.push(`e(\"${className}\", {`);\r\n if (hasProps) {\r\n parts.push(...props);\r\n }\r\n if (hasChildren) {\r\n parts.push(`${indent2}}, {`);\r\n parts.push(...childEntries);\r\n parts.push(`${indent}})`);\r\n } else {\r\n parts.push(`${indent}})`);\r\n }\r\n\r\n return parts.join('\\n');\r\n }\r\n\r\n function luaValue(val: unknown, _depth: number): string {\r\n if (val === null || val === undefined) return 'nil';\r\n if (typeof val === 'boolean') return String(val);\r\n if (typeof val === 'number') return cleanNum(val);\r\n if (typeof val === 'string') {\r\n // Detect special Roblox types from serialize_ui output\r\n if (val.startsWith('#') && val.length === 7) {\r\n return `Color3.fromHex(\"${val}\")`;\r\n }\r\n // Enum-like strings (single word, PascalCase)\r\n if (/^[A-Z][a-zA-Z]+$/.test(val)) {\r\n return `\"${val}\"`; // keep as string, Roact handles enum coercion\r\n }\r\n return `\"${val.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`;\r\n }\r\n if (Array.isArray(val)) {\r\n // UDim2: [xS, xO, yS, yO]\r\n if (val.length === 4 && val.every(v => typeof v === 'number')) {\r\n return `UDim2.new(${val.map(cleanNum).join(', ')})`;\r\n }\r\n // Vector2 / UDim: [x, y]\r\n if (val.length === 2 && val.every(v => typeof v === 'number')) {\r\n return `Vector2.new(${val.map(cleanNum).join(', ')})`;\r\n }\r\n // Color3: [r, g, b]\r\n if (val.length === 3 && val.every(v => typeof v === 'number')) {\r\n const allSmall = val.every(v => (v as number) <= 1);\r\n if (allSmall) return `Color3.new(${val.map(cleanNum).join(', ')})`;\r\n return `Color3.fromRGB(${val.map(v => String(Math.round(v as number))).join(', ')})`;\r\n }\r\n return `{${val.map(v => luaValue(v, _depth)).join(', ')}}`;\r\n }\r\n if (typeof val === 'object') {\r\n const entries = Object.entries(val as Record<string, unknown>);\r\n if (entries.length === 0) return '{}';\r\n return `{\\n${entries.map(([k, v]) => `${'\\t'.repeat(_depth + 1)}${k} = ${luaValue(v, _depth + 1)}`).join(',\\n')}\\n${'\\t'.repeat(_depth)}}`;\r\n }\r\n return String(val);\r\n }\r\n\r\n // --- Studio Tools ---\r\n\r\n mcp.tool(\r\n 'read_script',\r\n 'Read the source code of a script in Roblox Studio',\r\n { path: z.string().describe('Full instance path, e.g. \"ServerScriptService.GameManager\"') },\r\n async ({ path }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<ScriptContentPayload>(CliMsg.GET_SCRIPT, { path });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'edit_script',\r\n 'Replace the entire source code of a script in Roblox Studio',\r\n {\r\n path: z.string().describe('Full instance path'),\r\n source: z.string().describe('New complete source code'),\r\n },\r\n async ({ path, source }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.SET_SCRIPT, { path, source });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'run_code',\r\n 'Execute arbitrary Luau code in Roblox Studio. LAST RESORT — only use when no dedicated tool exists. ' +\r\n 'Do NOT use for: reading properties (use get_properties/inspect_selection/serialize_ui), creating instances (use create_part/create_ui/insert_instance/build_multiple), ' +\r\n 'modifying properties (use set_properties/bulk_set_properties), or inspecting the tree (use get_explorer). ' +\r\n 'Valid uses: complex procedural generation, terrain algorithms, raycasting, physics queries, custom logic with no tool equivalent.',\r\n { code: z.string().describe('Luau code to execute') },\r\n async ({ code }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_explorer',\r\n 'Get the DataModel explorer tree from Roblox Studio',\r\n {\r\n rootPath: z.string().optional().describe('Root path to start from. Omit for entire tree.'),\r\n maxDepth: z.number().optional().default(3).describe('Maximum tree depth'),\r\n },\r\n async ({ rootPath, maxDepth }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ tree: ExplorerNode[] }>(CliMsg.GET_EXPLORER, {\r\n rootPath: rootPath ?? null,\r\n maxDepth,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_properties',\r\n 'Get all properties of a single instance in Roblox Studio. Returns property name, value, type, and category. For inspecting UI trees, prefer serialize_ui (structured tree) or get_descendants_properties (flat list with compact filtering).',\r\n {\r\n path: z.string().describe('Full instance path (e.g. \"Workspace.Part\", \"StarterGui.MyUI.Frame\")'),\r\n compact: z.boolean().optional().default(true).describe('Strip read-only, nil, deprecated, and default-valued properties (default true). Set false for full dump.'),\r\n },\r\n async ({ path, compact }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ properties: PropertyEntry[] }>(CliMsg.GET_PROPERTIES, { path, compact });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_descendants_properties',\r\n 'Easily get all descendants of a UI instance (or any instance) and all of their properties. By default uses compact mode which strips read-only, nil, deprecated, and default-valued properties to keep responses small.',\r\n { \r\n path: z.string().describe('Full instance path (e.g., \"Workspace.Part\", \"StarterGui.ScreenGui\")'),\r\n compact: z.boolean().optional().default(true).describe('Strip noisy/default properties (default true). Set false for full dump.'),\r\n outputFile: z.string().optional().describe('Optional file path to write to prevent limit errors/timeouts'),\r\n },\r\n async ({ path, compact, outputFile }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<unknown>(CliMsg.GET_DESCENDANTS_PROPERTIES, { path, compact, outputFile }, 1000 * 60 * 5);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'set_properties',\r\n 'Set properties on an instance in Roblox Studio',\r\n {\r\n path: z.string().describe('Full instance path'),\r\n properties: z.record(z.unknown()).describe('Key-value pairs of properties to set'),\r\n },\r\n async ({ path, properties }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.SET_PROPERTIES, { path, properties });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'insert_instance',\r\n 'Create a new instance in the Roblox Studio DataModel',\r\n {\r\n className: z.string().describe('Class name (e.g. \"Part\", \"Script\")'),\r\n parentPath: z.string().describe('Parent instance path'),\r\n name: z.string().describe('Name for the new instance'),\r\n properties: z.record(z.unknown()).optional().describe('Optional properties to set'),\r\n },\r\n async ({ className, parentPath, name, properties }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.INSERT_INSTANCE, {\r\n className, parentPath, name, properties: properties ?? {},\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'delete_instance',\r\n 'Delete an instance from the Roblox Studio DataModel',\r\n { path: z.string().describe('Full instance path to delete') },\r\n async ({ path }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest(CliMsg.DELETE_INSTANCE, { path });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_selection',\r\n 'Get the currently selected instances in Roblox Studio. Returns paths and class names of all selected objects. ' +\r\n 'Use this FIRST when the user says \"my selection\" or \"what I have selected\". ' +\r\n 'Then use get_properties or serialize_ui on the returned paths to inspect details.',\r\n {},\r\n async () => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<SelectionPayload>(CliMsg.GET_SELECTION, {});\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'search_scripts',\r\n 'Search all scripts in Roblox Studio for a text pattern',\r\n {\r\n query: z.string().describe('Text to search for'),\r\n maxResults: z.number().optional().default(20).describe('Max results'),\r\n },\r\n async ({ query, maxResults }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<SearchResultPayload>(CliMsg.SEARCH_SCRIPTS, { query, maxResults });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_output',\r\n 'Get recent output log from Roblox Studio',\r\n {\r\n limit: z.number().optional().default(50).describe('Max entries'),\r\n level: z.enum(['info', 'warn', 'error']).optional().describe('Filter by level'),\r\n },\r\n async ({ limit, level }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ entries: OutputPayload[] }>(CliMsg.GET_OUTPUT, {\r\n limit, level: level ?? null,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'get_class_info',\r\n 'Look up the schema of any Roblox class using ReflectionService. Returns all properties (with types), methods (with parameters), and events. ' +\r\n 'ALWAYS use this before creating or modifying GUI elements to know correct property names and types.',\r\n { className: z.string().describe('Roblox class name, e.g. \"Frame\", \"TextLabel\", \"Part\", \"MeshPart\"') },\r\n async ({ className }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<unknown>(CliMsg.GET_REFLECTION, { className });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'create_ui',\r\n 'Create an entire UI tree in one call. Pass a declarative JSON tree — ClassName, Name, properties, Children. ' +\r\n 'All types auto-coerced in Luau (UDim2, Color3, Font, enums). 10x faster than run_code. ' +\r\n 'UDim2: [xScale, xOffset, yScale, yOffset]. Color3: \"#hex\" or \"rgb(r,g,b)\". Font: \"GothamBold\". Enums: string names.',\r\n {\r\n parent: z.string().optional().describe('Parent: \"StarterGui\", \"PlayerGui\", or path. Default: StarterGui'),\r\n tree: z.record(z.unknown()).describe(\r\n 'Root UI node: {ClassName, Name, properties..., Children: [{...}, ...]}. ' +\r\n 'UDim2 as [xScale, xOffset, yScale, yOffset], Color3 as \"#hex\", Font as \"GothamBold\"',\r\n ),\r\n animate: z.boolean().optional().describe('If true, task.wait() will be injected between creation of nodes so that the UI writes out dynamically.'),\r\n },\r\n async ({ parent, tree, animate }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ success: boolean; path?: string; instanceCount?: number; error?: string }>(\r\n CliMsg.BUILD_UI, { parent: parent ?? 'StarterGui', tree, animate },\r\n );\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'run_tests',\r\n 'Run tests by requiring ModuleScripts matching test naming conventions (*.test, *.spec, *Test, *Spec). Lightweight — does not enter Run/Play mode.',\r\n { testName: z.string().optional().describe('Specific test name, or omit to run all') },\r\n async ({ testName }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ results: TestResultPayload[] }>(CliMsg.RUN_TESTS, {\r\n testName: testName ?? null,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'execute_run_test',\r\n 'Start a Run mode test session using StudioTestService:ExecuteRunModeAsync(). ' +\r\n 'This actually enters Run mode in Studio. Pass args that server scripts can retrieve via GetTestArgs(). ' +\r\n 'Yields until EndTest() is called or the session stops. Returns the value from EndTest(). ' +\r\n 'Use for headless automated tests — no player, just server scripts.',\r\n { args: z.unknown().optional().describe('Arguments passed to the test session. Server scripts get this via StudioTestService:GetTestArgs()') },\r\n async ({ args }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<StudioTestResultPayload>(CliMsg.EXECUTE_RUN_TEST, { args: args ?? null }, 120_000);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'execute_play_test',\r\n 'Start a solo Play mode test session using StudioTestService:ExecutePlayModeAsync(). ' +\r\n 'This enters Play mode with a player character. Pass args that server scripts can retrieve via GetTestArgs(). ' +\r\n 'Yields until EndTest() is called or the session stops. Returns the value from EndTest(). ' +\r\n 'Use for tests needing a player character and full client-server simulation.',\r\n { args: z.unknown().optional().describe('Arguments passed to the test session. Server scripts get this via StudioTestService:GetTestArgs()') },\r\n async ({ args }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<StudioTestResultPayload>(CliMsg.EXECUTE_PLAY_TEST, { args: args ?? null }, 120_000);\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- Builder Tools ---\r\n\r\n mcp.tool(\r\n 'create_part',\r\n 'Create a Part with position, size, color, material — all in one call. Faster than insert_instance + set_properties.',\r\n {\r\n name: z.string().describe('Name for the part'),\r\n parent: z.string().optional().describe('Parent path (default: Workspace)'),\r\n shape: z.enum(['Block', 'Ball', 'Cylinder', 'Wedge', 'CornerWedge']).optional().describe('Part shape'),\r\n position: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('World position'),\r\n size: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('Size in studs'),\r\n color: z.string().optional().describe('Hex \"#00FF00\", BrickColor name, or \"rgb(0,255,0)\"'),\r\n material: z.string().optional().describe('Plastic, Wood, Grass, Neon, Metal, etc.'),\r\n transparency: z.number().optional().describe('0=opaque, 1=invisible'),\r\n anchored: z.boolean().optional().describe('Anchored (default: true)'),\r\n canCollide: z.boolean().optional().describe('Has collision'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const properties: Record<string, unknown> = {};\r\n if (params.position) properties.Position = { X: params.position.x, Y: params.position.y, Z: params.position.z };\r\n if (params.size) properties.Size = { X: params.size.x, Y: params.size.y, Z: params.size.z };\r\n if (params.color) {\r\n const c = params.color;\r\n if (c.startsWith('#')) properties.Color = c;\r\n else if (c.startsWith('rgb')) {\r\n const m = c.match(/(\\d+)/g);\r\n if (m && m.length >= 3) properties.Color = { red: parseInt(m[0]), green: parseInt(m[1]), blue: parseInt(m[2]) };\r\n } else properties.BrickColor = c;\r\n }\r\n if (params.material) properties.Material = params.material;\r\n if (params.transparency !== undefined) properties.Transparency = params.transparency;\r\n if (params.anchored !== undefined) properties.Anchored = params.anchored;\r\n else properties.Anchored = true;\r\n if (params.canCollide !== undefined) properties.CanCollide = params.canCollide;\r\n if (params.shape && params.shape !== 'Block') properties.Shape = params.shape;\r\n\r\n const className = params.shape === 'Wedge' ? 'WedgePart' : params.shape === 'CornerWedge' ? 'CornerWedgePart' : 'Part';\r\n\r\n const res = await bridge.sendRequest<{ success: boolean; path?: string; error?: string }>(CliMsg.INSERT_INSTANCE, {\r\n className,\r\n parentPath: params.parent ?? 'Workspace',\r\n name: params.name,\r\n properties,\r\n });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'clone_instance',\r\n 'Clone an existing instance, optionally rename it, move it, or offset its position',\r\n {\r\n path: z.string().describe('Path of instance to clone'),\r\n newName: z.string().optional().describe('Name for the clone'),\r\n newParent: z.string().optional().describe('Parent path for the clone'),\r\n offset: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional().describe('Position offset from original'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const lines = [`local orig = ${resolvePath(params.path)}`, `local clone = orig:Clone()`];\r\n if (params.newName) lines.push(`clone.Name = ${luaStr(params.newName)}`);\r\n if (params.newParent) {\r\n lines.push(`clone.Parent = ${resolvePath(params.newParent)}`);\r\n } else {\r\n lines.push(`clone.Parent = orig.Parent`);\r\n }\r\n if (params.offset) {\r\n lines.push(`if clone:IsA(\"BasePart\") then`);\r\n lines.push(` clone.Position = clone.Position + Vector3.new(${params.offset.x}, ${params.offset.y}, ${params.offset.z})`);\r\n lines.push(`end`);\r\n }\r\n lines.push(`print(\"Cloned: \" .. clone:GetFullName())`);\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code: lines.join('\\n') });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'group_instances',\r\n 'Group multiple instances into a Model or Folder. All listed instances become children of the new group.',\r\n {\r\n paths: z.array(z.string()).describe('Array of instance paths to group'),\r\n groupName: z.string().describe('Name for the group'),\r\n groupClass: z.enum(['Model', 'Folder']).optional().describe('Container class (default: Model)'),\r\n parent: z.string().optional().describe('Parent path (default: Workspace)'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const gc = params.groupClass ?? 'Model';\r\n const parent = params.parent ?? 'Workspace';\r\n\r\n const code = [\r\n `local group = Instance.new(${luaStr(gc)})`,\r\n `group.Name = ${luaStr(params.groupName)}`,\r\n `group.Parent = ${resolvePath(parent)}`,\r\n ...params.paths.map((p) => `${resolvePath(p)}.Parent = group`),\r\n `print(\"Grouped ${params.paths.length} instances into: \" .. group:GetFullName())`,\r\n ].join('\\n');\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'build_multiple',\r\n 'Create many parts/instances in one batch. Send an array of specs — all created in a single round-trip. Ideal for building trees, houses, vehicles. Supports hex colors, rgb() colors, and BrickColor names.',\r\n {\r\n parts: z.array(z.object({\r\n name: z.string(),\r\n className: z.string().optional(),\r\n parent: z.string().optional(),\r\n position: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional(),\r\n size: z.object({ x: z.number(), y: z.number(), z: z.number() }).optional(),\r\n color: z.string().optional().describe('Hex \"#RRGGBB\", \"rgb(r,g,b)\", or BrickColor name'),\r\n material: z.string().optional().describe('Enum.Material name: Plastic, Wood, Neon, Glass, etc.'),\r\n transparency: z.number().optional(),\r\n anchored: z.boolean().optional(),\r\n canCollide: z.boolean().optional(),\r\n shape: z.enum(['Block', 'Ball', 'Cylinder', 'Wedge']).optional(),\r\n })).describe('Array of part specifications'),\r\n groupName: z.string().optional().describe('Group all parts into a Model with this name'),\r\n groupParent: z.string().optional().describe('Parent for the group (default: Workspace)'),\r\n },\r\n async (params) => {\r\n assertConnected();\r\n const parts = params.parts;\r\n const groupName = params.groupName;\r\n const groupParent = params.groupParent ?? 'Workspace';\r\n\r\n const lines: string[] = [];\r\n if (groupName) {\r\n lines.push(`local _group = Instance.new(\"Model\")`);\r\n lines.push(`_group.Name = ${luaStr(groupName)}`);\r\n lines.push(`_group.Parent = ${resolvePath(groupParent)}`);\r\n }\r\n for (let i = 0; i < parts.length; i++) {\r\n const p = parts[i];\r\n const v = `_p${i}`;\r\n const cn = p.className ?? (p.shape === 'Wedge' ? 'WedgePart' : 'Part');\r\n lines.push(`local ${v} = Instance.new(${luaStr(cn)})`);\r\n lines.push(`${v}.Name = ${luaStr(p.name)}`);\r\n if (p.position) lines.push(`${v}.Position = Vector3.new(${p.position.x}, ${p.position.y}, ${p.position.z})`);\r\n if (p.size) lines.push(`${v}.Size = Vector3.new(${p.size.x}, ${p.size.y}, ${p.size.z})`);\r\n if (p.color) {\r\n if (p.color.startsWith('#')) {\r\n lines.push(`${v}.Color = Color3.fromHex(${luaStr(p.color)})`);\r\n } else if (p.color.startsWith('rgb(')) {\r\n const m = p.color.match(/rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/);\r\n if (m) lines.push(`${v}.Color = Color3.fromRGB(${m[1]}, ${m[2]}, ${m[3]})`);\r\n } else {\r\n lines.push(`${v}.BrickColor = BrickColor.new(${luaStr(p.color)})`);\r\n }\r\n }\r\n if (p.material) lines.push(`${v}.Material = Enum.Material.${p.material}`);\r\n if (p.transparency !== undefined) lines.push(`${v}.Transparency = ${p.transparency}`);\r\n lines.push(`${v}.Anchored = ${p.anchored ?? true}`);\r\n if (p.canCollide !== undefined) lines.push(`${v}.CanCollide = ${p.canCollide}`);\r\n if (p.shape && p.shape !== 'Block' && cn === 'Part') lines.push(`${v}.Shape = Enum.PartType.${p.shape}`);\r\n lines.push(`${v}.Parent = ${groupName ? '_group' : resolvePath(p.parent ?? 'Workspace')}`);\r\n }\r\n lines.push(`print(\"Built ${parts.length} parts${groupName ? ` in ${groupName}` : ''}\")`);\r\n\r\n const res = await bridge.sendRequest<RunCodeResponsePayload>(CliMsg.RUN_CODE, { code: lines.join('\\n') });\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- UI Serialization ---\r\n\r\n mcp.tool(\r\n 'serialize_ui',\r\n 'Serialize an existing Roblox UI tree into a compact, create_ui-compatible JSON tree. ' +\r\n 'This is the reverse of create_ui — reads any GUI instance and returns a declarative JSON tree ' +\r\n 'with ClassName, Name, non-default properties (Color3 as hex, UDim2 as arrays, etc.), and Children. ' +\r\n 'Perfect for: converting existing UI to Roact/React components, cloning/templating, understanding UI structure, ' +\r\n 'or refactoring. Use this INSTEAD of get_descendants_properties when you need to recreate or convert UI.',\r\n {\r\n path: z.string().describe('Instance path to serialize (e.g. \"StarterGui.MyScreenGui\")'),\r\n maxDepth: z.number().optional().default(50).describe('Maximum tree depth (default 50)'),\r\n },\r\n async ({ path, maxDepth }) => {\r\n assertConnected();\r\n const res = await bridge.sendRequest<{ success: boolean; tree?: unknown; error?: string }>(\r\n CliMsg.SERIALIZE_UI, { path, maxDepth }, 1000 * 60 * 2,\r\n );\r\n if (!res.payload.success) {\r\n return { content: [{ type: 'text' as const, text: `Error: ${res.payload.error ?? 'Serialization failed'}` }] };\r\n }\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(res.payload.tree, null, 2) }] };\r\n },\r\n );\r\n\r\n // --- Composite Skill Tools ---\r\n // Higher-level tools that combine multiple operations into a single call.\r\n // These prevent LLMs from falling back to run_code for common workflows.\r\n\r\n mcp.tool(\r\n 'inspect_selection',\r\n 'Inspect the user\\'s current selection in Roblox Studio. Returns the selected instance paths AND their properties (compact) in a single call. ' +\r\n 'Use this FIRST when the user says \"my selection\", \"what I selected\", or \"the selected thing\". ' +\r\n 'Much better than calling get_selection + get_properties separately.',\r\n {},\r\n async () => {\r\n assertConnected();\r\n // Step 1: get selection\r\n const selRes = await bridge.sendRequest<SelectionPayload>(CliMsg.GET_SELECTION, {});\r\n const paths: string[] = selRes.payload?.paths ?? [];\r\n if (paths.length === 0) {\r\n return { content: [{ type: 'text' as const, text: 'No instances selected in Studio.' }] };\r\n }\r\n\r\n // Step 2: get compact properties for each selected instance\r\n const results: Record<string, unknown> = {};\r\n for (const p of paths.slice(0, 10)) { // cap at 10 to avoid huge payloads\r\n try {\r\n const propRes = await bridge.sendRequest<{ properties?: PropertyEntry[]; error?: string }>(\r\n CliMsg.GET_PROPERTIES, { path: p, compact: true },\r\n );\r\n results[p] = propRes.payload.properties ?? propRes.payload;\r\n } catch {\r\n results[p] = { error: 'Failed to read properties' };\r\n }\r\n }\r\n if (paths.length > 10) {\r\n results['_truncated'] = `${paths.length - 10} more instances not shown`;\r\n }\r\n\r\n return { content: [{ type: 'text' as const, text: JSON.stringify(results, null, 2) }] };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'inspect_instance',\r\n 'Inspect a single instance: returns its compact properties AND its children tree in one call. ' +\r\n 'Combines get_properties + get_explorer into a single round-trip. ' +\r\n 'Use when you need to understand an instance and its subtree.',\r\n {\r\n path: z.string().describe('Full instance path (e.g. \"Workspace.MyModel\")'),\r\n childDepth: z.number().optional().default(2).describe('How deep to show the children tree (default 2)'),\r\n },\r\n async ({ path, childDepth }) => {\r\n assertConnected();\r\n // Parallel: get properties + get children tree\r\n const [propRes, treeRes] = await Promise.all([\r\n bridge.sendRequest<{ properties?: PropertyEntry[]; error?: string }>(\r\n CliMsg.GET_PROPERTIES, { path, compact: true },\r\n ),\r\n bridge.sendRequest<{ tree?: ExplorerNode; error?: string }>(\r\n CliMsg.GET_EXPLORER, { rootPath: path, maxDepth: childDepth ?? 2 },\r\n ),\r\n ]);\r\n\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({\r\n properties: propRes.payload.properties ?? propRes.payload,\r\n children: treeRes.payload.tree ?? treeRes.payload,\r\n }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'convert_ui_to_code',\r\n 'Convert an existing Roblox UI tree into Roact/React-lua component code. ' +\r\n 'Serializes the UI at the given path, then generates a ready-to-use Luau component. ' +\r\n 'Use when the user asks to \"turn this into a component\", \"convert to React\", or \"make a Roact version\".',\r\n {\r\n path: z.string().describe('Path to the UI instance to convert (e.g. \"StarterGui.MyScreenGui.MainFrame\")'),\r\n framework: z.enum(['roact', 'react']).optional().default('react').describe('Target framework: \"roact\" (legacy) or \"react\" (react-lua, default)'),\r\n componentName: z.string().optional().describe('Name for the generated component (defaults to instance Name)'),\r\n },\r\n async ({ path, framework, componentName }) => {\r\n assertConnected();\r\n // Step 1: serialize the UI tree\r\n const res = await bridge.sendRequest<{ success: boolean; tree?: Record<string, unknown>; error?: string }>(\r\n CliMsg.SERIALIZE_UI, { path, maxDepth: 50 }, 1000 * 60 * 2,\r\n );\r\n if (!res.payload.success || !res.payload.tree) {\r\n return { content: [{ type: 'text' as const, text: `Error serializing UI: ${res.payload.error ?? 'Unknown error'}` }] };\r\n }\r\n\r\n const tree = res.payload.tree;\r\n const name = componentName || (tree.Name as string) || 'GeneratedComponent';\r\n const fw = framework || 'react';\r\n\r\n // Step 2: generate code from the serialized tree\r\n const code = generateComponentCode(tree, name, fw);\r\n return { content: [{ type: 'text' as const, text: code }] };\r\n },\r\n );\r\n\r\n // --- Connection Management Tools ---\r\n\r\n mcp.tool(\r\n 'list_connections',\r\n 'List all Roblox Studio instances currently connected to Dominus. Shows placeId, placeName, and connection time for each. Use this when working with multiple Studio windows.',\r\n {},\r\n async () => {\r\n const connections = bridge.listConnections();\r\n const activePlaceId = bridge.getActivePlaceId();\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({\r\n activePlaceId: activePlaceId || 'auto',\r\n connections: connections.map(c => ({\r\n ...c,\r\n active: activePlaceId === 0 && connections.length === 1 ? true\r\n : c.placeId === activePlaceId,\r\n })),\r\n }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'set_active_place',\r\n 'Set which Roblox Studio instance to target when multiple are connected. Pass placeId=0 to reset to auto mode (works when only one is connected). ' +\r\n 'Call list_connections first to see available placeIds.',\r\n {\r\n placeId: z.number().describe('The placeId to target. Use 0 to reset to auto-select.'),\r\n },\r\n async ({ placeId }) => {\r\n const connections = bridge.listConnections();\r\n if (placeId !== 0 && !connections.some(c => c.placeId === placeId)) {\r\n const available = connections.map(c => `${c.placeName ?? 'Unknown'} (${c.placeId})`).join(', ');\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: `Place ${placeId} is not connected. Available: ${available || 'none'}`,\r\n }],\r\n };\r\n }\r\n bridge.setActivePlaceId(placeId);\r\n if (placeId === 0) {\r\n return { content: [{ type: 'text' as const, text: 'Active place reset to auto-select.' }] };\r\n }\r\n const target = connections.find(c => c.placeId === placeId);\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: `Active place set to ${target?.placeName ?? 'Unknown'} (${placeId})`,\r\n }],\r\n };\r\n },\r\n );\r\n\r\n // --- Memory Tools ---\r\n\r\n mcp.tool(\r\n 'recall_memory',\r\n 'Search persistent memory for facts about the current Roblox project',\r\n { query: z.string().describe('What to search for') },\r\n async ({ query }) => {\r\n const facts = recallFacts('current', query, 15);\r\n const scripts = getScriptIndex('current');\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({ facts: facts.map(f => f.content), scriptIndex: scripts }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n\r\n mcp.tool(\r\n 'remember',\r\n 'Store a fact about the project in persistent memory for future sessions',\r\n {\r\n fact: z.string().describe('The fact to remember'),\r\n category: z.enum(['architecture', 'pattern', 'preference', 'bug', 'api', 'general']).describe('Category'),\r\n },\r\n async ({ fact, category }) => {\r\n const now = Date.now();\r\n storeFact({ projectId: 'current', content: fact, category, source: 'mcp', relevance: 1.0, createdAt: now, accessedAt: now });\r\n return { content: [{ type: 'text' as const, text: `Remembered: ${fact}` }] };\r\n },\r\n );\r\n\r\n // --- Resources ---\r\n\r\n mcp.resource(\r\n 'studio://status',\r\n 'studio://status',\r\n async () => {\r\n const info = bridge.getConnectionInfo();\r\n return {\r\n contents: [{\r\n uri: 'studio://status',\r\n text: JSON.stringify({\r\n connected: bridge.isConnected(),\r\n placeName: info?.placeName,\r\n placeId: info?.placeId,\r\n studioVersion: info?.studioVersion,\r\n port: bridge.getPort(),\r\n }, null, 2),\r\n mimeType: 'application/json',\r\n }],\r\n };\r\n },\r\n );\r\n\r\n // Start the MCP server on stdio\r\n const transport = new StdioServerTransport();\r\n await mcp.connect(transport);\r\n}\r\n\r\nfunction assertConnected(): void {\r\n if (!bridge.isConnected()) {\r\n throw new Error(\r\n 'Roblox Studio is not connected. Open Studio and click the Dominus plugin Connect button.',\r\n );\r\n }\r\n}\r\n","import { startMcpServer } from './server.js';\r\n\r\nstartMcpServer().catch((err) => {\r\n console.error('Failed to start Dominus MCP server:', err);\r\n process.exit(1);\r\n});\r\n"]}