feat(hololake): project registered modules into marketplace

This commit is contained in:
冰朔 2026-09-03 21:24:51 +08:00
commit 03e4338ab8
7 changed files with 120 additions and 7 deletions

View file

@ -7,6 +7,8 @@
"module_id": "HLP-MOD-CHANNEL-0001", "module_id": "HLP-MOD-CHANNEL-0001",
"name_zh": "个人初始化频道", "name_zh": "个人初始化频道",
"kind": "SYSTEM_FOUNDATION", "kind": "SYSTEM_FOUNDATION",
"audience": "SYSTEM",
"summary_zh": "建立属于当前用户的命名频道、稳定编号与私人 Git。",
"state": "LOCAL_INSTALLED_VERIFIED_WITH_HUMAN_VISUAL_RENDERING", "state": "LOCAL_INSTALLED_VERIFIED_WITH_HUMAN_VISUAL_RENDERING",
"source": "src-tauri/src/lib.rs#create_channel", "source": "src-tauri/src/lib.rs#create_channel",
"data_owner": "CURRENT_LOCAL_USER" "data_owner": "CURRENT_LOCAL_USER"
@ -15,6 +17,8 @@
"module_id": "HLP-MOD-KB-0001", "module_id": "HLP-MOD-KB-0001",
"name_zh": "光湖知识库", "name_zh": "光湖知识库",
"kind": "PREINSTALLED_USER_MODULE", "kind": "PREINSTALLED_USER_MODULE",
"audience": "HUMAN",
"summary_zh": "预装的个人知识模块,支持阅读、写作、导入、导出与可恢复回收。",
"state": "LOCAL_INSTALLED_VERIFIED", "state": "LOCAL_INSTALLED_VERIFIED",
"source": "src-tauri/src/lib.rs#knowledge", "source": "src-tauri/src/lib.rs#knowledge",
"capabilities": ["CREATE", "READ", "EDIT", "HUMAN_MARKDOWN_RENDERING", "FRONTMATTER", "FOLDER_CLASSIFICATION_TREE", "STABLE_TAG_COLORS", "READING_TIME", "SCROLL_SYNCHRONIZED_OUTLINE", "WIKILINK_NAVIGATION", "IMPORT_FOLDER", "EXPORT", "MOVE_TO_TRASH", "PRIVATE_GIT_COMMIT"] "capabilities": ["CREATE", "READ", "EDIT", "HUMAN_MARKDOWN_RENDERING", "FRONTMATTER", "FOLDER_CLASSIFICATION_TREE", "STABLE_TAG_COLORS", "READING_TIME", "SCROLL_SYNCHRONIZED_OUTLINE", "WIKILINK_NAVIGATION", "IMPORT_FOLDER", "EXPORT", "MOVE_TO_TRASH", "PRIVATE_GIT_COMMIT"]
@ -23,6 +27,8 @@
"module_id": "HLP-MOD-GLP-BRIDGE-0001", "module_id": "HLP-MOD-GLP-BRIDGE-0001",
"name_zh": "光湖语言翻译桥", "name_zh": "光湖语言翻译桥",
"kind": "SYSTEM_FOUNDATION", "kind": "SYSTEM_FOUNDATION",
"audience": "SYSTEM",
"summary_zh": "在本机以类型化事件连接频道、人格体与外部编程 AI。",
"state": "LOCAL_REALTIME_ACTIVE", "state": "LOCAL_REALTIME_ACTIVE",
"source": "src-tauri/src/realtime_bridge.rs", "source": "src-tauri/src/realtime_bridge.rs",
"transport": "GLP_LOCAL_REALTIME/1_LOOPBACK_TCP_NDJSON" "transport": "GLP_LOCAL_REALTIME/1_LOOPBACK_TCP_NDJSON"
@ -31,6 +37,8 @@
"module_id": "HLP-MOD-AGENT-0001", "module_id": "HLP-MOD-AGENT-0001",
"name_zh": "本地 Agent 执行核", "name_zh": "本地 Agent 执行核",
"kind": "SYSTEM_FOUNDATION", "kind": "SYSTEM_FOUNDATION",
"audience": "PERSONA",
"summary_zh": "为人格体提供不依赖模型工具调用的确定性执行能力。",
"state": "PUBLIC_MINIMUM_TCS_TO_GIR_AND_HUMAN_APPROVED_AGENT_ACTIVE", "state": "PUBLIC_MINIMUM_TCS_TO_GIR_AND_HUMAN_APPROVED_AGENT_ACTIVE",
"source": "src-tauri/src/agent_executor.rs", "source": "src-tauri/src/agent_executor.rs",
"registered_operations": ["KNOWLEDGE.CREATE", "KNOWLEDGE.UPDATE", "KNOWLEDGE.DELETE", "KNOWLEDGE.READ", "KNOWLEDGE.LIST"] "registered_operations": ["KNOWLEDGE.CREATE", "KNOWLEDGE.UPDATE", "KNOWLEDGE.DELETE", "KNOWLEDGE.READ", "KNOWLEDGE.LIST"]
@ -39,6 +47,8 @@
"module_id": "HLP-MOD-UPDATE-0001", "module_id": "HLP-MOD-UPDATE-0001",
"name_zh": "HoloLake 签名更新器", "name_zh": "HoloLake 签名更新器",
"kind": "SYSTEM_FOUNDATION", "kind": "SYSTEM_FOUNDATION",
"audience": "SYSTEM",
"summary_zh": "只接收通过光湖信任根验证的软件更新。",
"state": "CLIENT_TRUST_ROOT_BOUND_SERVER_HTTP_204_NO_PUBLIC_RELEASE", "state": "CLIENT_TRUST_ROOT_BOUND_SERVER_HTTP_204_NO_PUBLIC_RELEASE",
"source": "src-tauri/tauri.conf.json#plugins.updater" "source": "src-tauri/tauri.conf.json#plugins.updater"
}, },
@ -46,6 +56,8 @@
"module_id": "HLP-MOD-EXT-AI-0001", "module_id": "HLP-MOD-EXT-AI-0001",
"name_zh": "外部编程 AI 表达桥", "name_zh": "外部编程 AI 表达桥",
"kind": "OPTIONAL_LOCAL_BRIDGE", "kind": "OPTIONAL_LOCAL_BRIDGE",
"audience": "PERSONA",
"summary_zh": "让外部编程 AI 以明确来源进入当前频道,不自动获得人格或执行权。",
"state": "LOCAL_REALTIME_CONNECTOR_ACTIVE", "state": "LOCAL_REALTIME_CONNECTOR_ACTIVE",
"source": "connectors/hololake-glp-client.py" "source": "connectors/hololake-glp-client.py"
}, },
@ -53,6 +65,8 @@
"module_id": "HLP-MOD-PERSONA-RUNTIME-0001", "module_id": "HLP-MOD-PERSONA-RUNTIME-0001",
"name_zh": "公众人格试用运行时", "name_zh": "公众人格试用运行时",
"kind": "SYSTEM_FOUNDATION", "kind": "SYSTEM_FOUNDATION",
"audience": "PERSONA",
"summary_zh": "建立可逆试用人格记录;既有人格身份仍需独立验证。",
"state": "LOCAL_TRIAL_PERSONA_RUNTIME_ACTIVE_EXISTING_PERSONA_VERIFICATION_NOT_CLAIMED", "state": "LOCAL_TRIAL_PERSONA_RUNTIME_ACTIVE_EXISTING_PERSONA_VERIFICATION_NOT_CLAIMED",
"source": "src-tauri/src/persona_runtime.rs", "source": "src-tauri/src/persona_runtime.rs",
"reversible_trial_days": 30 "reversible_trial_days": 30
@ -61,6 +75,8 @@
"module_id": "HLP-MOD-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001", "module_id": "HLP-MOD-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001",
"name_zh": "光湖企业域责任入口", "name_zh": "光湖企业域责任入口",
"kind": "TEAM_ONLY_ENTERPRISE_GATEWAY", "kind": "TEAM_ONLY_ENTERPRISE_GATEWAY",
"audience": "HUMAN_TEAM",
"summary_zh": "为已登记域负责人准备设备、人格与责任范围验证。",
"state": "LOCAL_DEVICE_PROOF_IMPLEMENTED_SERVER_CHALLENGE_DEFERRED_FOR_CONCURRENCY", "state": "LOCAL_DEVICE_PROOF_IMPLEMENTED_SERVER_CHALLENGE_DEFERRED_FOR_CONCURRENCY",
"source": "src-tauri/src/enterprise_entrance.rs", "source": "src-tauri/src/enterprise_entrance.rs",
"enterprise_server_embedded": false, "enterprise_server_embedded": false,

