Web install manifest metadata
Web 安装 manifest 元数据
The Web build has a document title and favicon but no manifest from which a browser can discover a stable installed identity, launch boundary, or installed presentation. Adding that metadata can also imply capabilities the app does not provide: a service worker suggests an offline contract, while a single language or palette value misrepresents a bilingual UI with resolved light and dark themes.
English
Problem
The Web build has a document title and favicon but no manifest from which a browser can discover a stable installed identity, launch boundary, or installed presentation. Adding that metadata can also imply capabilities the app does not provide: a service worker suggests an offline contract, while a single language or palette value misrepresents a bilingual UI with resolved light and dark themes.
Decision
The Web entry links /manifest.webmanifest, which Vite copies from apps/web/public/ into the production build. The manifest names the product DeepSeek Harness, gives installed chrome the compact name DSH, and fixes id, start_url, and scope at /. It requests display: "fullscreen" so supporting browsers can give the installed editor-like surface the available display area while leaving ordinary tabs unchanged; browsers may apply user overrides or fall back to another display mode. Its icon entry reuses /favicon.svg as an SVG of size any and purpose any.
This follows code-server's fullscreen choice without copying its window-controls-overlay display override. DSH has no custom title bar or layout around native window controls, so such an override would supersede fullscreen without owning the required safe layout.
The manifest deliberately has no lang, theme_color, or background_color. The product surface is bilingual rather than owned by one manifest language, and either static color can disagree with one of the resolved app palettes. Theme metadata therefore remains outside the install manifest.
This feature adds no service worker, cache policy, or offline fallback. The manifest supplies install metadata only; browser eligibility and install affordances remain browser policy. The shipped dsh-host-frontend-static fallback recognizes .webmanifest as application/manifest+json so the same asset is valid through the shipped HTTP composition rather than only in Vite's output directory.
Verification
The built-Web test parses the emitted manifest and pins the complete metadata object, including the human-visible name, compact name, icon, root identity, launch boundary, and display mode, while also verifying that the production index.html retains the link. The dsh-host-frontend-static real Loader composition test serves a .webmanifest fixture and pins its application/manifest+json media type.
Alternatives considered
Add a service worker and call the app offline-capable. Rejected because caching the shell without defining session transport, invalidation, failure behavior, and upgrade semantics would create a misleading partial offline contract.
Declare one lang. Rejected because no single language describes the bilingual product surface; omission avoids claiming that one locale owns the installed experience.
Choose one static background and theme color. Rejected because the app resolves light and dark palettes at runtime, so either fixed value is knowingly wrong for one supported state.
Ship raster and maskable icon variants immediately. Rejected until a supported installation target demonstrates a requirement the existing scalable favicon cannot meet. New variants remain an additive manifest change rather than a prerequisite for exposing the current identity.
Assert only root and display fields in the built artifact. Rejected because dropping or changing the product name, compact name, or icon is also a shipped install regression. The test intentionally requires an explicit edit whenever any manifest metadata changes.
Consequences
Supporting browsers can discover a stable root-scoped installed identity and fullscreen preference without the application promising offline behavior. Deploying this build below a path prefix requires revisiting the absolute link, identity, launch, scope, and icon URLs together. Browser-specific icon requirements may add variants later, and every intentional metadata change updates the exact built-artifact contract.
中文
问题
Web 构建产物已有文档标题和 favicon,却没有可供浏览器发现稳定安装身份、启动边界或安装后呈现方式的 manifest(元数据清单)。添加这类元数据也可能暗示应用并不具备的能力:service worker 会让人以为应用提供离线约定,而单一语言或调色板取值会错误描述这个能够解析浅色与深色主题的双语 UI。
决策
Web 入口链接 /manifest.webmanifest,Vite 会将其从 apps/web/public/ 复制到生产构建产物。manifest 将产品命名为 DeepSeek Harness,为安装后的浏览器界面提供简称 DSH,并把 id、start_url 和 scope 固定为 /。它请求 display: "fullscreen",使支持这一模式的浏览器能够把可用显示区域交给安装后的编辑器式界面,同时不改变普通标签页;浏览器可以应用用户覆盖设置,或回退到其他显示模式。其图标条目复用 /favicon.svg,将它作为尺寸为 any、用途为 any 的 SVG。
这一选择沿用了 code-server 的全屏方案,但没有照搬其 window-controls-overlay 显示覆盖项。DSH 没有自定义标题栏,也没有围绕原生窗口控件安排布局,因此使用这类覆盖项会在未落实所需安全布局的情况下取代全屏模式。
manifest 有意不包含 lang、theme_color 或 background_color。产品界面支持双语,并不由 manifest 中的单一语言定义;任一静态颜色值都可能与应用解析后的一套调色板不一致。因此,主题元数据仍放在安装 manifest 之外。
该功能不添加 service worker、缓存策略或离线回退。manifest 只提供安装元数据;是否具备安装资格、是否提供安装入口仍由浏览器策略决定。实际交付的 dsh-host-frontend-static 回退将 .webmanifest 识别为 application/manifest+json,因此同一资产经实际交付的 HTTP 组合提供时同样有效,而不只在 Vite 输出目录中有效。
验证
Web 构建产物测试解析输出的 manifest,并固定完整的元数据对象,包括面向用户显示的名称、简称、图标、根路径身份、启动边界和显示模式,同时验证生产构建的 index.html 仍保留该链接。dsh-host-frontend-static 的真实 Loader 组合测试提供一个 .webmanifest fixture(测试前置数据),并固定其 application/manifest+json 媒体类型。
曾考虑的替代方案
添加 service worker,并宣称应用支持离线。 不予采纳,因为只缓存应用外壳,却不定义会话传输、失效策略、失败行为和升级语义,会形成具有误导性的不完整离线约定。
声明单一的 lang。 不予采纳,因为没有任何一种语言足以描述双语产品界面;省略该字段可避免声称安装后的体验由某一种区域设置独占。
选择一组静态背景色和主题色。 不予采纳,因为应用会在运行时解析浅色和深色调色板,因此选择任一固定值,都是明知它与其中一种受支持状态不符。
立即交付光栅和可遮罩图标变体。 在某个受支持的安装目标证明现有可缩放 favicon 无法满足其要求之前,不予采纳。新变体只是对 manifest 的增量扩展,并非公开当前身份的前提。
只断言构建产物中的根路径字段和显示字段。 不予采纳,因为产品名称、简称或图标被删除或更改,同样属于已交付安装体验的回归。任何 manifest 元数据发生变化时,测试都有意要求显式改动。
后果
支持这一机制的浏览器可以发现以根路径为作用域的稳定安装身份和全屏偏好,而应用无需承诺离线行为。在路径前缀下部署该构建产物时,必须同时重新审视绝对路径的 manifest 链接,以及身份、启动、作用域和图标 URL。日后可能因浏览器特有的图标要求而新增变体;每一项有意的元数据变更都会同步更新精确的构建产物约定。