import { frameIsActive, frameSessionId, type FrameEvent, type FramePayload, type StoreState } from "./shared"; /** 代审帧处理组:approval_notice —— 主代理代审小字(design/11 §4,裁决 13.4.3)。 * 敏感操作(如 terminal)经代审后后端广播该帧,`explain` 是后端产出的固定文案 * 「xxx 想要干什么,我审查后批准了 / 拒绝了」,前端原样渲染成聊天流里的一行小字。 * 命中返回 true,未命中返回 false 交给下一组。 */ export function handleApprovalEvent(ev: FrameEvent, r: FramePayload, s: StoreState): boolean { if (ev.type !== "approval_notice") return false; // 小字是单槽状态,只认屏幕上这个会话:别的会话发生的代审不写进当前会话 // (与 stream_end / 忙态同一判据:shared 的 frameIsActive)。 if (!frameIsActive(frameSessionId(ev, r), s.activeSessionId)) return true; // 没有文案就没有可渲染的小字 —— 丢掉这帧,而不是编造一句。 const explain = typeof r?.explain === "string" ? r.explain : ""; if (!explain) return true; s.setApprovalNotice({ explain, actor: typeof r?.actor === "string" ? r.actor : "", tool: typeof r?.tool === "string" ? r.tool : "", op: typeof r?.op === "string" ? r.op : "", detail: typeof r?.detail === "string" ? r.detail : "", // 后端只在整条代审失败/拒绝时发 allowed=false;缺字段按「已批准」处理, // 与后端 RecordApproval 写入的布尔一致。 allowed: r?.allowed !== false, at: typeof r?.at === "string" ? r.at : "", }); return true; }