/** * 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'; /** 转义正则元字符。用于 autoload 名称匹配。 */ export declare function escapeRegExp(str: string): string; /** @internal 测试用:重置缓存 */ export declare function _resetAutoloadCache(): void; /** * 从 project.godot 解析 autoload 单例名列表。 * 全面 try-catch:任何错误返回空数组。 */ export declare function parseAutoloadNames(projectPath: string): string[]; /** * 纯函数:project.godot 内容含 orphan bridge autoload 行时返回移除后的新内容,否则 null。 * (逻辑/IO 分离:纯字符串可稳定单测。注意键大小写——真实键为 MCPBridge(大写, * bridge-client.ts AUTOLOAD_KEY),首版实现与测试双双手误小写 McpBridge,错打正着 * 掩盖至审查 I-2 修正;键名常量必须 grep 写入方核对,不能信记忆/注释。) */ export declare function removeOrphanBridgeLines(content: string): string | null; /** * P2-4 (2026-09-11): orphan autoload 修复——project.godot 残留 McpBridge autoload 条目但 * 脚本本体已删(手删/卸载残留)时,每次 headless 操作都会因 autoload 加载失败而崩 * (来源 Erodenn bridge-manager.ts repairOrphaned 的前置自愈)。IO 壳:读→纯函数判定→原子写。 * 返回 true = 本次修复了(调用方 warn 留痕)。幂等:无 orphan 返回 false 零写入。 * 行为断言走纯函数 removeOrphanBridgeLines(本壳 IO 含 tmpdir 写盘,冒烟级覆盖)。 */ export declare function repairOrphanedBridgeAutoload(projectPath: string): boolean; /** * 检测代码中是否引用了 autoload 单例。 * A-2 (advisory): 改用 stripLiterals 骨架扫描(剥注释/字符串),消除原词边界匹配的误触发。 */ export declare function detectAutoloadUsage(code: string, autoloadNames: string[]): string[]; export declare function stripLiterals(code: string): string; /** @internal 测试用:重置 extra patterns 缓存 */ export declare function _resetExtraDangerousPatternsCache(): void; /** * 从环境变量 GODOT_MCP_EXTRA_DANGEROUS_PATTERNS 加载用户自定义危险正则。 * 格式:JSON 数组 [{"pattern": <正则源码>, "label": <人类可读标签>}, ...] * * memoized:以 raw 字符串为键,相同 env 不重复解析(风格同 _autoloadCache)。 * 坏正则/坏 JSON 降级:跳过该条或整体忽略,记录 warn,绝不抛异常。 */ export declare function loadExtraDangerousPatterns(): Array<{ pattern: RegExp; label: string; }>; export declare function scanGdscriptSandbox(code: string, opts?: { skipPhase3?: boolean; }): string[]; 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;