import type { Issue } from '../gitea/types' export const KANBAN_SNAPSHOT_KEY = 'superpowers.kanbanSnapshot' export interface KanbanSnapshot { issues: Issue[] scope: 'mine' | 'all' me?: string /** Gitea login → 头像 data URI;团队视图下卡片按人贴头像。 */ avatars?: Record globalAutoReview: boolean youtrackConfigured: boolean } function isAvatarMap(raw: unknown): raw is Record { return !!raw && typeof raw === 'object' && Object.values(raw).every(v => typeof v === 'string') } export function parseKanbanSnapshot(raw: unknown): KanbanSnapshot | null { if (!raw || typeof raw !== 'object') return null const obj = raw as Record if (!Array.isArray(obj.issues)) return null if (obj.scope !== 'mine' && obj.scope !== 'all') return null return { issues: obj.issues as Issue[], scope: obj.scope, me: typeof obj.me === 'string' ? obj.me : undefined, avatars: isAvatarMap(obj.avatars) ? obj.avatars : undefined, globalAutoReview: obj.globalAutoReview === true, youtrackConfigured: obj.youtrackConfigured === true, } } /** 写入 HTML 的 JSON:小于号换成 \\u003c,避免 script 标签被提前关掉。 */ export function snapshotToScriptJson(snapshot: KanbanSnapshot): string { return JSON.stringify(snapshot).replace(/${snapshotToScriptJson(snapshot)}` }