import { type ChildProcess } from 'child_process'; export declare const BRIDGE_PORT = 9081; export declare const BRIDGE_HOST = "localhost"; export declare const BRIDGE_SCRIPT_NAME = "mcp_bridge.gd"; export declare const AUTOLOAD_KEY = "MCPBridge"; /** Bridge 连不上 / 未正常工作(游戏未运行、未装 autoload、认证失败)。agent 自愈:启动游戏 / 确认安装。 */ export declare class BridgeNotConnectedError extends Error { constructor(message: string); } /** Bridge 连上 + 认证成功后请求无响应(游戏被 runtime error 卡住)。agent 自愈:查游戏报错 / 加大 timeout。 * 批次2(2026-10-04 幂等层):携带 requestId 时 outcomeUnknown=true —— 超时不区分"未执行"与 * "已执行但响应丢失"(Godot 卡主线程:编译/场景切换),重试须传同一 requestId 命中 GD 侧去重。 */ export declare class BridgeTimeoutError extends Error { readonly outcomeUnknown = true; readonly requestId?: string; constructor(message: string, requestId?: string); } export declare const ERROR_CODES: { readonly BRIDGE_NOT_CONNECTED: "BRIDGE_NOT_CONNECTED"; readonly BRIDGE_TIMEOUT: "BRIDGE_TIMEOUT"; readonly BRIDGE_ERROR: "BRIDGE_ERROR"; }; /** Clamp a millisecond timeout value. Returns default on invalid/zero input. * Exported for pure-function unit tests (game-bridge-validation.test.ts)。 */ export declare function clampTimeoutMs(value: unknown, min?: number, max?: number, def?: number): number; declare const BRIDGE_REGISTRY_MAX_AGE_MS: number; export { BRIDGE_REGISTRY_MAX_AGE_MS }; /** 标记端口连接失败(ECONNREFUSED)——TTL 内 resolveBridgePort/scanSecretWindow 避开它。 */ export declare function _markPortFailed(port: number): void; /** 端口是否处于失败记忆期内。 */ export declare function _isPortFailed(port: number): boolean; /** 镜像 GD 侧 machine registry 目录。GD: OS.get_data_dir().get_base_dir().get_base_dir()/ * .godot-mcp/instances —— 实测三平台(Win %APPDATA%/Linux ~/.local/share/mac ~/Library/ * Application Support)两次 base_dir 都归一到用户主目录,与 instance-manager.getDefaultRegistryDir * (既有实现,~/.godot-mcp/instances)一致,直接复用防两处推导漂移。 * env GODOT_MCP_BRIDGE_REGISTRY_DIR 可重定向(测试注入;发现类信息源,重定向不涉安全边界)。 */ export declare function machineRegistryInstancesDir(): string; /** 项目路径归一化(分隔符统一 + Windows 大小写不敏感)用于跨进程 projectPath 匹配。 */ export declare function normalizeProjectKey(p: string): string; /** 解析 projectPath 对应 bridge 实例的实际监听端口(见区块注释);失败回落 BRIDGE_PORT。 * registryDir 参数仅供单测注入,生产走 machineRegistryInstancesDir()。 */ export declare function resolveBridgePort(projectPath: string, registryDir?: string): number; /** A4 (2026-09-16 反馈批,审查 B-1 修复): 读 machine-level registry,返回 projectPath 的 * 新鲜心跳端口集合 —— clean_stale_secrets 的判活依据。位置契约:与 resolveBridgePort 同源 * (GD machine_dir = OS.get_data_dir() 两次 base_dir → ~/.godot-mcp/instances,跨进程对齐 * 已被 resolveBridgePort 长期验证)。⚠️ 勿读 {project}/.godot/mcp-instances —— GD 的 * project-level 心跳写在 user://(app_userdata,非项目目录),TS 侧不可达(审查 B-1 教训: * 首版误按项目目录读,判活恒空集致清理永不执行)。过滤同 resolveBridgePort:capabilities * 含 registry-heartbeat(排除 server 自注册条目)+ projectPath 归一化匹配 + lastSeen 新鲜。 * registry 不可读/全损坏 → 空集(调用方按"无法判活"保守处理)。 */ export declare function liveHeartbeatPortsFor(projectPath: string, registryDir?: string): Set; /** 按实际端口拼 secret 文件路径(GD 侧 secret 文件名含避让后的端口)。 */ export declare function bridgeSecretPathFor(projectDir: string, port: number): string; export interface BridgeResponse { id: number | null; result?: unknown; error?: { code: number; message: string; }; } /** 桥身份快照(auth 响应协商所得;null=未知)。幂等重试提示据 capabilities 区分文案。 */ export declare function getBridgeIdentity(): { bridgeVersion: string | null; capabilities: string[]; } | null; /** 注入"首次 bridge 连接成功"回调(控制面 GodotServer.run() 接线 Dashboard 自动拉起);传 null 注销。 */ export declare function setOnBridgeConnected(cb: (() => void) | null): void; /** 登记订阅(同 method 仅保留最新一条 — GD 侧 per-peer 单例,重复 start 覆盖;登记表同步覆盖防重发重复订阅) */ export declare function _registerSubscription(method: 'watch.start' | 'monitor.start', params: Record): void; /** 移除订阅登记(watch_stop/monitor_stop 成功或重发被游戏侧拒绝时) */ export declare function _removeSubscription(method: 'watch.start' | 'monitor.start'): void; /** * P3-6: 注册 push 消息回调。Bridge addon 在 watch/monitor push 模式下, * 事件产生时主动推送 {method:"bridge/event", params:{type, data}} 消息。 * 此回调由 GodotServer 注册,将 push 事件转发为 MCP notification。 * 传 null 注销回调。 */ export declare function registerBridgePushHandler(handler: ((params: Record) => void) | null): void; /** Set the project directory for bridge secret lookup. Invalidates all cached bridge state. * * 2026-08-06 审查测试-P2(可靠性 §setBridgeProjectDir race): * 若 _sendLock 链上有 in-flight sendToBridge 请求(未 settle),直接 _invalidateSocket 会销毁 * in-flight 请求持有的 socket → 响应丢失 → 该请求在 timer 后 reject。跨项目切换的并发场景 * (client A 调 P1,client B 调 setBridgeProjectDir(P2))下,A 失败但 B 可继续,无原子性保证。 * * 本修复:检测到 in-flight 时记录 warn(可视化),仍 invalidate(保持现有契约——bridge 是 * per-server 单项目,跨项目切换是异常用法,由调用方保证不并发)。彻底修复需引入 per-project * 锁 + per-project socket 状态,属架构级改造,超本轮 scope(留 follow-up)。 */ /** 当前生效的 bridge 项目目录(未设置时 null;工具层 ensureProjectDir 回退判断用)。 */ export declare function getBridgeProjectDir(): string | null; /** 清除缓存的 bridge secret(auth 失败 -32001/-32002 或 uninstall 后,下次调用重读磁盘)。 */ export declare function invalidateBridgeSecret(): void; /** 销毁当前连接(状态重置;uninstall 等语义终结场景用,业务代码一般走自动重连)。 */ export declare function invalidateBridgeConnection(): void; export declare function setBridgeProjectDir(projectDir: string | null): void; /** 批次2(2026-10-04 幂等层): 请求级选项。requestId = 写命令幂等键 —— GD 侧按其去重 * (重复请求直接回首次响应),超时错误携带它供 agent 原身份重试(对齐 unity-mcp-server * "按身份重试而非按命令重试")。旧版 GD 忽略未知字段,透传无害。 */ export interface SendOptions { requestId?: string; } export declare function sendToBridge(method: string, params?: Record, timeout?: number, opts?: SendOptions): Promise; /** Reset all module state — for test isolation and service restart. */ export declare function resetBridgeState(): void; export interface BridgeReadyResult { ready: boolean; reason: string; } /** * 探测 bridge autoload 是否已启动并接受 auth。轮询直到就绪/进程退出/超时。 * 全程零接触模块级缓存:secret 由 projectDir 自拼路径自读。 */ export declare function isBridgeReady(projectDir: string, timeoutMs: number, opts?: { proc?: ChildProcess; isCancelled?: () => boolean; }): Promise; /** 测试专用:模块缓存快照,用于断言 isBridgeReady 零接触。 */ export declare function _testBridgeCacheState(): { projectDir: string | null; cachedSecret: string | null; socketNotNull: boolean; };