From 17bde3f5bea240c152fcddd51340a48adb1b9f22 Mon Sep 17 00:00:00 2001 From: Turtle Date: Fri, 21 Aug 2026 18:00:10 +0800 Subject: [PATCH] feat: label local build banner --- apps/web/tests/built-boot.snapshot.ts | 1 + packages/client/ui-sidebar/README.i18n.yaml | 4 +-- packages/client/ui-sidebar/README.md | 2 +- packages/client/ui-sidebar/README.zh.md | 2 +- .../src/client/SidebarRoot.module.css | 26 +++++++++++++++++++ .../ui-sidebar/src/client/SidebarRoot.tsx | 21 ++++++++------- .../sidebar-snapshot.client.spec.tsx.snap | 26 ++++++++++++++++--- .../tests/sidebar-root.client.spec.tsx | 2 ++ 8 files changed, 66 insertions(+), 18 deletions(-) diff --git a/apps/web/tests/built-boot.snapshot.ts b/apps/web/tests/built-boot.snapshot.ts index 3a688bbe5c..6999543b00 100644 --- a/apps/web/tests/built-boot.snapshot.ts +++ b/apps/web/tests/built-boot.snapshot.ts @@ -73,6 +73,7 @@ it('boots the built plugin graph and renders a fixture session end to end', asyn + (commit === undefined ? '' : `-${commit}`) + (clientBuildValue('DSH_CLIENT_GIT_DIRTY') === 'true' ? '-dirty' : '') screen.getByText('DSH') + screen.getByText('Local Build') screen.getByText(buildVersion) } // The compact layout dropped group session counts; the fixture workspace diff --git a/packages/client/ui-sidebar/README.i18n.yaml b/packages/client/ui-sidebar/README.i18n.yaml index d33c1ce612..2a3119689c 100644 --- a/packages/client/ui-sidebar/README.i18n.yaml +++ b/packages/client/ui-sidebar/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-sidebar/README.md -README.md: 8a7963f1cd5cd0cf9e1d951e68aa53a35f0c4c3c -README.zh.md: 4c9040589ab8a28897821a2e476786ccf8ace50c +README.md: 406f2930ac1deb9bf8e12caedbcfb11f7fc35fbc +README.zh.md: 147c30b5de5db07bbffa665157c3707430c0a099 diff --git a/packages/client/ui-sidebar/README.md b/packages/client/ui-sidebar/README.md index 8a7963f1cd..406f2930ac 100644 --- a/packages/client/ui-sidebar/README.md +++ b/packages/client/ui-sidebar/README.md @@ -4,7 +4,7 @@ English | [中文](README.zh.md) Sidebar shell plugin: the brand row, New Session action, layout-owned collapse control, scroll-aware region seat, and bottom-pinned Settings seat. [ui-workspace](../ui-workspace/README.md) owns the Workspace and Session browser rendered into `sidebar.workspaces`; this package neither derives its rows nor owns its view preferences. Collapse into the layout-owned 56px rail remains presentation-local. Contract: the [slot system standard](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md). -The expanded brand row renders `sidebar.brand.mark` and `sidebar.brand.name` as independent single slots, while the collapsed rail renders the same mark slot. Without occupants, the shell uses the fish mark and a local-build fallback: a complete build renders `DSH` plus a code badge assembled as `version[-commit][-dirty]` from `DSH_CLIENT_VERSION`, the optional 7-character `DSH_CLIENT_COMMIT_HASH`, and `DSH_CLIENT_GIT_DIRTY=true`; missing version metadata retains the defensive `DSH Local Build` label. A deployment package can replace either value without replacing the New Session control or rail geometry; declaration-aware `slots.inject()` lets such a package activate before or after the sidebar. +The expanded brand row renders `sidebar.brand.mark` and `sidebar.brand.name` as independent single slots, while the collapsed rail renders the same mark slot. Without occupants, the shell uses the fish mark and a local-build fallback: a complete build renders `DSH` with a small `Local Build` caption plus a code badge assembled as `version[-commit][-dirty]` from `DSH_CLIENT_VERSION`, the optional 7-character `DSH_CLIENT_COMMIT_HASH`, and `DSH_CLIENT_GIT_DIRTY=true`; missing version metadata retains the defensive `DSH Local Build` label. A deployment package can replace either value without replacing the New Session control or rail geometry; declaration-aware `slots.inject()` lets such a package activate before or after the sidebar. New Session starts the runtime's page-local frontend Session Intent. The runtime targets the explicit Workspace used by a scoped action, otherwise the current Session's Workspace, otherwise the most recently active Workspace; when none exists it clears into the blank New Session page. Workspace-specific controls and the shared picker belong to ui-workspace. diff --git a/packages/client/ui-sidebar/README.zh.md b/packages/client/ui-sidebar/README.zh.md index 4c9040589a..147c30b5de 100644 --- a/packages/client/ui-sidebar/README.zh.md +++ b/packages/client/ui-sidebar/README.zh.md @@ -4,7 +4,7 @@ 侧边栏外壳插件:负责品牌行、New Session 操作、布局持有的折叠控件、可感知滚动的区域 seat,以及固定在底部的 Settings seat。[ui-workspace](../ui-workspace/README.zh.md) 持有渲染到 `sidebar.workspaces` 的 Workspace 与 Session 浏览器;本包既不派生其中的行,也不持有其视图偏好。折叠到布局拥有的 56px 轨道仍属于本地呈现行为。约定:[slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.zh.md)。 -展开的品牌行把 `sidebar.brand.mark` 与 `sidebar.brand.name` 渲染为两个独立的 single slot,收起轨道则渲染同一个 mark slot。没有占位者时,外壳使用鱼形标记和本地构建 fallback:完整构建显示 `DSH`,并把 `DSH_CLIENT_VERSION`、可选的 7 位 `DSH_CLIENT_COMMIT_HASH` 及 `DSH_CLIENT_GIT_DIRTY=true` 组装成 `version[-commit][-dirty]` 代码徽标;缺少版本元数据时保留防御性的 `DSH Local Build` 标签。部署包可以单独替换任一值,而无须替换 New Session 控件或轨道几何;声明感知的 `slots.inject()` 让这种包无论先于还是后于侧边栏激活都能生效。 +展开的品牌行把 `sidebar.brand.mark` 与 `sidebar.brand.name` 渲染为两个独立的 single slot,收起轨道则渲染同一个 mark slot。没有占位者时,外壳使用鱼形标记和本地构建 fallback:完整构建显示 `DSH`、小号 `Local Build` 标注,以及把 `DSH_CLIENT_VERSION`、可选的 7 位 `DSH_CLIENT_COMMIT_HASH` 与 `DSH_CLIENT_GIT_DIRTY=true` 组装成的 `version[-commit][-dirty]` 代码徽标;缺少版本元数据时保留防御性的 `DSH Local Build` 标签。部署包可以单独替换任一值,而无须替换 New Session 控件或轨道几何;声明感知的 `slots.inject()` 让这种包无论先于还是后于侧边栏激活都能生效。 New Session 会启动运行时的页面局部前端 Session Intent。运行时优先使用作用域操作明确指定的 Workspace,否则使用当前 Session 所属 Workspace,再否则使用最近活跃 Workspace;一个 Workspace 都没有时则清空选择,进入空白 New Session 页面。Workspace 专属控件与共享选择器由 ui-workspace 持有。 diff --git a/packages/client/ui-sidebar/src/client/SidebarRoot.module.css b/packages/client/ui-sidebar/src/client/SidebarRoot.module.css index fc2ec94aaa..d280ab647f 100644 --- a/packages/client/ui-sidebar/src/client/SidebarRoot.module.css +++ b/packages/client/ui-sidebar/src/client/SidebarRoot.module.css @@ -159,6 +159,30 @@ white-space: nowrap; } +.localBuildBrand { + flex: none; + display: inline-flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + height: 24px; + white-space: nowrap; +} + +.localBuildName { + font-size: 16px; + line-height: 15px; + letter-spacing: 0; +} + +.localBuildLabel { + color: var(--dsw-alias-label-secondary); + font-size: 7px; + font-weight: 500; + line-height: 8px; + letter-spacing: 0.02em; +} + .iconButton { flex: none; display: inline-flex; @@ -211,6 +235,7 @@ } .buildVersion { + flex: none; display: inline-flex; align-items: center; height: 16px; @@ -222,6 +247,7 @@ font-size: 8px; font-weight: 500; line-height: 16px; + white-space: nowrap; } /* New Session: 38px bar, 12px radius (figma 133:7634 geometry, squared-off diff --git a/packages/client/ui-sidebar/src/client/SidebarRoot.tsx b/packages/client/ui-sidebar/src/client/SidebarRoot.tsx index 3fb2a68fd9..bdc5140b24 100644 --- a/packages/client/ui-sidebar/src/client/SidebarRoot.tsx +++ b/packages/client/ui-sidebar/src/client/SidebarRoot.tsx @@ -153,16 +153,17 @@ export function SidebarRoot({ {renderSlot('sidebar.brand.name', {}, { - fallback: ( - <> - - {buildVersion === undefined ? 'DSH Local Build' : 'DSH'} - - {buildVersion === undefined - ? null - : {buildVersion}} - - ), + fallback: buildVersion === undefined + ? DSH Local Build + : ( + <> + + DSH + Local Build + + {buildVersion} + + ), })} diff --git a/packages/client/ui-sidebar/tests/__snapshots__/sidebar-snapshot.client.spec.tsx.snap b/packages/client/ui-sidebar/tests/__snapshots__/sidebar-snapshot.client.spec.tsx.snap index 7780754125..929ce9d72a 100644 --- a/packages/client/ui-sidebar/tests/__snapshots__/sidebar-snapshot.client.spec.tsx.snap +++ b/packages/client/ui-sidebar/tests/__snapshots__/sidebar-snapshot.client.spec.tsx.snap @@ -138,9 +138,18 @@ exports[`sidebar shell snapshots > renders the expanded column (wordmark, capsul style="display: contents;" > - DSH + + DSH + + + Local Build + renders the expanded column in the default lo style="display: contents;" > - DSH + + DSH + + + Local Build + { />) expect(screen.getByText('DSH')).toBeTruthy() + expect(screen.getByText('Local Build')).toBeTruthy() expect(screen.getByText('1.2.3-rc.4-0123456-dirty')).toBeTruthy() expect(container.querySelector('svg')).not.toBeNull() }) @@ -129,6 +130,7 @@ describe('SidebarRoot shell', () => { />) expect(screen.getByText('DSH')).toBeTruthy() + expect(screen.getByText('Local Build')).toBeTruthy() expect(screen.getByText(expected)).toBeTruthy() })