/** * GDScript executor module for Godot MCP Enhanced. * * Enables execution of arbitrary GDScript code in a headless Godot process. * Inspired by Hastur Operation Plugin's remote execution design: * - Code snippet auto-wrapping (no `extends` → auto-wrap) * - Structured key-value output via `_mcp_output(key, value)` * - Marked output protocol for reliable parsing * * SECURITY WARNING: GDScript has full system access (FileAccess, DirAccess, * OS.execute = arbitrary shell). scanGdscriptSandbox provides a blacklist to catch * accidental misuse, NOT a security boundary — GDScript is Turing-complete so regex * cannot exhaustively block indirect/reflection bypasses (variable first-arg to * .call(), StringName(), etc.). Acceptable for local single-user MCP; for multi-user * or untrusted input use container/VM isolation + GODOT_MCP_ALLOW_UNSAFE=false. */ import { type ParsedError } from './error-analyzer.js'; import { MARKER_RESULT as MARKER_RESULT_SHARED, MARKER_ERROR as MARKER_ERROR_SHARED } from './tools/shared.js'; export { escapeRegExp, stripLiterals, scanGdscriptSandbox, loadExtraDangerousPatterns, detectAutoloadUsage, parseAutoloadNames, removeOrphanBridgeLines, repairOrphanedBridgeAutoload, _resetAutoloadCache, _resetExtraDangerousPatternsCache, } from './core/sandbox-scanner.js'; export interface OutputEntry { key: string; value: string; } export interface ExecuteGdscriptResult { success: boolean; compile_success: boolean; compile_error: string; /** Structured error list with type, file, line, message, and suggestion */ errors: ParsedError[]; run_success: boolean; run_error: string; outputs: OutputEntry[]; raw_output: string; duration_ms: number; /** Auto-detected autoload references (non-empty when load_autoloads was auto-enabled) */ autoload_detected?: string[]; /** C-AUDIT: per-execution id(对照 UE 9b128514),崩溃/超时后凭日志反查具体执行 */ executionId?: string; /** C-AUDIT: 原始用户 code 的字节级 SHA-256(hex),不含原始 code 本身(对齐 I-10) */ scriptSha256?: string; } export interface ExecuteGdscriptOptions { godotPath: string; projectPath: string; code: string; timeout: number; /** When true, runs with full autoload context (slower but can access autoloads like DataRegistry) */ loadAutoloads?: boolean; } export interface ExecAuditEvent { audit: 'EXECUTE_BEGIN'; executionId: string; scriptSha256: string; scriptPath: string; mode: string; autoload: boolean; } export declare function buildExecAuditEvent(input: { code: string; scriptPath: string; mode: string; autoload: boolean; }): ExecAuditEvent; /** Execute GDScript with sandbox scanning disabled. Only for internal trusted code paths. */ export declare function executeGdscriptTrusted(options: Omit): Promise; export declare function executeGdscriptRuntime(options: Omit): Promise; /** Re-export markers from shared.ts for consumers that import from this module */ export { MARKER_RESULT_SHARED as MARKER_RESULT, MARKER_ERROR_SHARED as MARKER_ERROR }; /** * Detect if the code is a "full class" (contains `extends`) * or a "snippet" that needs auto-wrapping. */ export declare function isFullClass(code: string): boolean; /** * Wrap a snippet into a valid `extends SceneTree` script with helper functions. * Splits user code into declarations (class-level) and statements (inside _initialize). * This allows func/var/const definitions to work correctly at class scope. */ export declare function wrapSnippet(code: string, resultMarker?: string): string; /** * Wrap a snippet as `extends Node` for autoload mode. * The loader scene instantiates this via .new(), so it must be a Node subclass. */ export declare function wrapSnippetAsNode(code: string, resultMarker?: string): string; /** * For full class mode, inject helper functions and result reporting. */ export declare function injectHelpers(code: string): string; export declare function parseMcpMarkers(raw: string, resultMarker?: string, errorMarker?: string): { parsed: { success: boolean; outputs?: OutputEntry[]; error?: string; } | null; logLines: string[]; }; export declare function executeGdscript(options: ExecuteGdscriptOptions): Promise; /** * Create a minimal .tscn scene that loads with autoload context. * The scene runs the user's script from _ready(). */ export declare function createAutoloadLoaderScene(loaderScriptPath: string): string; /** * Create the loader GDScript that loads with autoload context. * In _ready(), all autoloads are available. It then loads and runs the user script. */ export declare function createAutoloadLoaderScript(userScriptPath: string, errorMarker: string): string;