= (props: P) => ReactNode
+/**
+ * Registrant hooks compartment: bare observable sources (getSnapshot +
+ * subscribe pairs) supplied under the reserved `hooks` key of an inject
+ * face. The registrant-private twin of the `sessions.provide` hooks
+ * compartment: the renderer binds each source into a `use & PropsStore & PropsStore(sel: (s: string) => S) => S; hooks?: unknown; plain?: string }) => {
+ seen.push({ hooks: props.hooks, plain: props.plain, read: props.useBadge!(s => s) })
+ return null
+ },
+ inject: () => ({ plain: 'kept', hooks: { badge } }),
+ })
+ mountRoot(h, { 'k.single': SINGLE_ROOT }, renderSlot => renderSlot('k.single', {}))
+ // The raw compartment is consumed by the binding; the plain member passes through.
+ expect(seen.at(-1)).toEqual({ hooks: undefined, plain: 'kept', read: 'cold' })
+ act(() => { badge.set('hot') })
+ expect(seen.at(-1)!['read']).toBe('hot')
+ })
+
it('session inject receives sessionId and caches per (entry x session): switch-back reuses', () => {
const h = makeHost()
h.declare('k.session', SINGLE_SESSION)
From 0a625b1144bd5affebda2dcd486d5b73f1fca4cf Mon Sep 17 00:00:00 2001
From: Yif <877193178@qq.com>
Date: Tue, 28 Jul 2026 12:18:18 +0800
Subject: [PATCH 13/29] fix(web-ui): header title 14/20, drop turns counter,
global grayscale antialiasing
---
.../src/client/skeleton/ConversationRoot.module.css | 11 ++---------
.../src/client/skeleton/ConversationSession.tsx | 8 --------
packages/client/web/src/base.css | 4 ++++
3 files changed, 6 insertions(+), 17 deletions(-)
diff --git a/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css b/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css
index 6c18b8c1a5..de974da86c 100644
--- a/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css
+++ b/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css
@@ -54,8 +54,8 @@
border: none;
border-radius: 12px;
background: transparent;
- font-size: 13px;
- line-height: 16px;
+ font-size: 14px;
+ line-height: 20px;
color: var(--dsw-alias-label-tertiary);
text-overflow: ellipsis;
white-space: nowrap;
@@ -72,13 +72,6 @@
cursor: default;
}
-.meta {
- margin-left: 4px;
- font-size: 12px;
- line-height: 18px;
- color: var(--dsw-alias-label-tertiary);
-}
-
/* figma Tab_Group 34:11441: 35px strip, gap 36, pad-left 8, tabs bottom-aligned. */
.tabs {
display: flex;
diff --git a/packages/client/ui-conversation/src/client/skeleton/ConversationSession.tsx b/packages/client/ui-conversation/src/client/skeleton/ConversationSession.tsx
index 45d98c1693..0c1addcba7 100644
--- a/packages/client/ui-conversation/src/client/skeleton/ConversationSession.tsx
+++ b/packages/client/ui-conversation/src/client/skeleton/ConversationSession.tsx
@@ -31,7 +31,6 @@ export function ConversationSession({
const activeId = useStore(s => s.view) ?? 'chat'
const active = tabs.find(view => view.id === activeId) ?? tabs[0]
const ancestry = useSessions(s => deriveAncestry(s, sessionId), shallowEqual)
- const turns = useSession(s => countTurns(s))
const composerPhase = useSession(s => s.composerPhase)
const blank = useSession(s => s.blank)
const inputState = useInput(s => s)
@@ -69,7 +68,6 @@ export function ConversationSession({
)
})}
{ancestry.length === 0 && {sessionId}}
- · {turns} turns