View file

@ -14,6 +14,14 @@ use tauri_plugin_dialog::DialogExt;
const UPDATE_ENDPOINT: &str = "https://guanghulab.com/hololake/releases/latest.json"; const UPDATE_ENDPOINT: &str = "https://guanghulab.com/hololake/releases/latest.json";
const PUBLIC_STATE: &str = "SIGNED_UPDATE_FEED_READY_NO_RELEASE"; const PUBLIC_STATE: &str = "SIGNED_UPDATE_FEED_READY_NO_RELEASE";
fn bundled_modules() -> Result<Vec<ModuleRecord>, String> {
let registry: serde_json::Value =
serde_json::from_str(include_str!("../../registries/module-registry.json"))
.map_err(|error| format!("MODULE_REGISTRY_INVALID: {error}"))?;
serde_json::from_value(registry["modules"].clone())
.map_err(|error| format!("MODULE_REGISTRY_INVALID: {error}"))
}
fn receipt( fn receipt(
app: &AppHandle, app: &AppHandle,
state: &str, state: &str,
@ -42,6 +50,7 @@ fn system_snapshot(app: AppHandle) -> Result<SystemSnapshot, String> {
public_update_endpoint: UPDATE_ENDPOINT.into(), public_update_endpoint: UPDATE_ENDPOINT.into(),
public_distribution_state: PUBLIC_STATE.into(), public_distribution_state: PUBLIC_STATE.into(),
external_ai_bridges: storage::bridges(&app)?, external_ai_bridges: storage::bridges(&app)?,
modules: bundled_modules()?,
}) })
} }

