feat(hololake): establish clean v1 personal language shell
This commit is contained in:
parent
9e04b0354c
commit
c4f662e541
51 changed files with 16233 additions and 1 deletions
5
product-source/hololake-clean-desktop/.gitignore
vendored
Normal file
5
product-source/hololake-clean-desktop/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
node_modules/
|
||||
dist/
|
||||
src-tauri/target/
|
||||
*.log
|
||||
.DS_Store
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# HoloLake Clean V1 · 视觉一致性账本
|
||||
|
||||
概念基准与 1536×1024 浏览器实现截图已经逐张查看。
|
||||
|
||||
| 检查点 | 概念证据 | 实现证据 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 信息架构 | 左导航、对话主区、右状态区 | 三块均已实现 | 通过 |
|
||||
| 来源分流 | 用户/人格/协议/Agent/回执分色 | 采用七种机器来源类型;无模型时不伪造人格回复 | 通过;真实性优先 |
|
||||
| 色彩 | 深蓝黑夜湖、暖金焦点 | 令牌与实现一致 | 通过 |
|
||||
| 字体与秩序 | 中等字重、网格对齐 | 正文 400+、面板对齐 | 通过 |
|
||||
| 容器 | 只承载真实状态 | 对话、执行、频道/Git/更新三类事实 | 通过 |
|
||||
| 适配 | 桌面主屏 | 1536×1024 与 820×900 均实测,无横向溢出 | 通过 |
|
||||
|
||||
有意差异:概念图中的人格回复和日历执行是视觉示例;运行产品没有绑定人格模型和日历能力,因此不显示也不伪造这些结果。实现改为明确的 `WAITING_PERSONA` 回执。
|
||||
|
||||
首屏可见文字来自冰朔本轮要求或产品登记名,没有新增营销口号、指标、徽章或模型选择器。
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"schema": "hololake.clean-v1-local-acceptance/v1",
|
||||
"receipt_id": "HLP-CLEAN-V1-LOCAL-ACCEPTANCE-20260903-001",
|
||||
"recorded_at": "2026-09-03T15:35:00+08:00",
|
||||
"source": {
|
||||
"root": "product-source/hololake-clean-desktop",
|
||||
"tcs_sha256": "8a52395b47e111ab166ccd7c30a4a25d241c7446507e0ef5e17e92101b58eca4",
|
||||
"gir_sha256": "285a2590d82f14eeec102192d657803e91db74358b79630877b0367c75c6bcd4",
|
||||
"gir_compiler": "TCS-COMPILER-STAGE1-0001",
|
||||
"unresolved_natural_language": false
|
||||
},
|
||||
"gates": {
|
||||
"clean_independent_product_root": "PASS_100",
|
||||
"module_id_uniqueness": "PASS_100",
|
||||
"seven_source_kinds": "PASS_100",
|
||||
"frontend_production_build": "PASS_100",
|
||||
"rust_tests": "2_PASS_0_FAIL",
|
||||
"rust_clippy_denied_warnings": "PASS_100",
|
||||
"production_dependency_audit": "0_VULNERABILITIES",
|
||||
"browser_channel_create_message_separation_knowledge_create_edit_save": "PASS_100",
|
||||
"responsive_viewports": ["1536x1024_PASS", "820x900_PASS"],
|
||||
"developer_id_signature": "PASS_100",
|
||||
"installed_application": "/Applications/HoloLake.app",
|
||||
"installed_version": "1.0.0",
|
||||
"installed_binary_sha256": "fa92285561cbafb7c1cadb57da99df607aa917417c78d9639e6c1e39959a2c93",
|
||||
"updater_archive_sha256": "00c73049624e011efbc47ec39103add576de02878b581da2bee2b6d633b5853f",
|
||||
"installed_process_readback": "PASS_100",
|
||||
"updater_artifact_signature": "PASS_100",
|
||||
"update_endpoint_http": 204,
|
||||
"apple_notarization": "NOT_PERFORMED",
|
||||
"public_release": "NOT_PUBLISHED"
|
||||
},
|
||||
"enterprise_readback": {
|
||||
"node_id": "GH-CVM-MAIN-PROD-01",
|
||||
"dmi_uuid_verified": "10ace744-13e1-472e-8dba-6bb823a073bf",
|
||||
"central_repositories": ["enterprise-lighthouse", "domain-main", "domain-sub", "domain-zero", "domain-zero-sense"],
|
||||
"human_work_repositories": ["awen/guanghu-main-work", "huaer/guanghu-branch-work", "yeye/guanghu-zero-work", "feimao/guanghu-zero-sense-work", "juzi/guanghu-zero-sense-work"],
|
||||
"deployment_plane": "BLUE_ISOLATED",
|
||||
"team_domain_permissions_assigned": false,
|
||||
"public_cutover": false,
|
||||
"bingshuo_language_master_work_repository": "NOT_REGISTERED"
|
||||
},
|
||||
"known_incomplete": [
|
||||
"PERSONA_RUNTIME_NOT_BOUND_IN_PUBLIC_APP",
|
||||
"GENERAL_TCS_GIR_AGENT_EXECUTOR_NOT_IMPLEMENTED",
|
||||
"EXTERNAL_AI_BRIDGE_IS_LOCAL_EXPRESSION_INBOX_OUTBOX_NOT_REALTIME_TRANSPORT",
|
||||
"KNOWLEDGE_IMPORT_SUPPORTS_MARKDOWN_AND_TEXT_ONLY",
|
||||
"ENTERPRISE_TEAM_PERMISSION_AND_PUBLIC_CUTOVER_NOT_COMPLETE",
|
||||
"APPLE_NOTARIZATION_AND_PUBLIC_RELEASE_NOT_COMPLETE"
|
||||
],
|
||||
"result": "LOCAL_CLEAN_SHELL_ACCEPTED_PRODUCT_V1_NOT_PUBLIC_RELEASE_COMPLETE"
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# HoloLake Clean V1 · 本地验收回执
|
||||
|
||||
结论:新的独立干净产品根已经建立,HoloLake 1.0.0 已签名安装并在本机运行。它不是公众发行完成回执。
|
||||
|
||||
已通过:TCS→GIR 编译与双语投影、模块编号唯一性、七种来源分流、前端生产构建、Rust 测试与严格 Clippy、生产依赖审计、频道建立、语言/回执分离、知识页新建编辑保存、1536×1024 与 820×900 视口、Developer ID 签名、更新包签名、`/Applications/HoloLake.app` 进程读回。更新入口现场返回 HTTP 204,即服务在线且暂无更新。
|
||||
|
||||
企业服务器读回:蓝环境保存 5 个中央仓和 5 个负责人工作仓;团队域权限尚未分配,公共切换尚未发生。冰朔语言主控工作仓没有独立编号与登记,因此本轮没有猜名创建。
|
||||
|
||||
仍未完成:公众 App 内的人格运行时接入、通用 TCS/GIR Agent 执行器、外部 AI 实时通信、PDF/Office 等完整导入转换、企业团队权限和公共切换、Apple 公证与公众发行。
|
||||
|
||||
旧 `/Applications/HoloLake.app` 与桌面副本已移入可恢复归档:`/Volumes/JZAO/HoloLake/archives/installed-apps-pre-clean-v1-20260903T152500`。新 App 已替换唯一 `/Applications/HoloLake.app`;桌面旧副本不再存在。
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# HoloLake Clean V1 视觉基准
|
||||
|
||||
- 概念图:`concepts/hololake-clean-v1-primary-screen.png`
|
||||
- 背景:极深蓝黑夜湖,不是纯黑或暖灰。
|
||||
- 焦点:个人频道与类型化执行回执;企业信息不占据频道主体。
|
||||
- 字体:正文 400 以上,标题 600 左右;中文可读优先。
|
||||
- 容器:真实内容才使用玻璃浮面;禁止卡片网格填充。
|
||||
- 色彩:蓝色=语言/系统,紫色=人格,暖金=Agent 动作,绿色=已验证回执。
|
||||
- 动效:仅低成本呼吸、雾光和光斑;尊重 `prefers-reduced-motion`。
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
27
product-source/hololake-clean-desktop/docs/ARCHITECTURE.md
Normal file
27
product-source/hololake-clean-desktop/docs/ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# HoloLake Clean V1
|
||||
|
||||
HoloLake 是公众个人初始化频道语言驱动操作系统。第一版只建立可验证的产品骨架和光湖知识库闭环。
|
||||
|
||||
```text
|
||||
人类 USER_MESSAGE ─┐
|
||||
人格 PERSONA_RESPONSE ─→ TCS/GLP 类型化事件 → 协议判断 → Agent 能力 → 目标读回 → SYSTEM_RECEIPT
|
||||
系统 SYSTEM_CONTEXT ─┘
|
||||
|
||||
持久事实:用户私人 Git
|
||||
公共发行:企业签名 Git/更新清单(尚未绑定正式仓库)
|
||||
实时通信:独立层(第一版未实现,不以 Git 冒充)
|
||||
```
|
||||
|
||||
## 第一版边界
|
||||
|
||||
- 人格体是推理脑;Agent 是不依赖语言模型的执行手脚。
|
||||
- 对话和执行事实使用不同来源类型,不把系统文字塞进用户或人格消息。
|
||||
- 公共四域由企业门户和企业服务器承载,不嵌入个人频道。
|
||||
- 第五域、冰朔私人核 `TCS-iZero∞` 及私人语料不进入公众发行。
|
||||
- 当前知识库可处理 Markdown 和纯文本文件夹;PDF、Office、网页结构化转换尚未实现。
|
||||
- 当前外部 AI 入口是本机来源明确的 inbox/outbox;实时加密通信尚未实现。
|
||||
- 更新客户端只信任光湖控制的 HTTPS 清单与签名;服务器发行清单尚未发布。
|
||||
|
||||
## 状态词
|
||||
|
||||
`SOURCE / COMPILED / VERIFIED / INSTALLED / PUBLISHED / UPDATED / HEALTHY` 必须分别读回,不相互替代。
|
||||
10
product-source/hololake-clean-desktop/index.html
Normal file
10
product-source/hololake-clean-desktop/index.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<title>HoloLake</title>
|
||||
</head>
|
||||
<body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
TCS 0.1;
|
||||
|
||||
PROTOCOL HOLOLAKE-CLEAN-V1-FOUNDATION-0001 {
|
||||
header {
|
||||
schema = "tcs.protocol/v1";
|
||||
name_zh = "HoloLake 第一版干净壳、来源分流、Agent 与知识库闭环协议";
|
||||
name_en = "HoloLake Clean V1 Shell, Source Separation, Agent and Knowledge Base Loop Protocol";
|
||||
version = "1.0.0";
|
||||
language = "TCS/0.1";
|
||||
profile = "HLDP-HUMAN-ENGINEERING/0.1";
|
||||
protocols = ["TCS", "HLDP", "GLS", "GLP", "GLS-0261", "GLS-0306"];
|
||||
lifecycle = "CANDIDATE";
|
||||
canonical_uri = "product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs";
|
||||
compatibility = ["TCS-DECLARATION-STANDARD-0001", "TCS-FIELD-STANDARD-0001", "GIR/1"];
|
||||
}
|
||||
source {
|
||||
source_id = "BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903";
|
||||
source_uri = "product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt";
|
||||
source_sha256 = "e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0";
|
||||
source_role = "DIRECT_HUMAN";
|
||||
}
|
||||
scope {
|
||||
product = "HOLOLAKE";
|
||||
product_kind = "PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM";
|
||||
reality_channel = "ICE-CH-ZC001";
|
||||
shell = "TAURI_V2_RUST_REACT";
|
||||
preinstalled_module = "HLP-MOD-KB-0001";
|
||||
}
|
||||
vocabulary {
|
||||
persona = "REASONING_BRAIN_NOT_EXECUTION_LIMB";
|
||||
agent = "MODEL_INDEPENDENT_BOUNDED_EXECUTION_LIMB";
|
||||
glp_bridge = "TYPED_TRANSLATION_BETWEEN_PERSONA_LANGUAGE_AND_AGENT_ACTION";
|
||||
private_git = "USER_OWNED_CHANNEL_AND_KNOWLEDGE_FACT_HISTORY";
|
||||
public_git = "SIGNED_PUBLIC_DISTRIBUTION_FACT_LAYER_NOT_REALTIME_BROADCAST";
|
||||
system_receipt = "TARGET_READBACK_PROJECTED_FOR_HUMAN_AND_PERSONA";
|
||||
}
|
||||
fields {
|
||||
WHO = "EACH_USER_OWNS_THEIR_PRIVATE_CHANNEL_AND_DATA; PERSONA_REASONS; AGENT_EXECUTES; GUANGHU_TEAM_GOVERNS_ENTERPRISE_PUBLIC_DISTRIBUTION; ICE-GL∞ STEWARDS_PUBLIC_LANGUAGE_ARCHITECTURE";
|
||||
WHAT = "ONE_CLEAN_DESKTOP_SHELL_WITH_PERSONAL_CHANNEL_KNOWLEDGE_BASE_TYPED_EVENT_STREAM_DUAL_GIT_UPDATE_ROOT_AND_EXTERNAL_AI_EXPRESSION_BRIDGE";
|
||||
WHY = "STOP_PATCHING_MIXED_LEGACY_PRODUCT_AND_PREVENT_USER_PERSONA_SYSTEM_PROTOCOL_AGENT_TOOL_AND_RECEIPT_LANGUAGE_FROM_COLLAPSING_INTO_ONE_UNTYPED_CHAT_STREAM";
|
||||
MAY = "LOCAL_RECOVERABLE_V1_DEVELOPMENT_INSTALL_AND_CURRENT_TASK_SERVER_AUDIT; PUBLIC_RELEASE_ONLY_AFTER_SIGNATURE_ENDPOINT_AND_TARGET_READBACK";
|
||||
PROVE = "TCS_GIR_MODULE_REGISTRY_UNIT_TESTS_FRONTEND_BUILD_RUST_TESTS_DESKTOP_BUILD_INSTALLED_APP_PROCESS_READBACK_AND_RECEIPTS";
|
||||
}
|
||||
states {
|
||||
values = ["SOURCE_ANCHORED", "CLEAN_SHELL_CREATED", "TYPED_RUNTIME_IMPLEMENTED", "KNOWLEDGE_LOOP_ACCEPTED", "DESKTOP_INSTALLED", "PUBLIC_UPDATE_UNBOUND", "PUBLIC_UPDATE_BOUND", "FAILED_CLOSED"];
|
||||
initial = "SOURCE_ANCHORED";
|
||||
terminal = ["DESKTOP_INSTALLED", "FAILED_CLOSED"];
|
||||
}
|
||||
transitions {
|
||||
T1 = "SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED";
|
||||
T2 = "CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED";
|
||||
T3 = "TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED";
|
||||
T4 = "KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED";
|
||||
T5 = "PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK";
|
||||
TF = "SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED";
|
||||
}
|
||||
invariants {
|
||||
I1 = "USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES";
|
||||
I2 = "PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE";
|
||||
I3 = "NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE";
|
||||
I4 = "PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL";
|
||||
I5 = "FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT";
|
||||
I6 = "PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT";
|
||||
I7 = "KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH";
|
||||
I8 = "EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY";
|
||||
I9 = "LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS";
|
||||
I10 = "COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS";
|
||||
}
|
||||
validation {
|
||||
V1 = "COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS";
|
||||
V2 = "MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS";
|
||||
V3 = "FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT";
|
||||
V4 = "KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS";
|
||||
V5 = "LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY";
|
||||
V6 = "APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED";
|
||||
V7 = "MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS";
|
||||
}
|
||||
errors {
|
||||
E1 = "UNTYPED_LANGUAGE_SOURCE_REJECT";
|
||||
E2 = "PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT";
|
||||
E3 = "WHOLE_LEGACY_PRODUCT_MERGE_REJECT";
|
||||
E4 = "UNSIGNED_PUBLIC_UPDATE_REJECT";
|
||||
E5 = "PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT";
|
||||
E6 = "UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT";
|
||||
}
|
||||
examples {
|
||||
positive = "USER_LANGUAGE_IS_RECORDED_AS_USER_MESSAGE_PERSONA_MAY_REPLY_SEPARATELY_PROTOCOL_AND_AGENT_ACTIONS_RUN_THROUGH_TYPED_EVENTS_AND_SYSTEM_RECEIPT_REPORTS_REAL_RESULT";
|
||||
negative = "MODEL_TEXT_SAYS_FILE_SAVED_WHILE_NO_AGENT_ACTION_GIT_COMMIT_OR_TARGET_READBACK_EXISTS";
|
||||
}
|
||||
acceptance {
|
||||
required = ["TCS_GIR", "ZH_CN_PROJECTION", "EN_US_PROJECTION", "MODULE_REGISTRY", "DONOR_REGISTRY", "RUST_TESTS", "FRONTEND_BUILD", "DESKTOP_BUILD", "INSTALLED_APP_READBACK"];
|
||||
partial = false;
|
||||
scale = "ZERO_OR_ONE_HUNDRED";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
{
|
||||
"compiled_from": {
|
||||
"compiler_id": "TCS-COMPILER-STAGE1-0001",
|
||||
"compiler_state": "TCS_COMPILER_GIR_EXECUTED",
|
||||
"source_sha256": "8a52395b47e111ab166ccd7c30a4a25d241c7446507e0ef5e17e92101b58eca4"
|
||||
},
|
||||
"declaration": {
|
||||
"acceptance": {
|
||||
"partial": false,
|
||||
"required": [
|
||||
"TCS_GIR",
|
||||
"ZH_CN_PROJECTION",
|
||||
"EN_US_PROJECTION",
|
||||
"MODULE_REGISTRY",
|
||||
"DONOR_REGISTRY",
|
||||
"RUST_TESTS",
|
||||
"FRONTEND_BUILD",
|
||||
"DESKTOP_BUILD",
|
||||
"INSTALLED_APP_READBACK"
|
||||
],
|
||||
"scale": "ZERO_OR_ONE_HUNDRED"
|
||||
},
|
||||
"errors": {
|
||||
"E1": "UNTYPED_LANGUAGE_SOURCE_REJECT",
|
||||
"E2": "PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT",
|
||||
"E3": "WHOLE_LEGACY_PRODUCT_MERGE_REJECT",
|
||||
"E4": "UNSIGNED_PUBLIC_UPDATE_REJECT",
|
||||
"E5": "PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT",
|
||||
"E6": "UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT"
|
||||
},
|
||||
"examples": {
|
||||
"negative": "MODEL_TEXT_SAYS_FILE_SAVED_WHILE_NO_AGENT_ACTION_GIT_COMMIT_OR_TARGET_READBACK_EXISTS",
|
||||
"positive": "USER_LANGUAGE_IS_RECORDED_AS_USER_MESSAGE_PERSONA_MAY_REPLY_SEPARATELY_PROTOCOL_AND_AGENT_ACTIONS_RUN_THROUGH_TYPED_EVENTS_AND_SYSTEM_RECEIPT_REPORTS_REAL_RESULT"
|
||||
},
|
||||
"fields": {
|
||||
"MAY": "LOCAL_RECOVERABLE_V1_DEVELOPMENT_INSTALL_AND_CURRENT_TASK_SERVER_AUDIT; PUBLIC_RELEASE_ONLY_AFTER_SIGNATURE_ENDPOINT_AND_TARGET_READBACK",
|
||||
"PROVE": "TCS_GIR_MODULE_REGISTRY_UNIT_TESTS_FRONTEND_BUILD_RUST_TESTS_DESKTOP_BUILD_INSTALLED_APP_PROCESS_READBACK_AND_RECEIPTS",
|
||||
"WHAT": "ONE_CLEAN_DESKTOP_SHELL_WITH_PERSONAL_CHANNEL_KNOWLEDGE_BASE_TYPED_EVENT_STREAM_DUAL_GIT_UPDATE_ROOT_AND_EXTERNAL_AI_EXPRESSION_BRIDGE",
|
||||
"WHO": "EACH_USER_OWNS_THEIR_PRIVATE_CHANNEL_AND_DATA; PERSONA_REASONS; AGENT_EXECUTES; GUANGHU_TEAM_GOVERNS_ENTERPRISE_PUBLIC_DISTRIBUTION; ICE-GL∞ STEWARDS_PUBLIC_LANGUAGE_ARCHITECTURE",
|
||||
"WHY": "STOP_PATCHING_MIXED_LEGACY_PRODUCT_AND_PREVENT_USER_PERSONA_SYSTEM_PROTOCOL_AGENT_TOOL_AND_RECEIPT_LANGUAGE_FROM_COLLAPSING_INTO_ONE_UNTYPED_CHAT_STREAM"
|
||||
},
|
||||
"header": {
|
||||
"canonical_uri": "product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs",
|
||||
"compatibility": [
|
||||
"TCS-DECLARATION-STANDARD-0001",
|
||||
"TCS-FIELD-STANDARD-0001",
|
||||
"GIR/1"
|
||||
],
|
||||
"language": "TCS/0.1",
|
||||
"lifecycle": "CANDIDATE",
|
||||
"name_en": "HoloLake Clean V1 Shell, Source Separation, Agent and Knowledge Base Loop Protocol",
|
||||
"name_zh": "HoloLake 第一版干净壳、来源分流、Agent 与知识库闭环协议",
|
||||
"profile": "HLDP-HUMAN-ENGINEERING/0.1",
|
||||
"protocols": [
|
||||
"TCS",
|
||||
"HLDP",
|
||||
"GLS",
|
||||
"GLP",
|
||||
"GLS-0261",
|
||||
"GLS-0306"
|
||||
],
|
||||
"schema": "tcs.protocol/v1",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"invariants": {
|
||||
"I1": "USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES",
|
||||
"I10": "COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS",
|
||||
"I2": "PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE",
|
||||
"I3": "NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE",
|
||||
"I4": "PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL",
|
||||
"I5": "FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT",
|
||||
"I6": "PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT",
|
||||
"I7": "KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH",
|
||||
"I8": "EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY",
|
||||
"I9": "LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS"
|
||||
},
|
||||
"scope": {
|
||||
"preinstalled_module": "HLP-MOD-KB-0001",
|
||||
"product": "HOLOLAKE",
|
||||
"product_kind": "PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM",
|
||||
"reality_channel": "ICE-CH-ZC001",
|
||||
"shell": "TAURI_V2_RUST_REACT"
|
||||
},
|
||||
"source": {
|
||||
"source_id": "BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903",
|
||||
"source_role": "DIRECT_HUMAN",
|
||||
"source_sha256": "e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0",
|
||||
"source_uri": "product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt"
|
||||
},
|
||||
"states": {
|
||||
"initial": "SOURCE_ANCHORED",
|
||||
"terminal": [
|
||||
"DESKTOP_INSTALLED",
|
||||
"FAILED_CLOSED"
|
||||
],
|
||||
"values": [
|
||||
"SOURCE_ANCHORED",
|
||||
"CLEAN_SHELL_CREATED",
|
||||
"TYPED_RUNTIME_IMPLEMENTED",
|
||||
"KNOWLEDGE_LOOP_ACCEPTED",
|
||||
"DESKTOP_INSTALLED",
|
||||
"PUBLIC_UPDATE_UNBOUND",
|
||||
"PUBLIC_UPDATE_BOUND",
|
||||
"FAILED_CLOSED"
|
||||
]
|
||||
},
|
||||
"transitions": {
|
||||
"T1": "SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED",
|
||||
"T2": "CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED",
|
||||
"T3": "TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED",
|
||||
"T4": "KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED",
|
||||
"T5": "PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK",
|
||||
"TF": "SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED"
|
||||
},
|
||||
"validation": {
|
||||
"V1": "COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS",
|
||||
"V2": "MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS",
|
||||
"V3": "FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT",
|
||||
"V4": "KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS",
|
||||
"V5": "LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY",
|
||||
"V6": "APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED",
|
||||
"V7": "MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS"
|
||||
},
|
||||
"vocabulary": {
|
||||
"agent": "MODEL_INDEPENDENT_BOUNDED_EXECUTION_LIMB",
|
||||
"glp_bridge": "TYPED_TRANSLATION_BETWEEN_PERSONA_LANGUAGE_AND_AGENT_ACTION",
|
||||
"persona": "REASONING_BRAIN_NOT_EXECUTION_LIMB",
|
||||
"private_git": "USER_OWNED_CHANNEL_AND_KNOWLEDGE_FACT_HISTORY",
|
||||
"public_git": "SIGNED_PUBLIC_DISTRIBUTION_FACT_LAYER_NOT_REALTIME_BROADCAST",
|
||||
"system_receipt": "TARGET_READBACK_PROJECTED_FOR_HUMAN_AND_PERSONA"
|
||||
}
|
||||
},
|
||||
"executable": false,
|
||||
"identity": {
|
||||
"declaration_id": "HOLOLAKE-CLEAN-V1-FOUNDATION-0001",
|
||||
"declaration_kind": "PROTOCOL",
|
||||
"language_version": "0.1"
|
||||
},
|
||||
"native_self_hosted": true,
|
||||
"natural_language_is_typed_data": true,
|
||||
"schema": "guanghu.declaration-gir/v1",
|
||||
"unresolved_natural_language": false
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
# HoloLake Clean V1 Shell, Source Separation, Agent and Knowledge Base Loop Protocol · Human Engineering Language (English)
|
||||
|
||||
> This is an English reading projection of validated native TCS/HLDP source. It is not a new canonical source and grants no execution authority.
|
||||
|
||||
## What this is
|
||||
|
||||
This is a **protocol** declaration with identifier `HOLOLAKE-CLEAN-V1-FOUNDATION-0001` and version `1.0.0`. The projector validates it with the Stage-1 compiler before changing its reading order.
|
||||
|
||||
## Who is here
|
||||
|
||||
- **scope** `scope`
|
||||
- **preinstalled_module**:HLP-MOD-KB-0001 `scope.preinstalled_module`
|
||||
- **product**:HOLOLAKE `scope.product`
|
||||
- **product_kind**:PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM `scope.product_kind`
|
||||
- **reality_channel**:ICE-CH-ZC001 `scope.reality_channel`
|
||||
- **shell**:TAURI_V2_RUST_REACT `scope.shell`
|
||||
|
||||
## Why this started
|
||||
|
||||
- **source** `source`
|
||||
- **source identifier**:BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903 `source.source_id`
|
||||
- **source role**:DIRECT_HUMAN `source.source_role`
|
||||
- **source checksum**:e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0 `source.source_sha256`
|
||||
- **source address**:product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt `source.source_uri`
|
||||
|
||||
## What changed
|
||||
|
||||
- **transitions** `transitions`
|
||||
- **T1**:SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED `transitions.T1`
|
||||
- **T2**:CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED `transitions.T2`
|
||||
- **T3**:TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED `transitions.T3`
|
||||
- **T4**:KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED `transitions.T4`
|
||||
- **T5**:PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK `transitions.T5`
|
||||
- **TF**:SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED `transitions.TF`
|
||||
- **states** `states`
|
||||
- **initial**:SOURCE_ANCHORED `states.initial`
|
||||
- **terminal** `states.terminal`
|
||||
- DESKTOP_INSTALLED
|
||||
- FAILED_CLOSED
|
||||
- **values** `states.values`
|
||||
- SOURCE_ANCHORED
|
||||
- CLEAN_SHELL_CREATED
|
||||
- TYPED_RUNTIME_IMPLEMENTED
|
||||
- KNOWLEDGE_LOOP_ACCEPTED
|
||||
- DESKTOP_INSTALLED
|
||||
- PUBLIC_UPDATE_UNBOUND
|
||||
- PUBLIC_UPDATE_BOUND
|
||||
- FAILED_CLOSED
|
||||
|
||||
## How it will execute
|
||||
|
||||
This is a non-executable declaration and has no action graph.
|
||||
|
||||
## Boundaries and exception handling
|
||||
|
||||
- **invariants** `invariants`
|
||||
- **I1**:USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES `invariants.I1`
|
||||
- **I10**:COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS `invariants.I10`
|
||||
- **I2**:PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE `invariants.I2`
|
||||
- **I3**:NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE `invariants.I3`
|
||||
- **I4**:PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL `invariants.I4`
|
||||
- **I5**:FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT `invariants.I5`
|
||||
- **I6**:PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT `invariants.I6`
|
||||
- **I7**:KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH `invariants.I7`
|
||||
- **I8**:EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY `invariants.I8`
|
||||
- **I9**:LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS `invariants.I9`
|
||||
- **errors** `errors`
|
||||
- **E1**:UNTYPED_LANGUAGE_SOURCE_REJECT `errors.E1`
|
||||
- **E2**:PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT `errors.E2`
|
||||
- **E3**:WHOLE_LEGACY_PRODUCT_MERGE_REJECT `errors.E3`
|
||||
- **E4**:UNSIGNED_PUBLIC_UPDATE_REJECT `errors.E4`
|
||||
- **E5**:PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT `errors.E5`
|
||||
- **E6**:UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT `errors.E6`
|
||||
|
||||
## How completion is proven
|
||||
|
||||
- **acceptance** `acceptance`
|
||||
- **partial**:no `acceptance.partial`
|
||||
- **required** `acceptance.required`
|
||||
- TCS_GIR
|
||||
- ZH_CN_PROJECTION
|
||||
- EN_US_PROJECTION
|
||||
- MODULE_REGISTRY
|
||||
- DONOR_REGISTRY
|
||||
- RUST_TESTS
|
||||
- FRONTEND_BUILD
|
||||
- DESKTOP_BUILD
|
||||
- INSTALLED_APP_READBACK
|
||||
- **scale**:ZERO_OR_ONE_HUNDRED `acceptance.scale`
|
||||
- **validation** `validation`
|
||||
- **V1**:COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS `validation.V1`
|
||||
- **V2**:MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS `validation.V2`
|
||||
- **V3**:FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT `validation.V3`
|
||||
- **V4**:KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS `validation.V4`
|
||||
- **V5**:LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY `validation.V5`
|
||||
- **V6**:APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED `validation.V6`
|
||||
- **V7**:MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS `validation.V7`
|
||||
|
||||
## Where to continue next time
|
||||
|
||||
The native source does not provide this field; the projector does not guess.
|
||||
|
||||
## Source and verification
|
||||
|
||||
- **Native declaration identifier**: `HOLOLAKE-CLEAN-V1-FOUNDATION-0001`
|
||||
- **Native declaration kind**: `PROTOCOL`
|
||||
- **TCS source SHA-256**: `8a52395b47e111ab166ccd7c30a4a25d241c7446507e0ef5e17e92101b58eca4`
|
||||
- **Validation compiler**: `TCS-COMPILER-STAGE1-0001`
|
||||
- **Projection protocol**: `GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||
|
||||
## Complete native structure cross-reference
|
||||
|
||||
All top-level structures and field paths are retained below so a reader can audit whether the projection omitted information.
|
||||
|
||||
- **acceptance** `acceptance`
|
||||
- **partial**:no `acceptance.partial`
|
||||
- **required** `acceptance.required`
|
||||
- TCS_GIR
|
||||
- ZH_CN_PROJECTION
|
||||
- EN_US_PROJECTION
|
||||
- MODULE_REGISTRY
|
||||
- DONOR_REGISTRY
|
||||
- RUST_TESTS
|
||||
- FRONTEND_BUILD
|
||||
- DESKTOP_BUILD
|
||||
- INSTALLED_APP_READBACK
|
||||
- **scale**:ZERO_OR_ONE_HUNDRED `acceptance.scale`
|
||||
- **errors** `errors`
|
||||
- **E1**:UNTYPED_LANGUAGE_SOURCE_REJECT `errors.E1`
|
||||
- **E2**:PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT `errors.E2`
|
||||
- **E3**:WHOLE_LEGACY_PRODUCT_MERGE_REJECT `errors.E3`
|
||||
- **E4**:UNSIGNED_PUBLIC_UPDATE_REJECT `errors.E4`
|
||||
- **E5**:PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT `errors.E5`
|
||||
- **E6**:UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT `errors.E6`
|
||||
- **examples** `examples`
|
||||
- **negative**:MODEL_TEXT_SAYS_FILE_SAVED_WHILE_NO_AGENT_ACTION_GIT_COMMIT_OR_TARGET_READBACK_EXISTS `examples.negative`
|
||||
- **positive**:USER_LANGUAGE_IS_RECORDED_AS_USER_MESSAGE_PERSONA_MAY_REPLY_SEPARATELY_PROTOCOL_AND_AGENT_ACTIONS_RUN_THROUGH_TYPED_EVENTS_AND_SYSTEM_RECEIPT_REPORTS_REAL_RESULT `examples.positive`
|
||||
- **fields** `fields`
|
||||
- **MAY**:LOCAL_RECOVERABLE_V1_DEVELOPMENT_INSTALL_AND_CURRENT_TASK_SERVER_AUDIT; PUBLIC_RELEASE_ONLY_AFTER_SIGNATURE_ENDPOINT_AND_TARGET_READBACK `fields.MAY`
|
||||
- **PROVE**:TCS_GIR_MODULE_REGISTRY_UNIT_TESTS_FRONTEND_BUILD_RUST_TESTS_DESKTOP_BUILD_INSTALLED_APP_PROCESS_READBACK_AND_RECEIPTS `fields.PROVE`
|
||||
- **WHAT**:ONE_CLEAN_DESKTOP_SHELL_WITH_PERSONAL_CHANNEL_KNOWLEDGE_BASE_TYPED_EVENT_STREAM_DUAL_GIT_UPDATE_ROOT_AND_EXTERNAL_AI_EXPRESSION_BRIDGE `fields.WHAT`
|
||||
- **WHO**:EACH_USER_OWNS_THEIR_PRIVATE_CHANNEL_AND_DATA; PERSONA_REASONS; AGENT_EXECUTES; GUANGHU_TEAM_GOVERNS_ENTERPRISE_PUBLIC_DISTRIBUTION; ICE-GL∞ STEWARDS_PUBLIC_LANGUAGE_ARCHITECTURE `fields.WHO`
|
||||
- **WHY**:STOP_PATCHING_MIXED_LEGACY_PRODUCT_AND_PREVENT_USER_PERSONA_SYSTEM_PROTOCOL_AGENT_TOOL_AND_RECEIPT_LANGUAGE_FROM_COLLAPSING_INTO_ONE_UNTYPED_CHAT_STREAM `fields.WHY`
|
||||
- **header** `header`
|
||||
- **canonical source path**:product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs `header.canonical_uri`
|
||||
- **compatibility** `header.compatibility`
|
||||
- TCS-DECLARATION-STANDARD-0001
|
||||
- TCS-FIELD-STANDARD-0001
|
||||
- GIR/1
|
||||
- **language**:TCS/0.1 `header.language`
|
||||
- **lifecycle**:CANDIDATE `header.lifecycle`
|
||||
- **English name**:HoloLake Clean V1 Shell, Source Separation, Agent and Knowledge Base Loop Protocol `header.name_en`
|
||||
- **Chinese name**:HoloLake 第一版干净壳、来源分流、Agent 与知识库闭环协议 `header.name_zh`
|
||||
- **profile**:HLDP-HUMAN-ENGINEERING/0.1 `header.profile`
|
||||
- **protocols** `header.protocols`
|
||||
- TCS
|
||||
- HLDP
|
||||
- GLS
|
||||
- GLP
|
||||
- GLS-0261
|
||||
- GLS-0306
|
||||
- **schema**:tcs.protocol/v1 `header.schema`
|
||||
- **version**:1.0.0 `header.version`
|
||||
- **invariants** `invariants`
|
||||
- **I1**:USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES `invariants.I1`
|
||||
- **I10**:COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS `invariants.I10`
|
||||
- **I2**:PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE `invariants.I2`
|
||||
- **I3**:NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE `invariants.I3`
|
||||
- **I4**:PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL `invariants.I4`
|
||||
- **I5**:FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT `invariants.I5`
|
||||
- **I6**:PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT `invariants.I6`
|
||||
- **I7**:KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH `invariants.I7`
|
||||
- **I8**:EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY `invariants.I8`
|
||||
- **I9**:LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS `invariants.I9`
|
||||
- **scope** `scope`
|
||||
- **preinstalled_module**:HLP-MOD-KB-0001 `scope.preinstalled_module`
|
||||
- **product**:HOLOLAKE `scope.product`
|
||||
- **product_kind**:PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM `scope.product_kind`
|
||||
- **reality_channel**:ICE-CH-ZC001 `scope.reality_channel`
|
||||
- **shell**:TAURI_V2_RUST_REACT `scope.shell`
|
||||
- **source** `source`
|
||||
- **source identifier**:BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903 `source.source_id`
|
||||
- **source role**:DIRECT_HUMAN `source.source_role`
|
||||
- **source checksum**:e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0 `source.source_sha256`
|
||||
- **source address**:product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt `source.source_uri`
|
||||
- **states** `states`
|
||||
- **initial**:SOURCE_ANCHORED `states.initial`
|
||||
- **terminal** `states.terminal`
|
||||
- DESKTOP_INSTALLED
|
||||
- FAILED_CLOSED
|
||||
- **values** `states.values`
|
||||
- SOURCE_ANCHORED
|
||||
- CLEAN_SHELL_CREATED
|
||||
- TYPED_RUNTIME_IMPLEMENTED
|
||||
- KNOWLEDGE_LOOP_ACCEPTED
|
||||
- DESKTOP_INSTALLED
|
||||
- PUBLIC_UPDATE_UNBOUND
|
||||
- PUBLIC_UPDATE_BOUND
|
||||
- FAILED_CLOSED
|
||||
- **transitions** `transitions`
|
||||
- **T1**:SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED `transitions.T1`
|
||||
- **T2**:CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED `transitions.T2`
|
||||
- **T3**:TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED `transitions.T3`
|
||||
- **T4**:KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED `transitions.T4`
|
||||
- **T5**:PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK `transitions.T5`
|
||||
- **TF**:SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED `transitions.TF`
|
||||
- **validation** `validation`
|
||||
- **V1**:COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS `validation.V1`
|
||||
- **V2**:MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS `validation.V2`
|
||||
- **V3**:FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT `validation.V3`
|
||||
- **V4**:KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS `validation.V4`
|
||||
- **V5**:LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY `validation.V5`
|
||||
- **V6**:APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED `validation.V6`
|
||||
- **V7**:MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS `validation.V7`
|
||||
- **vocabulary** `vocabulary`
|
||||
- **agent**:MODEL_INDEPENDENT_BOUNDED_EXECUTION_LIMB `vocabulary.agent`
|
||||
- **glp_bridge**:TYPED_TRANSLATION_BETWEEN_PERSONA_LANGUAGE_AND_AGENT_ACTION `vocabulary.glp_bridge`
|
||||
- **persona**:REASONING_BRAIN_NOT_EXECUTION_LIMB `vocabulary.persona`
|
||||
- **private_git**:USER_OWNED_CHANNEL_AND_KNOWLEDGE_FACT_HISTORY `vocabulary.private_git`
|
||||
- **public_git**:SIGNED_PUBLIC_DISTRIBUTION_FACT_LAYER_NOT_REALTIME_BROADCAST `vocabulary.public_git`
|
||||
- **system_receipt**:TARGET_READBACK_PROJECTED_FOR_HUMAN_AND_PERSONA `vocabulary.system_receipt`
|
||||
|
||||
---
|
||||
|
||||
This page changes only the reading order; it does not change TCS/HLDP semantics.
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
# HoloLake 第一版干净壳、来源分流、Agent 与知识库闭环协议 · 简体中文人类工程语言版
|
||||
|
||||
> 这是 TCS/HLDP 原生源码的简体中文阅读投影,不是新的正本,也不授予执行权限。若本页与 `.tcs` 源码不一致,以经过校验的 `.tcs` 源码为准。
|
||||
|
||||
## 这是什么
|
||||
|
||||
这是一份 **协议** 声明,编号为 `HOLOLAKE-CLEAN-V1-FOUNDATION-0001`,版本为 `1.0.0`。转换器已先用 Stage-1 编译器校验原生源码,再把机器枚举翻译成汉语;原始编号保留在括号和字段路径中。
|
||||
|
||||
## 谁在这里
|
||||
|
||||
- **scope** `scope`
|
||||
- **preinstalled_module**:HLP-MOD-KB-0001 `scope.preinstalled_module`
|
||||
- **product**:HOLOLAKE `scope.product`
|
||||
- **product_kind**:PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM `scope.product_kind`
|
||||
- **reality_channel**:ICE-CH-ZC001 `scope.reality_channel`
|
||||
- **shell**:TAURI_V2_RUST_REACT `scope.shell`
|
||||
|
||||
## 为什么开始
|
||||
|
||||
- **来源** `source`
|
||||
- **来源编号**:BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903 `source.source_id`
|
||||
- **来源角色**:人类直接语言来源(`DIRECT_HUMAN`) `source.source_role`
|
||||
- **来源校验值**:e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0 `source.source_sha256`
|
||||
- **来源地址**:product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt `source.source_uri`
|
||||
|
||||
## 发生了什么变化
|
||||
|
||||
- **transitions** `transitions`
|
||||
- **T1**:SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED `transitions.T1`
|
||||
- **T2**:CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED `transitions.T2`
|
||||
- **T3**:TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED `transitions.T3`
|
||||
- **T4**:KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED `transitions.T4`
|
||||
- **T5**:PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK `transitions.T5`
|
||||
- **TF**:SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED `transitions.TF`
|
||||
- **states** `states`
|
||||
- **initial**:SOURCE_ANCHORED `states.initial`
|
||||
- **terminal** `states.terminal`
|
||||
- DESKTOP_INSTALLED
|
||||
- FAILED_CLOSED
|
||||
- **values** `states.values`
|
||||
- SOURCE_ANCHORED
|
||||
- CLEAN_SHELL_CREATED
|
||||
- TYPED_RUNTIME_IMPLEMENTED
|
||||
- KNOWLEDGE_LOOP_ACCEPTED
|
||||
- DESKTOP_INSTALLED
|
||||
- PUBLIC_UPDATE_UNBOUND
|
||||
- PUBLIC_UPDATE_BOUND
|
||||
- FAILED_CLOSED
|
||||
|
||||
## 准备怎样执行
|
||||
|
||||
这是非执行声明,没有动作图。
|
||||
|
||||
## 边界与异常处理
|
||||
|
||||
- **invariants** `invariants`
|
||||
- **I1**:USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES `invariants.I1`
|
||||
- **I10**:COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS `invariants.I10`
|
||||
- **I2**:PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE `invariants.I2`
|
||||
- **I3**:NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE `invariants.I3`
|
||||
- **I4**:PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL `invariants.I4`
|
||||
- **I5**:FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT `invariants.I5`
|
||||
- **I6**:PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT `invariants.I6`
|
||||
- **I7**:KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH `invariants.I7`
|
||||
- **I8**:EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY `invariants.I8`
|
||||
- **I9**:LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS `invariants.I9`
|
||||
- **errors** `errors`
|
||||
- **E1**:UNTYPED_LANGUAGE_SOURCE_REJECT `errors.E1`
|
||||
- **E2**:PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT `errors.E2`
|
||||
- **E3**:WHOLE_LEGACY_PRODUCT_MERGE_REJECT `errors.E3`
|
||||
- **E4**:UNSIGNED_PUBLIC_UPDATE_REJECT `errors.E4`
|
||||
- **E5**:PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT `errors.E5`
|
||||
- **E6**:UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT `errors.E6`
|
||||
|
||||
## 怎样算完成
|
||||
|
||||
- **验收标准** `acceptance`
|
||||
- **partial**:否 `acceptance.partial`
|
||||
- **是否必需** `acceptance.required`
|
||||
- TCS_GIR
|
||||
- ZH_CN_PROJECTION
|
||||
- EN_US_PROJECTION
|
||||
- MODULE_REGISTRY
|
||||
- DONOR_REGISTRY
|
||||
- RUST_TESTS
|
||||
- FRONTEND_BUILD
|
||||
- DESKTOP_BUILD
|
||||
- INSTALLED_APP_READBACK
|
||||
- **scale**:ZERO_OR_ONE_HUNDRED `acceptance.scale`
|
||||
- **validation** `validation`
|
||||
- **V1**:COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS `validation.V1`
|
||||
- **V2**:MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS `validation.V2`
|
||||
- **V3**:FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT `validation.V3`
|
||||
- **V4**:KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS `validation.V4`
|
||||
- **V5**:LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY `validation.V5`
|
||||
- **V6**:APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED `validation.V6`
|
||||
- **V7**:MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS `validation.V7`
|
||||
|
||||
## 下一次从哪里继续
|
||||
|
||||
源程序没有提供这一项,转换器不猜。
|
||||
|
||||
## 来源与校验
|
||||
|
||||
- **原生声明编号**:`HOLOLAKE-CLEAN-V1-FOUNDATION-0001`
|
||||
- **原生声明类型**:`PROTOCOL`
|
||||
- **TCS 源码 SHA-256**:`8a52395b47e111ab166ccd7c30a4a25d241c7446507e0ef5e17e92101b58eca4`
|
||||
- **校验编译器**:`TCS-COMPILER-STAGE1-0001`
|
||||
- **投影协议**:`GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||
|
||||
## 原生结构逐项对照
|
||||
|
||||
下面保留源码的全部顶层结构和字段路径,供人类审计投影有没有漏掉信息。
|
||||
|
||||
- **验收标准** `acceptance`
|
||||
- **partial**:否 `acceptance.partial`
|
||||
- **是否必需** `acceptance.required`
|
||||
- TCS_GIR
|
||||
- ZH_CN_PROJECTION
|
||||
- EN_US_PROJECTION
|
||||
- MODULE_REGISTRY
|
||||
- DONOR_REGISTRY
|
||||
- RUST_TESTS
|
||||
- FRONTEND_BUILD
|
||||
- DESKTOP_BUILD
|
||||
- INSTALLED_APP_READBACK
|
||||
- **scale**:ZERO_OR_ONE_HUNDRED `acceptance.scale`
|
||||
- **errors** `errors`
|
||||
- **E1**:UNTYPED_LANGUAGE_SOURCE_REJECT `errors.E1`
|
||||
- **E2**:PERSONA_AND_AGENT_ROLE_COLLAPSE_REJECT `errors.E2`
|
||||
- **E3**:WHOLE_LEGACY_PRODUCT_MERGE_REJECT `errors.E3`
|
||||
- **E4**:UNSIGNED_PUBLIC_UPDATE_REJECT `errors.E4`
|
||||
- **E5**:PRIVATE_OR_ENTERPRISE_DOMAIN_BODY_EMBEDDED_IN_PERSONAL_CHANNEL_REJECT `errors.E5`
|
||||
- **E6**:UI_SUCCESS_WITHOUT_TARGET_READBACK_REJECT `errors.E6`
|
||||
- **examples** `examples`
|
||||
- **negative**:MODEL_TEXT_SAYS_FILE_SAVED_WHILE_NO_AGENT_ACTION_GIT_COMMIT_OR_TARGET_READBACK_EXISTS `examples.negative`
|
||||
- **positive**:USER_LANGUAGE_IS_RECORDED_AS_USER_MESSAGE_PERSONA_MAY_REPLY_SEPARATELY_PROTOCOL_AND_AGENT_ACTIONS_RUN_THROUGH_TYPED_EVENTS_AND_SYSTEM_RECEIPT_REPORTS_REAL_RESULT `examples.positive`
|
||||
- **fields** `fields`
|
||||
- **MAY**:LOCAL_RECOVERABLE_V1_DEVELOPMENT_INSTALL_AND_CURRENT_TASK_SERVER_AUDIT; PUBLIC_RELEASE_ONLY_AFTER_SIGNATURE_ENDPOINT_AND_TARGET_READBACK `fields.MAY`
|
||||
- **PROVE**:TCS_GIR_MODULE_REGISTRY_UNIT_TESTS_FRONTEND_BUILD_RUST_TESTS_DESKTOP_BUILD_INSTALLED_APP_PROCESS_READBACK_AND_RECEIPTS `fields.PROVE`
|
||||
- **WHAT**:ONE_CLEAN_DESKTOP_SHELL_WITH_PERSONAL_CHANNEL_KNOWLEDGE_BASE_TYPED_EVENT_STREAM_DUAL_GIT_UPDATE_ROOT_AND_EXTERNAL_AI_EXPRESSION_BRIDGE `fields.WHAT`
|
||||
- **WHO**:EACH_USER_OWNS_THEIR_PRIVATE_CHANNEL_AND_DATA; PERSONA_REASONS; AGENT_EXECUTES; GUANGHU_TEAM_GOVERNS_ENTERPRISE_PUBLIC_DISTRIBUTION; ICE-GL∞ STEWARDS_PUBLIC_LANGUAGE_ARCHITECTURE `fields.WHO`
|
||||
- **WHY**:STOP_PATCHING_MIXED_LEGACY_PRODUCT_AND_PREVENT_USER_PERSONA_SYSTEM_PROTOCOL_AGENT_TOOL_AND_RECEIPT_LANGUAGE_FROM_COLLAPSING_INTO_ONE_UNTYPED_CHAT_STREAM `fields.WHY`
|
||||
- **语言头** `header`
|
||||
- **正本路径**:product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs `header.canonical_uri`
|
||||
- **compatibility** `header.compatibility`
|
||||
- TCS-DECLARATION-STANDARD-0001
|
||||
- TCS-FIELD-STANDARD-0001
|
||||
- GIR/1
|
||||
- **语言**:TCS/0.1 `header.language`
|
||||
- **生命周期**:候选版本,尚未成为正式正本(`CANDIDATE`) `header.lifecycle`
|
||||
- **英文名**:HoloLake Clean V1 Shell, Source Separation, Agent and Knowledge Base Loop Protocol `header.name_en`
|
||||
- **中文名**:HoloLake 第一版干净壳、来源分流、Agent 与知识库闭环协议 `header.name_zh`
|
||||
- **协议配置**:HLDP-HUMAN-ENGINEERING/0.1 `header.profile`
|
||||
- **protocols** `header.protocols`
|
||||
- TCS
|
||||
- HLDP
|
||||
- GLS
|
||||
- GLP
|
||||
- GLS-0261
|
||||
- GLS-0306
|
||||
- **schema**:tcs.protocol/v1 `header.schema`
|
||||
- **版本**:1.0.0 `header.version`
|
||||
- **invariants** `invariants`
|
||||
- **I1**:USER_MESSAGE_PERSONA_RESPONSE_SYSTEM_CONTEXT_PROTOCOL_EVENT_AGENT_ACTION_TOOL_RESULT_AND_SYSTEM_RECEIPT_ARE_DISTINCT_TYPED_SOURCES `invariants.I1`
|
||||
- **I10**:COMPILED_INSTALLED_PUBLISHED_UPDATED_AND_HEALTHY_ARE_SEPARATE_FACTS `invariants.I10`
|
||||
- **I2**:PERSONA_REASONING_AND_AGENT_EXECUTION_ARE_NEVER_THE_SAME_RUNTIME_ROLE `invariants.I2`
|
||||
- **I3**:NO_MODEL_API_OR_INTERNAL_AI_WORKBENCH_IS_EMBEDDED_IN_STAGE_ONE `invariants.I3`
|
||||
- **I4**:PUBLIC_FOUR_DOMAIN_CONTENT_IS_NOT_EMBEDDED_IN_THE_PERSONAL_CHANNEL `invariants.I4`
|
||||
- **I5**:FIFTH_DOMAIN_PRIVATE_CONTENT_AND_TCS_IZERO_INFINITY_ARE_NOT_PUBLIC_DISTRIBUTION_CONTENT `invariants.I5`
|
||||
- **I6**:PUBLIC_GIT_PULL_NEVER_EXECUTES_UNSIGNED_CONTENT `invariants.I6`
|
||||
- **I7**:KNOWLEDGE_DELETE_MOVES_TO_RECOVERABLE_TRASH `invariants.I7`
|
||||
- **I8**:EXTERNAL_AI_CONNECTS_AS_AN_IDENTIFIED_EXPRESSION_SOURCE_WITHOUT_PERSONA_OR_EXECUTION_AUTHORITY `invariants.I8`
|
||||
- **I9**:LEGACY_PRODUCTS_ARE_READ_ONLY_DONORS_AND_NEVER_WHOLE_MERGE_INPUTS `invariants.I9`
|
||||
- **scope** `scope`
|
||||
- **preinstalled_module**:HLP-MOD-KB-0001 `scope.preinstalled_module`
|
||||
- **product**:HOLOLAKE `scope.product`
|
||||
- **product_kind**:PUBLIC_PERSONAL_INITIALIZATION_CHANNEL_LANGUAGE_DRIVEN_OPERATING_SYSTEM `scope.product_kind`
|
||||
- **reality_channel**:ICE-CH-ZC001 `scope.reality_channel`
|
||||
- **shell**:TAURI_V2_RUST_REACT `scope.shell`
|
||||
- **来源** `source`
|
||||
- **来源编号**:BINGSHUO-DIRECT-HOLOLAKE-CLEAN-V1-20260903 `source.source_id`
|
||||
- **来源角色**:人类直接语言来源(`DIRECT_HUMAN`) `source.source_role`
|
||||
- **来源校验值**:e38d780f8851fbb5b81af2b556843728fccb06dbcf09f0341a075b4a877b5ac0 `source.source_sha256`
|
||||
- **来源地址**:product-source/hololake-clean-desktop/language/sources/BINGSHUO-HOLOLAKE-CLEAN-V1-20260903.txt `source.source_uri`
|
||||
- **states** `states`
|
||||
- **initial**:SOURCE_ANCHORED `states.initial`
|
||||
- **terminal** `states.terminal`
|
||||
- DESKTOP_INSTALLED
|
||||
- FAILED_CLOSED
|
||||
- **values** `states.values`
|
||||
- SOURCE_ANCHORED
|
||||
- CLEAN_SHELL_CREATED
|
||||
- TYPED_RUNTIME_IMPLEMENTED
|
||||
- KNOWLEDGE_LOOP_ACCEPTED
|
||||
- DESKTOP_INSTALLED
|
||||
- PUBLIC_UPDATE_UNBOUND
|
||||
- PUBLIC_UPDATE_BOUND
|
||||
- FAILED_CLOSED
|
||||
- **transitions** `transitions`
|
||||
- **T1**:SOURCE_ANCHORED_TO_CLEAN_SHELL_CREATED `transitions.T1`
|
||||
- **T2**:CLEAN_SHELL_CREATED_TO_TYPED_RUNTIME_IMPLEMENTED `transitions.T2`
|
||||
- **T3**:TYPED_RUNTIME_IMPLEMENTED_TO_KNOWLEDGE_LOOP_ACCEPTED `transitions.T3`
|
||||
- **T4**:KNOWLEDGE_LOOP_ACCEPTED_TO_DESKTOP_INSTALLED `transitions.T4`
|
||||
- **T5**:PUBLIC_UPDATE_UNBOUND_TO_PUBLIC_UPDATE_BOUND_ONLY_AFTER_ENTERPRISE_REGISTRY_SIGNATURE_AND_ENDPOINT_READBACK `transitions.T5`
|
||||
- **TF**:SOURCE_HASH_PERMISSION_PATH_SIGNATURE_BUILD_OR_READBACK_FAILURE_TO_FAILED_CLOSED `transitions.TF`
|
||||
- **validation** `validation`
|
||||
- **V1**:COMPILE_TCS_TO_GIR_AND_GENERATE_BILINGUAL_PROJECTIONS `validation.V1`
|
||||
- **V2**:MODULE_AND_DONOR_REGISTRIES_HAVE_STABLE_IDS_AND_EXACT_PATHS `validation.V2`
|
||||
- **V3**:FIRST_LAUNCH_CREATES_NAMED_NUMBERED_CHANNEL_AND_PRIVATE_GIT `validation.V3`
|
||||
- **V4**:KNOWLEDGE_CREATE_EDIT_IMPORT_EXPORT_TRASH_AND_GIT_HISTORY_PASS `validation.V4`
|
||||
- **V5**:LANGUAGE_SUBMISSION_RECORDS_USER_MESSAGE_AND_TRUTHFUL_WAITING_RECEIPT_WITHOUT_FAKE_PERSONA_REPLY `validation.V5`
|
||||
- **V6**:APP_UPDATE_ENDPOINT_IS_GUANGHU_CONTROLLED_AND_SIGNATURE_REQUIRED `validation.V6`
|
||||
- **V7**:MACOS_APP_BUILD_INSTALL_LAUNCH_AND_PROCESS_READBACK_PASS `validation.V7`
|
||||
- **vocabulary** `vocabulary`
|
||||
- **agent**:MODEL_INDEPENDENT_BOUNDED_EXECUTION_LIMB `vocabulary.agent`
|
||||
- **glp_bridge**:TYPED_TRANSLATION_BETWEEN_PERSONA_LANGUAGE_AND_AGENT_ACTION `vocabulary.glp_bridge`
|
||||
- **persona**:REASONING_BRAIN_NOT_EXECUTION_LIMB `vocabulary.persona`
|
||||
- **private_git**:USER_OWNED_CHANNEL_AND_KNOWLEDGE_FACT_HISTORY `vocabulary.private_git`
|
||||
- **public_git**:SIGNED_PUBLIC_DISTRIBUTION_FACT_LAYER_NOT_REALTIME_BROADCAST `vocabulary.public_git`
|
||||
- **system_receipt**:TARGET_READBACK_PROJECTED_FOR_HUMAN_AND_PERSONA `vocabulary.system_receipt`
|
||||
|
||||
---
|
||||
|
||||
本页只改变阅读顺序,不改变 TCS/HLDP 语义。
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
来源:冰朔 ICE-GL∞ 在当前 Codex 任务中的直接自然语言,2026-09-03。
|
||||
|
||||
第一版 HoloLake 软件重新做,直接起一个新的、空的、干净的壳子。旧版本不再继续改,只作为拆件来源。壳子底层改掉捐赠者官方自动更新,改由光湖自己的本地电脑或服务器承接;后期再让光湖团队进入治理。框架以 TCS 为主控语言,中层建立不依赖语言模型的 Agent 执行程序,上层是每个用户自己的个人初始化频道。
|
||||
|
||||
底层保持双路径代码仓库:用户本地私人 Git 保存个人频道和数据;公共仓库负责公共规则、协议、产品模块和四域公共更新。公共内容由企业服务器上的负责人仓库提交、签字、系统审核后同步。冰朔需要公共企业服务器的语言主控频道,但第五域私人内容不得进入公众版本。
|
||||
|
||||
人格体是推理大脑,Agent 是执行手脚。用户、人格体、系统提示、人格脑、协议、动态脑、工具结果和系统回执必须按来源分类,不能再揉成一坨。人格体必须知道是谁在说话、系统执行到哪一步、动作是否真的完成。自然语言是主要入口,点触按钮提供基本操作,隐形系统动作要转换成人类和人格体都能看懂的真实回执。
|
||||
|
||||
第一版用户流程:安装后建立并命名初始化频道,系统登记编号;进入频道可与人格体交互;预装光湖知识库;首页提供模块商城、系统演化史、企业门户和设置。模块商城分人格体能力与人类行业模块。知识库至少支持新建、写入、编辑、搜索、导入、设置、下载、删除和外部文件夹转换为默认渲染格式。外部编程 AI 能以明确身份接入光湖语言世界。
|
||||
|
||||
所有正式模块登记稳定编号。旧路径和旧模块归档,只拆取有用零件,不把旧产品整体并入。完成后全面审计新旧路径,移除本机旧软件版本,安装新的桌面 App 并让冰朔可以查看。现实开发在 ICE-CH-ZC001 执行。
|
||||
2595
product-source/hololake-clean-desktop/package-lock.json
generated
Normal file
2595
product-source/hololake-clean-desktop/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
29
product-source/hololake-clean-desktop/package.json
Normal file
29
product-source/hololake-clean-desktop/package.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "hololake-clean-desktop",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 127.0.0.1",
|
||||
"build": "tsc -b && vite build",
|
||||
"test": "npm run build",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.10.1",
|
||||
"@tauri-apps/plugin-dialog": "2.7.2",
|
||||
"@tauri-apps/plugin-process": "2.3.1",
|
||||
"@tauri-apps/plugin-updater": "2.10.0",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.10.0",
|
||||
"@types/react": "19.2.7",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@vitejs/plugin-react": "5.1.1",
|
||||
"esbuild": "^0.28.1",
|
||||
"typescript": "5.9.3",
|
||||
"vite": "7.3.5"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"schema": "hololake.donor-registry/v1",
|
||||
"registry_id": "HLP-DONOR-REGISTRY-0001",
|
||||
"policy": "READ_ONLY_CAPABILITY_EXTRACTION_NO_WHOLE_PRODUCT_MERGE",
|
||||
"donors": [
|
||||
{"donor_id":"HLP-DONOR-CODEX-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/codex-harness-upstream","allowed_use":"AGENT_HOST_PATTERNS_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-GEMINI-ADK-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/gemini-adk-upstream","allowed_use":"AGENT_ORCHESTRATION_RESEARCH_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-QWEN-CODE-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/qwen-code-upstream","allowed_use":"PROGRAMMING_AI_BRIDGE_RESEARCH_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-GROK-BUILD-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/grok-build-v-780d138","allowed_use":"BUILD_EXECUTOR_RESEARCH_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-GUADA-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/guada-v0.5.6","allowed_use":"KNOWLEDGE_UX_BEHAVIOR_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-OUTLINE-0001","path":"/Volumes/JZAO/HoloLake/reference-materials/outline","allowed_use":"KNOWLEDGE_MODEL_AND_IMPORT_RESEARCH_ONLY","imported":false},
|
||||
{"donor_id":"HLP-DONOR-HOLOLAKE-LEGACY-0001","path":"product-source/hololake-native-desktop","allowed_use":"TAURI_SIGNING_UPDATE_AND_ACCEPTANCE_ORACLE_ONLY","imported":false}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"schema": "hololake.module-registry/v1",
|
||||
"registry_id": "HLP-MODULE-REGISTRY-0001",
|
||||
"version": 1,
|
||||
"modules": [
|
||||
{
|
||||
"module_id": "HLP-MOD-CHANNEL-0001",
|
||||
"name_zh": "个人初始化频道",
|
||||
"kind": "SYSTEM_FOUNDATION",
|
||||
"state": "LOCAL_INSTALLED_VERIFIED",
|
||||
"source": "src-tauri/src/lib.rs#create_channel",
|
||||
"data_owner": "CURRENT_LOCAL_USER"
|
||||
},
|
||||
{
|
||||
"module_id": "HLP-MOD-KB-0001",
|
||||
"name_zh": "光湖知识库",
|
||||
"kind": "PREINSTALLED_USER_MODULE",
|
||||
"state": "LOCAL_INSTALLED_VERIFIED",
|
||||
"source": "src-tauri/src/lib.rs#knowledge",
|
||||
"capabilities": ["CREATE", "READ", "EDIT", "IMPORT_FOLDER", "EXPORT", "MOVE_TO_TRASH", "PRIVATE_GIT_COMMIT"]
|
||||
},
|
||||
{
|
||||
"module_id": "HLP-MOD-GLP-BRIDGE-0001",
|
||||
"name_zh": "光湖语言翻译桥",
|
||||
"kind": "SYSTEM_FOUNDATION",
|
||||
"state": "TYPED_SOURCE_ENVELOPE_IMPLEMENTED_FULL_PERSONA_TO_AGENT_TRANSLATION_PENDING",
|
||||
"source": "src/types.ts#SourceKind"
|
||||
},
|
||||
{
|
||||
"module_id": "HLP-MOD-AGENT-0001",
|
||||
"name_zh": "本地 Agent 执行核",
|
||||
"kind": "SYSTEM_FOUNDATION",
|
||||
"state": "KNOWLEDGE_CAPABILITY_SLICE_IMPLEMENTED_GENERAL_TCS_GIR_EXECUTOR_PENDING",
|
||||
"source": "src-tauri/src/lib.rs"
|
||||
},
|
||||
{
|
||||
"module_id": "HLP-MOD-UPDATE-0001",
|
||||
"name_zh": "HoloLake 签名更新器",
|
||||
"kind": "SYSTEM_FOUNDATION",
|
||||
"state": "CLIENT_TRUST_ROOT_BOUND_SERVER_HTTP_204_NO_PUBLIC_RELEASE",
|
||||
"source": "src-tauri/tauri.conf.json#plugins.updater"
|
||||
},
|
||||
{
|
||||
"module_id": "HLP-MOD-EXT-AI-0001",
|
||||
"name_zh": "外部编程 AI 表达桥",
|
||||
"kind": "OPTIONAL_LOCAL_BRIDGE",
|
||||
"state": "LOCAL_EXPRESSION_INBOX_OUTBOX_IMPLEMENTED",
|
||||
"source": "src-tauri/src/lib.rs#register_external_ai_bridge"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python3
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
REPO = ROOT.parents[1]
|
||||
errors = []
|
||||
|
||||
registry = json.loads((ROOT / "registries/module-registry.json").read_text())
|
||||
ids = [m["module_id"] for m in registry["modules"]]
|
||||
if len(ids) != len(set(ids)):
|
||||
errors.append("duplicate module id")
|
||||
|
||||
required_sources = {
|
||||
"USER_MESSAGE", "PERSONA_RESPONSE", "SYSTEM_CONTEXT", "PROTOCOL_EVENT",
|
||||
"AGENT_ACTION", "TOOL_RESULT", "SYSTEM_RECEIPT",
|
||||
}
|
||||
types = (ROOT / "src/types.ts").read_text()
|
||||
missing = sorted(x for x in required_sources if f'"{x}"' not in types)
|
||||
if missing:
|
||||
errors.append(f"missing source kinds: {missing}")
|
||||
|
||||
package = json.loads((ROOT / "package.json").read_text())
|
||||
for forbidden in ("openai", "anthropic", "@google/generative-ai", "langchain"):
|
||||
if forbidden in package.get("dependencies", {}):
|
||||
errors.append(f"internal model dependency forbidden: {forbidden}")
|
||||
|
||||
tauri = json.loads((ROOT / "src-tauri/tauri.conf.json").read_text())
|
||||
endpoints = tauri["plugins"]["updater"]["endpoints"]
|
||||
if endpoints != ["https://guanghulab.com/hololake/releases/latest.json"]:
|
||||
errors.append("update endpoint drift")
|
||||
if not tauri["plugins"]["updater"].get("pubkey"):
|
||||
errors.append("update signature trust missing")
|
||||
|
||||
architecture = json.loads((REPO / "routing/hololake-current-architecture.json").read_text())
|
||||
clean = architecture.get("clean_v1_rebuild", {})
|
||||
if clean.get("source") != "product-source/hololake-clean-desktop":
|
||||
errors.append("current architecture does not point to clean V1")
|
||||
if clean.get("enterprise_four_domains_embedded") is not False:
|
||||
errors.append("enterprise domains embedded in personal product")
|
||||
if clean.get("fifth_domain_private_content_embedded") is not False:
|
||||
errors.append("Fifth Domain private content embedded in public product")
|
||||
|
||||
if errors:
|
||||
print(json.dumps({"result": "FAIL_0", "errors": errors}, ensure_ascii=False, indent=2))
|
||||
sys.exit(1)
|
||||
print(json.dumps({"result": "PASS_100", "module_ids": ids, "source_kinds": sorted(required_sources)}, ensure_ascii=False, indent=2))
|
||||
5506
product-source/hololake-clean-desktop/src-tauri/Cargo.lock
generated
Normal file
5506
product-source/hololake-clean-desktop/src-tauri/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
30
product-source/hololake-clean-desktop/src-tauri/Cargo.toml
Normal file
30
product-source/hololake-clean-desktop/src-tauri/Cargo.toml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
name = "hololake-clean-desktop"
|
||||
version = "1.0.0"
|
||||
description = "HoloLake clean personal language operating system shell"
|
||||
authors = ["HoloLake"]
|
||||
license = "AGPL-3.0-or-later"
|
||||
edition = "2021"
|
||||
rust-version = "1.77.2"
|
||||
|
||||
[lib]
|
||||
name = "hololake_clean_desktop_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "=2.5.5", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "=2.10.2", features = [] }
|
||||
tauri-runtime = "=2.10.0"
|
||||
tauri-runtime-wry = "=2.10.0"
|
||||
tauri-plugin-dialog = "=2.7.2"
|
||||
tauri-plugin-process = "=2.3.1"
|
||||
tauri-plugin-updater = "=2.10.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
sha2 = "0.10"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
3
product-source/hololake-clean-desktop/src-tauri/build.rs
Normal file
3
product-source/hololake-clean-desktop/src-tauri/build.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "HoloLake clean shell: one typed IPC boundary plus signed update and native dialogs.",
|
||||
"windows": ["main"],
|
||||
"permissions": ["core:default", "dialog:default", "updater:default", "process:allow-restart"]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
{"default":{"identifier":"default","description":"HoloLake clean shell: one typed IPC boundary plus signed update and native dialogs.","local":true,"windows":["main"],"permissions":["core:default","dialog:default","updater:default","process:allow-restart"]}}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.icns
Normal file
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.icns
Normal file
Binary file not shown.
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.ico
Normal file
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.png
Normal file
BIN
product-source/hololake-clean-desktop/src-tauri/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
370
product-source/hololake-clean-desktop/src-tauri/src/lib.rs
Normal file
370
product-source/hololake-clean-desktop/src-tauri/src/lib.rs
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
mod model;
|
||||
mod storage;
|
||||
|
||||
use model::*;
|
||||
use std::{fs, path::Path};
|
||||
use tauri::AppHandle;
|
||||
use tauri_plugin_dialog::DialogExt;
|
||||
|
||||
const UPDATE_ENDPOINT: &str = "https://guanghulab.com/hololake/releases/latest.json";
|
||||
const PUBLIC_STATE: &str = "SIGNED_UPDATE_FEED_READY_NO_RELEASE";
|
||||
|
||||
fn receipt(
|
||||
app: &AppHandle,
|
||||
state: &str,
|
||||
message: &str,
|
||||
git: Option<String>,
|
||||
event: TimelineEvent,
|
||||
) -> Result<MutationReceipt, String> {
|
||||
storage::append_event(app, &event)?;
|
||||
Ok(MutationReceipt {
|
||||
receipt_id: storage::id("HL-RCP"),
|
||||
state: state.into(),
|
||||
message: message.into(),
|
||||
git_commit: git,
|
||||
event,
|
||||
})
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn system_snapshot(app: AppHandle) -> Result<SystemSnapshot, String> {
|
||||
Ok(SystemSnapshot {
|
||||
app_version: env!("CARGO_PKG_VERSION").into(),
|
||||
channel: storage::channel(&app)?,
|
||||
timeline: storage::events(&app)?,
|
||||
documents: storage::list_docs(&app)?,
|
||||
module_registry_version: "1".into(),
|
||||
public_update_endpoint: UPDATE_ENDPOINT.into(),
|
||||
public_distribution_state: PUBLIC_STATE.into(),
|
||||
external_ai_bridges: storage::bridges(&app)?,
|
||||
})
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn create_channel(app: AppHandle, name: String) -> Result<Channel, String> {
|
||||
let name = name.trim();
|
||||
if name.is_empty() || name.chars().count() > 48 {
|
||||
return Err("CHANNEL_NAME_INVALID".into());
|
||||
}
|
||||
if storage::channel(&app)?.is_some() {
|
||||
return Err("CHANNEL_ALREADY_EXISTS".into());
|
||||
}
|
||||
let repo = storage::private_repo_root(&app)?;
|
||||
let c = Channel {
|
||||
channel_id: format!(
|
||||
"HL-CH-{}",
|
||||
uuid::Uuid::new_v4().simple().to_string()[..8].to_uppercase()
|
||||
),
|
||||
name: name.into(),
|
||||
created_at: storage::now(),
|
||||
private_git_path: repo.to_string_lossy().into_owned(),
|
||||
public_distribution_state: PUBLIC_STATE.into(),
|
||||
};
|
||||
storage::save_channel(&app, &c)?;
|
||||
let e = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"频道已建立",
|
||||
format!("{} 已登记;私人 Git 已初始化。", c.channel_id),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
storage::append_event(&app, &e)?;
|
||||
storage::git_commit(
|
||||
&repo,
|
||||
"chore(channel): initialize personal HoloLake channel",
|
||||
)?;
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn submit_user_message(app: AppHandle, content: String) -> Result<MutationReceipt, String> {
|
||||
let content = content.trim();
|
||||
if content.is_empty() {
|
||||
return Err("EMPTY_USER_MESSAGE".into());
|
||||
}
|
||||
if storage::channel(&app)?.is_none() {
|
||||
return Err("CHANNEL_NOT_INITIALIZED".into());
|
||||
}
|
||||
let e = storage::event(SourceKind::UserMessage, "用户语言", content, "RECORDED");
|
||||
storage::append_event(&app, &e)?;
|
||||
let waiting = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"系统回执",
|
||||
"用户语言已按 USER_MESSAGE 保存;当前未绑定人格模型,不伪造人格回应。",
|
||||
"WAITING",
|
||||
);
|
||||
receipt(
|
||||
&app,
|
||||
"WAITING_PERSONA",
|
||||
"用户语言已记录,等待人格体接入。",
|
||||
None,
|
||||
waiting,
|
||||
)
|
||||
}
|
||||
|
||||
fn clean_title(title: &str) -> Result<String, String> {
|
||||
let t = title.trim();
|
||||
if t.is_empty() || t.chars().count() > 120 {
|
||||
return Err("KNOWLEDGE_TITLE_INVALID".into());
|
||||
}
|
||||
Ok(t.chars()
|
||||
.map(|c| if "\\/:*?\"<>|".contains(c) { '-' } else { c })
|
||||
.collect())
|
||||
}
|
||||
#[tauri::command]
|
||||
fn read_knowledge_document(app: AppHandle, path: String) -> Result<KnowledgeDocument, String> {
|
||||
storage::read_doc(&app, &path)
|
||||
}
|
||||
#[tauri::command]
|
||||
fn create_knowledge_document(app: AppHandle, title: String) -> Result<MutationReceipt, String> {
|
||||
let title = clean_title(&title)?;
|
||||
let root = storage::knowledge_root(&app)?;
|
||||
let rel = format!("{}.md", title);
|
||||
let p = root.join("docs").join(&rel);
|
||||
if p.exists() {
|
||||
return Err("KNOWLEDGE_DOCUMENT_EXISTS".into());
|
||||
}
|
||||
fs::write(&p, format!("# {}\n\n", title)).map_err(|e| e.to_string())?;
|
||||
let git = storage::git_commit(&root, "feat(knowledge): create document")?;
|
||||
let e = storage::event(
|
||||
SourceKind::AgentAction,
|
||||
"Agent 执行",
|
||||
format!("已创建知识页 {rel}"),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
receipt(&app, "SUCCEEDED", "知识页已创建。", git, e)
|
||||
}
|
||||
#[tauri::command]
|
||||
fn save_knowledge_document(
|
||||
app: AppHandle,
|
||||
path: String,
|
||||
body: String,
|
||||
) -> Result<MutationReceipt, String> {
|
||||
let rel = storage::safe_rel(&path)?;
|
||||
if rel.extension().and_then(|x| x.to_str()) != Some("md") {
|
||||
return Err("KNOWLEDGE_DOCUMENT_TYPE_REJECTED".into());
|
||||
}
|
||||
let root = storage::knowledge_root(&app)?;
|
||||
let p = root.join("docs").join(rel);
|
||||
if !p.exists() {
|
||||
return Err("KNOWLEDGE_DOCUMENT_NOT_FOUND".into());
|
||||
}
|
||||
fs::write(&p, body).map_err(|e| e.to_string())?;
|
||||
let git = storage::git_commit(&root, "docs(knowledge): save document")?;
|
||||
let e = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"系统回执",
|
||||
format!("{path} 已写入私人 Git。"),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
receipt(&app, "SUCCEEDED", "保存完成。", git, e)
|
||||
}
|
||||
#[tauri::command]
|
||||
fn delete_knowledge_document(app: AppHandle, path: String) -> Result<MutationReceipt, String> {
|
||||
let rel = storage::safe_rel(&path)?;
|
||||
let root = storage::knowledge_root(&app)?;
|
||||
let from = root.join("docs").join(&rel);
|
||||
if !from.exists() {
|
||||
return Err("KNOWLEDGE_DOCUMENT_NOT_FOUND".into());
|
||||
}
|
||||
let trash = root.join(".trash").join(format!(
|
||||
"{}-{}",
|
||||
storage::id("deleted"),
|
||||
rel.file_name()
|
||||
.and_then(|x| x.to_str())
|
||||
.unwrap_or("document.md")
|
||||
));
|
||||
fs::create_dir_all(trash.parent().unwrap()).map_err(|e| e.to_string())?;
|
||||
fs::rename(from, &trash).map_err(|e| e.to_string())?;
|
||||
let git = storage::git_commit(&root, "chore(knowledge): move document to trash")?;
|
||||
let e = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"系统回执",
|
||||
format!("{path} 已移入可恢复回收站。"),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
receipt(&app, "SUCCEEDED", "已移入回收站。", git, e)
|
||||
}
|
||||
|
||||
fn copy_import(src: &Path, dst: &Path, count: &mut usize) -> Result<(), String> {
|
||||
if *count >= 1000 {
|
||||
return Err("IMPORT_FILE_LIMIT_EXCEEDED".into());
|
||||
}
|
||||
for entry in fs::read_dir(src).map_err(|e| e.to_string())? {
|
||||
let entry = entry.map_err(|e| e.to_string())?;
|
||||
let p = entry.path();
|
||||
if p.file_name()
|
||||
.and_then(|x| x.to_str())
|
||||
.map(|x| x.starts_with('.'))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if p.is_dir() {
|
||||
copy_import(&p, dst, count)?;
|
||||
continue;
|
||||
}
|
||||
let ext = p
|
||||
.extension()
|
||||
.and_then(|x| x.to_str())
|
||||
.unwrap_or("")
|
||||
.to_lowercase();
|
||||
if !["md", "txt", "markdown"].contains(&ext.as_str()) {
|
||||
continue;
|
||||
}
|
||||
let bytes = fs::read(&p).map_err(|e| e.to_string())?;
|
||||
if bytes.len() > 10 * 1024 * 1024 {
|
||||
continue;
|
||||
}
|
||||
let body = String::from_utf8_lossy(&bytes);
|
||||
let title = p.file_stem().and_then(|x| x.to_str()).unwrap_or("导入页面");
|
||||
let name = format!("{}-{}.md", clean_title(title)?, &storage::sha(&bytes)[..8]);
|
||||
fs::write(
|
||||
dst.join(name),
|
||||
if ext == "md" || ext == "markdown" {
|
||||
body.into_owned()
|
||||
} else {
|
||||
format!("# {}\n\n{}", title, body)
|
||||
},
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
*count += 1
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[tauri::command]
|
||||
async fn import_knowledge_folder(app: AppHandle) -> Result<Option<MutationReceipt>, String> {
|
||||
let Some(folder) = app
|
||||
.dialog()
|
||||
.file()
|
||||
.set_title("导入到光湖知识库")
|
||||
.blocking_pick_folder()
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
let src = folder.into_path().map_err(|e| e.to_string())?;
|
||||
let root = storage::knowledge_root(&app)?;
|
||||
let dst = root.join("docs").join("导入");
|
||||
fs::create_dir_all(&dst).map_err(|e| e.to_string())?;
|
||||
let mut count = 0;
|
||||
copy_import(&src, &dst, &mut count)?;
|
||||
let git = storage::git_commit(&root, "feat(knowledge): import external folder")?;
|
||||
let protocol = storage::event(
|
||||
SourceKind::ProtocolEvent,
|
||||
"协议运行",
|
||||
format!("导入边界校验完成;接受 Markdown/纯文本,共 {count} 页。原目录未改写。"),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
storage::append_event(&app, &protocol)?;
|
||||
let e = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"系统回执",
|
||||
format!("外部文件夹已转换为 {count} 个光湖知识页。"),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
Ok(Some(receipt(
|
||||
&app,
|
||||
"SUCCEEDED",
|
||||
"文件夹导入完成。",
|
||||
git,
|
||||
e,
|
||||
)?))
|
||||
}
|
||||
#[tauri::command]
|
||||
async fn export_knowledge_document(app: AppHandle, path: String) -> Result<Option<String>, String> {
|
||||
let doc = storage::read_doc(&app, &path)?;
|
||||
let Some(target) = app
|
||||
.dialog()
|
||||
.file()
|
||||
.set_title("下载知识页")
|
||||
.set_file_name(&path)
|
||||
.blocking_save_file()
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
let p = target.into_path().map_err(|e| e.to_string())?;
|
||||
fs::write(&p, doc.body).map_err(|e| e.to_string())?;
|
||||
let e = storage::event(
|
||||
SourceKind::ToolResult,
|
||||
"工具结果",
|
||||
format!("知识页已下载到 {}", p.display()),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
storage::append_event(&app, &e)?;
|
||||
Ok(Some(p.to_string_lossy().into_owned()))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn register_external_ai_bridge(
|
||||
app: AppHandle,
|
||||
display_name: String,
|
||||
) -> Result<ExternalAiBridge, String> {
|
||||
let name = display_name.trim();
|
||||
if name.is_empty() || name.chars().count() > 64 {
|
||||
return Err("EXTERNAL_AI_NAME_INVALID".into());
|
||||
}
|
||||
let bridge_id = format!(
|
||||
"HL-AI-{}",
|
||||
uuid::Uuid::new_v4().simple().to_string()[..8].to_uppercase()
|
||||
);
|
||||
let root = storage::root(&app)?.join("external-ai").join(&bridge_id);
|
||||
let inbox = root.join("inbox");
|
||||
let outbox = root.join("outbox");
|
||||
fs::create_dir_all(&inbox).map_err(|e| e.to_string())?;
|
||||
fs::create_dir_all(&outbox).map_err(|e| e.to_string())?;
|
||||
let bridge = ExternalAiBridge {
|
||||
bridge_id,
|
||||
display_name: name.into(),
|
||||
inbox_path: inbox.to_string_lossy().into_owned(),
|
||||
outbox_path: outbox.to_string_lossy().into_owned(),
|
||||
state: "LOCAL_EXPRESSION_ONLY_NO_EXECUTION_AUTHORITY".into(),
|
||||
};
|
||||
let mut all = storage::bridges(&app)?;
|
||||
all.push(bridge.clone());
|
||||
storage::save_bridges(&app, &all)?;
|
||||
let e = storage::event(
|
||||
SourceKind::SystemReceipt,
|
||||
"外部 AI 入口已建立",
|
||||
format!(
|
||||
"{} 仅获得来源明确的语言收发目录,不获得人格与执行权限。",
|
||||
bridge.bridge_id
|
||||
),
|
||||
"SUCCEEDED",
|
||||
);
|
||||
storage::append_event(&app, &e)?;
|
||||
Ok(bridge)
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
system_snapshot,
|
||||
create_channel,
|
||||
submit_user_message,
|
||||
read_knowledge_document,
|
||||
create_knowledge_document,
|
||||
save_knowledge_document,
|
||||
delete_knowledge_document,
|
||||
import_knowledge_folder,
|
||||
export_knowledge_document,
|
||||
register_external_ai_bridge
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("HoloLake runtime failed")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn title_rejects_empty() {
|
||||
assert!(clean_title(" ").is_err())
|
||||
}
|
||||
#[test]
|
||||
fn title_sanitizes_paths() {
|
||||
assert_eq!(clean_title("a/b").unwrap(), "a-b")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
fn main() {
|
||||
hololake_clean_desktop_lib::run();
|
||||
}
|
||||
86
product-source/hololake-clean-desktop/src-tauri/src/model.rs
Normal file
86
product-source/hololake-clean-desktop/src-tauri/src/model.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Channel {
|
||||
pub channel_id: String,
|
||||
pub name: String,
|
||||
pub created_at: String,
|
||||
pub private_git_path: String,
|
||||
pub public_distribution_state: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum SourceKind {
|
||||
UserMessage,
|
||||
PersonaResponse,
|
||||
SystemContext,
|
||||
ProtocolEvent,
|
||||
AgentAction,
|
||||
ToolResult,
|
||||
SystemReceipt,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TimelineEvent {
|
||||
pub event_id: String,
|
||||
pub source_kind: SourceKind,
|
||||
pub title: String,
|
||||
pub content: String,
|
||||
pub occurred_at: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KnowledgeSummary {
|
||||
pub path: String,
|
||||
pub title: String,
|
||||
pub updated_at: String,
|
||||
pub sha256: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KnowledgeDocument {
|
||||
pub path: String,
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub updated_at: String,
|
||||
pub sha256: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ExternalAiBridge {
|
||||
pub bridge_id: String,
|
||||
pub display_name: String,
|
||||
pub inbox_path: String,
|
||||
pub outbox_path: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SystemSnapshot {
|
||||
pub app_version: String,
|
||||
pub channel: Option<Channel>,
|
||||
pub timeline: Vec<TimelineEvent>,
|
||||
pub documents: Vec<KnowledgeSummary>,
|
||||
pub module_registry_version: String,
|
||||
pub public_update_endpoint: String,
|
||||
pub public_distribution_state: String,
|
||||
pub external_ai_bridges: Vec<ExternalAiBridge>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MutationReceipt {
|
||||
pub receipt_id: String,
|
||||
pub state: String,
|
||||
pub message: String,
|
||||
pub git_commit: Option<String>,
|
||||
pub event: TimelineEvent,
|
||||
}
|
||||
244
product-source/hololake-clean-desktop/src-tauri/src/storage.rs
Normal file
244
product-source/hololake-clean-desktop/src-tauri/src/storage.rs
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
use crate::model::{
|
||||
Channel, ExternalAiBridge, KnowledgeDocument, KnowledgeSummary, SourceKind, TimelineEvent,
|
||||
};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Component, Path, PathBuf},
|
||||
process::Command,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
pub fn now() -> String {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map(|d| format!("{}.{:03}Z", d.as_secs(), d.subsec_millis()))
|
||||
.unwrap_or_else(|_| "0Z".into())
|
||||
}
|
||||
pub fn id(prefix: &str) -> String {
|
||||
format!("{}-{}", prefix, UuidPart::new())
|
||||
}
|
||||
struct UuidPart(String);
|
||||
impl UuidPart {
|
||||
fn new() -> Self {
|
||||
Self(uuid::Uuid::new_v4().simple().to_string()[..12].to_uppercase())
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UuidPart {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
pub fn sha(bytes: &[u8]) -> String {
|
||||
format!("{:x}", Sha256::digest(bytes))
|
||||
}
|
||||
|
||||
pub fn root(app: &AppHandle) -> Result<PathBuf, String> {
|
||||
let p = app
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.map_err(|e| e.to_string())?
|
||||
.join("runtime-v1");
|
||||
fs::create_dir_all(&p).map_err(|e| e.to_string())?;
|
||||
Ok(p)
|
||||
}
|
||||
fn read_json<T: serde::de::DeserializeOwned>(p: &Path) -> Result<T, String> {
|
||||
serde_json::from_slice(&fs::read(p).map_err(|e| e.to_string())?).map_err(|e| e.to_string())
|
||||
}
|
||||
fn write_json<T: serde::Serialize>(p: &Path, v: &T) -> Result<(), String> {
|
||||
if let Some(x) = p.parent() {
|
||||
fs::create_dir_all(x).map_err(|e| e.to_string())?
|
||||
}
|
||||
let tmp = p.with_extension("tmp");
|
||||
fs::write(
|
||||
&tmp,
|
||||
serde_json::to_vec_pretty(v).map_err(|e| e.to_string())?,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
fs::rename(tmp, p).map_err(|e| e.to_string())
|
||||
}
|
||||
pub fn channel(app: &AppHandle) -> Result<Option<Channel>, String> {
|
||||
let p = root(app)?.join("channel.json");
|
||||
if p.exists() {
|
||||
read_json(&p).map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
pub fn save_channel(app: &AppHandle, c: &Channel) -> Result<(), String> {
|
||||
write_json(&root(app)?.join("channel.json"), c)
|
||||
}
|
||||
pub fn event(
|
||||
kind: SourceKind,
|
||||
title: impl Into<String>,
|
||||
content: impl Into<String>,
|
||||
state: &str,
|
||||
) -> TimelineEvent {
|
||||
TimelineEvent {
|
||||
event_id: id("HL-EVT"),
|
||||
source_kind: kind,
|
||||
title: title.into(),
|
||||
content: content.into(),
|
||||
occurred_at: now(),
|
||||
state: state.into(),
|
||||
}
|
||||
}
|
||||
pub fn append_event(app: &AppHandle, e: &TimelineEvent) -> Result<(), String> {
|
||||
let p = root(app)?.join("events.jsonl");
|
||||
let mut s = if p.exists() {
|
||||
fs::read_to_string(&p).map_err(|e| e.to_string())?
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
s.push_str(&serde_json::to_string(e).map_err(|e| e.to_string())?);
|
||||
s.push('\n');
|
||||
fs::write(p, s).map_err(|e| e.to_string())
|
||||
}
|
||||
pub fn events(app: &AppHandle) -> Result<Vec<TimelineEvent>, String> {
|
||||
let p = root(app)?.join("events.jsonl");
|
||||
if !p.exists() {
|
||||
return Ok(vec![]);
|
||||
};
|
||||
let mut v = fs::read_to_string(p)
|
||||
.map_err(|e| e.to_string())?
|
||||
.lines()
|
||||
.filter_map(|l| serde_json::from_str(l).ok())
|
||||
.collect::<Vec<_>>();
|
||||
v.reverse();
|
||||
Ok(v)
|
||||
}
|
||||
pub fn knowledge_root(app: &AppHandle) -> Result<PathBuf, String> {
|
||||
let p = root(app)?.join("private-repository").join("knowledge");
|
||||
fs::create_dir_all(p.join("docs")).map_err(|e| e.to_string())?;
|
||||
ensure_git(&p)?;
|
||||
Ok(p)
|
||||
}
|
||||
pub fn private_repo_root(app: &AppHandle) -> Result<PathBuf, String> {
|
||||
let p = root(app)?.join("private-repository");
|
||||
fs::create_dir_all(&p).map_err(|e| e.to_string())?;
|
||||
ensure_git(&p)?;
|
||||
Ok(p)
|
||||
}
|
||||
pub fn ensure_git(p: &Path) -> Result<(), String> {
|
||||
if !p.join(".git").exists() {
|
||||
run_git(p, &["init", "--initial-branch=main"])?;
|
||||
run_git(p, &["config", "user.name", "HoloLake Local"])?;
|
||||
run_git(p, &["config", "user.email", "local@hololake.invalid"])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn git_commit(p: &Path, msg: &str) -> Result<Option<String>, String> {
|
||||
run_git(p, &["add", "."])?;
|
||||
let status = run_git(p, &["status", "--porcelain"])?;
|
||||
if status.trim().is_empty() {
|
||||
return Ok(None);
|
||||
};
|
||||
run_git(p, &["commit", "-m", msg])?;
|
||||
Ok(Some(run_git(p, &["rev-parse", "HEAD"])?.trim().into()))
|
||||
}
|
||||
fn run_git(p: &Path, args: &[&str]) -> Result<String, String> {
|
||||
let o = Command::new("git")
|
||||
.current_dir(p)
|
||||
.args(args)
|
||||
.output()
|
||||
.map_err(|e| format!("GIT_UNAVAILABLE: {e}"))?;
|
||||
if !o.status.success() {
|
||||
return Err(format!(
|
||||
"GIT_FAILED: {}",
|
||||
String::from_utf8_lossy(&o.stderr)
|
||||
));
|
||||
};
|
||||
Ok(String::from_utf8_lossy(&o.stdout).into_owned())
|
||||
}
|
||||
pub fn safe_rel(value: &str) -> Result<PathBuf, String> {
|
||||
let p = Path::new(value);
|
||||
if p.is_absolute()
|
||||
|| p.components().any(|c| {
|
||||
matches!(
|
||||
c,
|
||||
Component::ParentDir | Component::RootDir | Component::Prefix(_)
|
||||
)
|
||||
})
|
||||
{
|
||||
return Err("PATH_OUT_OF_SCOPE".into());
|
||||
}
|
||||
Ok(p.to_path_buf())
|
||||
}
|
||||
pub fn list_docs(app: &AppHandle) -> Result<Vec<KnowledgeSummary>, String> {
|
||||
let root = knowledge_root(app)?.join("docs");
|
||||
let mut out = vec![];
|
||||
collect(&root, &root, &mut out)?;
|
||||
out.sort_by(|a, b| b.updated_at.cmp(&a.updated_at));
|
||||
Ok(out)
|
||||
}
|
||||
fn collect(root: &Path, p: &Path, out: &mut Vec<KnowledgeSummary>) -> Result<(), String> {
|
||||
for e in fs::read_dir(p).map_err(|e| e.to_string())? {
|
||||
let e = e.map_err(|e| e.to_string())?;
|
||||
let path = e.path();
|
||||
if path.is_dir() {
|
||||
collect(root, &path, out)?
|
||||
} else if path.extension().and_then(|x| x.to_str()) == Some("md") {
|
||||
let b = fs::read(&path).map_err(|e| e.to_string())?;
|
||||
let rel = path
|
||||
.strip_prefix(root)
|
||||
.map_err(|e| e.to_string())?
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
let body = String::from_utf8_lossy(&b);
|
||||
let title = body
|
||||
.lines()
|
||||
.find_map(|x| x.strip_prefix("# "))
|
||||
.unwrap_or_else(|| {
|
||||
path.file_stem()
|
||||
.and_then(|x| x.to_str())
|
||||
.unwrap_or("未命名")
|
||||
})
|
||||
.into();
|
||||
let updated = e
|
||||
.metadata()
|
||||
.map_err(|e| e.to_string())?
|
||||
.modified()
|
||||
.ok()
|
||||
.and_then(|t| t.duration_since(UNIX_EPOCH).ok())
|
||||
.map(|d| d.as_secs().to_string())
|
||||
.unwrap_or_else(|| "0".into());
|
||||
out.push(KnowledgeSummary {
|
||||
path: rel,
|
||||
title,
|
||||
updated_at: updated,
|
||||
sha256: sha(&b),
|
||||
})
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn read_doc(app: &AppHandle, path: &str) -> Result<KnowledgeDocument, String> {
|
||||
let rel = safe_rel(path)?;
|
||||
let p = knowledge_root(app)?.join("docs").join(rel);
|
||||
let b = fs::read(&p).map_err(|e| e.to_string())?;
|
||||
let body = String::from_utf8(b.clone()).map_err(|_| "DOCUMENT_NOT_UTF8".to_string())?;
|
||||
let title = body
|
||||
.lines()
|
||||
.find_map(|x| x.strip_prefix("# "))
|
||||
.unwrap_or_else(|| p.file_stem().and_then(|x| x.to_str()).unwrap_or("未命名"))
|
||||
.into();
|
||||
Ok(KnowledgeDocument {
|
||||
path: path.into(),
|
||||
title,
|
||||
body,
|
||||
updated_at: now(),
|
||||
sha256: sha(&b),
|
||||
})
|
||||
}
|
||||
pub fn bridges(app: &AppHandle) -> Result<Vec<ExternalAiBridge>, String> {
|
||||
let p = root(app)?.join("external-ai-bridges.json");
|
||||
if p.exists() {
|
||||
read_json(&p)
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
pub fn save_bridges(app: &AppHandle, v: &[ExternalAiBridge]) -> Result<(), String> {
|
||||
write_json(&root(app)?.join("external-ai-bridges.json"), &v)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "HoloLake",
|
||||
"version": "1.0.0",
|
||||
"identifier": "world.guanghu.hololake",
|
||||
"build": { "frontendDist": "../dist", "devUrl": "http://127.0.0.1:5211", "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run build" },
|
||||
"app": {
|
||||
"windows": [{ "label": "main", "title": "HoloLake", "width": 1320, "height": 860, "minWidth": 760, "minHeight": 560, "center": true }],
|
||||
"security": { "csp": "default-src 'self'; connect-src 'self' ipc: http://ipc.localhost https://guanghulab.com; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'" }
|
||||
},
|
||||
"plugins": { "updater": { "endpoints": ["https://guanghulab.com/hololake/releases/latest.json"], "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDEzQkYzRTQ5QTE2MEFDMzEKUldReHJHQ2hTVDYvRTZNNDVqZDUxLzRZMmxuT1pSM2Q5RTRZbzRCZUZ0d0FxVVNidGJ0dUQyMnoK" } },
|
||||
"bundle": { "active": true, "targets": ["app", "dmg"], "createUpdaterArtifacts": true, "category": "Productivity", "icon": ["icons/icon.icns", "icons/icon.png", "icons/icon.ico"], "macOS": { "signingIdentity": "Developer ID Application: bei sun (825A9L3G7Q)" } }
|
||||
}
|
||||
629
product-source/hololake-clean-desktop/src/App.tsx
Normal file
629
product-source/hololake-clean-desktop/src/App.tsx
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { check } from "@tauri-apps/plugin-updater";
|
||||
import { relaunch } from "@tauri-apps/plugin-process";
|
||||
import { Icon } from "./icons";
|
||||
import * as api from "./runtime";
|
||||
import type { KnowledgeDocument, SourceKind, SystemSnapshot } from "./types";
|
||||
|
||||
type View =
|
||||
| "channel"
|
||||
| "knowledge"
|
||||
| "market"
|
||||
| "history"
|
||||
| "portal"
|
||||
| "settings";
|
||||
const nav: [View, string, string][] = [
|
||||
["channel", "我的频道", "channel"],
|
||||
["knowledge", "光湖知识库", "book"],
|
||||
["market", "模块商城", "cube"],
|
||||
["history", "系统演化史", "history"],
|
||||
["portal", "企业门户", "building"],
|
||||
["settings", "设置", "settings"],
|
||||
];
|
||||
const labels: Record<SourceKind, string> = {
|
||||
USER_MESSAGE: "用户语言",
|
||||
PERSONA_RESPONSE: "人格回应",
|
||||
SYSTEM_CONTEXT: "系统环境",
|
||||
PROTOCOL_EVENT: "协议运行",
|
||||
AGENT_ACTION: "Agent 执行",
|
||||
TOOL_RESULT: "工具结果",
|
||||
SYSTEM_RECEIPT: "系统回执",
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const [data, setData] = useState<SystemSnapshot | null>(null),
|
||||
[view, setView] = useState<View>("channel"),
|
||||
[error, setError] = useState(""),
|
||||
[busy, setBusy] = useState(false);
|
||||
const refresh = () =>
|
||||
api
|
||||
.snapshot()
|
||||
.then(setData)
|
||||
.catch((e) => setError(String(e)));
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
}, []);
|
||||
if (!data)
|
||||
return (
|
||||
<div className="boot">
|
||||
<div className="lake-mark" />
|
||||
正在进入 HoloLake…
|
||||
</div>
|
||||
);
|
||||
if (!data.channel) return <Onboarding onDone={refresh} error={error} />;
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<div className="titlebar">
|
||||
<div className="traffic">
|
||||
<i />
|
||||
<i />
|
||||
<i />
|
||||
</div>
|
||||
<span>HoloLake</span>
|
||||
<span className="version">
|
||||
v{data.appVersion.replace("-browser", "")}
|
||||
</span>
|
||||
</div>
|
||||
<aside className="rail">
|
||||
<div className="brand-orbit">
|
||||
<span />
|
||||
</div>
|
||||
<nav>
|
||||
{nav.map(([id, label, icon]) => (
|
||||
<button
|
||||
key={id}
|
||||
className={view === id ? "active" : ""}
|
||||
aria-label={label}
|
||||
onClick={() => setView(id)}
|
||||
>
|
||||
<Icon name={icon} />
|
||||
<span>{label}</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
<div className="channel-mini">
|
||||
<div className="mini-lake" />
|
||||
<div>
|
||||
<strong>{data.channel.name}</strong>
|
||||
<small>{data.channel.channelId}</small>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<main>
|
||||
{view === "channel" && (
|
||||
<Channel
|
||||
data={data}
|
||||
refresh={refresh}
|
||||
openKnowledge={() => setView("knowledge")}
|
||||
/>
|
||||
)}{" "}
|
||||
{view === "knowledge" && <Knowledge data={data} refresh={refresh} />}{" "}
|
||||
{view === "market" && <Market />}{" "}
|
||||
{view === "history" && <History data={data} />}{" "}
|
||||
{view === "portal" && <Portal />}{" "}
|
||||
{view === "settings" && (
|
||||
<Settings
|
||||
data={data}
|
||||
refresh={refresh}
|
||||
busy={busy}
|
||||
setBusy={setBusy}
|
||||
setError={setError}
|
||||
/>
|
||||
)}
|
||||
</main>
|
||||
{error && (
|
||||
<div className="toast" role="alert">
|
||||
<span>{error}</span>
|
||||
<button onClick={() => setError("")}>关闭</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Onboarding({ onDone, error }: { onDone: () => void; error: string }) {
|
||||
const [name, setName] = useState("");
|
||||
const go = async () => {
|
||||
if (!name.trim()) return;
|
||||
await api.createChannel(name.trim());
|
||||
onDone();
|
||||
};
|
||||
return (
|
||||
<div className="onboard">
|
||||
<div className="stars" />
|
||||
<section>
|
||||
<div className="origin-light" />
|
||||
<h1>为你的频道起一个名字</h1>
|
||||
<p>
|
||||
这是属于你的私人初始化频道。系统将为它登记唯一编号,并在本机建立私人
|
||||
Git。
|
||||
</p>
|
||||
<label>
|
||||
频道名称
|
||||
<input
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
onKeyDown={(e) => e.key === "Enter" && go()}
|
||||
placeholder="例如:我的光湖"
|
||||
autoFocus
|
||||
/>
|
||||
</label>
|
||||
<button onClick={go} disabled={!name.trim()}>
|
||||
建立我的频道
|
||||
</button>
|
||||
{error && <small>{error}</small>}
|
||||
</section>
|
||||
<footer>GH-AIOS · 光湖语言系统 · 通用人工智能操作平台</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Channel({
|
||||
data,
|
||||
refresh,
|
||||
openKnowledge,
|
||||
}: {
|
||||
data: SystemSnapshot;
|
||||
refresh: () => void;
|
||||
openKnowledge: () => void;
|
||||
}) {
|
||||
const [text, setText] = useState("");
|
||||
const send = async () => {
|
||||
if (!text.trim()) return;
|
||||
await api.submitMessage(text.trim());
|
||||
setText("");
|
||||
refresh();
|
||||
};
|
||||
return (
|
||||
<div className="page channel-page">
|
||||
<header>
|
||||
<div>
|
||||
<h1>{data.channel?.name}</h1>
|
||||
<p>个人初始化频道</p>
|
||||
</div>
|
||||
<button className="soft" onClick={openKnowledge}>
|
||||
打开光湖知识库
|
||||
</button>
|
||||
</header>
|
||||
<div className="channel-grid">
|
||||
<div className="channel-primary">
|
||||
<section className="conversation">
|
||||
<div className="welcome">
|
||||
<div className="lake-mark" />
|
||||
<h2>频道已经准备好</h2>
|
||||
<p>
|
||||
这里保存你与人格体的语言。系统动作会被分流到下方执行记录,不再混入对话。
|
||||
</p>
|
||||
</div>
|
||||
{data.timeline
|
||||
.filter(
|
||||
(e) =>
|
||||
e.sourceKind === "USER_MESSAGE" ||
|
||||
e.sourceKind === "PERSONA_RESPONSE",
|
||||
)
|
||||
.slice(0, 8)
|
||||
.reverse()
|
||||
.map((e) => (
|
||||
<article
|
||||
className={
|
||||
e.sourceKind === "USER_MESSAGE" ? "human" : "persona"
|
||||
}
|
||||
key={e.eventId}
|
||||
>
|
||||
<span>{labels[e.sourceKind]}</span>
|
||||
<p>{e.content}</p>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
<ReceiptStream data={data} />
|
||||
<div className="composer">
|
||||
<textarea
|
||||
value={text}
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
placeholder={`和${data.channel?.name}说点什么…`}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
send();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button onClick={send} aria-label="发送">
|
||||
↗
|
||||
</button>
|
||||
<small>Enter 发送 · Shift + Enter 换行</small>
|
||||
</div>
|
||||
</div>
|
||||
<aside className="channel-context" aria-label="频道运行状态">
|
||||
<article>
|
||||
<h2>当前频道</h2>
|
||||
<strong>{data.channel?.name}</strong>
|
||||
<p>{data.channel?.channelId}</p>
|
||||
</article>
|
||||
<article>
|
||||
<h2>私人 Git</h2>
|
||||
<strong>本机已建立</strong>
|
||||
<p className="path">{data.channel?.privateGitPath}</p>
|
||||
</article>
|
||||
<article>
|
||||
<h2>公共更新</h2>
|
||||
<strong>
|
||||
{data.publicDistributionState === "SIGNED_UPDATE_FEED_READY_NO_RELEASE"
|
||||
? "更新入口在线 · 暂无发行"
|
||||
: data.publicDistributionState}
|
||||
</strong>
|
||||
<p>只接收签名发行,不自动执行普通 Git 拉取。</p>
|
||||
</article>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ReceiptStream({ data }: { data: SystemSnapshot }) {
|
||||
const rows = data.timeline
|
||||
.filter(
|
||||
(e) =>
|
||||
e.sourceKind !== "USER_MESSAGE" && e.sourceKind !== "PERSONA_RESPONSE",
|
||||
)
|
||||
.slice(0, 5);
|
||||
return (
|
||||
<section className="receipt-stream">
|
||||
<h2>执行记录</h2>
|
||||
{rows.length === 0 ? (
|
||||
<p className="empty">
|
||||
还没有系统动作。你的语言与执行记录会在这里分开呈现。
|
||||
</p>
|
||||
) : (
|
||||
rows.map((e) => (
|
||||
<div
|
||||
className={`receipt ${e.sourceKind.toLowerCase()}`}
|
||||
key={e.eventId}
|
||||
>
|
||||
<span className="kind">{labels[e.sourceKind]}</span>
|
||||
<strong>{e.title}</strong>
|
||||
<p>{e.content}</p>
|
||||
<time>
|
||||
{new Date(e.occurredAt).toLocaleTimeString("zh-CN", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
})}
|
||||
</time>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function Knowledge({
|
||||
data,
|
||||
refresh,
|
||||
}: {
|
||||
data: SystemSnapshot;
|
||||
refresh: () => void;
|
||||
}) {
|
||||
const [selected, setSelected] = useState<string | null>(
|
||||
data.documents[0]?.path ?? null,
|
||||
),
|
||||
[doc, setDoc] = useState<KnowledgeDocument | null>(null),
|
||||
[body, setBody] = useState(""),
|
||||
[query, setQuery] = useState(""),
|
||||
[newTitle, setNewTitle] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
if (selected)
|
||||
api.readDocument(selected).then((d) => {
|
||||
setDoc(d);
|
||||
setBody(d.body);
|
||||
});
|
||||
}, [selected]);
|
||||
const list = useMemo(
|
||||
() =>
|
||||
data.documents.filter((d) =>
|
||||
d.title.toLowerCase().includes(query.toLowerCase()),
|
||||
),
|
||||
[data.documents, query],
|
||||
);
|
||||
const create = async () => {
|
||||
const title = newTitle?.trim();
|
||||
if (title) {
|
||||
await api.createDocument(title);
|
||||
setNewTitle(null);
|
||||
await refresh();
|
||||
setSelected(`${title.replace(/[\\/:*?\"<>|]/g, "-")}.md`);
|
||||
}
|
||||
};
|
||||
const save = async () => {
|
||||
if (doc) {
|
||||
await api.saveDocument(doc.path, body);
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
const del = async () => {
|
||||
if (doc && confirm(`把“${doc.title}”移入回收站?`)) {
|
||||
await api.deleteDocument(doc.path);
|
||||
setSelected(null);
|
||||
setDoc(null);
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="page knowledge-page">
|
||||
<header>
|
||||
<div>
|
||||
<h1>光湖知识库</h1>
|
||||
<p>预装模块 · HLP-MOD-KB-0001</p>
|
||||
</div>
|
||||
<div className="actions">
|
||||
<button
|
||||
className="soft"
|
||||
onClick={async () => {
|
||||
await api.importFolder();
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
导入文件夹
|
||||
</button>
|
||||
<button onClick={() => setNewTitle("")}>新建知识页</button>
|
||||
</div>
|
||||
</header>
|
||||
<div className="knowledge-workspace">
|
||||
<aside>
|
||||
<input
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="搜索知识库"
|
||||
/>
|
||||
{list.length === 0 ? (
|
||||
<p className="empty">暂无知识页</p>
|
||||
) : (
|
||||
list.map((d) => (
|
||||
<button
|
||||
className={selected === d.path ? "selected" : ""}
|
||||
key={d.path}
|
||||
onClick={() => setSelected(d.path)}
|
||||
>
|
||||
<strong>{d.title}</strong>
|
||||
<small>
|
||||
{new Date(d.updatedAt).toLocaleDateString("zh-CN")}
|
||||
</small>
|
||||
</button>
|
||||
))
|
||||
)}
|
||||
</aside>
|
||||
<section>
|
||||
{doc ? (
|
||||
<>
|
||||
<div className="editor-tools">
|
||||
<strong>{doc.title}</strong>
|
||||
<span />
|
||||
<button onClick={() => api.exportDocument(doc.path)}>
|
||||
下载
|
||||
</button>
|
||||
<button className="danger" onClick={del}>
|
||||
删除
|
||||
</button>
|
||||
<button onClick={save}>保存</button>
|
||||
</div>
|
||||
<textarea
|
||||
className="editor"
|
||||
value={body}
|
||||
onChange={(e) => setBody(e.target.value)}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div className="welcome">
|
||||
<Icon name="book" />
|
||||
<h2>从第一条知识开始</h2>
|
||||
<p>新建页面,或导入一个外部文件夹。原文件不会被改写。</p>
|
||||
<button onClick={() => setNewTitle("")}>新建知识页</button>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
{newTitle !== null && (
|
||||
<div className="modal-backdrop" onMouseDown={() => setNewTitle(null)}>
|
||||
<form
|
||||
className="modal"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
create();
|
||||
}}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h2>新建知识页</h2>
|
||||
<p>名称将成为本地 Markdown 文件名,并进入私人 Git。</p>
|
||||
<label>
|
||||
知识页名称
|
||||
<input
|
||||
value={newTitle}
|
||||
onChange={(e) => setNewTitle(e.target.value)}
|
||||
placeholder="例如:第一条知识"
|
||||
autoFocus
|
||||
/>
|
||||
</label>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="soft"
|
||||
onClick={() => setNewTitle(null)}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button type="submit" disabled={!newTitle.trim()}>
|
||||
创建
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Market() {
|
||||
return (
|
||||
<div className="page simple">
|
||||
<header>
|
||||
<div>
|
||||
<h1>模块商城</h1>
|
||||
<p>能力按使用主体分开登记</p>
|
||||
</div>
|
||||
</header>
|
||||
<section className="split-list">
|
||||
<div>
|
||||
<h2>人格体使用</h2>
|
||||
<p>动态脑、技能和执行零件将在签名审核后出现。</p>
|
||||
<span>当前没有已发布模块</span>
|
||||
</div>
|
||||
<div>
|
||||
<h2>人类使用</h2>
|
||||
<p>行业工作模块将在完成独立验收后出现。</p>
|
||||
<span>光湖知识库为预装模块</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function History({ data }: { data: SystemSnapshot }) {
|
||||
return (
|
||||
<div className="page simple">
|
||||
<header>
|
||||
<div>
|
||||
<h1>系统演化史</h1>
|
||||
<p>事实与计划分开记录</p>
|
||||
</div>
|
||||
</header>
|
||||
<section className="timeline-list">
|
||||
{data.timeline.map((e) => (
|
||||
<article key={e.eventId}>
|
||||
<time>{new Date(e.occurredAt).toLocaleString("zh-CN")}</time>
|
||||
<div>
|
||||
<strong>
|
||||
{labels[e.sourceKind]} · {e.title}
|
||||
</strong>
|
||||
<p>{e.content}</p>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function Portal() {
|
||||
return (
|
||||
<div className="page simple">
|
||||
<header>
|
||||
<div>
|
||||
<h1>企业门户</h1>
|
||||
<p>公共四域的官方入口位于企业服务器</p>
|
||||
</div>
|
||||
</header>
|
||||
<section className="portal">
|
||||
<div className="origin-light" />
|
||||
<h2>公共内容不嵌入私人频道</h2>
|
||||
<p>
|
||||
官方通知、四域规则和团队发布由企业门户承载。HoloLake
|
||||
只读取经过签名审核的公共发行事实。
|
||||
</p>
|
||||
<a href="https://guanghu.chat" target="_blank" rel="noreferrer">
|
||||
打开企业门户 ↗
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function Settings({
|
||||
data,
|
||||
refresh,
|
||||
busy,
|
||||
setBusy,
|
||||
setError,
|
||||
}: {
|
||||
data: SystemSnapshot;
|
||||
refresh: () => void;
|
||||
busy: boolean;
|
||||
setBusy: (v: boolean) => void;
|
||||
setError: (v: string) => void;
|
||||
}) {
|
||||
const [bridgeName, setBridgeName] = useState("");
|
||||
const update = async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
const u = await check();
|
||||
if (!u) throw new Error("当前已是最新版本,或公共发行尚未发布。");
|
||||
if (confirm(`发现 HoloLake ${u.version},现在安装?`)) {
|
||||
await u.downloadAndInstall();
|
||||
await relaunch();
|
||||
}
|
||||
} catch (e) {
|
||||
setError(String(e));
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="page simple">
|
||||
<header>
|
||||
<div>
|
||||
<h1>设置</h1>
|
||||
<p>本机节点、公共更新与外部 AI</p>
|
||||
</div>
|
||||
</header>
|
||||
<section className="settings-list">
|
||||
<article>
|
||||
<div>
|
||||
<h2>私人 Git</h2>
|
||||
<p>{data.channel?.privateGitPath}</p>
|
||||
</div>
|
||||
<span className="status ok">已建立</span>
|
||||
</article>
|
||||
<article>
|
||||
<div>
|
||||
<h2>公共更新</h2>
|
||||
<p>{data.publicUpdateEndpoint}</p>
|
||||
</div>
|
||||
<button className="soft" onClick={update} disabled={busy}>
|
||||
{busy ? "正在检查…" : "检查更新"}
|
||||
</button>
|
||||
</article>
|
||||
<article className="bridge">
|
||||
<div>
|
||||
<h2>外部编程 AI</h2>
|
||||
<p>以来源明确的本地表达桥接入;不能取得人格或执行主控权。</p>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
value={bridgeName}
|
||||
onChange={(e) => setBridgeName(e.target.value)}
|
||||
placeholder="给这个 AI 入口起名"
|
||||
/>
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (bridgeName.trim()) {
|
||||
await api.registerBridge(bridgeName.trim());
|
||||
setBridgeName("");
|
||||
refresh();
|
||||
}
|
||||
}}
|
||||
>
|
||||
建立入口
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
{data.externalAiBridges.map((b) => (
|
||||
<article key={b.bridgeId}>
|
||||
<div>
|
||||
<h2>{b.displayName}</h2>
|
||||
<p>
|
||||
{b.bridgeId} · {b.inboxPath}
|
||||
</p>
|
||||
</div>
|
||||
<span className="status">{b.state}</span>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
product-source/hololake-clean-desktop/src/icons.tsx
Normal file
12
product-source/hololake-clean-desktop/src/icons.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import type { SVGProps } from "react";
|
||||
export function Icon({name,...props}:{name:string}&SVGProps<SVGSVGElement>){
|
||||
const paths:Record<string,React.ReactNode>={
|
||||
channel:<><path d="M4 5.5h16v11H8l-4 3v-14Z"/><path d="M8 10h8M8 13h5"/></>,
|
||||
book:<><path d="M4 5.5A3.5 3.5 0 0 1 7.5 2H11v17H7.5A3.5 3.5 0 0 0 4 22V5.5ZM20 5.5A3.5 3.5 0 0 0 16.5 2H13v17h3.5A3.5 3.5 0 0 1 20 22V5.5Z"/></>,
|
||||
cube:<><path d="m12 2 8 4.5v10L12 21l-8-4.5v-10L12 2Z"/><path d="m4 6.5 8 4.5 8-4.5M12 11v10"/></>,
|
||||
history:<><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5M12 7v5l3 2"/></>,
|
||||
building:<><path d="M4 21V4h10v17M14 9h6v12M8 8h2M8 12h2M8 16h2M17 13h1M17 17h1M2 21h20"/></>,
|
||||
settings:<><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1a1.7 1.7 0 0 0 1.9.3A1.7 1.7 0 0 0 10 3V2.8h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z"/></>
|
||||
};
|
||||
return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}>{paths[name]}</svg>
|
||||
}
|
||||
6
product-source/hololake-clean-desktop/src/main.tsx
Normal file
6
product-source/hololake-clean-desktop/src/main.tsx
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import "./styles.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(<React.StrictMode><App/></React.StrictMode>);
|
||||
53
product-source/hololake-clean-desktop/src/runtime.ts
Normal file
53
product-source/hololake-clean-desktop/src/runtime.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type { Channel, ExternalAiBridge, KnowledgeDocument, MutationReceipt, SystemSnapshot, TimelineEvent } from "./types";
|
||||
|
||||
const tauri = () => "__TAURI_INTERNALS__" in window;
|
||||
const now = () => new Date().toISOString();
|
||||
const key = "hololake.clean.browser-state.v1";
|
||||
|
||||
type BrowserState = { channel: Channel | null; timeline: TimelineEvent[]; documents: KnowledgeDocument[]; bridges: ExternalAiBridge[] };
|
||||
const empty: BrowserState = { channel: null, timeline: [], documents: [], bridges: [] };
|
||||
const load = (): BrowserState => JSON.parse(localStorage.getItem(key) ?? JSON.stringify(empty));
|
||||
const save = (state: BrowserState) => localStorage.setItem(key, JSON.stringify(state));
|
||||
const event = (sourceKind: TimelineEvent["sourceKind"], title: string, content: string, state: TimelineEvent["state"] = "SUCCEEDED"): TimelineEvent => ({ eventId: crypto.randomUUID(), sourceKind, title, content, occurredAt: now(), state });
|
||||
|
||||
export async function snapshot(): Promise<SystemSnapshot> {
|
||||
if (tauri()) return invoke("system_snapshot");
|
||||
const s = load();
|
||||
return { appVersion: "1.0.0-browser", channel: s.channel, timeline: s.timeline, documents: s.documents.map(({ path, title, updatedAt, sha256 }) => ({ path, title, updatedAt, sha256 })), moduleRegistryVersion: "1", publicUpdateEndpoint: "https://guanghulab.com/hololake/releases/latest.json", publicDistributionState: "SIGNED_UPDATE_FEED_READY_NO_RELEASE", externalAiBridges: s.bridges };
|
||||
}
|
||||
|
||||
export async function createChannel(name: string): Promise<Channel> {
|
||||
if (tauri()) return invoke("create_channel", { name });
|
||||
const s = load(); const channel: Channel = { channelId: `HL-CH-${crypto.randomUUID().slice(0,8).toUpperCase()}`, name, createdAt: now(), privateGitPath: "浏览器预览不写入磁盘", publicDistributionState: "SIGNED_UPDATE_FEED_READY_NO_RELEASE" };
|
||||
s.channel = channel; s.timeline.unshift(event("SYSTEM_RECEIPT", "频道已建立", `${channel.channelId} 已登记。`)); save(s); return channel;
|
||||
}
|
||||
|
||||
export async function submitMessage(content: string): Promise<MutationReceipt> {
|
||||
if (tauri()) return invoke("submit_user_message", { content });
|
||||
const s = load(); const e = event("USER_MESSAGE", "用户语言", content, "RECORDED"); s.timeline.unshift(e, event("SYSTEM_RECEIPT", "系统回执", "用户语言已分流保存;等待人格体接入,不伪造人格回应。", "WAITING")); save(s);
|
||||
return { receiptId: crypto.randomUUID(), state: "WAITING_PERSONA", message: "用户语言已记录", gitCommit: null, event: e };
|
||||
}
|
||||
|
||||
export async function readDocument(path: string): Promise<KnowledgeDocument> {
|
||||
if (tauri()) return invoke("read_knowledge_document", { path });
|
||||
const doc = load().documents.find(d => d.path === path); if (!doc) throw new Error("文档不存在"); return doc;
|
||||
}
|
||||
export async function createDocument(title: string): Promise<MutationReceipt> {
|
||||
if (tauri()) return invoke("create_knowledge_document", { title });
|
||||
const s = load(); const path = `${title.trim().replace(/[\\/:*?\"<>|]/g,"-")}.md`; const d = { path, title: title.trim(), body: `# ${title.trim()}\n\n`, updatedAt: now(), sha256: "browser-preview" }; s.documents.unshift(d); const e=event("AGENT_ACTION","Agent 执行",`已创建 ${path}`); s.timeline.unshift(e); save(s); return {receiptId:crypto.randomUUID(),state:"SUCCEEDED",message:"文档已创建",gitCommit:"browser-preview",event:e};
|
||||
}
|
||||
export async function saveDocument(path: string, body: string): Promise<MutationReceipt> {
|
||||
if (tauri()) return invoke("save_knowledge_document", { path, body });
|
||||
const s=load(); const d=s.documents.find(x=>x.path===path); if(!d) throw new Error("文档不存在"); d.body=body; d.updatedAt=now(); const e=event("SYSTEM_RECEIPT","系统回执",`${path} 已保存到私人 Git 预览层。`); s.timeline.unshift(e); save(s); return {receiptId:crypto.randomUUID(),state:"SUCCEEDED",message:"保存完成",gitCommit:"browser-preview",event:e};
|
||||
}
|
||||
export async function deleteDocument(path: string): Promise<MutationReceipt> {
|
||||
if (tauri()) return invoke("delete_knowledge_document", { path });
|
||||
const s=load(); s.documents=s.documents.filter(x=>x.path!==path); const e=event("SYSTEM_RECEIPT","系统回执",`${path} 已移入回收站。`); s.timeline.unshift(e); save(s); return {receiptId:crypto.randomUUID(),state:"SUCCEEDED",message:"已移入回收站",gitCommit:"browser-preview",event:e};
|
||||
}
|
||||
export async function importFolder(): Promise<MutationReceipt | null> { if (!tauri()) throw new Error("文件夹导入请在已安装的 HoloLake 中使用"); return invoke("import_knowledge_folder"); }
|
||||
export async function exportDocument(path: string): Promise<string | null> { if (!tauri()) throw new Error("下载请在已安装的 HoloLake 中使用"); return invoke("export_knowledge_document", { path }); }
|
||||
export async function registerBridge(displayName: string): Promise<ExternalAiBridge> {
|
||||
if (tauri()) return invoke("register_external_ai_bridge", { displayName });
|
||||
const s=load(); const b={bridgeId:`HL-AI-${crypto.randomUUID().slice(0,8).toUpperCase()}`,displayName,inboxPath:"浏览器预览",outboxPath:"浏览器预览",state:"LOCAL_EXPRESSION_ONLY"}; s.bridges.push(b); save(s); return b;
|
||||
}
|
||||
855
product-source/hololake-clean-desktop/src/styles.css
Normal file
855
product-source/hololake-clean-desktop/src/styles.css
Normal file
|
|
@ -0,0 +1,855 @@
|
|||
:root {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, "SF Pro Display", "PingFang SC",
|
||||
"Microsoft YaHei", sans-serif;
|
||||
color: #eaf2ff;
|
||||
background: #050a13;
|
||||
font-synthesis: none;
|
||||
--bg: #050a13;
|
||||
--panel: rgba(9, 23, 41, 0.78);
|
||||
--panel2: rgba(12, 30, 52, 0.68);
|
||||
--line: rgba(151, 191, 230, 0.18);
|
||||
--muted: #92a8be;
|
||||
--text: #eaf2ff;
|
||||
--gold: #f0c56b;
|
||||
--blue: #69b9f3;
|
||||
--green: #76d99c;
|
||||
--danger: #ff8f93;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 760px;
|
||||
min-height: 100vh;
|
||||
overflow: hidden;
|
||||
background:
|
||||
radial-gradient(ellipse at 55% 35%, #0b3151 0, transparent 33%),
|
||||
linear-gradient(180deg, #06101f 0%, #071628 54%, #030911 100%);
|
||||
}
|
||||
button,
|
||||
input,
|
||||
textarea {
|
||||
font: inherit;
|
||||
}
|
||||
button {
|
||||
color: inherit;
|
||||
}
|
||||
.app-shell {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
grid-template: 48px 1fr/244px 1fr;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(2, 9, 19, 0.22),
|
||||
rgba(2, 8, 15, 0.7)
|
||||
);
|
||||
position: relative;
|
||||
}
|
||||
.app-shell:after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 48px 0 0 244px;
|
||||
pointer-events: none;
|
||||
opacity: 0.26;
|
||||
background-image:
|
||||
radial-gradient(circle at 12% 14%, #fff 0 1px, transparent 1.5px),
|
||||
radial-gradient(circle at 74% 8%, #badaff 0 1px, transparent 1.5px),
|
||||
radial-gradient(circle at 52% 26%, #fff 0 1px, transparent 1.5px);
|
||||
background-size:
|
||||
260px 230px,
|
||||
340px 290px,
|
||||
440px 360px;
|
||||
}
|
||||
.titlebar {
|
||||
grid-column: 1/-1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--line);
|
||||
background: rgba(3, 11, 22, 0.82);
|
||||
backdrop-filter: blur(24px);
|
||||
z-index: 5;
|
||||
}
|
||||
.traffic {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding-left: 18px;
|
||||
}
|
||||
.traffic i {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: #ff6259;
|
||||
}
|
||||
.traffic i:nth-child(2) {
|
||||
background: #ffbd2e;
|
||||
}
|
||||
.traffic i:nth-child(3) {
|
||||
background: #28c941;
|
||||
}
|
||||
.titlebar > span {
|
||||
font-size: 14px;
|
||||
font-weight: 560;
|
||||
}
|
||||
.titlebar .version {
|
||||
justify-self: end;
|
||||
margin-right: 18px;
|
||||
color: #738aa0;
|
||||
font-size: 11px;
|
||||
}
|
||||
.rail {
|
||||
grid-row: 2;
|
||||
padding: 26px 14px 18px;
|
||||
border-right: 1px solid var(--line);
|
||||
background: rgba(3, 11, 22, 0.68);
|
||||
backdrop-filter: blur(22px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 3;
|
||||
}
|
||||
.brand-orbit {
|
||||
height: 96px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.brand-orbit span,
|
||||
.lake-mark {
|
||||
display: block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
border: 1px solid rgba(240, 197, 107, 0.7);
|
||||
border-radius: 50%;
|
||||
box-shadow:
|
||||
0 0 22px rgba(240, 197, 107, 0.17),
|
||||
inset 0 0 18px rgba(240, 197, 107, 0.09);
|
||||
position: relative;
|
||||
}
|
||||
.brand-orbit span:before,
|
||||
.lake-mark:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
top: 26px;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--gold), transparent);
|
||||
box-shadow: 0 5px 7px rgba(240, 197, 107, 0.55);
|
||||
}
|
||||
.brand-orbit span:after,
|
||||
.lake-mark:after {
|
||||
content: "✦";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #f8d98c;
|
||||
text-shadow: 0 0 13px var(--gold);
|
||||
}
|
||||
nav {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
nav button {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 13px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 12px;
|
||||
color: #b8c7d7;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
nav button svg {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
nav button:hover {
|
||||
background: rgba(255, 255, 255, 0.045);
|
||||
color: #fff;
|
||||
}
|
||||
nav button.active {
|
||||
color: #f7dc9a;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(153, 103, 26, 0.38),
|
||||
rgba(255, 255, 255, 0.025)
|
||||
);
|
||||
box-shadow: inset 2px 0 var(--gold);
|
||||
}
|
||||
.channel-mini {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 11px;
|
||||
}
|
||||
.mini-lake {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(
|
||||
circle at 50% 58%,
|
||||
#e5c477 0 2%,
|
||||
#236b8f 5%,
|
||||
#08182c 42%,
|
||||
#020811 70%
|
||||
);
|
||||
box-shadow: 0 0 14px rgba(105, 185, 243, 0.3);
|
||||
}
|
||||
.channel-mini strong,
|
||||
.channel-mini small {
|
||||
display: block;
|
||||
}
|
||||
.channel-mini strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
.channel-mini small {
|
||||
font-size: 9px;
|
||||
color: #70879d;
|
||||
margin-top: 3px;
|
||||
}
|
||||
main {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
overflow: auto;
|
||||
z-index: 1;
|
||||
}
|
||||
.page {
|
||||
width: min(1240px, 100%);
|
||||
min-height: calc(100vh - 48px);
|
||||
margin: auto;
|
||||
padding: 38px 40px 30px;
|
||||
}
|
||||
.page > header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.page h1 {
|
||||
font-size: 30px;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 8px;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.page header p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
.page button,
|
||||
.portal a {
|
||||
border: 1px solid rgba(240, 197, 107, 0.55);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(194, 142, 51, 0.35),
|
||||
rgba(114, 72, 19, 0.45)
|
||||
);
|
||||
border-radius: 10px;
|
||||
padding: 10px 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 580;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.page button:hover,
|
||||
.portal a:hover {
|
||||
filter: brightness(1.18);
|
||||
}
|
||||
.page button.soft {
|
||||
border-color: var(--line);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.conversation {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(7, 27, 48, 0.68),
|
||||
rgba(6, 18, 34, 0.74)
|
||||
);
|
||||
overflow: hidden;
|
||||
min-height: 230px;
|
||||
}
|
||||
.channel-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 250px;
|
||||
gap: 18px;
|
||||
align-items: start;
|
||||
}
|
||||
.channel-primary {
|
||||
min-width: 0;
|
||||
}
|
||||
.channel-context {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
.channel-context article {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
background: rgba(6, 20, 36, 0.74);
|
||||
padding: 19px;
|
||||
}
|
||||
.channel-context h2 {
|
||||
color: #b8cadb;
|
||||
font-size: 13px;
|
||||
margin: 0 0 17px;
|
||||
}
|
||||
.channel-context strong {
|
||||
font-size: 14px;
|
||||
font-weight: 620;
|
||||
}
|
||||
.channel-context p {
|
||||
color: #7f97ad;
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
margin: 7px 0 0;
|
||||
}
|
||||
.channel-context .path {
|
||||
word-break: break-all;
|
||||
}
|
||||
.welcome {
|
||||
text-align: center;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
align-content: center;
|
||||
min-height: 210px;
|
||||
padding: 25px;
|
||||
color: var(--muted);
|
||||
}
|
||||
.welcome h2 {
|
||||
font-size: 18px;
|
||||
color: var(--text);
|
||||
margin: 14px 0 6px;
|
||||
}
|
||||
.welcome p {
|
||||
max-width: 500px;
|
||||
line-height: 1.7;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.welcome svg {
|
||||
width: 34px;
|
||||
color: var(--blue);
|
||||
}
|
||||
.conversation article {
|
||||
display: grid;
|
||||
grid-template-columns: 100px 1fr;
|
||||
padding: 20px 24px;
|
||||
border-top: 1px solid rgba(151, 191, 230, 0.11);
|
||||
}
|
||||
.conversation article span {
|
||||
font-size: 12px;
|
||||
color: var(--blue);
|
||||
font-weight: 650;
|
||||
}
|
||||
.conversation article.persona span {
|
||||
color: #c5a6ff;
|
||||
}
|
||||
.conversation article p {
|
||||
margin: 0;
|
||||
line-height: 1.7;
|
||||
font-size: 15px;
|
||||
}
|
||||
.receipt-stream {
|
||||
margin-top: 18px;
|
||||
padding: 18px 20px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
background: rgba(4, 16, 30, 0.74);
|
||||
}
|
||||
.receipt-stream h2 {
|
||||
font-size: 13px;
|
||||
font-weight: 570;
|
||||
color: #b8cadb;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
.receipt {
|
||||
display: grid;
|
||||
grid-template-columns: 90px 120px 1fr auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
margin-top: 7px;
|
||||
border-radius: 10px;
|
||||
background: rgba(12, 34, 56, 0.7);
|
||||
font-size: 12px;
|
||||
}
|
||||
.receipt .kind {
|
||||
color: #63d6cc;
|
||||
font-weight: 650;
|
||||
}
|
||||
.receipt strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
.receipt p {
|
||||
margin: 0;
|
||||
color: #aabbd0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.receipt time {
|
||||
color: #6f879e;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.receipt.agent_action .kind {
|
||||
color: var(--gold);
|
||||
}
|
||||
.receipt.system_receipt .kind {
|
||||
color: var(--green);
|
||||
}
|
||||
.empty {
|
||||
color: #7890a8;
|
||||
font-size: 13px;
|
||||
}
|
||||
.composer {
|
||||
margin-top: 18px;
|
||||
border: 1px solid rgba(179, 210, 239, 0.3);
|
||||
border-radius: 18px;
|
||||
background: rgba(10, 26, 46, 0.78);
|
||||
padding: 14px 16px 10px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: end;
|
||||
}
|
||||
.composer textarea {
|
||||
resize: none;
|
||||
height: 62px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
color: #eaf2ff;
|
||||
font-size: 15px;
|
||||
padding: 7px;
|
||||
}
|
||||
.composer textarea::placeholder {
|
||||
color: #6f8298;
|
||||
}
|
||||
.composer button {
|
||||
border-radius: 50%;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
padding: 0;
|
||||
font-size: 22px;
|
||||
}
|
||||
.composer small {
|
||||
grid-column: 1/-1;
|
||||
color: #5f7489;
|
||||
font-size: 10px;
|
||||
padding: 5px 7px 0;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
}
|
||||
.knowledge-workspace {
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
min-height: 650px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
overflow: hidden;
|
||||
background: rgba(5, 17, 31, 0.76);
|
||||
}
|
||||
.knowledge-workspace > aside {
|
||||
border-right: 1px solid var(--line);
|
||||
padding: 13px;
|
||||
background: rgba(3, 12, 24, 0.55);
|
||||
}
|
||||
.knowledge-workspace > aside > input,
|
||||
.settings-list input {
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.045);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 9px;
|
||||
color: #fff;
|
||||
padding: 10px 12px;
|
||||
outline: none;
|
||||
}
|
||||
.knowledge-workspace > aside > button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
text-align: left;
|
||||
margin-top: 7px;
|
||||
padding: 11px 12px;
|
||||
}
|
||||
.knowledge-workspace > aside > button.selected {
|
||||
background: rgba(73, 141, 194, 0.15);
|
||||
box-shadow: inset 2px 0 #74bee9;
|
||||
}
|
||||
.knowledge-workspace > aside strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
.knowledge-workspace > aside small {
|
||||
color: #6e879e;
|
||||
margin-top: 5px;
|
||||
font-size: 10px;
|
||||
}
|
||||
.knowledge-workspace > section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
.editor-tools {
|
||||
height: 55px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 16px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.editor-tools > span {
|
||||
flex: 1;
|
||||
}
|
||||
.editor-tools button {
|
||||
padding: 7px 11px;
|
||||
border-color: var(--line);
|
||||
background: transparent;
|
||||
}
|
||||
.editor-tools button.danger {
|
||||
color: var(--danger);
|
||||
}
|
||||
.editor {
|
||||
flex: 1;
|
||||
resize: none;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding: 32px 38px;
|
||||
background: rgba(1, 8, 17, 0.24);
|
||||
color: #dce8f5;
|
||||
line-height: 1.8;
|
||||
font-family: "SFMono-Regular", Menlo, monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
.split-list {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
.split-list > div,
|
||||
.settings-list article,
|
||||
.portal {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
background: rgba(8, 24, 42, 0.72);
|
||||
padding: 25px;
|
||||
}
|
||||
.split-list h2,
|
||||
.settings-list h2 {
|
||||
font-size: 17px;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
.split-list p,
|
||||
.settings-list p,
|
||||
.portal p {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.split-list span {
|
||||
display: block;
|
||||
color: #6f879e;
|
||||
margin-top: 30px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.timeline-list {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.timeline-list article {
|
||||
display: grid;
|
||||
grid-template-columns: 170px 1fr;
|
||||
gap: 25px;
|
||||
padding: 20px 4px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.timeline-list time {
|
||||
color: #71869b;
|
||||
font-size: 12px;
|
||||
}
|
||||
.timeline-list strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
.timeline-list p {
|
||||
color: #9eb0c2;
|
||||
margin: 7px 0 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.portal {
|
||||
text-align: center;
|
||||
min-height: 360px;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
.portal h2 {
|
||||
font-size: 22px;
|
||||
margin: 18px 0 2px;
|
||||
}
|
||||
.portal p {
|
||||
max-width: 570px;
|
||||
}
|
||||
.portal .origin-light {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
}
|
||||
.origin-light {
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
#fff7c9 0 2%,
|
||||
#f2c76c 3%,
|
||||
rgba(105, 185, 243, 0.55) 10%,
|
||||
rgba(24, 71, 105, 0.24) 38%,
|
||||
transparent 70%
|
||||
);
|
||||
box-shadow: 0 0 70px rgba(105, 185, 243, 0.16);
|
||||
}
|
||||
.settings-list {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
.settings-list article {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 19px 22px;
|
||||
}
|
||||
.settings-list h2 {
|
||||
font-size: 14px;
|
||||
}
|
||||
.settings-list p {
|
||||
margin: 0;
|
||||
word-break: break-all;
|
||||
}
|
||||
.status {
|
||||
font-size: 11px;
|
||||
color: #8ebde0;
|
||||
}
|
||||
.status.ok {
|
||||
color: var(--green);
|
||||
}
|
||||
.settings-list .bridge {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.bridge > div:last-child {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
min-width: 370px;
|
||||
}
|
||||
.onboard {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background:
|
||||
radial-gradient(
|
||||
ellipse at 50% 70%,
|
||||
rgba(22, 92, 126, 0.45),
|
||||
transparent 37%
|
||||
),
|
||||
linear-gradient(#06101f, #03070e);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.onboard section {
|
||||
z-index: 2;
|
||||
width: min(520px, 80vw);
|
||||
text-align: center;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
}
|
||||
.onboard .origin-light {
|
||||
width: 118px;
|
||||
height: 118px;
|
||||
}
|
||||
.onboard h1 {
|
||||
font-size: 32px;
|
||||
margin: 20px 0 9px;
|
||||
}
|
||||
.onboard p {
|
||||
color: #9db0c4;
|
||||
line-height: 1.8;
|
||||
margin: 0 0 26px;
|
||||
}
|
||||
.onboard label {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #a9bed1;
|
||||
}
|
||||
.onboard input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 8px 0 14px;
|
||||
padding: 15px 16px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(164, 201, 235, 0.27);
|
||||
background: rgba(6, 19, 35, 0.85);
|
||||
color: #fff;
|
||||
outline: 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
.onboard button {
|
||||
border: 1px solid rgba(240, 197, 107, 0.65);
|
||||
border-radius: 11px;
|
||||
background: linear-gradient(#bd8e3c, #7f561d);
|
||||
color: #fff;
|
||||
padding: 12px 22px;
|
||||
font-weight: 650;
|
||||
}
|
||||
.onboard footer {
|
||||
position: absolute;
|
||||
bottom: 24px;
|
||||
color: #5e7488;
|
||||
font-size: 11px;
|
||||
}
|
||||
.stars {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.45;
|
||||
background-image:
|
||||
radial-gradient(circle at 15% 20%, #fff 0 1px, transparent 1.5px),
|
||||
radial-gradient(circle at 70% 12%, #fff 0 1px, transparent 1.5px),
|
||||
radial-gradient(circle at 42% 39%, #9fd7ff 0 1px, transparent 1.5px);
|
||||
background-size:
|
||||
270px 230px,
|
||||
390px 310px,
|
||||
520px 440px;
|
||||
}
|
||||
.boot {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
color: #b9cadb;
|
||||
}
|
||||
.toast {
|
||||
position: fixed;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
background: #18263a;
|
||||
border: 1px solid rgba(255, 143, 147, 0.45);
|
||||
border-radius: 12px;
|
||||
padding: 13px 15px;
|
||||
z-index: 10;
|
||||
max-width: 520px;
|
||||
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
}
|
||||
.toast button {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #ffb1b4;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.modal-backdrop {
|
||||
position: fixed;
|
||||
inset: 48px 0 0;
|
||||
background: rgba(1, 5, 11, 0.7);
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.modal {
|
||||
width: min(430px, 80vw);
|
||||
border: 1px solid rgba(164, 201, 235, 0.25);
|
||||
border-radius: 18px;
|
||||
background: #09182a;
|
||||
padding: 25px;
|
||||
box-shadow: 0 28px 80px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
.modal h2 {
|
||||
font-size: 20px;
|
||||
margin: 0 0 7px;
|
||||
}
|
||||
.modal p {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
.modal label {
|
||||
display: block;
|
||||
color: #aabed2;
|
||||
font-size: 12px;
|
||||
}
|
||||
.modal input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 8px 0 22px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
padding: 12px 13px;
|
||||
outline: none;
|
||||
}
|
||||
.modal > div {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.app-shell {
|
||||
grid-template-columns: 72px 1fr;
|
||||
}
|
||||
.rail {
|
||||
padding-inline: 8px;
|
||||
}
|
||||
.brand-orbit {
|
||||
height: 62px;
|
||||
}
|
||||
.brand-orbit span {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
.rail nav button {
|
||||
justify-content: center;
|
||||
padding: 12px;
|
||||
}
|
||||
.rail nav span,
|
||||
.channel-mini > div:last-child {
|
||||
display: none;
|
||||
}
|
||||
.channel-mini {
|
||||
justify-content: center;
|
||||
}
|
||||
.app-shell:after {
|
||||
inset-left: 72px;
|
||||
}
|
||||
.page {
|
||||
padding: 26px 22px;
|
||||
}
|
||||
.receipt {
|
||||
grid-template-columns: 88px 1fr;
|
||||
}
|
||||
.receipt p {
|
||||
display: none;
|
||||
}
|
||||
.knowledge-workspace {
|
||||
grid-template-columns: 210px 1fr;
|
||||
}
|
||||
.split-list {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.channel-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.channel-context {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
9
product-source/hololake-clean-desktop/src/types.ts
Normal file
9
product-source/hololake-clean-desktop/src/types.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export type SourceKind = "USER_MESSAGE" | "PERSONA_RESPONSE" | "SYSTEM_CONTEXT" | "PROTOCOL_EVENT" | "AGENT_ACTION" | "TOOL_RESULT" | "SYSTEM_RECEIPT";
|
||||
|
||||
export interface Channel { channelId: string; name: string; createdAt: string; privateGitPath: string; publicDistributionState: string; }
|
||||
export interface TimelineEvent { eventId: string; sourceKind: SourceKind; title: string; content: string; occurredAt: string; state: "RECORDED" | "WAITING" | "RUNNING" | "SUCCEEDED" | "FAILED"; }
|
||||
export interface KnowledgeDocument { path: string; title: string; body: string; updatedAt: string; sha256: string; }
|
||||
export interface KnowledgeSummary { path: string; title: string; updatedAt: string; sha256: string; }
|
||||
export interface SystemSnapshot { appVersion: string; channel: Channel | null; timeline: TimelineEvent[]; documents: KnowledgeSummary[]; moduleRegistryVersion: string; publicUpdateEndpoint: string; publicDistributionState: string; externalAiBridges: ExternalAiBridge[]; }
|
||||
export interface ExternalAiBridge { bridgeId: string; displayName: string; inboxPath: string; outboxPath: string; state: string; }
|
||||
export interface MutationReceipt { receiptId: string; state: string; message: string; gitCommit: string | null; event: TimelineEvent; }
|
||||
1
product-source/hololake-clean-desktop/src/vite-env.d.ts
vendored
Normal file
1
product-source/hololake-clean-desktop/src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
9
product-source/hololake-clean-desktop/tsconfig.app.json
Normal file
9
product-source/hololake-clean-desktop/tsconfig.app.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022", "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"allowJs": false, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true,
|
||||
"strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", "moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"root":["./src/app.tsx","./src/icons.tsx","./src/main.tsx","./src/runtime.ts","./src/types.ts","./src/vite-env.d.ts"],"version":"5.9.3"}
|
||||
4
product-source/hololake-clean-desktop/tsconfig.json
Normal file
4
product-source/hololake-clean-desktop/tsconfig.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
4
product-source/hololake-clean-desktop/tsconfig.node.json
Normal file
4
product-source/hololake-clean-desktop/tsconfig.node.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "Bundler" },
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
2
product-source/hololake-clean-desktop/vite.config.d.ts
vendored
Normal file
2
product-source/hololake-clean-desktop/vite.config.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("vite").UserConfig;
|
||||
export default _default;
|
||||
3
product-source/hololake-clean-desktop/vite.config.js
Normal file
3
product-source/hololake-clean-desktop/vite.config.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
export default defineConfig({ plugins: [react()], server: { port: 5211, strictPort: true }, clearScreen: false });
|
||||
4
product-source/hololake-clean-desktop/vite.config.ts
Normal file
4
product-source/hololake-clean-desktop/vite.config.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
export default defineConfig({ plugins: [react()], server: { port: 5211, strictPort: true }, clearScreen: false });
|
||||
|
|
@ -1,8 +1,26 @@
|
|||
{
|
||||
"schema": "hololake.current-architecture/v1",
|
||||
"architecture_id": "HLP-CURRENT-ARCH-001",
|
||||
"version": "2026-08-30.3",
|
||||
"version": "2026-09-03.1-clean-v1",
|
||||
"state": "CURRENT_CANONICAL",
|
||||
"clean_v1_rebuild": {
|
||||
"record_id": "HLP-CLEAN-V1-REBUILD-20260903-001",
|
||||
"state": "LOCAL_CLEAN_V1_INSTALLED_ACCEPTED_PUBLIC_RELEASE_PENDING",
|
||||
"source": "product-source/hololake-clean-desktop",
|
||||
"canonical_tcs": "product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs",
|
||||
"old_product_role": "READ_ONLY_DONOR_NO_WHOLE_MERGE",
|
||||
"first_preinstalled_module": "HLP-MOD-KB-0001",
|
||||
"typed_language_sources": ["USER_MESSAGE", "PERSONA_RESPONSE", "SYSTEM_CONTEXT", "PROTOCOL_EVENT", "AGENT_ACTION", "TOOL_RESULT", "SYSTEM_RECEIPT"],
|
||||
"public_update_endpoint": "https://guanghulab.com/hololake/releases/latest.json",
|
||||
"public_update_release_state": "SERVER_HTTP_204_NO_PUBLIC_RELEASE",
|
||||
"enterprise_repository_registry_state": "BLUE_ISOLATED_FIVE_CENTRAL_REPOSITORIES_AND_FIVE_HUMAN_WORK_REPOSITORIES_TEAM_PERMISSIONS_NOT_ASSIGNED_NO_PUBLIC_CUTOVER",
|
||||
"bingshuo_enterprise_language_master_work_repository": "NOT_REGISTERED_EXACT_NAME_AND_NUMBER_REQUIRED_NO_INVENTION",
|
||||
"private_git": "LOCAL_USER_OWNED",
|
||||
"public_git": "SIGNED_ENTERPRISE_DISTRIBUTION_PENDING_EXACT_REGISTRY",
|
||||
"realtime_transport": "NOT_IMPLEMENTED_GIT_IS_NOT_REALTIME",
|
||||
"enterprise_four_domains_embedded": false,
|
||||
"fifth_domain_private_content_embedded": false
|
||||
},
|
||||
"product": {
|
||||
"formal_name": "光湖语言系统 · 通用人工智能操作平台",
|
||||
"short_name": "GH-AIOS",
|
||||
|
|
@ -52,6 +70,8 @@
|
|||
"forgejo_role": "OPTIONAL_REMOTE_COLLABORATION_ADAPTER_NOT_PRODUCT_SHELL"
|
||||
},
|
||||
"read_order": [
|
||||
"product-source/hololake-clean-desktop/docs/ARCHITECTURE.md",
|
||||
"product-source/hololake-clean-desktop/language/HOLOLAKE-CLEAN-V1-FOUNDATION.tcs",
|
||||
"product-source/hololake-platform/architecture/HOLOLAKE-PUBLIC-OS-STAGE1-BLANK-CANVAS-EXECUTION-BRIDGE-AND-DUAL-GIT-20260830.md",
|
||||
"product-source/hololake-platform/architecture/HOLOLAKE-MODEL-RECEIPT-DONOR-AUDIT-AND-STAGE-BOUNDARY-20260830.md",
|
||||
"product-source/hololake-platform/architecture/HOLOLAKE-FIFTH-DOMAIN-NUMBERED-LANGUAGE-AND-REALITY-CHANNELS-20260821.md",
|
||||
|
|
|
|||
Loading…
Reference in a new issue