export interface WebGuiRegistration { pid: number; port: number; token: string; startedAt: string; /** server 版本(实例管理批 2026-09-30):面板区分新旧代码实例的判据。 * 可选——旧版本登记文件无此字段,parseRegistrationFile 不校验它(向后兼容), * 前端以在场性显示「早期实例」。 */ version?: string; /** daemon 批 A(2026-09-30 spec §3.4):实例类型。可选——旧登记无此字段, * parseRegistrationFile 不校验(对齐 version 字段先例),前端按「早期实例」语义兼容。 */ kind?: 'stdio' | 'daemon'; /** daemon 批 B(2026-09-30 spec §3.7):受控交接关联——新 daemon 以 --respawn-of=<旧pid> * 启动时写入旧 pid,前端/daemon status 对旧条目显示「交接中」的标注数据源。 * 可选,parseRegistrationFile 不校验(对齐 kind 字段先例,向后兼容)。 */ respawnOf?: number; } export interface RegistryOpts { /** 测试注入目录;缺省 ~/.godot-mcp/web-gui/ */ dir?: string; /** pid 探活注入点(测试 mock);缺省 process.kill(pid, 0) */ isPidAlive?: (pid: number) => boolean; } export declare function webGuiRegistryDir(): string; /** 共享 token 形状(导出复用:portal.ts 内嵌前同款校验,单一校验来源)。 */ export declare const SHARED_TOKEN_RE: RegExp; /** * 共享持久 token(2026-09-16 入口简化批):registry 目录一份 token.txt,首实例生成后续复用。 * 动机:原 token 每进程随机生成,server 重启即换 → 旧面板 cookie 立即作废(入口不自愈根因)。 * cookie 域不分端口(RFC 6265),同 host 全端口有效 → 所有实例共享一份 token 后, * 任一实例种下的 cookie 对全部端口有效,前端跨实例/跨重启迁移无需重新鉴权。 * 并发窗口:两实例同时首启可能各生成一份各写各的——写后以重读文件为准,收敛到最后写者的值 * (毫秒级窗口,仅影响启动瞬间,方向安全:两实例最终一致)。 * 0o600 + Windows icacls 对齐登记文件惯例;损坏/格式非法时重新生成。 */ export declare function getOrCreateSharedToken(opts?: RegistryOpts): string; export interface RotateTokenOpts extends RegistryOpts { /** 入口页重写目标包根;缺省按本模块位置上三级推导(server.ts 同款)。 */ packageRoot?: string; } /** * 轮换共享 token(M-2,2026-09-17 审查批):删 token.txt → getOrCreateSharedToken 生成新值 * → 若包根入口页(面板入口.html,内嵌 token 的落盘副本)存在则用新 token 重写 → 返回新值。 * 动机:token 疑似泄露(终端贴 URL/录屏/分享截图)后的主动止损出口——旧值作废,新实例/新会话 * 收敛新值。诚实边界:已运行实例的内存 token 不热更新,须重启才认新值(rotate 防守的是 * "后续不再认旧 token",不是即时踢线);入口页仅在已存在时重写,不新增写入面。 */ export declare function rotateSharedToken(opts?: RotateTokenOpts): string; /** S-5 同款(instance-manager.ts:94):Windows 无视 mode,用 icacls 收紧 ACL;best-effort。 * 导出复用供 projects-store 等同域持久化文件共享(I-E 教训:导出复用而非复制; * Web GUI 项目面板 spec 2026-09-15 §3.1 要求照抄本模式)。 * 批4-T10(五维评估 P3): :F → :M 对齐 editor/bridge/api secret 收紧惯例——token.txt * 同为凭证,属主无需改 ACL/取所有权(Modify 含读写删,rotate/生命周期写不受影响); * instance-manager.ts 私有副本保持 :F(非凭证,既有注释有生命周期论证,不属本面对齐范围)。 */ export declare function hardenFilePermissionsWindows(filePath: string): void; export declare function writeRegistration(entry: WebGuiRegistration, opts?: RegistryOpts): Promise; export declare function removeRegistration(pid: number, opts?: RegistryOpts): Promise; /** * daemon 批 A(spec §3.7 第 2 轮 m-7):校验内容后删登记——PID 复用场景下防误删他人登记。 * 交接序列步骤 3(旧进程删自身登记)的消费点:OS 回收 pid 后新进程可能撞上旧文件名 * `.json`,仅凭 pid 删会把别人的登记清掉。文件不存在/解析失败 → false(视为已清); * pid 或 startedAt 不匹配 → false 且不删。 */ export declare function removeRegistrationVerified(pid: number, expectedStartedAt: string, opts?: RegistryOpts): Promise; /** * 登记文件读取 + 形状校验(审查 Low,2026-09-17 批 3 抽取):listRegistrations 与 * sweepStaleRegistrations 共用的单一校验来源。读失败/JSON 损坏/三字段判型不过/ * token 字符集白名单(/^[A-Za-z0-9_-]+$/,无 shell 元字符即安全等价)任一不过 → null; * 合法返回 WebGuiRegistration。 */ export declare function parseRegistrationFile(dir: string, fileName: string): Promise; export declare function listRegistrations(opts?: RegistryOpts): Promise; /** * 陈旧登记清扫(2026-09-15 独立批):删除 pid 已死的登记文件,返回删除数。 * 动机:Windows 强杀(taskkill/断电)不走 exit-hook,死登记只靠 listRegistrations * 的顺手清——而该函数仅 dashboard CLI 探活路径调用,server 自身只写不读 → 持续堆积。 * server 启动时 fire-and-forget 调本函数(server.ts start() 接线)。 * 诚实边界:pid 复用时 isPidAlive 误报 true → 该条目保留(方向安全:垃圾无害,误删活登记才有害)。 * 非 WebGuiRegistration 形态文件(如 projects.json)经同 listRegistrations 的格式校验跳过,不删。 */ export declare function sweepStaleRegistrations(opts?: RegistryOpts): Promise;