diff --git a/apps/mobile-shell/src/host-bridge/haptics.test.ts b/apps/mobile-shell/src/host-bridge/haptics.test.ts new file mode 100644 index 000000000..d40ab534b --- /dev/null +++ b/apps/mobile-shell/src/host-bridge/haptics.test.ts @@ -0,0 +1,102 @@ +import * as Haptics from 'expo-haptics'; +import { beforeEach, describe, expect, test, vi } from 'vitest'; + +import { + HOST_BRIDGE_PROTOCOL, + HOST_BRIDGE_VERSION, + type HostBridgeRequest, +} from '../../../../packages/shared/src/contracts/hostBridge'; +import { + runMobileHapticsImpact, + runMobileHostBridgeHapticsImpact, +} from './haptics'; + +vi.mock('expo-haptics', () => ({ + ImpactFeedbackStyle: { + Heavy: 'heavy', + Light: 'light', + Medium: 'medium', + }, + impactAsync: vi.fn(), +})); + +function request(payload?: unknown): HostBridgeRequest { + return { + bridge: HOST_BRIDGE_PROTOCOL, + version: HOST_BRIDGE_VERSION, + id: 'haptics-request', + method: 'haptics.impact', + payload, + }; +} + +beforeEach(() => { + vi.mocked(Haptics.impactAsync).mockReset(); +}); + +describe('mobile haptics helpers', () => { + test('maps allowed impact styles to Expo Haptics styles', async () => { + await expect(runMobileHapticsImpact('light')).resolves.toBe(true); + expect(Haptics.impactAsync).toHaveBeenLastCalledWith( + Haptics.ImpactFeedbackStyle.Light, + ); + + await expect(runMobileHapticsImpact('medium')).resolves.toBe(true); + expect(Haptics.impactAsync).toHaveBeenLastCalledWith( + Haptics.ImpactFeedbackStyle.Medium, + ); + + await expect(runMobileHapticsImpact('heavy')).resolves.toBe(true); + expect(Haptics.impactAsync).toHaveBeenLastCalledWith( + Haptics.ImpactFeedbackStyle.Heavy, + ); + }); + + test('defaults missing style to light impact', async () => { + await expect(runMobileHapticsImpact(undefined)).resolves.toBe(true); + + expect(Haptics.impactAsync).toHaveBeenCalledWith( + Haptics.ImpactFeedbackStyle.Light, + ); + }); + + test('rejects unknown styles without triggering device feedback', async () => { + await expect(runMobileHapticsImpact('rigid')).resolves.toBe(false); + + expect(Haptics.impactAsync).not.toHaveBeenCalled(); + }); + + test('wraps HostBridge success response after real impact dispatch', async () => { + const response = await runMobileHostBridgeHapticsImpact( + request({ + style: 'medium', + }), + ); + + expect(response).toEqual({ + bridge: HOST_BRIDGE_PROTOCOL, + version: HOST_BRIDGE_VERSION, + id: 'haptics-request', + ok: true, + result: true, + }); + expect(Haptics.impactAsync).toHaveBeenCalledWith( + Haptics.ImpactFeedbackStyle.Medium, + ); + }); + + test('wraps HostBridge invalid request before device feedback', async () => { + await expect( + runMobileHostBridgeHapticsImpact( + request({ + style: 'rigid', + }), + ), + ).rejects.toMatchObject({ + code: 'invalid_request', + message: 'haptics impact style must be light, medium, or heavy', + }); + + expect(Haptics.impactAsync).not.toHaveBeenCalled(); + }); +}); diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index c6b877a83..d07aef8a2 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -61,6 +61,7 @@ - 2026-06-20 桌面壳未声明 method 禁伪成功:Tauri 桌面壳只声明真实可用 capability;共享 HostBridge method 白名单中未进入桌面 capability profile 的 method,例如 `auth.requestLogin`、`payment.request`、`file.captureImage`、`scanner.scanQrCode` 和 `haptics.impact`,请求实际到达桌面壳时必须统一返回明确 `unsupported_method`,不得伪造成功或半接入。桌面 Rust 测试必须从 `HOST_BRIDGE_METHODS` 与 `capabilities()` 差集派生 unsupported 覆盖清单,桌面单端配置检查会反查该派生路径,后续共享契约新增 method 时必须同步声明真实桌面能力或补进 unsupported 语义。 - 2026-06-18 移动壳触觉反馈边界:`haptics.impact` 只接受 `light`、`medium`、`heavy` 三档 impact style,缺省为 `light`;未知值必须返回 `invalid_request`,不得静默降级成真实设备触觉反馈。桌面壳不声明该 capability,H5 继续按 HostBridge fallback 处理。 - 2026-06-19 移动壳触觉反馈模块边界:Expo `haptics.impact` 的 HostBridge payload 解析、共享 style 归一、`light` / `medium` / `heavy` 到 `Haptics.ImpactFeedbackStyle` 的映射、真实 `Haptics.impactAsync(...)` 调用和成功响应包装统一收口在 `apps/mobile-shell/src/host-bridge/haptics.ts`;`dispatch.ts` 只负责把完整 request 委托给 `runMobileHostBridgeHapticsImpact(...)`,不得直接导入 `expo-haptics`、读取 `HapticsImpactPayload`、调用 `Haptics.impactAsync` 或包装触觉反馈成功响应。移动壳配置检查会覆盖该模块结构、共享 style 边界和 dispatch 委托关系,避免触觉反馈能力散落到分发层。 +- 2026-06-20 移动触觉反馈单测边界:`apps/mobile-shell/src/host-bridge/haptics.test.ts` 直接覆盖 `haptics.impact` 的 `light` / `medium` / `heavy` 到 Expo Haptics style 映射、缺省 `light`、未知 style 不触发设备反馈、HostBridge 成功响应和 `invalid_request` 失败包装;根级 `npm run check:native-shells` 会把该测试文件列入移动桥接层结构清单,避免触觉反馈边界只靠完整 HostBridge bridge 流程间接覆盖。 - 2026-06-18 分享卡图片导出:新增 `file.exportImage` HostBridge capability,H5 分享卡下载在 native app 中优先把 canvas 生成的 base64 图片交给宿主导出;Expo 壳写缓存图片后交给系统分享 / 保存面板,Tauri 壳通过系统保存对话框写入图片字节。该能力只接受 `image/png` / `image/jpeg` / `image/webp`、单次 5 MiB 内图片数据,成功只返回文件名和字节数,不暴露本机绝对路径;宿主未声明时保留浏览器下载。Expo 图片导出的 payload 校验、缓存写入、系统分享 / 保存面板和 HostBridge 成功响应包装统一收口在 `apps/mobile-shell/src/host-bridge/files.ts`,`dispatch.ts` 只委托文件模块。 - 2026-06-18 应用角标能力:新增 `app.setBadgeCount` HostBridge capability,H5 只传 `0` 到共享契约 `HOST_BRIDGE_BADGE_COUNT_MAX` 之间的整数并在宿主未声明时静默 fallback;Expo 壳只在 iOS 声明并通过 React Native `PushNotificationIOS` 设置应用图标角标,Android 不声明、不伪造成功;Tauri 壳通过主窗口 `set_badge_count` 设置任务栏角标,底层平台不支持时返回真实错误。 - 2026-06-18 草稿生成未读角标:平台壳层把“可见作品架里未读的草稿生成完成更新”同步到 `app.setBadgeCount`;同一草稿的 work/profile/session 等多个恢复 ID 只计 1,已读、失败、生成中和不可见草稿不计入。该角标只消费已有 HostBridge 能力,宿主不支持或设置失败不影响 H5 红点、作品架或后端状态。 diff --git a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md index a0e55a0ed..3778213ed 100644 --- a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md +++ b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md @@ -66,11 +66,11 @@ src/ 三端宿主桥接层按职责对齐命名:微信小程序页面路由仍保留在 `miniprogram/pages/*`,`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,不把微信小程序硬改成 Expo / Tauri 的 request 总线;Page 生命周期、`wx.*` 容器调用、WebView 容器行为和页面工厂统一放在 `miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面入口只做 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 只引用共享 HostBridge capability profile 并选择 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`appearance.ts` 承接系统配色读取,`navigation.ts` 承接外链打开、受控 H5 跳转和 WebView 刷新,`network.ts` 承接网络状态查询,`badge.ts` 承接受控角标能力,`clipboard.ts` 承接剪贴板读写与 HostBridge payload / 响应边界,`files.ts` 承接 Expo DocumentPicker / ImagePicker / File / Sharing 系统交互、取消语义、读写编排和 HostBridge 响应包装,`filePayloads.ts` 承接文件 MIME、大小、base64、文件名清洗和 picker 结果到 HostBridge payload 的边界,`share.ts` / `scanner.ts` / `notifications.ts` 分别承接分享、扫码和本地通知能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区、扫码 overlay 和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`runtime.rs` 承接桌面 runtime 回包的平台、hostVersion、bridgeVersion 和 capability 清单组装,`appearance.rs` 承接窗口主题读取和 HostBridge 配色归一,`navigation.rs` 承接外链打开、受控 H5 跳转和主窗口刷新,`network.rs` 承接网络状态查询,`badge.rs` 承接受控任务栏角标能力,`clipboard.rs` 承接剪贴板读写与 HostBridge payload / 响应边界,`title.rs` 承接窗口标题 payload / 响应边界,`capabilities.rs` 承接共享桌面 capability profile 的 Rust 运行时镜像,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` 承接系统文件对话框、取消语义和异步读写编排,`file_payloads.rs` 承接文件 MIME、大小、base64、文件名清洗、本地副本读写和 HostBridge payload 边界,`share.rs` / `notifications.rs` 分别承接分享和本地通知能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`menu.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、应用菜单、窗口状态持久化和 WebView 门面,`apps/desktop-shell/src-tauri/src/app.rs` 承接 Tauri builder / plugin / window 装配,`main.rs` 只保留薄入口并调用 `app::run()`。 -当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动源码根 `env.d.ts`;移动桥接层 `appearance.ts`、`badge.ts`、`bridge.ts`、`capabilities.ts`、`clipboard.ts`、`dispatch.ts`、`filePayloads.test.ts`、`filePayloads.ts`、`files.ts`、`haptics.ts`、`navigation.ts`、`network.ts`、`notifications.test.ts`、`notifications.ts`、`protocol.ts`、`runtime.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `appearance.rs`、`badge.rs`、`capabilities.rs`、`clipboard.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`notifications.rs`、`protocol.rs`、`runtime.rs`、`share.rs`、`title.rs`;桌面 shell 层 `deep_link.rs`、`events.rs`、`file_drop.rs`、`lifecycle.rs`、`menu.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`runtime.rs`、`tray.rs`、`url.rs`、`webview.rs`、`window_state.rs`。 +当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动源码根 `env.d.ts`;移动桥接层 `appearance.ts`、`badge.ts`、`bridge.ts`、`capabilities.ts`、`clipboard.ts`、`dispatch.ts`、`filePayloads.test.ts`、`filePayloads.ts`、`files.ts`、`haptics.test.ts`、`haptics.ts`、`navigation.ts`、`network.ts`、`notifications.test.ts`、`notifications.ts`、`protocol.ts`、`runtime.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `appearance.rs`、`badge.rs`、`capabilities.rs`、`clipboard.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`notifications.rs`、`protocol.rs`、`runtime.rs`、`share.rs`、`title.rs`;桌面 shell 层 `deep_link.rs`、`events.rs`、`file_drop.rs`、`lifecycle.rs`、`menu.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`runtime.rs`、`tray.rs`、`url.rs`、`webview.rs`、`window_state.rs`。 生产替身词扫描只覆盖上述壳源码、分发配置、共享 HostBridge 契约和已接入真实宿主能力的 H5 调用链;Expo export、Tauri `target/`、Cargo / Metro 缓存和 release 构建产物不进入扫描范围,避免本地或 CI 生成文件污染源码门禁。 -结构门禁按完整相对路径反查文档和目录:微信桥接层为 `miniprogram/host-bridge/dispatch.js`、`miniprogram/host-bridge/payment.js`、`miniprogram/host-bridge/protocol.js`、`miniprogram/host-bridge/shareGrid.js`、`miniprogram/host-bridge/subscribeMessage.js`、`miniprogram/host-bridge/webView.js`;微信 shell 层为 `miniprogram/shell/payment.js`、`miniprogram/shell/shareGrid.js`、`miniprogram/shell/subscribeMessage.js`、`miniprogram/shell/webView.js`;微信页面包装层为 `miniprogram/pages/share-grid/index.js`、`miniprogram/pages/share-grid/index.json`、`miniprogram/pages/share-grid/index.wxml`、`miniprogram/pages/share-grid/index.wxss`、`miniprogram/pages/subscribe-message/index.js`、`miniprogram/pages/subscribe-message/index.json`、`miniprogram/pages/subscribe-message/index.wxml`、`miniprogram/pages/subscribe-message/index.wxss`、`miniprogram/pages/web-view/index.js`、`miniprogram/pages/web-view/index.json`、`miniprogram/pages/web-view/index.wxml`、`miniprogram/pages/web-view/index.wxss`、`miniprogram/pages/wechat-pay/index.js`、`miniprogram/pages/wechat-pay/index.json`、`miniprogram/pages/wechat-pay/index.wxml`、`miniprogram/pages/wechat-pay/index.wxss`;移动源码根为 `apps/mobile-shell/src/env.d.ts`;移动桥接层为 `apps/mobile-shell/src/host-bridge/appearance.ts`、`apps/mobile-shell/src/host-bridge/badge.ts`、`apps/mobile-shell/src/host-bridge/bridge.ts`、`apps/mobile-shell/src/host-bridge/capabilities.ts`、`apps/mobile-shell/src/host-bridge/clipboard.ts`、`apps/mobile-shell/src/host-bridge/dispatch.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.test.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.ts`、`apps/mobile-shell/src/host-bridge/files.ts`、`apps/mobile-shell/src/host-bridge/haptics.ts`、`apps/mobile-shell/src/host-bridge/navigation.ts`、`apps/mobile-shell/src/host-bridge/network.ts`、`apps/mobile-shell/src/host-bridge/notifications.test.ts`、`apps/mobile-shell/src/host-bridge/notifications.ts`、`apps/mobile-shell/src/host-bridge/protocol.ts`、`apps/mobile-shell/src/host-bridge/runtime.ts`、`apps/mobile-shell/src/host-bridge/scanner.ts`、`apps/mobile-shell/src/host-bridge/share.ts`;移动 shell 层为 `apps/mobile-shell/src/shell/QrScannerOverlay.tsx`、`apps/mobile-shell/src/shell/ShellApp.tsx`、`apps/mobile-shell/src/shell/deepLink.ts`、`apps/mobile-shell/src/shell/lifecycle.ts`、`apps/mobile-shell/src/shell/loadFailure.ts`、`apps/mobile-shell/src/shell/navigation.ts`、`apps/mobile-shell/src/shell/network.ts`、`apps/mobile-shell/src/shell/runtime.ts`、`apps/mobile-shell/src/shell/safeArea.ts`、`apps/mobile-shell/src/shell/url.ts`、`apps/mobile-shell/src/shell/webViewGlobals.d.ts`、`apps/mobile-shell/src/shell/webViewHistory.ts`、`apps/mobile-shell/src/shell/webViewPolicy.ts`;桌面入口为 `apps/desktop-shell/src-tauri/src/app.rs`、`apps/desktop-shell/src-tauri/src/main.rs`;桌面桥接层为 `apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/badge.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/capabilities.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/clipboard.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/dispatch.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/file_payloads.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/files.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/mod.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/navigation.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/network.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/notifications.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/runtime.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/share.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/title.rs`;桌面 shell 层为 `apps/desktop-shell/src-tauri/src/shell/deep_link.rs`、`apps/desktop-shell/src-tauri/src/shell/events.rs`、`apps/desktop-shell/src-tauri/src/shell/file_drop.rs`、`apps/desktop-shell/src-tauri/src/shell/lifecycle.rs`、`apps/desktop-shell/src-tauri/src/shell/menu.rs`、`apps/desktop-shell/src-tauri/src/shell/mod.rs`、`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/src-tauri/src/shell/network.rs`、`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`apps/desktop-shell/src-tauri/src/shell/tray.rs`、`apps/desktop-shell/src-tauri/src/shell/url.rs`、`apps/desktop-shell/src-tauri/src/shell/webview.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`。这些目录不得新增未登记子目录或生产入口;移动端和桌面端单端配置检查同样会拒绝未登记生产模块。 +结构门禁按完整相对路径反查文档和目录:微信桥接层为 `miniprogram/host-bridge/dispatch.js`、`miniprogram/host-bridge/payment.js`、`miniprogram/host-bridge/protocol.js`、`miniprogram/host-bridge/shareGrid.js`、`miniprogram/host-bridge/subscribeMessage.js`、`miniprogram/host-bridge/webView.js`;微信 shell 层为 `miniprogram/shell/payment.js`、`miniprogram/shell/shareGrid.js`、`miniprogram/shell/subscribeMessage.js`、`miniprogram/shell/webView.js`;微信页面包装层为 `miniprogram/pages/share-grid/index.js`、`miniprogram/pages/share-grid/index.json`、`miniprogram/pages/share-grid/index.wxml`、`miniprogram/pages/share-grid/index.wxss`、`miniprogram/pages/subscribe-message/index.js`、`miniprogram/pages/subscribe-message/index.json`、`miniprogram/pages/subscribe-message/index.wxml`、`miniprogram/pages/subscribe-message/index.wxss`、`miniprogram/pages/web-view/index.js`、`miniprogram/pages/web-view/index.json`、`miniprogram/pages/web-view/index.wxml`、`miniprogram/pages/web-view/index.wxss`、`miniprogram/pages/wechat-pay/index.js`、`miniprogram/pages/wechat-pay/index.json`、`miniprogram/pages/wechat-pay/index.wxml`、`miniprogram/pages/wechat-pay/index.wxss`;移动源码根为 `apps/mobile-shell/src/env.d.ts`;移动桥接层为 `apps/mobile-shell/src/host-bridge/appearance.ts`、`apps/mobile-shell/src/host-bridge/badge.ts`、`apps/mobile-shell/src/host-bridge/bridge.ts`、`apps/mobile-shell/src/host-bridge/capabilities.ts`、`apps/mobile-shell/src/host-bridge/clipboard.ts`、`apps/mobile-shell/src/host-bridge/dispatch.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.test.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.ts`、`apps/mobile-shell/src/host-bridge/files.ts`、`apps/mobile-shell/src/host-bridge/haptics.test.ts`、`apps/mobile-shell/src/host-bridge/haptics.ts`、`apps/mobile-shell/src/host-bridge/navigation.ts`、`apps/mobile-shell/src/host-bridge/network.ts`、`apps/mobile-shell/src/host-bridge/notifications.test.ts`、`apps/mobile-shell/src/host-bridge/notifications.ts`、`apps/mobile-shell/src/host-bridge/protocol.ts`、`apps/mobile-shell/src/host-bridge/runtime.ts`、`apps/mobile-shell/src/host-bridge/scanner.ts`、`apps/mobile-shell/src/host-bridge/share.ts`;移动 shell 层为 `apps/mobile-shell/src/shell/QrScannerOverlay.tsx`、`apps/mobile-shell/src/shell/ShellApp.tsx`、`apps/mobile-shell/src/shell/deepLink.ts`、`apps/mobile-shell/src/shell/lifecycle.ts`、`apps/mobile-shell/src/shell/loadFailure.ts`、`apps/mobile-shell/src/shell/navigation.ts`、`apps/mobile-shell/src/shell/network.ts`、`apps/mobile-shell/src/shell/runtime.ts`、`apps/mobile-shell/src/shell/safeArea.ts`、`apps/mobile-shell/src/shell/url.ts`、`apps/mobile-shell/src/shell/webViewGlobals.d.ts`、`apps/mobile-shell/src/shell/webViewHistory.ts`、`apps/mobile-shell/src/shell/webViewPolicy.ts`;桌面入口为 `apps/desktop-shell/src-tauri/src/app.rs`、`apps/desktop-shell/src-tauri/src/main.rs`;桌面桥接层为 `apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/badge.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/capabilities.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/clipboard.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/dispatch.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/file_payloads.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/files.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/mod.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/navigation.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/network.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/notifications.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/runtime.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/share.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/title.rs`;桌面 shell 层为 `apps/desktop-shell/src-tauri/src/shell/deep_link.rs`、`apps/desktop-shell/src-tauri/src/shell/events.rs`、`apps/desktop-shell/src-tauri/src/shell/file_drop.rs`、`apps/desktop-shell/src-tauri/src/shell/lifecycle.rs`、`apps/desktop-shell/src-tauri/src/shell/menu.rs`、`apps/desktop-shell/src-tauri/src/shell/mod.rs`、`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/src-tauri/src/shell/network.rs`、`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`apps/desktop-shell/src-tauri/src/shell/tray.rs`、`apps/desktop-shell/src-tauri/src/shell/url.rs`、`apps/desktop-shell/src-tauri/src/shell/webview.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`。这些目录不得新增未登记子目录或生产入口;移动端和桌面端单端配置检查同样会拒绝未登记生产模块。 ## HostBridge 消息协议 diff --git a/docs/【前端架构】宿主壳能力统一协议-2026-06-17.md b/docs/【前端架构】宿主壳能力统一协议-2026-06-17.md index 1c7b46f25..ee1a10f4a 100644 --- a/docs/【前端架构】宿主壳能力统一协议-2026-06-17.md +++ b/docs/【前端架构】宿主壳能力统一协议-2026-06-17.md @@ -39,11 +39,11 @@ AI H5 sandbox 桥接层文件结构按宿主统一为“协议 / 能力清单 / 分发 / 宿主容器行为”四类职责。微信小程序不硬套 Expo / Tauri 的 request 总线:`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别放在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`;`miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js` 承接 Page 生命周期、`wx.*` 容器调用、WebView 容器行为、支付页和订阅页装配,页面目录只保留 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 只引用共享 HostBridge capability profile 并选择 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`appearance.ts` 承接系统配色读取,`navigation.ts` 承接外链打开、受控 H5 跳转和 WebView 刷新,`network.ts` 承接网络状态查询,`badge.ts` 承接受控角标能力,`clipboard.ts` 承接剪贴板读写与 HostBridge payload / 响应边界,`files.ts` 承接 Expo DocumentPicker / ImagePicker / File / Sharing 系统交互、取消语义、读写编排和 HostBridge 响应包装,`filePayloads.ts` 承接文件 MIME、大小、base64、文件名清洗和 picker 结果到 HostBridge payload 的边界,`share.ts` / `scanner.ts` / `notifications.ts` 分别承接分享、扫码和本地通知能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区、扫码 overlay 和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`runtime.rs` 承接桌面 runtime 回包的平台、hostVersion、bridgeVersion 和 capability 清单组装,`appearance.rs` 承接窗口主题读取和 HostBridge 配色归一,`navigation.rs` 承接外链打开、受控 H5 跳转和主窗口刷新,`network.rs` 承接网络状态查询,`badge.rs` 承接受控任务栏角标能力,`clipboard.rs` 承接剪贴板读写与 HostBridge payload / 响应边界,`title.rs` 承接窗口标题 payload / 响应边界,`capabilities.rs` 承接共享桌面 capability profile 的 Rust 运行时镜像,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` 承接系统文件对话框、取消语义和异步读写编排,`file_payloads.rs` 承接文件 MIME、大小、base64、文件名清洗、本地副本读写和 HostBridge payload 边界,`share.rs` / `notifications.rs` 分别承接分享和本地通知能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`menu.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、应用菜单、窗口状态持久化和 WebView 门面,`apps/desktop-shell/src-tauri/src/app.rs` 承接 Tauri builder / plugin / window 装配,`main.rs` 只保留薄入口并调用 `app::run()`。`npm run check:native-shells` 会检查这些目录清单。 -当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动源码根 `env.d.ts`;移动桥接层 `appearance.ts`、`badge.ts`、`bridge.ts`、`capabilities.ts`、`clipboard.ts`、`dispatch.ts`、`filePayloads.test.ts`、`filePayloads.ts`、`files.ts`、`haptics.ts`、`navigation.ts`、`network.ts`、`notifications.test.ts`、`notifications.ts`、`protocol.ts`、`runtime.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `appearance.rs`、`badge.rs`、`capabilities.rs`、`clipboard.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`notifications.rs`、`protocol.rs`、`runtime.rs`、`share.rs`、`title.rs`;桌面 shell 层 `deep_link.rs`、`events.rs`、`file_drop.rs`、`lifecycle.rs`、`menu.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`runtime.rs`、`tray.rs`、`url.rs`、`webview.rs`、`window_state.rs`。 +当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动源码根 `env.d.ts`;移动桥接层 `appearance.ts`、`badge.ts`、`bridge.ts`、`capabilities.ts`、`clipboard.ts`、`dispatch.ts`、`filePayloads.test.ts`、`filePayloads.ts`、`files.ts`、`haptics.test.ts`、`haptics.ts`、`navigation.ts`、`network.ts`、`notifications.test.ts`、`notifications.ts`、`protocol.ts`、`runtime.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `appearance.rs`、`badge.rs`、`capabilities.rs`、`clipboard.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`notifications.rs`、`protocol.rs`、`runtime.rs`、`share.rs`、`title.rs`;桌面 shell 层 `deep_link.rs`、`events.rs`、`file_drop.rs`、`lifecycle.rs`、`menu.rs`、`mod.rs`、`navigation.rs`、`network.rs`、`runtime.rs`、`tray.rs`、`url.rs`、`webview.rs`、`window_state.rs`。 生产替身词扫描只覆盖上述壳源码、分发配置、共享 HostBridge 契约和已接入真实宿主能力的 H5 调用链;Expo export、Tauri `target/`、Cargo / Metro 缓存和 release 构建产物不进入扫描范围,避免本地或 CI 生成文件污染源码门禁。 -结构门禁按完整相对路径反查文档和目录:微信桥接层为 `miniprogram/host-bridge/dispatch.js`、`miniprogram/host-bridge/payment.js`、`miniprogram/host-bridge/protocol.js`、`miniprogram/host-bridge/shareGrid.js`、`miniprogram/host-bridge/subscribeMessage.js`、`miniprogram/host-bridge/webView.js`;微信 shell 层为 `miniprogram/shell/payment.js`、`miniprogram/shell/shareGrid.js`、`miniprogram/shell/subscribeMessage.js`、`miniprogram/shell/webView.js`;微信页面包装层为 `miniprogram/pages/share-grid/index.js`、`miniprogram/pages/share-grid/index.json`、`miniprogram/pages/share-grid/index.wxml`、`miniprogram/pages/share-grid/index.wxss`、`miniprogram/pages/subscribe-message/index.js`、`miniprogram/pages/subscribe-message/index.json`、`miniprogram/pages/subscribe-message/index.wxml`、`miniprogram/pages/subscribe-message/index.wxss`、`miniprogram/pages/web-view/index.js`、`miniprogram/pages/web-view/index.json`、`miniprogram/pages/web-view/index.wxml`、`miniprogram/pages/web-view/index.wxss`、`miniprogram/pages/wechat-pay/index.js`、`miniprogram/pages/wechat-pay/index.json`、`miniprogram/pages/wechat-pay/index.wxml`、`miniprogram/pages/wechat-pay/index.wxss`;移动源码根为 `apps/mobile-shell/src/env.d.ts`;移动桥接层为 `apps/mobile-shell/src/host-bridge/appearance.ts`、`apps/mobile-shell/src/host-bridge/badge.ts`、`apps/mobile-shell/src/host-bridge/bridge.ts`、`apps/mobile-shell/src/host-bridge/capabilities.ts`、`apps/mobile-shell/src/host-bridge/clipboard.ts`、`apps/mobile-shell/src/host-bridge/dispatch.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.test.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.ts`、`apps/mobile-shell/src/host-bridge/files.ts`、`apps/mobile-shell/src/host-bridge/haptics.ts`、`apps/mobile-shell/src/host-bridge/navigation.ts`、`apps/mobile-shell/src/host-bridge/network.ts`、`apps/mobile-shell/src/host-bridge/notifications.test.ts`、`apps/mobile-shell/src/host-bridge/notifications.ts`、`apps/mobile-shell/src/host-bridge/protocol.ts`、`apps/mobile-shell/src/host-bridge/runtime.ts`、`apps/mobile-shell/src/host-bridge/scanner.ts`、`apps/mobile-shell/src/host-bridge/share.ts`;移动 shell 层为 `apps/mobile-shell/src/shell/QrScannerOverlay.tsx`、`apps/mobile-shell/src/shell/ShellApp.tsx`、`apps/mobile-shell/src/shell/deepLink.ts`、`apps/mobile-shell/src/shell/lifecycle.ts`、`apps/mobile-shell/src/shell/loadFailure.ts`、`apps/mobile-shell/src/shell/navigation.ts`、`apps/mobile-shell/src/shell/network.ts`、`apps/mobile-shell/src/shell/runtime.ts`、`apps/mobile-shell/src/shell/safeArea.ts`、`apps/mobile-shell/src/shell/url.ts`、`apps/mobile-shell/src/shell/webViewGlobals.d.ts`、`apps/mobile-shell/src/shell/webViewHistory.ts`、`apps/mobile-shell/src/shell/webViewPolicy.ts`;桌面入口为 `apps/desktop-shell/src-tauri/src/app.rs`、`apps/desktop-shell/src-tauri/src/main.rs`;桌面桥接层为 `apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/badge.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/capabilities.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/clipboard.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/dispatch.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/file_payloads.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/files.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/mod.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/navigation.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/network.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/notifications.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/runtime.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/share.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/title.rs`;桌面 shell 层为 `apps/desktop-shell/src-tauri/src/shell/deep_link.rs`、`apps/desktop-shell/src-tauri/src/shell/events.rs`、`apps/desktop-shell/src-tauri/src/shell/file_drop.rs`、`apps/desktop-shell/src-tauri/src/shell/lifecycle.rs`、`apps/desktop-shell/src-tauri/src/shell/menu.rs`、`apps/desktop-shell/src-tauri/src/shell/mod.rs`、`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/src-tauri/src/shell/network.rs`、`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`apps/desktop-shell/src-tauri/src/shell/tray.rs`、`apps/desktop-shell/src-tauri/src/shell/url.rs`、`apps/desktop-shell/src-tauri/src/shell/webview.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`。这些目录不得新增未登记子目录或生产入口;移动端和桌面端单端配置检查同样会拒绝未登记生产模块。 +结构门禁按完整相对路径反查文档和目录:微信桥接层为 `miniprogram/host-bridge/dispatch.js`、`miniprogram/host-bridge/payment.js`、`miniprogram/host-bridge/protocol.js`、`miniprogram/host-bridge/shareGrid.js`、`miniprogram/host-bridge/subscribeMessage.js`、`miniprogram/host-bridge/webView.js`;微信 shell 层为 `miniprogram/shell/payment.js`、`miniprogram/shell/shareGrid.js`、`miniprogram/shell/subscribeMessage.js`、`miniprogram/shell/webView.js`;微信页面包装层为 `miniprogram/pages/share-grid/index.js`、`miniprogram/pages/share-grid/index.json`、`miniprogram/pages/share-grid/index.wxml`、`miniprogram/pages/share-grid/index.wxss`、`miniprogram/pages/subscribe-message/index.js`、`miniprogram/pages/subscribe-message/index.json`、`miniprogram/pages/subscribe-message/index.wxml`、`miniprogram/pages/subscribe-message/index.wxss`、`miniprogram/pages/web-view/index.js`、`miniprogram/pages/web-view/index.json`、`miniprogram/pages/web-view/index.wxml`、`miniprogram/pages/web-view/index.wxss`、`miniprogram/pages/wechat-pay/index.js`、`miniprogram/pages/wechat-pay/index.json`、`miniprogram/pages/wechat-pay/index.wxml`、`miniprogram/pages/wechat-pay/index.wxss`;移动源码根为 `apps/mobile-shell/src/env.d.ts`;移动桥接层为 `apps/mobile-shell/src/host-bridge/appearance.ts`、`apps/mobile-shell/src/host-bridge/badge.ts`、`apps/mobile-shell/src/host-bridge/bridge.ts`、`apps/mobile-shell/src/host-bridge/capabilities.ts`、`apps/mobile-shell/src/host-bridge/clipboard.ts`、`apps/mobile-shell/src/host-bridge/dispatch.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.test.ts`、`apps/mobile-shell/src/host-bridge/filePayloads.ts`、`apps/mobile-shell/src/host-bridge/files.ts`、`apps/mobile-shell/src/host-bridge/haptics.test.ts`、`apps/mobile-shell/src/host-bridge/haptics.ts`、`apps/mobile-shell/src/host-bridge/navigation.ts`、`apps/mobile-shell/src/host-bridge/network.ts`、`apps/mobile-shell/src/host-bridge/notifications.test.ts`、`apps/mobile-shell/src/host-bridge/notifications.ts`、`apps/mobile-shell/src/host-bridge/protocol.ts`、`apps/mobile-shell/src/host-bridge/runtime.ts`、`apps/mobile-shell/src/host-bridge/scanner.ts`、`apps/mobile-shell/src/host-bridge/share.ts`;移动 shell 层为 `apps/mobile-shell/src/shell/QrScannerOverlay.tsx`、`apps/mobile-shell/src/shell/ShellApp.tsx`、`apps/mobile-shell/src/shell/deepLink.ts`、`apps/mobile-shell/src/shell/lifecycle.ts`、`apps/mobile-shell/src/shell/loadFailure.ts`、`apps/mobile-shell/src/shell/navigation.ts`、`apps/mobile-shell/src/shell/network.ts`、`apps/mobile-shell/src/shell/runtime.ts`、`apps/mobile-shell/src/shell/safeArea.ts`、`apps/mobile-shell/src/shell/url.ts`、`apps/mobile-shell/src/shell/webViewGlobals.d.ts`、`apps/mobile-shell/src/shell/webViewHistory.ts`、`apps/mobile-shell/src/shell/webViewPolicy.ts`;桌面入口为 `apps/desktop-shell/src-tauri/src/app.rs`、`apps/desktop-shell/src-tauri/src/main.rs`;桌面桥接层为 `apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/badge.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/capabilities.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/clipboard.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/dispatch.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/file_payloads.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/files.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/mod.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/navigation.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/network.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/notifications.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/runtime.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/share.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/title.rs`;桌面 shell 层为 `apps/desktop-shell/src-tauri/src/shell/deep_link.rs`、`apps/desktop-shell/src-tauri/src/shell/events.rs`、`apps/desktop-shell/src-tauri/src/shell/file_drop.rs`、`apps/desktop-shell/src-tauri/src/shell/lifecycle.rs`、`apps/desktop-shell/src-tauri/src/shell/menu.rs`、`apps/desktop-shell/src-tauri/src/shell/mod.rs`、`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/src-tauri/src/shell/network.rs`、`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`apps/desktop-shell/src-tauri/src/shell/tray.rs`、`apps/desktop-shell/src-tauri/src/shell/url.rs`、`apps/desktop-shell/src-tauri/src/shell/webview.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`。这些目录不得新增未登记子目录或生产入口;移动端和桌面端单端配置检查同样会拒绝未登记生产模块。 Tauri 桌面壳启动时必须按 `label="main"` 解析 `tauri.conf.json` 主窗口配置,并在创建 WebView 前补写 `native_app`、`tauri_desktop` 和真实 capability 上下文;缺少主窗口配置时启动直接失败,不允许按 `windows[0]` 兜底或无主窗口静默运行。 diff --git a/scripts/check-native-shells.mjs b/scripts/check-native-shells.mjs index bbc4bfbc4..7252c52e9 100644 --- a/scripts/check-native-shells.mjs +++ b/scripts/check-native-shells.mjs @@ -259,6 +259,7 @@ const expectedMobileHostBridgeFiles = [ 'filePayloads.test.ts', 'filePayloads.ts', 'files.ts', + 'haptics.test.ts', 'haptics.ts', 'navigation.ts', 'network.ts',