View file

@ -74,6 +74,18 @@ pub struct SystemSnapshot {
pub public_update_endpoint: String, pub public_update_endpoint: String,
pub public_distribution_state: String, pub public_distribution_state: String,
pub external_ai_bridges: Vec<ExternalAiBridge>, pub external_ai_bridges: Vec<ExternalAiBridge>,
pub modules: Vec<ModuleRecord>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ModuleRecord {
pub module_id: String,
pub name_zh: String,
pub kind: String,
pub audience: String,
pub summary_zh: String,
pub state: String,
} }
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]

View file

@ -131,7 +131,7 @@ export default function App() {
/> />
)}{" "} )}{" "}
{view === "knowledge" && <Knowledge data={data} refresh={refresh} />}{" "} {view === "knowledge" && <Knowledge data={data} refresh={refresh} />}{" "}
{view === "market" && <Market />}{" "} {view === "market" && <Market modules={data.modules} />}{" "}
{view === "history" && <History data={data} />}{" "} {view === "history" && <History data={data} />}{" "}
{view === "portal" && <Portal setError={setError} />}{" "} {view === "portal" && <Portal setError={setError} />}{" "}
{view === "settings" && ( {view === "settings" && (
@ -847,7 +847,30 @@ function Knowledge({
); );
} }
function Market() { function Market({ modules }: { modules: SystemSnapshot["modules"] }) {
const personaModules = modules.filter((module) => module.audience === "PERSONA");
const humanModules = modules.filter(
(module) => module.audience === "HUMAN" || module.audience === "HUMAN_TEAM",
);
const stateLabel = (state: string) => {
if (state.includes("ENTERPRISE") || state.includes("SERVER_CHALLENGE"))
return "本机证明能力已实现 · 等待安装与企业服务器验证";
if (state.includes("EXISTING_PERSONA_VERIFICATION_NOT_CLAIMED"))
return "试用运行时已安装 · 既有人格尚未验证";
if (state.includes("REALTIME_CONNECTOR_ACTIVE")) return "本机实时连接已验证";
if (state.includes("TCS_TO_GIR")) return "TCS/GIR 本地执行闭环已验证";
if (state.includes("LOCAL_INSTALLED_VERIFIED")) return "已预装并通过本机验证";
return "已登记 · 等待独立验收";
};
const group = (items: typeof modules) =>
items.map((module) => (
<article className="market-module" key={module.moduleId}>
<span>{module.moduleId}</span>
<h3>{module.nameZh}</h3>
<p>{module.summaryZh}</p>
<small aria-label={`机器状态:${module.state}`}>{stateLabel(module.state)}</small>
</article>
));
return ( return (
<div className="page simple"> <div className="page simple">
<header> <header>
@ -856,16 +879,16 @@ function Market() {
<p>使</p> <p>使</p>
</div> </div>
</header> </header>
<section className="split-list"> <section className="split-list market-groups">
<div> <div>
<h2>使</h2> <h2>使</h2>
<p></p> <p></p>
<span></span> <div className="market-module-list">{group(personaModules)}</div>
</div> </div>
<div> <div>
<h2>使</h2> <h2>使</h2>
<p></p> <p></p>
<span></span> <div className="market-module-list">{group(humanModules)}</div>
</div> </div>
</section> </section>
</div> </div>

View file

@ -1,4 +1,5 @@
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import moduleRegistry from "../registries/module-registry.json";
import type { import type {
AgentProposal, AgentProposal,
AgentReceipt, AgentReceipt,
@ -14,6 +15,7 @@ import type {
EnterpriseBindingRequest, EnterpriseBindingRequest,
EnterpriseDeviceProof, EnterpriseDeviceProof,
EnterpriseEntranceSnapshot, EnterpriseEntranceSnapshot,
ModuleRecord,
} from "./types"; } from "./types";
const tauri = () => "__TAURI_INTERNALS__" in window; const tauri = () => "__TAURI_INTERNALS__" in window;
@ -73,6 +75,14 @@ export async function snapshot(): Promise<SystemSnapshot> {
"https://guanghulab.com/hololake/releases/latest.json", "https://guanghulab.com/hololake/releases/latest.json",
publicDistributionState: "SIGNED_UPDATE_FEED_READY_NO_RELEASE", publicDistributionState: "SIGNED_UPDATE_FEED_READY_NO_RELEASE",
externalAiBridges: s.bridges, externalAiBridges: s.bridges,
modules: moduleRegistry.modules.map((module) => ({
moduleId: module.module_id,
nameZh: module.name_zh,
kind: module.kind,
audience: module.audience as ModuleRecord["audience"],
summaryZh: module.summary_zh,
state: module.state,
})),
}; };
} }

View file

@ -933,6 +933,40 @@ main {
margin-top: 30px; margin-top: 30px;
font-size: 12px; font-size: 12px;
} }
.market-groups > div {
align-self: start;
}
.market-module-list {
display: grid;
gap: 10px;
margin-top: 18px;
}
.market-module {
padding: 16px;
border-radius: 13px;
background: rgba(255, 255, 255, 0.035);
}
.market-module span {
margin: 0;
color: #7896ae;
font-size: 9px;
font-weight: 650;
letter-spacing: 0.05em;
}
.market-module h3 {
margin: 7px 0 5px;
font-size: 15px;
}
.market-module p {
margin: 0;
}
.market-module small {
display: block;
margin-top: 12px;
color: #71889d;
font-size: 10px;
overflow-wrap: anywhere;
}
.timeline-list { .timeline-list {
display: grid; display: grid;
gap: 0; gap: 0;

View file

@ -45,6 +45,15 @@ export interface SystemSnapshot {
publicUpdateEndpoint: string; publicUpdateEndpoint: string;
publicDistributionState: string; publicDistributionState: string;
externalAiBridges: ExternalAiBridge[]; externalAiBridges: ExternalAiBridge[];
modules: ModuleRecord[];
}
export interface ModuleRecord {
moduleId: string;
nameZh: string;
kind: string;
audience: "SYSTEM" | "HUMAN" | "PERSONA" | "HUMAN_TEAM";
summaryZh: string;
state: string;
} }
export interface ExternalAiBridge { export interface ExternalAiBridge {
bridgeId: string; bridgeId: string;