feat: ship dual-signed online module marketplace
This commit is contained in:
parent
3153771bf2
commit
b0eeade03d
40 changed files with 5774 additions and 111 deletions
|
|
@ -8,6 +8,7 @@ import { StarlakeSurface, type DomainId } from './modules/qoder-surface/Starlake
|
|||
import { FINISHES, TraditionalSurface, type FinishId, type TraditionalBroadcast, type TraditionalChannel, type TraditionalSystem } from './modules/qoder-surface/TraditionalSurface'
|
||||
import { resolveVisualBalance } from './modules/qoder-surface/visual-balance'
|
||||
import { PrivateChannelSurface, type InstalledChannelModule, type PrivateChannelAction } from './modules/private-channel/PrivateChannelSurface'
|
||||
import { HumanAuthorizationCenter, type DirectSessionProjection } from './modules/human-authorization-center'
|
||||
|
||||
const ChannelWorkbenchStudio = lazy(() => import('./modules/channel-workbench').then((module) => ({ default: module.ChannelWorkbenchStudio })))
|
||||
const PersonaChannelBody = lazy(() => import('./modules/persona-channel-body').then((module) => ({ default: module.PersonaChannelBody })))
|
||||
|
|
@ -60,7 +61,7 @@ import './design-tokens.css'
|
|||
import './styles.css'
|
||||
|
||||
type ThemeId = 'night' | 'dawn' | 'nebula' | 'candle' | 'clear'
|
||||
type ViewId = 'overview' | 'knowledge' | 'composition' | 'workbench' | 'education' | 'webNovel' | 'mobileSync' | 'persona' | 'code' | 'receipts' | 'system'
|
||||
type ViewId = 'overview' | 'knowledge' | 'composition' | 'workbench' | 'education' | 'webNovel' | 'mobileSync' | 'persona' | 'code' | 'marketplace' | 'receipts' | 'system'
|
||||
type WorldStage = 'domain' | 'heart' | 'heartbeat' | 'lightLake' | 'love' | 'tomorrow' | 'bottle' | 'channel' | 'enterpriseWork' | 'personalNodeGuide' | 'tool'
|
||||
type KnowledgeSource = 'native' | 'legacy'
|
||||
|
||||
|
|
@ -74,6 +75,43 @@ interface BundledModuleDescriptor {
|
|||
installedState: string
|
||||
signatureVerified: boolean
|
||||
}
|
||||
type MarketplaceKind = 'PHYSICAL_MODULE' | 'COGNITIVE_SKILL'
|
||||
interface MarketplaceItemView {
|
||||
itemNumber: string
|
||||
artifactKind: MarketplaceKind
|
||||
displayName: string
|
||||
summary: string
|
||||
version: string
|
||||
sourceRepository: string
|
||||
sourceRevision: string
|
||||
artifactSha256: string
|
||||
adapter?: string | null
|
||||
permissions: string[]
|
||||
executionAuthority: boolean
|
||||
installedState: string
|
||||
updateAvailable: boolean
|
||||
}
|
||||
interface MarketplaceSnapshot {
|
||||
schema: 'hololake.online-marketplace-snapshot/v1'
|
||||
state: string
|
||||
trustState: string
|
||||
catalogEpoch: number
|
||||
catalogSha256: string
|
||||
itemCount: number
|
||||
catalogReceiptCount: number
|
||||
latestCatalogReceiptHash: string
|
||||
lastSyncNote: string
|
||||
items: MarketplaceItemView[]
|
||||
}
|
||||
interface MarketplaceMutationOutcome {
|
||||
state: string
|
||||
itemNumber: string
|
||||
artifactKind: MarketplaceKind
|
||||
artifactSha256: string
|
||||
packageCodeExecuted: false
|
||||
realityAuthorityGranted: false
|
||||
snapshot: MarketplaceSnapshot
|
||||
}
|
||||
interface WorldClimateSnapshot {
|
||||
schema: 'hololake.world-climate/v1'
|
||||
state: 'VERIFIED_LIVE' | 'TIME_ONLY_WEATHER_UNAVAILABLE'
|
||||
|
|
@ -93,6 +131,7 @@ interface HomeStatus {
|
|||
directLocalBrokerState: string
|
||||
directConnectionCount: number
|
||||
resumableSessionCount: number
|
||||
directSessions: DirectSessionProjection[]
|
||||
codeRepositoryMountCount: number
|
||||
pnccReceiptCount: number
|
||||
updateState: string
|
||||
|
|
@ -284,8 +323,18 @@ interface ZeroPointSnapshot {
|
|||
resolvedDomain: string
|
||||
lastValidCheck: number
|
||||
graceDeadline: number
|
||||
protocol: { gracePeriodDays: number; lighthouseAnchorUrl: string; lighthouseResolveUrl: string; coreChannelSource: string; origin: string }
|
||||
protocol: { gracePeriodDays: number; lighthouseAnchorUrl: string; lighthouseResolveUrl: string; enterpriseResolveUrl: string; coreChannelSource: string; origin: string }
|
||||
syncNote: string
|
||||
publicDistribution: {
|
||||
state: string
|
||||
epoch: number
|
||||
version: string
|
||||
contentRootSha256: string
|
||||
rollbackAvailable: boolean
|
||||
receiptCount: number
|
||||
latestReceiptHash: string
|
||||
trustState: string
|
||||
}
|
||||
}
|
||||
|
||||
function domainDisplayName(domain: string): string {
|
||||
|
|
@ -385,14 +434,14 @@ interface EnterpriseReceiptEnvelope {
|
|||
repository_projection?: EnterpriseReceiptProjection
|
||||
}
|
||||
|
||||
const previewStatus: HomeStatus = { directLocalBrokerState: 'UNVERIFIED', directConnectionCount: 0, resumableSessionCount: 0, codeRepositoryMountCount: 0, pnccReceiptCount: 0, updateState: 'READY_HUMAN_CONFIRMATION_REQUIRED', releaseRecoveryState: 'NONE', mcpRole: 'DISCOVERY_RECOVERY_COMPATIBILITY_ONLY', terminalLinkProtocol: 'HOLOLAKE_TERMINAL_LINK/3', terminalLinkTransport: 'UNVERIFIED', environmentFramePolicy: 'REQUIRED_AFTER_CONNECT_RESUME_AND_BEFORE_MUTATION' }
|
||||
const previewStatus: HomeStatus = { directLocalBrokerState: 'UNVERIFIED', directConnectionCount: 0, resumableSessionCount: 0, directSessions: [], codeRepositoryMountCount: 0, pnccReceiptCount: 0, updateState: 'READY_HUMAN_CONFIRMATION_REQUIRED', releaseRecoveryState: 'NONE', mcpRole: 'DISCOVERY_RECOVERY_COMPATIBILITY_ONLY', terminalLinkProtocol: 'HOLOLAKE_TERMINAL_LINK/3', terminalLinkTransport: 'UNVERIFIED', environmentFramePolicy: 'REQUIRED_AFTER_CONNECT_RESUME_AND_BEFORE_MUTATION' }
|
||||
const previewPersonal: PersonalChannelSnapshot = { state: 'UNAVAILABLE', recentEvents: [], modules: [], integrity: { state: 'UNKNOWN', eventCount: 0, receiptCount: 0 } }
|
||||
const previewKnowledge: KnowledgeSnapshot = { state: 'UNAVAILABLE', nativeRoot: '', legacyAvailable: false, documents: [], rawDocumentCount: 0, uniqueDocumentCount: 0, duplicateDocumentCount: 0, truncated: false }
|
||||
const previewCode: CodeChannelSnapshot = { state: 'UNAVAILABLE', channels: [], authority: 'LOCAL_SOURCE_ACCESS_ONLY_NO_PUSH_OR_DEPLOY_AUTHORITY' }
|
||||
const themes: Array<{ id: ThemeId; name: string }> = [
|
||||
{ id: 'night', name: '夜湖星光' }, { id: 'dawn', name: '晨湖曦光' }, { id: 'nebula', name: '星云紫夜' }, { id: 'candle', name: '烛畔暖湖' }, { id: 'clear', name: '清浅澄湖' },
|
||||
]
|
||||
const viewLabels: Record<ViewId, string> = { overview: '个人频道', knowledge: '知识空间', composition: '结构组合', workbench: '频道资料工作台', education: '教育工作台', webNovel: '网文作者工作台', mobileSync: '移动同步桥', persona: '人格频道本体', code: '人格代码频道', receipts: '运行回执', system: '系统详情' }
|
||||
const viewLabels: Record<ViewId, string> = { overview: '个人频道', knowledge: '知识空间', composition: '结构组合', workbench: '频道资料工作台', education: '教育工作台', webNovel: '网文作者工作台', mobileSync: '移动同步桥', persona: '人格频道本体', code: '人格代码频道', marketplace: '分域模块商城', receipts: '运行回执', system: '授权与连接' }
|
||||
const domainGates = [
|
||||
{ domain: 'BRANCH_DOMAIN', className: 'd-sub', title: '光湖分域', gate: 'GATE 02 · ONLINE', facts: [
|
||||
['公共作用', '行业成品模块商城 · 人格体大脑技能商城'], ['域标识', 'BRANCH_DOMAIN'], ['责任主体', '花尔 · TCS-GL-0005∞'], ['人格体主体', '爆米花 · PER-BMH001 · AGE'], ['关系支持', '糖星云 · PER-TXY001 · AGE'], ['工作仓库', 'PRIVATE · 1 · LIVE'],
|
||||
|
|
@ -498,6 +547,11 @@ function humanError(error: unknown, context: 'knowledge' | 'code' | 'identity' |
|
|||
if (value.includes('LOGIN_ACCOUNT_BINDING_UNREGISTERED')) return '这个编号尚未登记对应的仓库账号,系统已停止进入。'
|
||||
if (value.includes('DOMAIN_LOGIN_NOT_PROVISIONED')) return '该域的企业服务器尚未接入,当前不能继续登录。'
|
||||
if (value.includes('PERSISTENT_CREDENTIAL_UNAVAILABLE')) return '当前系统尚未接通安全凭证存储,不能完成签署。'
|
||||
if (value.includes('MARKETPLACE_PERMISSION_CONFIRMATION_REQUIRED')) return '新增现实权限尚未得到本人确认,安装已停止。'
|
||||
if (value.includes('MARKETPLACE_CATALOG_NOT_SYNCED')) return '模块商城目录尚未完成双签同步。'
|
||||
if (value.includes('MARKETPLACE_CATALOG_CHANGED')) return '商城目录已更新,请重新确认后安装。'
|
||||
if (value.includes('MARKETPLACE') && value.includes('SIGNATURE')) return '商城签名验证未通过,目录或安装包没有被采用。'
|
||||
if (value.includes('MARKETPLACE') || value.includes('SKILL_')) return '模块商城操作未完成;本机现有安装保持不变。'
|
||||
if (value.includes('ENTERPRISE_RECEIPT_FAILED')) return '企业回执没有写入,请稍后重新提交。'
|
||||
if (value.includes('ENTERPRISE_RECEIPT_ROUTE_REQUIRED')) return '此签署入口仅适用于企业四域。'
|
||||
if (value.includes('DOMAIN_ROUTE_REQUIRED') || value.includes('ZP_DOMAIN_ROUTE_REQUIRED')) return '编号尚未解析到已登记域,不能开始登录。'
|
||||
|
|
@ -648,6 +702,11 @@ function HoloLakeApp() {
|
|||
const [worldClimate, setWorldClimate] = useState<WorldClimateSnapshot | null>(null)
|
||||
const [dynamicSurfaceBusy, setDynamicSurfaceBusy] = useState(false)
|
||||
const [dynamicSurfaceMessage, setDynamicSurfaceMessage] = useState('')
|
||||
const [marketplace, setMarketplace] = useState<MarketplaceSnapshot | null>(null)
|
||||
const [marketplaceKind, setMarketplaceKind] = useState<MarketplaceKind>('PHYSICAL_MODULE')
|
||||
const [marketplaceBusyItem, setMarketplaceBusyItem] = useState('')
|
||||
const [marketplaceSyncing, setMarketplaceSyncing] = useState(false)
|
||||
const [marketplaceMessage, setMarketplaceMessage] = useState('')
|
||||
const [expanded, setExpanded] = useState<Set<string>>(() => new Set(['导入']))
|
||||
const [editing, setEditing] = useState(false)
|
||||
const [draft, setDraft] = useState('')
|
||||
|
|
@ -1295,6 +1354,86 @@ function HoloLakeApp() {
|
|||
else { setDynamicSurfaceModule(null); setWorldClimate(null); setDynamicSurfaceMessage('') }
|
||||
}, [repoLogin?.username, repoLogin?.domain])
|
||||
|
||||
const refreshMarketplace = async () => {
|
||||
try {
|
||||
const snapshot = await invoke<MarketplaceSnapshot>('get_marketplace_snapshot')
|
||||
setMarketplace(snapshot)
|
||||
setMarketplaceMessage(snapshot.lastSyncNote)
|
||||
return snapshot
|
||||
} catch (error) {
|
||||
setMarketplaceMessage(humanError(error, 'system'))
|
||||
return null
|
||||
}
|
||||
}
|
||||
const syncMarketplace = async () => {
|
||||
setMarketplaceSyncing(true)
|
||||
setMarketplaceMessage('正在读取线上目录并核验零点原核与企业发布双签……')
|
||||
try {
|
||||
const snapshot = await invoke<MarketplaceSnapshot>('sync_marketplace_catalog')
|
||||
setMarketplace(snapshot)
|
||||
setMarketplaceMessage(snapshot.lastSyncNote)
|
||||
} catch (error) {
|
||||
setMarketplaceMessage(humanError(error, 'system'))
|
||||
} finally {
|
||||
setMarketplaceSyncing(false)
|
||||
}
|
||||
}
|
||||
const openMarketplace = () => {
|
||||
openWorldTool('marketplace')
|
||||
void refreshMarketplace().then((snapshot) => {
|
||||
if (!snapshot || snapshot.state !== 'ACTIVE_VERIFIED_CATALOG') void syncMarketplace()
|
||||
})
|
||||
}
|
||||
const installMarketplaceItem = async (item: MarketplaceItemView) => {
|
||||
if (!marketplace) return
|
||||
const permissionText = item.permissions.length
|
||||
? `该模块请求以下现实能力:\n\n${item.permissions.map((permission) => `• ${permission}`).join('\n')}\n\n是否确认安装?`
|
||||
: `确认安装“${item.displayName}”?`
|
||||
if (!window.confirm(permissionText)) return
|
||||
setMarketplaceBusyItem(item.itemNumber)
|
||||
setMarketplaceMessage(`正在下载、验签并安装 ${item.displayName}……`)
|
||||
try {
|
||||
const result = await invoke<MarketplaceMutationOutcome>('install_marketplace_item', { input: {
|
||||
itemNumber: item.itemNumber,
|
||||
expectedCatalogEpoch: marketplace.catalogEpoch,
|
||||
expectedArtifactSha256: item.artifactSha256,
|
||||
humanConfirmedPermissionExpansion: item.artifactKind === 'PHYSICAL_MODULE' && item.permissions.length > 0,
|
||||
} })
|
||||
setMarketplace(result.snapshot)
|
||||
setMarketplaceMessage(`${item.displayName} 已完成下载、验签、自检和安装。`)
|
||||
} catch (error) {
|
||||
setMarketplaceMessage(humanError(error, 'system'))
|
||||
} finally {
|
||||
setMarketplaceBusyItem('')
|
||||
}
|
||||
}
|
||||
const uninstallMarketplaceItem = async (item: MarketplaceItemView) => {
|
||||
if (!window.confirm(`确认停用“${item.displayName}”?安装证据与用户数据会保留。`)) return
|
||||
setMarketplaceBusyItem(item.itemNumber)
|
||||
try {
|
||||
const result = await invoke<MarketplaceMutationOutcome>('uninstall_marketplace_item', { input: { itemNumber: item.itemNumber } })
|
||||
setMarketplace(result.snapshot)
|
||||
setMarketplaceMessage(`${item.displayName} 已停用;数据与回执保留。`)
|
||||
} catch (error) {
|
||||
setMarketplaceMessage(humanError(error, 'system'))
|
||||
} finally {
|
||||
setMarketplaceBusyItem('')
|
||||
}
|
||||
}
|
||||
const rollbackMarketplaceItem = async (item: MarketplaceItemView) => {
|
||||
if (!window.confirm(`确认把“${item.displayName}”回退到上一份已验签版本?`)) return
|
||||
setMarketplaceBusyItem(item.itemNumber)
|
||||
try {
|
||||
const result = await invoke<MarketplaceMutationOutcome>('rollback_marketplace_item', { input: { itemNumber: item.itemNumber } })
|
||||
setMarketplace(result.snapshot)
|
||||
setMarketplaceMessage(`${item.displayName} 已回退到上一份已验签版本。`)
|
||||
} catch (error) {
|
||||
setMarketplaceMessage(humanError(error, 'system'))
|
||||
} finally {
|
||||
setMarketplaceBusyItem('')
|
||||
}
|
||||
}
|
||||
|
||||
const cloneCodeChannel = async (event: React.FormEvent) => {
|
||||
event.preventDefault()
|
||||
if (!cloneUrl.trim()) return
|
||||
|
|
@ -1558,7 +1697,11 @@ function HoloLakeApp() {
|
|||
}
|
||||
const syncZeroPoint = async () => {
|
||||
setZpBusy(true); setZpMessage('')
|
||||
try { setZeroPoint(await invoke<ZeroPointSnapshot>('zero_point_sync')) } catch (error) { setZpMessage(String(error)) } finally { setZpBusy(false) }
|
||||
try {
|
||||
const snapshot = await invoke<ZeroPointSnapshot>('zero_point_sync')
|
||||
setZeroPoint(snapshot)
|
||||
setZpMessage(snapshot.syncNote)
|
||||
} catch (error) { setZpMessage(String(error)) } finally { setZpBusy(false) }
|
||||
}
|
||||
const renderOverview = () => (
|
||||
<section className="content-page overview-page">
|
||||
|
|
@ -1779,9 +1922,54 @@ function HoloLakeApp() {
|
|||
</section>
|
||||
)
|
||||
|
||||
const renderMarketplace = () => {
|
||||
const items = marketplace?.items.filter((item) => item.artifactKind === marketplaceKind) || []
|
||||
const active = marketplace?.state === 'ACTIVE_VERIFIED_CATALOG'
|
||||
return <section className="content-page marketplace-page">
|
||||
<header className="page-title marketplace-title"><div><span className="kicker">BRANCH DOMAIN · VERIFIED DISTRIBUTION</span><h1>分域模块商城</h1><p>同一个入口,两条互不混用的安装链:成品模块进入现实功能容器;思维技能只进入只读认知层。</p></div><button className="primary-button" type="button" disabled={marketplaceSyncing} onClick={() => void syncMarketplace()}>{marketplaceSyncing ? '正在双签同步…' : active ? '检查线上更新' : '同步线上目录'}</button></header>
|
||||
<section className="marketplace-proof" aria-label="商城信任状态">
|
||||
<div><span>目录状态</span><b>{active ? '线上双签已核验' : '等待首次同步'}</b></div>
|
||||
<div><span>目录纪元</span><b>{marketplace?.catalogEpoch || '—'}</b></div>
|
||||
<div><span>已登记资源</span><b>{marketplace?.itemCount ?? '—'}</b></div>
|
||||
<div><span>验真回执</span><b>{marketplace?.catalogReceiptCount || 0}</b></div>
|
||||
</section>
|
||||
<div className="marketplace-tabs" role="tablist" aria-label="商城资源类型">
|
||||
<button className={marketplaceKind === 'PHYSICAL_MODULE' ? 'active' : ''} type="button" role="tab" onClick={() => setMarketplaceKind('PHYSICAL_MODULE')}><b>成品模块应用</b><span>下载验签后装入已登记的现实功能适配器</span></button>
|
||||
<button className={marketplaceKind === 'COGNITIVE_SKILL' ? 'active' : ''} type="button" role="tab" onClick={() => setMarketplaceKind('COGNITIVE_SKILL')}><b>思维大脑技能</b><span>只读认知方法,不获得工具、终端或现实执行权</span></button>
|
||||
</div>
|
||||
<p className="marketplace-boundary">{marketplaceKind === 'PHYSICAL_MODULE' ? '成品模块可以声明现实权限;每次新增权限都必须由当前人类看见并确认。代码仓库只作为来源证据,客户端不会克隆并执行仓库。' : '思维技能执行权固定为 false、权限列表固定为空;系统只在需要时读取,不会自动塞进每轮提示词。'}</p>
|
||||
<div className="marketplace-list">
|
||||
{items.length ? items.map((item) => {
|
||||
const busy = marketplaceBusyItem === item.itemNumber
|
||||
const installed = item.installedState === 'ACTIVE' || item.installedState === 'ACTIVE_READONLY'
|
||||
return <article className="marketplace-item" key={item.itemNumber}>
|
||||
<header><div><span>{item.artifactKind === 'PHYSICAL_MODULE' ? '成品模块' : '只读思维技能'}</span><h2>{item.displayName}</h2><p>{item.summary}</p></div><em className={installed ? 'installed' : ''}>{item.updateAvailable ? '有已验签更新' : installed ? '已安装' : '可安装'}</em></header>
|
||||
<dl>
|
||||
<div><dt>版本 / 编号</dt><dd>{item.version} · {item.itemNumber}</dd></div>
|
||||
<div><dt>来源证据</dt><dd>{item.sourceRepository} · {item.sourceRevision.slice(0, 12)}</dd></div>
|
||||
<div><dt>现实执行边界</dt><dd>{item.artifactKind === 'PHYSICAL_MODULE' ? '仅经已登记适配器与所列权限' : '无现实执行权'}</dd></div>
|
||||
<div><dt>权限</dt><dd>{item.permissions.length ? item.permissions.join(' · ') : '无现实权限'}</dd></div>
|
||||
</dl>
|
||||
<div className="marketplace-actions">
|
||||
{installed && !item.updateAvailable
|
||||
? <button type="button" disabled={busy} onClick={() => void uninstallMarketplaceItem(item)}>{busy ? '处理中…' : '停用并保留数据'}</button>
|
||||
: <button className="primary-button" type="button" disabled={busy || !active} onClick={() => void installMarketplaceItem(item)}>{busy ? '正在验签安装…' : item.updateAvailable ? '安装已验签更新' : '安装'}</button>}
|
||||
{installed && <button type="button" disabled={busy} onClick={() => void rollbackMarketplaceItem(item)}>回退上一版本</button>}
|
||||
</div>
|
||||
</article>
|
||||
}) : <div className="marketplace-empty"><b>{active ? '当前分类尚无已登记资源' : '尚未取得可验证目录'}</b><p>{active ? '资源发布后会在下一次目录同步中出现。' : '点击“同步线上目录”;只有零点原核与企业发布双签同时通过,目录才会显示。'}</p></div>}
|
||||
</div>
|
||||
{marketplaceMessage && <p className="global-message marketplace-message">{marketplaceMessage}</p>}
|
||||
{marketplace?.latestCatalogReceiptHash && <footer className="marketplace-receipt">最新目录回执 · {marketplace.latestCatalogReceiptHash.slice(0, 20)} · 目录摘要 {marketplace.catalogSha256.slice(0, 20)}</footer>}
|
||||
</section>
|
||||
}
|
||||
|
||||
const renderSystem = () => (
|
||||
<section className="content-page">
|
||||
<header className="page-title"><div><span className="kicker">SYSTEM EVIDENCE</span><h1>系统详情</h1><p>显示可验证的当前状态;无法读取的项目将明确标记为不可用。</p></div></header>
|
||||
<header className="page-title"><div><span className="kicker">HUMAN CONTROL</span><h1>授权与连接</h1><p>先把需要你决定的事和当前协作对象说清楚;机器诊断放在后面。</p></div></header>
|
||||
<HumanAuthorizationCenter brokerState={status.directLocalBrokerState} activeConnectionCount={status.directConnectionCount} sessions={status.directSessions || []}/>
|
||||
<details className="system-diagnostics">
|
||||
<summary>系统诊断与协议证据</summary>
|
||||
<div className="system-grid">
|
||||
<section className="plain-panel connection-panel">
|
||||
<header><div><h2>光湖近场连接</h2><p>外部 AI 可像发现附近网络一样发现本机 HoloLake;MCP 仅用于兼容与恢复。</p></div><span className={nearbyDiscovery?.automaticSameDeviceDiscovery ? 'status-chip online' : 'status-chip'}>{nearbyDiscovery?.automaticSameDeviceDiscovery ? '本机自动发现已开启' : '自动发现不可用'}</span></header>
|
||||
|
|
@ -1812,6 +2000,10 @@ function HoloLakeApp() {
|
|||
<dl className="evidence-list">
|
||||
<div><dt>绑定状态</dt><dd>{zeroPoint ? (zeroPoint.binding === 'bound' ? `已绑定(${zeroPoint.userNumber})` : '等待绑定(空白态)') : '—'}</dd></div>
|
||||
<div><dt>协议来源</dt><dd>{zeroPoint ? protocolOriginDisplayName(zeroPoint.protocol.origin) : '—'}</dd></div>
|
||||
<div><dt>公众运行面</dt><dd>企业服务器 · 不包含私人第五域</dd></div>
|
||||
<div><dt>双签信任</dt><dd>{zeroPoint?.publicDistribution.trustState === 'PROVISIONED' ? '零点原点与企业分发公钥已配置' : '等待配置两把独立发布公钥'}</dd></div>
|
||||
<div><dt>已激活协议</dt><dd>{zeroPoint?.publicDistribution.version ? `${zeroPoint.publicDistribution.version} · epoch ${zeroPoint.publicDistribution.epoch}` : '尚无线上双签版本'}</dd></div>
|
||||
<div><dt>激活回执</dt><dd>{zeroPoint ? `${zeroPoint.publicDistribution.receiptCount} 条${zeroPoint.publicDistribution.rollbackAvailable ? ' · 保留上一可信版本' : ''}` : '—'}</dd></div>
|
||||
<div><dt>离线有效期</dt><dd>{zeroPoint ? `${zeroPoint.protocol.gracePeriodDays} 天` : '—'}</dd></div>
|
||||
<div><dt>同步状态</dt><dd>{zeroPoint?.syncNote ?? '—'}</dd></div>
|
||||
</dl>
|
||||
|
|
@ -1819,7 +2011,7 @@ function HoloLakeApp() {
|
|||
<input value={zpNumber} placeholder="输入用户编号,如 ICE-GL∞" onChange={(event) => setZpNumber(event.target.value)}/>
|
||||
<button className="secondary-button" type="button" disabled={zpBusy || !zpNumber.trim()} onClick={() => void bindZeroPoint()}>绑定并校验</button>
|
||||
<button className="secondary-button" type="button" disabled={zpBusy || zeroPoint?.binding !== 'bound'} onClick={() => void verifyZeroPoint()}>重新校验编号</button>
|
||||
<button className="secondary-button" type="button" disabled={zpBusy} onClick={() => void syncZeroPoint()}>检查协议版本</button>
|
||||
<button className="secondary-button" type="button" disabled={zpBusy} onClick={() => void syncZeroPoint()}>同步公众协议</button>
|
||||
</div>
|
||||
{zpMessage && <p className="global-message">{zpMessage}</p>}
|
||||
</section>
|
||||
|
|
@ -1831,6 +2023,7 @@ function HoloLakeApp() {
|
|||
</section>
|
||||
<section className="plain-panel"><header><div><h2>软件更新</h2><p>仅接受已登记信任根验证通过的 HoloLake 发布包。</p></div></header>{releaseCandidate ? <div className="release-summary"><b>HoloLake {releaseCandidate.version}</b><p>{releaseCandidate.notes}</p><button className="primary-button" onClick={() => void installUpdate()}>验证并安装</button></div> : <button className="secondary-button" disabled={systemBusy} onClick={() => void checkUpdate()}>检查签名更新</button>}</section>
|
||||
</div>
|
||||
</details>
|
||||
{systemMessage && <p className="global-message">{systemMessage}</p>}
|
||||
</section>
|
||||
)
|
||||
|
|
@ -2032,6 +2225,7 @@ function HoloLakeApp() {
|
|||
<div className="world-location"><h1>{repoLogin.domain === 'FIFTH_DOMAIN' ? domainDisplayName(repoLogin.domain) : '光湖零感域'}</h1><p>{repoLogin.domain === 'FIFTH_DOMAIN' ? '世界正在发生什么' : '公共工作入口 · 世界正在发生什么'}</p></div>
|
||||
<div className="broadcast-stream"><p><i/>光湖公共灯塔 · 在线</p><p><i/>协议版本 · {enterpriseEntry?.registry_version || 'HLDP v1.0'}</p>{repoLogin.domain !== 'FIFTH_DOMAIN' && <p><i/>本人责任域 · {domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)}</p>}<p><i/>HoloLake · V0.5.0</p></div>
|
||||
<LakePool className="home-primary" title={repoLogin.domain === 'FIFTH_DOMAIN' ? '永恒湖心系统' : '光湖频道'} meta={repoLogin.domain === 'FIFTH_DOMAIN' ? '进入私人系统' : `${domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)} · 责任工作入口`} open onClick={() => setWorldStage(repoLogin.domain === 'FIFTH_DOMAIN' ? (isZhizhi ? 'heart' : 'channel') : 'channel')}/>
|
||||
<LakePool className="channel-knowledge" title="分域模块商城" meta="成品模块 · 思维大脑技能" onClick={openMarketplace}/>
|
||||
<LakePool className="home-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
<EraHomeEntry timeline={eraTimeline} coordinate={beijingCoordinate} onOpen={openEraTimeline}/>
|
||||
</section>}
|
||||
|
|
@ -2071,12 +2265,14 @@ function HoloLakeApp() {
|
|||
<LakePool className="channel-knowledge system-branch-heartbeat" title="心跳核心频道" meta="冰朔 · 私人频道" open onClick={() => setWorldStage('heartbeat')}/>
|
||||
<LakePool className="channel-code system-branch-light-lake" title="光之湖" meta="人格体居所" onClick={() => setWorldStage('lightLake')}/>
|
||||
<LakePool className="channel-light system-branch-love" title="爱之核心子系统" meta="责任主体 · 之之" onClick={() => setWorldStage('love')}/>
|
||||
<LakePool className="channel-main" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
</> : <>
|
||||
<LakePool className="channel-main" title={domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)} meta="本人责任工作域" open={enterpriseWork?.state === 'READY_READ_ONLY_WORK_PROJECTION'} onClick={() => setWorldStage('enterpriseWork')}/>
|
||||
<LakePool className="channel-code" title="私有责任工作仓库" meta={enterpriseWork ? `${enterpriseWork.repository} · 已认证` : userPnccBusy ? '正在接入' : '暂不可用'} onClick={() => void openEnterpriseRepository()}/>
|
||||
<LakePool className="channel-light" title="责任签署状态" meta={enterpriseEntry?.responsibility_receipt?.decision === 'ACCEPT' ? '已接受 · 已留存' : '等待本人确认'} onClick={() => openWorldTool('receipts')}/>
|
||||
<LakePool className="channel-knowledge" title="前往我的频道" meta="接入说明 · 由本人或人格体完成" onClick={() => setWorldStage('personalNodeGuide')}/>
|
||||
<LakePool className="channel-main" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
</>}
|
||||
</section>}
|
||||
|
|
@ -2102,7 +2298,7 @@ function HoloLakeApp() {
|
|||
<footer><b>当前状态 · 待本人接入</b><span>可由本人人格体协助执行,但不能替代人类节点所有权确认。</span></footer>
|
||||
</div>
|
||||
</section>}
|
||||
{worldStage === 'heartbeat' && repoLogin.domain === 'FIFTH_DOMAIN' && <PrivateChannelSurface ownerName="冰朔" ownerNumber="ICE-GL∞" knowledgeCount={knowledge.uniqueDocumentCount} onBack={() => setWorldStage('channel')} onMarketplace={() => { setWorldStage('domain'); setActiveDomainInfo('BRANCH_DOMAIN') }} nativeActions={privateNativeActions} installedModules={privateInstalledModules}/>}
|
||||
{worldStage === 'heartbeat' && repoLogin.domain === 'FIFTH_DOMAIN' && <PrivateChannelSurface ownerName="冰朔" ownerNumber="ICE-GL∞" knowledgeCount={knowledge.uniqueDocumentCount} onBack={() => setWorldStage('channel')} onMarketplace={openMarketplace} nativeActions={privateNativeActions} installedModules={privateInstalledModules}/>}
|
||||
{worldStage === 'lightLake' && repoLogin.domain === 'FIFTH_DOMAIN' && <section className="channel-world light-lake-world">
|
||||
<button className="world-back" type="button" onClick={() => setWorldStage('channel')}>← 退回永恒湖心</button>
|
||||
<div className="world-location"><h1>光之湖</h1><p>人格体居所 · AGE 人格体语言生活空间</p></div>
|
||||
|
|
@ -2113,7 +2309,7 @@ function HoloLakeApp() {
|
|||
</section>}
|
||||
{worldStage === 'tool' && <section className={`world-tool world-tool-${view}`}>
|
||||
<header className="tool-worldbar"><button type="button" onClick={() => setWorldStage(toolReturnStage)}>← 退回频道全景</button><b>{viewLabels[view]}</b><span>{domainDisplayName(repoLogin.domain)}</span></header>
|
||||
<div className={`tool-projection${inspectorOpen ? '' : ' inspector-closed'}`}>{view === 'overview' ? renderOverview() : view === 'knowledge' ? renderKnowledge() : view === 'composition' ? renderComposition() : view === 'workbench' ? renderWorkbench() : view === 'education' ? renderEducation() : view === 'webNovel' ? renderWebNovel() : view === 'mobileSync' ? renderMobileSync() : view === 'persona' ? renderPersonaBody() : view === 'code' ? renderCode() : view === 'receipts' ? renderReceipts() : renderSystem()}</div>
|
||||
<div className={`tool-projection${inspectorOpen ? '' : ' inspector-closed'}`}>{view === 'overview' ? renderOverview() : view === 'knowledge' ? renderKnowledge() : view === 'composition' ? renderComposition() : view === 'workbench' ? renderWorkbench() : view === 'education' ? renderEducation() : view === 'webNovel' ? renderWebNovel() : view === 'mobileSync' ? renderMobileSync() : view === 'persona' ? renderPersonaBody() : view === 'code' ? renderCode() : view === 'marketplace' ? renderMarketplace() : view === 'receipts' ? renderReceipts() : renderSystem()}</div>
|
||||
</section>}
|
||||
</main>
|
||||
{worldStage === 'domain' && surface === 'world' && signedActiveGate && <><button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/><section className={`domain-info-card info-${signedActiveGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${signedActiveGate.title}系统信息`}><button className="gate-close" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}>×</button><b>{signedActiveGate.title}</b><small>{signedActiveGate.gate}</small><span className="pool-facts">{signedActiveGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span></section></>}
|
||||
|
|
|
|||
Loading…
Reference in a new issue