import { useCallback, useEffect, useMemo, useState } from 'react' import { numberedInvoke } from './numbered-ipc' export interface DirectSessionProjection { sessionId: string laneId: string clientInstanceId: string state: 'LIVE' | 'RESUMABLE' openedAtUnixMs: number observedAtUnixMs: number lastEventSequence: number } interface AuthorizationRequest { requestId: string action: 'OPEN_MAINTENANCE' | 'UNMOUNT' | 'PROMOTE_VERSION' | 'RETIRE' targetNumber: string targetKind: string targetLabel: string reason: string impact: string rollbackPlan: string requesterLabel: string state: 'PENDING_HUMAN' | 'APPROVED' | 'DENIED' | 'EXPIRED' | 'CONSUMED' createdAtUnixMs: number expiresAtUnixMs: number humanNumber?: string decidedAtUnixMs?: number ticketId?: string ticketExpiresAtUnixMs?: number consumedAtUnixMs?: number receiptHash: string } interface AuthorizationCenterSnapshot { state: string pendingCount: number requests: AuthorizationRequest[] purgeEnabled: boolean } interface Props { brokerState: string activeConnectionCount: number sessions: DirectSessionProjection[] } const actionLabels: Record = { OPEN_MAINTENANCE: '打开受控维护区', UNMOUNT: '从当前频道卸载', PROMOTE_VERSION: '登记并启用新版本', RETIRE: '停用并保留历史坐标', } const stateLabels: Record = { PENDING_HUMAN: '等待你决定', APPROVED: '已同意 · 等待执行体领取', DENIED: '已拒绝', EXPIRED: '已过期', CONSUMED: '票据已领取一次', } function time(value?: number) { return value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '—' } export function HumanAuthorizationCenter({ brokerState, activeConnectionCount, sessions }: Props) { const [snapshot, setSnapshot] = useState(null) const [busy, setBusy] = useState('') const [message, setMessage] = useState('') const refresh = useCallback(async () => { try { setSnapshot(await numberedInvoke('get_authorization_center')) setMessage('') } catch (error) { setSnapshot(null) setMessage(String(error).includes('AUTHENTICATED_ACCOUNT_REQUIRED') ? '登录并完成编号验证后,授权中心才会打开。' : '授权中心当前不可读取;系统不会把未知状态当成已授权。') } }, []) useEffect(() => { void refresh() const timer = window.setInterval(() => { if (!document.hidden) void refresh() }, 4_000) return () => window.clearInterval(timer) }, [refresh]) const decide = async (requestId: string, decision: 'APPROVE' | 'DENY') => { setBusy(requestId) setMessage('') try { await numberedInvoke('decide_authorization_request', { input: { requestId, decision } }) setMessage(decision === 'APPROVE' ? '已签发一次性票据;它只对原执行会话和本次目标有效。' : '已拒绝;执行体不会获得继续通道。') await refresh() } catch { setMessage('这次决定没有写入。授权状态保持不变,请刷新后再看。') } finally { setBusy('') } } const pending = snapshot?.requests.filter((item) => item.state === 'PENDING_HUMAN') || [] const history = snapshot?.requests.filter((item) => item.state !== 'PENDING_HUMAN').slice(0, 6) || [] const connectionState = activeConnectionCount > 0 ? '正在直连' : sessions.some((item) => item.state === 'LIVE') ? '最近仍有心跳' : '当前没有在线执行体' const sessionList = useMemo(() => sessions.slice(0, 6), [sessions]) return
HUMAN DECISION

需要你决定的事

人格体提出申请,系统把对象、原因、影响和退路交给你;只有你点同意,原执行会话才会收到一次性票据。

{pending.length ? `${pending.length} 项待确认` : '没有待确认事项'}
{pending.length === 0 ?
现在不需要你操作删除、停用、维护和正式更新不会在后台静默通过。
:
{pending.map((request) =>
{actionLabels[request.action]}

{request.targetLabel}

{request.targetNumber}
{stateLabels[request.state]}
为什么要做
{request.reason}
会影响什么
{request.impact}
出问题怎么退
{request.rollbackPlan}
谁在申请
{request.requesterLabel}
申请到期
{time(request.expiresAtUnixMs)}
)}
} {message &&

{message}

}
LIVE COLLABORATION

当前谁连着 HoloLake

这里显示真实本机会话和最近心跳,不把“装过 Agent”冒充成“正在连接”。

0 ? 'status-chip online' : 'status-chip'}>{connectionState}
{activeConnectionCount}当前直连
{sessions.length}可续接会话
{brokerState === 'READY' ? '就绪' : '等待'}本机入口
{sessionList.length ?
{sessionList.map((session) =>
{session.clientInstanceId}{session.laneId} · 最近心跳 {time(session.observedAtUnixMs)}
{session.state === 'LIVE' ? '在线' : '可续接'}
)}
:
还没有执行体会话外部编程 AI 通过 HoloLake 本机连接后,会在这里出现。
}
{history.length > 0 &&
最近的授权回执 · {history.length}
{history.map((request) =>
{request.targetLabel}{actionLabels[request.action]}
{stateLabels[request.state]}{request.humanNumber ? `由 ${request.humanNumber} 决定 · ` : ''}{time(request.decidedAtUnixMs || request.createdAtUnixMs)}
)}
}
}