dsh-smooth-stream 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["css","IconChevronDownOutline14","useRef","useState","useRef","useCallback","useRef","useCallback","useRef","css","useState","memo","useRef","css","MarkdownText","IconThinkOutline14","useCallback","useMemo","ImageGallery","JsonBlock","useRef","useState","useCallback","entranceCss","createElement","useState","css","IconChevronDownOutline14","IconRefreshOutline14","css","Tooltip","IconQuestionOutline14","useState","writeClipboard","IconCopyOutline16","IconCloseOutline16","IconRefreshOutline16","IconCodeOutline16","createPortal","useSyncExternalStore","SETTINGS_NS","createElement"],"sources":["../src/client/AnimatedDisclosure.tsx","../src/settings.ts","../src/client/clientStore.ts","../src/client/debugRuntime.ts","../src/client/teleprompterGlide.ts","../src/client/useSmoothStreamContent.ts","../src/client/useFpsGuard.ts","../src/client/FollowHost.tsx","../src/config.ts","../src/client/TypewriterAssistantNodeView.tsx","../src/client/useProgressiveDomText.ts","../src/client/TypewriterToolNodeView.tsx","../src/client/SmoothStreamCard.tsx","../src/client/smooth-stream-card-controller.ts","../src/settings-api.ts","../src/client/smooth-stream-settings-api.ts","../src/client/DebugPanel.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["// AnimatedDisclosure: the harness DisclosureRow chrome (24px row, hover\n// chevron preview, whole-row click/Enter/Space toggle) with one deliberate\n// difference - the expanded body stays mounted while collapsed and animates\n// between 0fr and 1fr grid tracks, so expand/collapse glides instead of\n// snapping. The harness primitive unmounts closed children (`{open &&\n// children}`) and a plugin cannot change that in place, so this fork mirrors\n// its DOM shape and `data-disclosure-row` contract: host styling keyed on the\n// row attribute and the Think chrome keep working unchanged.\n\nimport { type KeyboardEvent, type ReactNode } from 'react'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './TypewriterAssistantNodeView.module.css'\n\n/** Class-name join for optional overlay classes over the chrome defaults. */\nfunction cx(...parts: Array<string | undefined>): string {\n return parts.filter(part => part !== undefined && part !== '').join(' ')\n}\n\nexport interface AnimatedDisclosureProps {\n icon: ReactNode\n title: string\n open: boolean\n onToggle: () => void\n collapsedContent?: ReactNode\n children?: ReactNode\n rowClassName?: string | undefined\n leadingClassName?: string | undefined\n titleClassName?: string | undefined\n chevronClassName?: string | undefined\n /**\n * When false the body snaps between states with no grid-track transition.\n * The auto-close at stream end uses this: the conversation follower's\n * settle spring absorbs the height step through the compositor instead,\n * which glides identically without twelve frames of layout animation.\n */\n bodyTransition?: boolean\n}\n\n/**\n * Render one disclosure header whose expanded body is height-animated.\n * @param props - Visual content, controlled open state, and the toggle\n * callback fired by row click and Enter/Space.\n * @returns the animated disclosure row.\n */\nexport function AnimatedDisclosure({\n icon,\n title,\n open,\n onToggle,\n collapsedContent,\n children,\n rowClassName,\n leadingClassName,\n titleClassName,\n chevronClassName,\n bodyTransition = true,\n}: AnimatedDisclosureProps) {\n const toggleFromKeyboard = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Enter' && event.key !== ' ') return\n event.preventDefault()\n onToggle()\n }\n return (\n <div className={css.disclosureRoot} data-open={open || undefined}>\n <div\n className={cx(css.disclosureRow, rowClassName)}\n data-disclosure-row\n data-expandable=\"\"\n role=\"button\"\n tabIndex={0}\n aria-expanded={open}\n onClick={onToggle}\n onKeyDown={toggleFromKeyboard}\n >\n <span className={cx(css.disclosureLeading, leadingClassName)}>\n {open\n ? <IconChevronDownOutline14 className={chevronClassName} />\n : (\n <>\n <span className={css.disclosureIconIdle}>{icon}</span>\n <IconChevronDownOutline14 className={cx(chevronClassName, css.disclosureChevronHover)} />\n </>\n )}\n </span>\n <span className={cx(css.disclosureTitle, titleClassName)}>{title}</span>\n {!open && collapsedContent}\n </div>\n <div\n className={css.disclosureContent}\n data-disclosure-content\n data-collapsed={open ? undefined : ''}\n data-no-transition={bodyTransition ? undefined : ''}\n >\n {children}\n </div>\n </div>\n )\n}\n","/**\n * User-owned settings for the smooth-stream plugin, exposed to the Host\n * settings service and edited from the Web Settings \"plugin configuration\"\n * page. This is the runtime-editable complement to {@link StreamConfig}: that\n * contract is composed at load and bridged once through the boot global, while\n * these preferences live in the durable user-settings document and take effect\n * live.\n */\n\n/** Settings namespace registered by the Host and served through the plugin RPC. */\nexport const STREAM_SETTINGS_NS = 'smooth-stream'\n\n/** Runtime knobs exposed only while the diagnostics switch is enabled. */\nexport interface StreamDebugTuning {\n /** Multiplier applied to the reveal cadence (1 = preset default). */\n revealScale: number\n /** Multiplier for backlog pressure in the adaptive reveal queue. */\n queuePressure: number\n /** Upper bound for reveal cadence, in characters per second. */\n maxRevealCps: number\n /** Spring stiffness used by the conversation follower. */\n springStiffness: number\n /** Spring damping used by the conversation follower. */\n springDamping: number\n /** Spring mass used by the conversation follower. */\n springMass: number\n /** Predictive runway before the fixed conversation chrome, in pixels. */\n runwayPx: number\n /** Response time for opening/closing the predictive runway, in ms. */\n reserveResponseMs: number\n /** Lowest reveal multiplier when visual lag fills the safe paint room. */\n backpressureMinScale: number\n}\n\n/** Defaults preserve the production engine exactly. */\nexport const DEFAULT_STREAM_DEBUG_TUNING: StreamDebugTuning = {\n revealScale: 1,\n queuePressure: 0.85,\n maxRevealCps: 600,\n springStiffness: 130,\n springDamping: 24,\n springMass: 1,\n runwayPx: 72,\n reserveResponseMs: 180,\n backpressureMinScale: 0.55,\n}\n\n/**\n * How the typewriter reveal responds to the OS reduced-motion preference.\n * Credit: three-state design proposed by @Zn-Dk in #21/#22.\n */\nexport type StreamMotionPreference =\n /** Follow the OS preference: reduced-motion users get raw text (accessibility first). */\n | 'auto'\n /** Always run the smoothing engine, ignoring the OS preference. */\n | 'force-smooth'\n /** Always render raw text, ignoring the OS preference. */\n | 'force-reduced'\n\n/**\n * Preferences a user may set. Deliberately separate from {@link StreamConfig}\n * because the two change at different times: composition-time values go\n * through the boot global, a live UI edit goes through the protected plugin RPC.\n */\nexport interface StreamSettings {\n /**\n * Whether this plugin replaces and wraps Harness conversation renderers.\n * Off returns all rendering ownership to the built-in UI.\n */\n enabled: boolean\n /**\n * Whether this plugin also takes over conversation bottom-follow. Off leaves\n * scroll ownership to the Harness; text reveal still runs.\n */\n controlScroll: boolean\n /**\n * How the reveal honors the OS reduced-motion preference. `auto` preserves\n * the accessibility-first default; `force-smooth` keeps the engine on\n * machines where a system-wide reduce-motion switch (performance tooling,\n * RDP sessions, forced browser flags) would otherwise bypass it silently.\n */\n motionPreference: StreamMotionPreference\n /**\n * Whether a reasoning (\"Think\") block auto-expands while it is the\n * streaming tail. Off keeps the block collapsed — the user can still open\n * it by hand — and stops the running state from re-owning the disclosure.\n */\n thinkAutoExpand: boolean\n /** Whether the live renderer diagnostics panel is enabled. */\n debugEnabled: boolean\n /** Values edited by the diagnostics panel. */\n debugTuning: StreamDebugTuning\n}\n\n/** Defaults shared by the Host schema and the client-side fallback. */\nexport const DEFAULT_STREAM_SETTINGS: StreamSettings = {\n enabled: true,\n controlScroll: true,\n motionPreference: 'auto',\n thinkAutoExpand: true,\n debugEnabled: false,\n debugTuning: DEFAULT_STREAM_DEBUG_TUNING,\n}\n","/**\n * Kernel compatibility for the client store engine.\n *\n * DSH 0.1.2 split the snapshot store out of `@deepseek-ai/dsh-client-runtime`\n * into a bare `@deepseek-ai/dsh-client-store` module-table seed, while ≤ 0.1.1\n * kernels keep it on the client-runtime client face. The client module table\n * only answers what the booting kernel actually ships, so the face must be\n * probed at runtime: a static require of either specifier kills the whole\n * loader tree on the other generation (issue #17: a top-level\n * `require(\"@deepseek-ai/dsh-client-runtime/client\")` took down the web UI on\n * DSH Desktop 2.0.4 / kernel 0.1.2-alpha.1).\n */\n\ntype ClientRuntimeClient = typeof import('@deepseek-ai/dsh-client-runtime/client')\n\nexport interface SnapshotStoreLike<T> {\n getSnapshot(): T\n subscribe(listener: (state: T) => void): () => void\n update(mutator: (draft: T) => void): void\n set(next: T): void\n}\n\nfunction fallbackSnapshotStore<T extends object>(init: T): SnapshotStoreLike<T> {\n let state = init\n const listeners = new Set<(state: T) => void>()\n return {\n getSnapshot: () => state,\n subscribe: listener => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n update: mutator => {\n const draft = Object.create(\n Object.getPrototypeOf(state),\n Object.getOwnPropertyDescriptors(state),\n ) as T\n mutator(draft)\n state = draft\n for (const listener of [...listeners]) listener(state)\n },\n set: next => {\n state = next\n for (const listener of [...listeners]) listener(state)\n },\n }\n}\n\n/**\n * Runtime require: the module-loader factory scopes its own resolver over the\n * booting kernel's table; under Node (vitest) there is no global require, so\n * fall back to `createRequire`.\n */\nfunction pickRequire(): NodeRequire | null {\n if (typeof require === 'function') {\n try {\n return require\n } catch {\n return null\n }\n }\n if (typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function') {\n try {\n const { createRequire } = process.getBuiltinModule('node:module')\n return createRequire(process.cwd() + '/package.json')\n } catch {\n return null\n }\n }\n return null\n}\n\nlet clientStore: Partial<ClientRuntimeClient> | undefined\n\ntry {\n const req = pickRequire()\n if (req !== null) {\n try {\n // 0.1.2+ seeds the split store package directly into the module table.\n clientStore = req('@deepseek-ai/dsh-client-store') as ClientRuntimeClient\n } catch {\n try {\n // ≤ 0.1.1 owns the store engine on the client-runtime client face.\n clientStore = req('@deepseek-ai/dsh-client-runtime/client') as ClientRuntimeClient\n } catch {\n // Fallback below\n }\n }\n }\n} catch {\n // Fallback below\n}\n\nexport interface SnapshotStore<T> {\n getSnapshot(): T\n subscribe(listener: () => void): () => void\n update(mutator: (draft: T) => void): void\n set(next: T): void\n}\n\nexport const createSnapshotStore = (clientStore?.createSnapshotStore ?? fallbackSnapshotStore) as <T extends object>(init: T) => SnapshotStore<T>\n","/**\n * Shared browser-side diagnostics state.\n *\n * The settings card owns persistence. This module is the live bridge used by\n * the renderer and the chat-side panel: renderer loops publish measurements,\n * while panel edits are staged through the settings-card controller.\n */\n\nimport { createSnapshotStore, type SnapshotStore } from './clientStore.ts'\nimport {\n DEFAULT_STREAM_DEBUG_TUNING,\n type StreamDebugTuning,\n type StreamSettings,\n} from '../settings.ts'\n\nexport interface DebugMetrics {\n fps: number | null\n frameMs: number | null\n fpsDegraded: boolean\n streamActive: boolean\n streamBacklog: number\n streamSpeedCps: number\n streamTargetChars: number\n streamDisplayedChars: number\n followActive: boolean\n followLagPx: number\n followVelocityPxPerSec: number\n followReservePx: number\n followCapacityPx: number\n followRevealScale: number\n followFollowing: boolean\n followConstrained: boolean\n scrollTop: number | null\n scrollHeight: number | null\n clientHeight: number | null\n lastUpdatedMs: number | null\n}\n\nexport interface DebugRuntimeState {\n available: boolean\n enabled: boolean\n writable: boolean\n dirty: boolean\n status: 'loading' | 'ready' | 'unavailable'\n tuning: StreamDebugTuning\n metrics: DebugMetrics\n}\n\nexport type DebugSettingsPatch = Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>\n\nexport interface DebugPanelFace {\n hooks: {\n debugRuntime: SnapshotStore<DebugRuntimeState>\n }\n edit: (patch: DebugSettingsPatch) => void\n save: () => void\n discard: () => void\n reset: () => void\n}\n\ninterface DebugSettingsActions {\n edit: (patch: DebugSettingsPatch) => void\n save: () => void\n discard: () => void\n}\n\ninterface StreamMetric {\n backlog: number\n speedCps: number\n targetChars: number\n displayedChars: number\n active: boolean\n updatedAt: number\n}\n\ninterface FollowMetric {\n lagPx: number\n velocityPxPerSec: number\n reservePx: number\n capacityPx: number\n revealScale: number\n following: boolean\n constrained: boolean\n scrollTop: number\n scrollHeight: number\n clientHeight: number\n active: boolean\n updatedAt: number\n}\n\nconst EMPTY_METRICS: DebugMetrics = {\n fps: null,\n frameMs: null,\n fpsDegraded: false,\n streamActive: false,\n streamBacklog: 0,\n streamSpeedCps: 0,\n streamTargetChars: 0,\n streamDisplayedChars: 0,\n followActive: false,\n followLagPx: 0,\n followVelocityPxPerSec: 0,\n followReservePx: 0,\n followCapacityPx: 0,\n followRevealScale: 1,\n followFollowing: false,\n followConstrained: false,\n scrollTop: null,\n scrollHeight: null,\n clientHeight: null,\n lastUpdatedMs: null,\n}\n\nconst INITIAL_STATE: DebugRuntimeState = {\n available: false,\n enabled: false,\n writable: false,\n dirty: false,\n status: 'loading',\n tuning: { ...DEFAULT_STREAM_DEBUG_TUNING },\n metrics: EMPTY_METRICS,\n}\n\nconst store = createSnapshotStore<DebugRuntimeState>(INITIAL_STATE)\nconst streamMetrics = new Map<string, StreamMetric>()\nconst followMetrics = new Map<HTMLElement, FollowMetric>()\nlet actions: DebugSettingsActions | undefined\nlet lastMetricPublish = 0\n\nfunction resetMetrics(): void {\n streamMetrics.clear()\n followMetrics.clear()\n lastMetricPublish = 0\n}\n\nfunction resetRuntime(): void {\n actions = undefined\n resetMetrics()\n store.set({ ...INITIAL_STATE, metrics: EMPTY_METRICS })\n}\n\nfunction now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n}\n\nfunction sameTuning(left: StreamDebugTuning, right: StreamDebugTuning): boolean {\n return left.revealScale === right.revealScale\n && left.queuePressure === right.queuePressure\n && left.maxRevealCps === right.maxRevealCps\n && left.springStiffness === right.springStiffness\n && left.springDamping === right.springDamping\n && left.springMass === right.springMass\n && left.runwayPx === right.runwayPx\n && left.reserveResponseMs === right.reserveResponseMs\n && left.backpressureMinScale === right.backpressureMinScale\n}\n\nfunction currentMetrics(timestamp: number): DebugMetrics {\n let stream: StreamMetric | undefined\n for (const candidate of streamMetrics.values()) {\n if (stream === undefined || candidate.updatedAt > stream.updatedAt) stream = candidate\n }\n let follow: FollowMetric | undefined\n for (const candidate of followMetrics.values()) {\n if (follow === undefined || candidate.updatedAt > follow.updatedAt) follow = candidate\n }\n return {\n fps: store.getSnapshot().metrics.fps,\n frameMs: store.getSnapshot().metrics.frameMs,\n fpsDegraded: store.getSnapshot().metrics.fpsDegraded,\n streamActive: stream?.active ?? false,\n streamBacklog: stream?.backlog ?? 0,\n streamSpeedCps: stream?.speedCps ?? 0,\n streamTargetChars: stream?.targetChars ?? 0,\n streamDisplayedChars: stream?.displayedChars ?? 0,\n followActive: follow?.active ?? false,\n followLagPx: follow?.lagPx ?? 0,\n followVelocityPxPerSec: follow?.velocityPxPerSec ?? 0,\n followReservePx: follow?.reservePx ?? 0,\n followCapacityPx: follow?.capacityPx ?? 0,\n followRevealScale: follow?.revealScale ?? 1,\n followFollowing: follow?.following ?? false,\n followConstrained: follow?.constrained ?? false,\n scrollTop: follow?.scrollTop ?? null,\n scrollHeight: follow?.scrollHeight ?? null,\n clientHeight: follow?.clientHeight ?? null,\n lastUpdatedMs: timestamp,\n }\n}\n\nfunction publishMetrics(force = false): void {\n const timestamp = now()\n if (!force && timestamp - lastMetricPublish < 80) return\n lastMetricPublish = timestamp\n store.set({ ...store.getSnapshot(), metrics: currentMetrics(timestamp) })\n}\n\nexport const debugRuntime = {\n store,\n\n getSnapshot(): DebugRuntimeState {\n return store.getSnapshot()\n },\n\n subscribe(listener: () => void): () => void {\n return store.subscribe(listener)\n },\n\n /** Whether hot-path instrumentation should do any work. */\n isEnabled(): boolean {\n return store.getSnapshot().enabled\n },\n\n tuning(): StreamDebugTuning {\n return store.getSnapshot().tuning\n },\n\n /** Production values remain untouched until the user explicitly enables diagnostics. */\n activeTuning(): StreamDebugTuning {\n return store.getSnapshot().enabled ? store.getSnapshot().tuning : DEFAULT_STREAM_DEBUG_TUNING\n },\n\n bindSettings(nextActions: DebugSettingsActions | undefined): () => void {\n actions = nextActions\n return () => {\n if (actions !== nextActions) return\n resetRuntime()\n }\n },\n\n syncSettings(input: {\n available?: boolean\n enabled: boolean\n writable: boolean\n dirty: boolean\n status: DebugRuntimeState['status']\n tuning?: StreamDebugTuning\n }): void {\n const current = store.getSnapshot()\n // Callers predating the Host capability flag are local diagnostics tests\n // and renderer probes; preserve their enabled behavior unless the wiring\n // explicitly reports that the RPC is unavailable.\n const available = input.available ?? true\n const enabled = available && input.enabled\n const availabilityChanged = current.available !== available\n const enabledChanged = current.enabled !== enabled\n if (availabilityChanged || enabledChanged) resetMetrics()\n const tuning = input.tuning === undefined\n ? current.tuning\n : { ...DEFAULT_STREAM_DEBUG_TUNING, ...input.tuning }\n if (\n current.available === available\n && current.enabled === enabled\n && current.writable === input.writable\n && current.dirty === input.dirty\n && current.status === input.status\n && sameTuning(current.tuning, tuning)\n ) return\n store.set({\n ...current,\n available,\n enabled,\n writable: input.writable,\n dirty: input.dirty,\n status: input.status,\n tuning,\n metrics: availabilityChanged || enabledChanged || !enabled ? EMPTY_METRICS : current.metrics,\n })\n },\n\n edit(patch: DebugSettingsPatch): void {\n const current = store.getSnapshot()\n const enabled = patch.debugEnabled ?? current.enabled\n const enabledChanged = current.enabled !== enabled\n if (enabledChanged) resetMetrics()\n const tuning = patch.debugTuning === undefined\n ? current.tuning\n : { ...current.tuning, ...patch.debugTuning }\n store.set({\n ...current,\n enabled,\n dirty: true,\n tuning,\n metrics: enabledChanged || !enabled ? EMPTY_METRICS : current.metrics,\n })\n actions?.edit({\n ...(patch.debugEnabled === undefined ? {} : { debugEnabled: patch.debugEnabled }),\n ...(patch.debugTuning === undefined ? {} : { debugTuning: tuning }),\n })\n },\n\n save(): void {\n actions?.save()\n },\n\n discard(): void {\n actions?.discard()\n },\n\n reset(): void {\n this.edit({ debugTuning: { ...DEFAULT_STREAM_DEBUG_TUNING } })\n },\n\n reportStream(id: string, metric: Omit<StreamMetric, 'updatedAt'> | null): void {\n if (!this.isEnabled()) return\n if (metric === null) streamMetrics.delete(id)\n else streamMetrics.set(id, { ...metric, updatedAt: now() })\n publishMetrics(metric === null)\n },\n\n reportFollow(port: HTMLElement, metric: Omit<FollowMetric, 'updatedAt'> | null): void {\n if (!this.isEnabled()) return\n if (metric === null) followMetrics.delete(port)\n else followMetrics.set(port, { ...metric, updatedAt: now() })\n publishMetrics(metric === null)\n },\n\n reportFps(fps: number, frameMs: number, degraded: boolean): void {\n if (!this.isEnabled()) return\n const current = store.getSnapshot()\n store.set({\n ...current,\n metrics: { ...current.metrics, fps, frameMs, fpsDegraded: degraded, lastUpdatedMs: now() },\n })\n },\n\n clearFps(): void {\n if (!this.isEnabled()) return\n const current = store.getSnapshot()\n store.set({\n ...current,\n metrics: {\n ...current.metrics,\n fps: null,\n frameMs: null,\n fpsDegraded: false,\n lastUpdatedMs: now(),\n },\n })\n },\n\n panelFace(): DebugPanelFace {\n return {\n hooks: { debugRuntime: store },\n edit: patch => { this.edit(patch) },\n save: () => { this.save() },\n discard: () => { this.discard() },\n reset: () => { this.reset() },\n }\n },\n\n resetRuntime(): void {\n resetRuntime()\n },\n}\n","/**\n * Conversation-port follow while an assistant reply streams.\n *\n * A sub-stepped spring physics engine drives a float `animatedH`, rather\n * than restarting native smooth-scroll animations as every glyph lands.\n * Remaining lag rides a small compositor transform while the real scrollport\n * stays at its floor. The transform is bounded by the measured paint gap\n * before conversation chrome. This follower:\n *\n * - marks programmatic writes via `data-follow-owned` for compatible hosts;\n * - sets `overflow-anchor: none` so CSS scroll-anchoring does not snap;\n * - restores `animatedH` in a ResizeObserver (before paint) so a layout\n * pass cannot flash a snapped frame;\n * - expresses safe lag as a compositor transform on message rows;\n * - opens a speed-adaptive layout runway before fast output wraps, preserving\n * the reference spring constants at every reveal speed;\n * - catches up any lag that cannot fit before turn status / composer chrome,\n * so fixed chrome never has to counter-shift and the host stays at-bottom;\n * - never clips or overlays streamed text.\n *\n * A real reader gesture receives the effective visual position before the\n * transform clears. Lifecycle completion instead settles at the floor.\n *\n * Directional wheel/touch intent unpins immediately; pointer/key input falls\n * back to an upward scroll delta from the engine's own written position. A\n * reader release re-acquires only after returning to the real floor.\n */\n\nimport { useLayoutEffect, useRef, type RefObject } from 'react'\nimport { DEFAULT_STREAM_DEBUG_TUNING, type StreamDebugTuning } from '../settings.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\n/**\n * Programmatic follow marker retained for hosts that recognize external\n * scroll ownership. Current Harness also sees the write land at the floor.\n */\nconst FOLLOW_OWNED_ATTR = 'data-follow-owned'\n\n/** Physics parameters from `ultimate_stream_physics_scroller.html`. */\nexport const FOLLOW_SPRING_STIFFNESS = 130\nexport const FOLLOW_SPRING_DAMPING = 24\nexport const FOLLOW_SPRING_MASS = 1\nexport const FOLLOW_SPRING_SUBSTEPS = 4\nexport const FOLLOW_SPRING_MAX_STEP_MS = 32\n\n/** Minimum visible room for one ordinary line-wrap impulse. */\nexport const FOLLOW_RESERVE_MIN_PX = 31\n\n/** Reveal speeds at or below this are idle; no predictive room is held. */\nexport const FOLLOW_RESERVE_IDLE_CPS = 20\n\n/** Reveal-speed range produced by the pressure-buffer typewriter. */\n/** Retained for consumers that tune the old pressure threshold. */\nexport const FOLLOW_RESERVE_MIN_CPS = 90\nexport const FOLLOW_RESERVE_MAX_CPS = 600\n\n/** Time constant for opening/closing predictive paint room. */\nexport const FOLLOW_RESERVE_RESPONSE_MS = 180\n\n/**\n * The reference engine clamps physical time to one 32ms visual interval.\n * Replaying a 250ms main-thread stall in one paint teleports the transcript;\n * leaving the remaining distance in the spring makes the next frames catch up\n * smoothly instead.\n */\nexport const FOLLOW_MAX_FRAME_MS = 32\n\n/** Retained as the neutral reveal-speed seed for follow hosts. */\nexport const FOLLOW_SPEED_REF_CPS = 35\n\n/** Reader-return / still-pinned boundary, matching ChatView + the demo. */\nexport const FOLLOW_SLACK_PX = 25\n\n/**\n * Fallback upward scroll distance that releases the pin when the browser does\n * not expose a directional wheel/touch event. Directional intent releases\n * immediately even if the follow write erases the small physical delta.\n */\nexport const FOLLOW_UNPIN_GESTURE_PX = 8\n\n/** A reader-released follow only re-acquires at the actual floor. */\nexport const FOLLOW_REPIN_PX = 1\n\n/** ChatView's <=25px bottom band remains host-pinned; release beyond it. */\nexport const FOLLOW_HOST_RELEASE_PX = FOLLOW_SLACK_PX + 1\n\n/** Sub-pixel paint guard before status/composer chrome. */\nexport const FOLLOW_PAINT_GUARD_PX = 1\n\n/**\n * Maximum predictive paint room before status/composer chrome. The\n * feed-forward phase leads the real floor by up to one wrapped line, so the\n * runway must hold steady lag + one line + guard (35 + 26 + 8 ≈ 72) or the\n * leading shift gets clipped against chrome at the wrap cadence.\n */\nexport const FOLLOW_STATUS_RUNWAY_PX = 72\n\n/**\n * Duration of completion runway retirement. The final pad is visible motion:\n * its shrinking floor brings the transcript down to its natural resting\n * position. 1.5s keeps the default 72px runway at 48px/s (0.8px per 60Hz\n * frame), matching the configured default reading-follow velocity instead of\n * the old 160ms / 450px/s staircase that looked like repeated completion\n * jumps.\n */\nexport const FOLLOW_RUNWAY_RETIRE_MS = 1500\n\n/** How long a gesture keeps `isUserInteracting` so the next scroll can unpin. */\nexport const FOLLOW_GESTURE_MS = 800\n\n/** Sub-pixel settle threshold; clearing below this cannot produce a visible rebound. */\nexport const FOLLOW_SETTLE_EPSILON_PX = 0.25\n\n/**\n * How long the completion settle waits for the HOST's completion cascade —\n * status-row swap, think auto-collapse, metrics-tail mount — to stop moving\n * the scroll extent before the follower releases the port. Releasing earlier\n * hands a still-changing layout to the host's hard floor-snap, which paints\n * each host action as a single-frame slam of the whole transcript.\n */\nexport const FOLLOW_SETTLE_QUIET_MS = 240\n\n/**\n * Ceiling for the flow's completion pad. The pad backs the floor so the\n * pinned viewport can follow the reading anchor through host completion\n * commits (row swaps/insertions); capping it bounds the below-fold blank\n * space a long conversation accumulates.\n */\nexport const FOLLOW_SETTLE_PAD_CAP_PX = 2 * FOLLOW_STATUS_RUNWAY_PX\n\n/** Retained visual-motion budget for compatibility with diagnostics/tests. */\nexport const FOLLOW_CATCHUP_MAX_STEP_PX = 8\n\n/**\n * Max painted-shift change per frame, in px. A line-wrap adds one line height\n * (24-28px) to the floor in a single layout pass; letting the shift follow it\n * instantly paints that whole step as a hard jump of the newest line. Capping\n * the shift's per-frame change spreads the step across a few frames so the\n * line glides in (slow start) instead of snapping.\n */\n/**\n * Per-frame bound on the DECAY side of the painted shift (runway retirement\n * and settle), widened by any same-frame floor drop so extent collapses are\n * always fully repainted — see the clamp site in `applyVisual`. The growth\n * side stays unlimited: it is wrap compensation locked to the same-frame\n * floor step.\n */\nexport const FOLLOW_PAINT_SHIFT_MAX_STEP_PX = 8\n\n/** Runway size emitted by bundles before the 72px predictive runway. */\nconst LEGACY_RUNWAY_PX = 48\n\n/** Lowest reveal rate retained while the spring is short on paint room. */\nexport const FOLLOW_REVEAL_MIN_SCALE = 0.55\n\n/** Safe-lag occupancy band over which reveal pressure is progressively reduced. */\nexport const FOLLOW_BACKPRESSURE_START_RATIO = 0.1\nexport const FOLLOW_BACKPRESSURE_FULL_RATIO = 0.75\n\n/** Slow release prevents the reveal rate from oscillating around each wrap. */\nexport const FOLLOW_BACKPRESSURE_RELEASE_MS = 240\n\n/** Effective-scroll acceleration budget, in px/ms². */\nexport const FOLLOW_TRAJECTORY_ACCELERATION = 0.00022\n\n/** Leave one line of phase range inside the visible runway. */\nexport const FOLLOW_TRAJECTORY_PHASE_PX = 32\n\n/** Keep adaptive runway retirement from exposing an oversized chrome gap. */\nexport const FOLLOW_TRAJECTORY_MIN_LAG_PX = 20\n\n/** Phase-centering response; slow enough to preserve continuous velocity. */\nexport const FOLLOW_TRAJECTORY_CENTERING_MS = 120\n\nconst GESTURE_EVENTS = [\n 'wheel',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'pointerdown',\n 'keydown',\n] as const\n\n/** Visible runway needed for the current reveal pressure. */\nexport function computeFollowReserve(\n speedCps: number,\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n): number {\n const available = Math.max(0, runwayPx)\n if (available <= 0) return 0\n if (speedCps <= FOLLOW_RESERVE_IDLE_CPS) return 0\n const normalized = Math.min(1, Math.max(0, (\n speedCps - FOLLOW_RESERVE_IDLE_CPS\n ) / (FOLLOW_RESERVE_MAX_CPS - FOLLOW_RESERVE_IDLE_CPS)))\n const minimum = Math.min(available, FOLLOW_RESERVE_MIN_PX)\n return minimum + normalized * (available - minimum)\n}\n\nexport interface FollowTrajectoryInput {\n readonly positionPx: number\n readonly velocityPxPerMs: number\n readonly targetPx: number\n readonly targetVelocityPxPerMs: number\n readonly minLagPx: number\n readonly maxLagPx: number\n /** Real scroll floor used to turn logical position into a painted shift. */\n readonly paintFloorPx?: number\n}\n\nexport interface FollowRevealPhaseOptions {\n readonly seedCharsPerLine?: number\n readonly seedLineHeightPx?: number\n}\n\nexport interface FollowRevealPhase {\n readonly targetPx: number\n readonly phase: number\n readonly charsPerLine: number\n readonly lineHeightPx: number\n}\n\n/**\n * Character-domain feed-forward for the stepped layout floor. Callers only\n * provide committed reveal progress and the measured floor; wrap capacity and\n * line height stay local to this module and adapt when a real wrap lands.\n */\nexport class FollowRevealPhaseTracker {\n private charsPerLine: number\n private lineHeightPx: number\n private floorPx: number | null = null\n private wrapRevealCount = 0\n private lastRevealCount = 0\n\n constructor({\n seedCharsPerLine = 50,\n seedLineHeightPx = 26,\n }: FollowRevealPhaseOptions = {}) {\n this.charsPerLine = Math.max(1, seedCharsPerLine)\n this.lineHeightPx = Math.max(1, seedLineHeightPx)\n }\n\n advance(floorPx: number, revealedChars: number): FollowRevealPhase {\n const nextFloor = Math.max(0, floorPx)\n const nextRevealCount = Math.max(0, revealedChars)\n if (this.floorPx === null || nextRevealCount < this.lastRevealCount) {\n this.floorPx = nextFloor\n this.wrapRevealCount = nextRevealCount\n this.lastRevealCount = nextRevealCount\n return this.snapshot(nextFloor, 0)\n }\n\n const floorDelta = nextFloor - this.floorPx\n const lineStepThreshold = Math.max(4, this.lineHeightPx * 0.5)\n if (floorDelta >= lineStepThreshold) {\n const wrappedLines = Math.max(1, Math.round(floorDelta / this.lineHeightPx))\n const sampledLineHeight = floorDelta / wrappedLines\n const revealedSinceWrap = nextRevealCount - this.wrapRevealCount\n if (revealedSinceWrap >= this.charsPerLine * 0.5) {\n const sampledCharsPerLine = revealedSinceWrap / wrappedLines\n const alpha = 0.25\n this.charsPerLine += (sampledCharsPerLine - this.charsPerLine) * alpha\n this.lineHeightPx += (sampledLineHeight - this.lineHeightPx) * alpha\n this.wrapRevealCount = nextRevealCount\n } else {\n // A flow sibling can grow without the text arm committing a glyph.\n // Treat that as an unrelated layout event so its height is not folded\n // into the next text-wrap capacity sample.\n this.wrapRevealCount = nextRevealCount\n }\n } else if (floorDelta <= -lineStepThreshold) {\n this.wrapRevealCount = nextRevealCount\n }\n\n this.floorPx = nextFloor\n this.lastRevealCount = nextRevealCount\n const phase = Math.min(1, Math.max(\n 0,\n (nextRevealCount - this.wrapRevealCount) / this.charsPerLine,\n ))\n return this.snapshot(nextFloor, phase)\n }\n\n private snapshot(floorPx: number, phase: number): FollowRevealPhase {\n return {\n targetPx: floorPx + this.lineHeightPx * phase,\n phase,\n charsPerLine: this.charsPerLine,\n lineHeightPx: this.lineHeightPx,\n }\n }\n}\n\n/** Advance a continuous effective scroll position behind a stepped floor. */\nexport function computeFollowTrajectoryStep(\n dtMs: number,\n input: FollowTrajectoryInput,\n): { positionPx: number, shiftPx: number, velocityPxPerMs: number } {\n if (dtMs <= 0) {\n return {\n positionPx: input.positionPx,\n shiftPx: Math.max(0, (input.paintFloorPx ?? input.targetPx) - input.positionPx),\n velocityPxPerMs: input.velocityPxPerMs,\n }\n }\n const elapsedMs = Math.min(FOLLOW_MAX_FRAME_MS, dtMs)\n const currentLagPx = input.targetPx - input.positionPx\n const maxLagPx = Math.max(0, input.maxLagPx)\n const minLagPx = Math.min(Math.max(0, input.minLagPx), maxLagPx)\n const centerLagPx = (minLagPx + maxLagPx) / 2\n const desiredVelocity = Math.max(\n 0,\n input.targetVelocityPxPerMs\n + (currentLagPx - centerLagPx) / FOLLOW_TRAJECTORY_CENTERING_MS,\n )\n const maxVelocityChange = FOLLOW_TRAJECTORY_ACCELERATION * elapsedMs\n const velocityPxPerMs = desiredVelocity >= input.velocityPxPerMs\n ? Math.min(desiredVelocity, input.velocityPxPerMs + maxVelocityChange)\n : Math.max(desiredVelocity, input.velocityPxPerMs - maxVelocityChange)\n const minPosition = input.targetPx - maxLagPx\n const maxPosition = input.targetPx - minLagPx\n // The frame budget follows controlled velocity rather than a refresh-rate\n // dependent pixel constant. `elapsedMs` is already capped at 32ms, so a\n // stalled browser cannot replay an unbounded jump when it catches up.\n const frameAdvancePx = velocityPxPerMs * elapsedMs\n const boundedPositionPx = Math.min(\n maxPosition,\n Math.max(minPosition, input.positionPx + frameAdvancePx),\n )\n const positionPx = Math.max(input.positionPx, boundedPositionPx)\n return {\n positionPx,\n shiftPx: Math.max(0, (input.paintFloorPx ?? input.targetPx) - positionPx),\n velocityPxPerMs,\n }\n}\n\n/**\n * Reveal-rate multiplier needed to retain one-wrap headroom for the spring.\n * Throttling starts only after a quarter of the safe transform is occupied;\n * a constrained paint lands at the minimum immediately so the next reveal\n * commit cannot keep feeding an already-full visual buffer.\n */\nexport function computeFollowRevealScale(\n lagPx: number,\n capacityPx: number,\n constrained = false,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): number {\n if (constrained) return tuning.backpressureMinScale\n if (!Number.isFinite(capacityPx)) return 1\n if (capacityPx <= 0) return lagPx > 0 ? tuning.backpressureMinScale : 1\n const ratio = Math.min(1, Math.max(0, lagPx / capacityPx))\n if (ratio >= FOLLOW_BACKPRESSURE_FULL_RATIO) return tuning.backpressureMinScale\n const progress = Math.min(1, Math.max(0, (\n ratio - FOLLOW_BACKPRESSURE_START_RATIO\n ) / (FOLLOW_BACKPRESSURE_FULL_RATIO - FOLLOW_BACKPRESSURE_START_RATIO)))\n const eased = progress * progress * (3 - 2 * progress)\n return 1 - (1 - tuning.backpressureMinScale) * eased\n}\n\nexport interface FollowGlideInput {\n /** How far the interpolated top trails the floor, in px. */\n readonly lag: number\n /** Observed reveal rate, retained for the public follow-step contract. */\n readonly speedEma: number\n /** Physics velocity carried from the previous frame, in px/s. */\n readonly velocityPxPerSec?: number\n}\n\nexport interface FollowGlideStep {\n /** Pixels to advance the floating content extent this frame. */\n readonly advancePx: number\n /** Applied lerp fraction, for tests. */\n readonly lerpStep: number\n /** Physics velocity to carry into the next frame, in px/s. */\n readonly velocityPxPerSec: number\n}\n\n/** Semi-implicit spring integration with four substeps per <=32ms slice. */\nexport function computeFollowStep(\n dtMs: number,\n input: FollowGlideInput,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): FollowGlideStep {\n if (input.lag <= 0.1 || dtMs <= 0) {\n return { advancePx: 0, lerpStep: 0, velocityPxPerSec: 0 }\n }\n let lag = input.lag\n let velocity = Math.max(0, input.velocityPxPerSec ?? 0)\n const elapsedMs = Math.min(FOLLOW_MAX_FRAME_MS, dtMs)\n const slices = Math.max(1, Math.ceil(elapsedMs / FOLLOW_SPRING_MAX_STEP_MS))\n const subDt = elapsedMs / 1000 / slices / FOLLOW_SPRING_SUBSTEPS\n for (let slice = 0; slice < slices; slice += 1) {\n for (let substep = 0; substep < FOLLOW_SPRING_SUBSTEPS; substep += 1) {\n const acceleration = (\n tuning.springStiffness * lag - tuning.springDamping * velocity\n ) / tuning.springMass\n velocity = Math.max(0, velocity + acceleration * subDt)\n const advance = velocity * subDt\n if (advance >= lag) return { advancePx: input.lag, lerpStep: 1, velocityPxPerSec: 0 }\n lag -= advance\n }\n }\n const advancePx = input.lag - lag\n return { advancePx, lerpStep: advancePx / input.lag, velocityPxPerSec: velocity }\n}\n\n/** Element whose resize signals flow growth for the before-paint restore. */\nfunction resizeProxyOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector('[data-chat-transcript]') ?? port.querySelector('[data-chat-flow]')\n}\n\n/**\n * Outermost message surfaces; nested tool rows ride their parent.\n *\n * Another plugin may insert its own element as a flow sibling of the Chat rows\n * (meow-memory's fold bar is one).\n * Such a row carries no `data-chat-anchor-key`, so selecting only anchored\n * rows would shift the conversation while leaving the foreign row at its\n * natural offset, letting the shifted rows paint over it. Every direct flow\n * child therefore rides the same transform, keeping the visual order of the\n * column intact.\n */\nexport function shiftSurfacesOf(port: HTMLElement): HTMLElement[] {\n const transcript = port.querySelector<HTMLElement>('[data-chat-transcript]')\n if (transcript !== null) return [transcript]\n const anchored = [...port.querySelectorAll<HTMLElement>('[data-chat-anchor-key]')]\n .filter(row => row.parentElement?.closest('[data-chat-anchor-key]') === null)\n const flow = port.querySelector<HTMLElement>('[data-chat-flow]')\n if (flow === null) return anchored\n const status = turnStatusOf(port)\n const anchoredSet = new Set(anchored)\n // One document-order pass: an anchored row, or a foreign child that contains\n // no anchored row of its own (a wrapper around real rows would double-shift\n // the rows inside it).\n return [...flow.children].filter((child): child is HTMLElement =>\n child instanceof HTMLElement\n && child !== status\n && (anchoredSet.has(child) || child.querySelector('[data-chat-anchor-key]') === null))\n}\n\nfunction currentShiftOf(element: HTMLElement): number {\n return Number(\n /translate3d\\(0(?:px)?,\\s*(-?[\\d.]+)px,\\s*0(?:px)?\\)/.exec(element.style.transform)?.[1] ?? 0,\n )\n}\n\n/* An open fixed tooltip (role=\"tooltip\") inside a surface is the only reason a\n * naive translate would misalign content during the follow shift: the applied\n * transform turns the surface into the tooltip's containing block and drags\n * the bubble off its anchor. Rather than re-derive viewport coordinates every\n * frame (a fragile engine that needed four follow-up fixes), hold the affected\n * surface untransformed while a tooltip is open. A tooltip exists in the DOM\n * only during hover, so the transient un-shifted row is invisible to a reader\n * and matches the release 0.4.0 feel; the shift resumes on the next frame once\n * it closes. */\n\nfunction setDirectShift(element: HTMLElement, px: number): void {\n if (Math.abs(px) > 0.01) {\n if (\n Math.abs(currentShiftOf(element) - px) <= 0.01\n && element.style.willChange === 'transform'\n && element.style.clipPath === ''\n ) return\n element.style.transform = `translate3d(0, ${px}px, 0)`\n element.style.willChange = 'transform'\n } else {\n if (element.style.transform === '' && element.style.willChange === '' && element.style.clipPath === '') return\n element.style.transform = ''\n element.style.willChange = ''\n }\n element.style.clipPath = ''\n}\n\nfunction setShift(element: HTMLElement, px: number): void {\n // Guard: while an open fixed tooltip lives on the surface, hold it\n // untransformed (see the comment above). When the shift is zero the tooltip\n // cannot detach, so skip the subtree scan entirely and keep the fast path.\n if (Math.abs(px) > 0.01 && element.querySelector('[role=\"tooltip\"]') !== null) {\n setDirectShift(element, 0)\n return\n }\n setDirectShift(element, px)\n}\n\nfunction turnStatusOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector<HTMLElement>(\n '[data-chat-turn-status], [data-chat-flow] > [role=\"status\"]',\n )\n}\n\n/**\n * Bottom-anchored hosts (ChatView packs the flow with `justify-content:\n * flex-end`) translate every pre-overflow growth into an instant upward step\n * of the whole column — a line lands and everything on screen hops up by one\n * line-height. No scroll-domain engine can smooth that, because\n * `scrollHeight` does not move while the host slack absorbs the growth.\n *\n * Owning `min-height` on the flow removes the slack instead: the column\n * always fills the scrollport, content grows downward where it is visible,\n * and real overflow — which the spring does model — begins with the very\n * first wrapped line. The style is owned in a page-realm registry so a\n * re-injected bundle adopts it rather than fighting it.\n *\n * The fill targets the VISIBLE client box, not the raw `clientHeight`.\n * Imposing `min-height: clientHeight` inflates `scrollHeight` by whatever\n * the scroller holds beyond the flow (its own padding-bottom, adjacent\n * chrome); with short content the engine then sees a phantom floor equal to\n * that padding and scrolls the conversation up — top edge off-screen while\n * blank padding sits at the bottom. The overshoot is measured once per port\n * and subtracted, so short content reaches `scrollHeight == clientHeight`\n * and the floor is exactly zero.\n */\ninterface FollowFlowFill {\n readonly element: HTMLElement\n readonly original: string\n /** Scroller height held by padding/chrome above the flow, px. */\n readonly overshootPx: number\n}\nconst FOLLOW_FLOW_FILL_SYMBOL = Symbol.for('dsh-smooth-stream.follow-flow-fill')\nconst followFlowFillHost = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, FollowFlowFill> | undefined\n}\nconst followFlowFills = followFlowFillHost[FOLLOW_FLOW_FILL_SYMBOL]\n ?? new WeakMap<HTMLElement, FollowFlowFill>()\nfollowFlowFillHost[FOLLOW_FLOW_FILL_SYMBOL] = followFlowFills\nconst FOLLOW_FLOW_FILL_USERS_SYMBOL = Symbol.for('dsh-smooth-stream.follow-flow-fill-users')\nconst followFlowFillUsersHost = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, number> | undefined\n}\nconst followFlowFillUsers = followFlowFillUsersHost[FOLLOW_FLOW_FILL_USERS_SYMBOL]\n ?? new WeakMap<HTMLElement, number>()\nfollowFlowFillUsersHost[FOLLOW_FLOW_FILL_USERS_SYMBOL] = followFlowFillUsers\n\nfunction flowElementOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector<HTMLElement>('[data-chat-transcript]')\n ?? port.querySelector<HTMLElement>('[data-chat-flow]')\n}\n\nfunction ensureFlowFillsPort(port: HTMLElement): void {\n const element = flowElementOf(port)\n const owned = followFlowFills.get(port)\n if (element === null) {\n if (owned !== undefined) restoreFlowFill(port)\n return\n }\n const client = Math.max(0, port.clientHeight)\n let overshoot = owned?.overshootPx\n if (overshoot === undefined) {\n // Measure once per port: impose the full fill, read the scrollHeight\n // excess (scroller padding / chrome), then restore the natural state.\n const pendingOriginal = element.style.minHeight\n element.style.minHeight = `${client}px`\n overshoot = Math.max(0, port.scrollHeight - client)\n element.style.minHeight = pendingOriginal\n if (owned !== undefined) restoreFlowFill(port)\n }\n const target = `${Math.max(0, client - overshoot)}px`\n if (owned !== undefined) {\n if (owned.element === element && owned.overshootPx === overshoot && element.style.minHeight === target) return\n restoreFlowFill(port)\n }\n const original = element.style.minHeight\n element.style.minHeight = target\n followFlowFills.set(port, { element, original, overshootPx: overshoot })\n}\n\nfunction restoreFlowFill(port: HTMLElement): void {\n const owned = followFlowFills.get(port)\n if (owned === undefined) return\n owned.element.style.minHeight = owned.original\n followFlowFills.delete(port)\n}\n\n/** Height committed by one newly mounted Chat row, including its flex gap. */\nfunction entranceExtentOf(root: HTMLElement): number {\n const row = root.closest<HTMLElement>('[data-chat-flow-key]') ?? root\n const rect = row.getBoundingClientRect()\n const height = Math.max(0, rect.height, rect.bottom - rect.top, row.offsetHeight)\n let previous = row.previousElementSibling\n while (previous instanceof HTMLElement) {\n const previousRect = previous.getBoundingClientRect()\n if (previousRect.height > 0 || previousRect.bottom > previousRect.top) {\n return Math.max(height, rect.bottom - previousRect.bottom)\n }\n previous = previous.previousElementSibling\n }\n return height\n}\n\ninterface FollowRunway {\n readonly element: HTMLElement\n readonly offset: number\n readonly original: string\n readonly property: 'marginBottom' | 'marginTop'\n readonly requestedPx: number\n readonly normalizedLegacy?: boolean\n}\n\n/**\n * The plugin can be reinjected without replacing the conversation DOM. Keep\n * runway ownership in the page realm so a fresh bundle adopts the existing\n * margin instead of treating it as host layout and adding another 48px.\n */\nconst FOLLOW_RUNWAYS_SYMBOL = Symbol.for('dsh-smooth-stream.follow-runways')\nconst followRunwayRegistry = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, FollowRunway> | undefined\n}\nconst followRunways = followRunwayRegistry[FOLLOW_RUNWAYS_SYMBOL]\n ?? new WeakMap<HTMLElement, FollowRunway>()\nfollowRunwayRegistry[FOLLOW_RUNWAYS_SYMBOL] = followRunways\n\ninterface FollowPaintLimit {\n readonly clientHeight: number\n readonly limit: number\n readonly measuredAtMs: number\n readonly composer: HTMLElement | null\n readonly status: HTMLElement | null\n readonly surface: HTMLElement | undefined\n}\n\n/**\n * A rect read can force a layout flush. At the floor the flow bottom sits on\n * the scrollport bottom, so while content streams the paint limit (chrome top\n * minus flow bottom) is constant; it only truly changes when the viewport or\n * conversation chrome changes. A measured limit therefore stays trusted for\n * this long even as contentHeight grows, so ordinary glyph frames never pay\n * a forced layout.\n */\nexport const FOLLOW_PAINT_LIMIT_TTL_MS = 250\n\nconst followPaintLimits = new WeakMap<HTMLElement, FollowPaintLimit>()\nconst followHadChrome = new WeakSet<HTMLElement>()\n/** Last painted shift per port, to spread a wrap's one-line step over frames. */\nconst followLastShiftPx = new WeakMap<HTMLElement, number>()\n/** Last settled floor per port, to size the shift decay bound against extent collapse. */\nconst followLastFloorPx = new WeakMap<HTMLElement, number>()\n/**\n * Screen-space completion anchor per port, SHARED by every follower arm and\n * the settle loop. Per-arm closures made the guard incoherent across the\n * completion cascade: block arms hand off leadership mid-turn, each new\n * settle loop re-seeded its own baseline at the already-jumped position, and\n * the cascade's one-frame clamp jump painted uncompensated. One baseline per\n * port also makes concurrent guards idempotent — whoever compensates first\n * restores the anchor, so the second measure reads ~0 and grants nothing.\n *\n * The anchor is the READING surface (the current turn's assistant row), not\n * the bottom-most shift surface: the cascade mounts/unmounts rows at the\n * column's bottom (process/tail mount, status swap), which switches\n * `at(-1)`'s identity mid-guard. Measuring across that switch reads a newly\n * mounted tail row as a >1000px \"content moved down\" push and floods the\n * pad, while the reading surface's real clamp jump goes uncompensated.\n */\ninterface FollowGuardAnchor {\n readonly element: HTMLElement\n /** Held viewport top — the position the reader should keep seeing. */\n readonly top: number\n /** Flow-child index, to tell an in-place replacement from a new turn. */\n readonly index: number\n /** Scroll geometry at store time, to identify an extent-neutral scroll. */\n readonly scrollTop: number\n readonly scrollHeight: number\n /**\n * Compositor shift and owned pad at store time. The engine moves the\n * rendered anchor between guard passes through TWO channels — the shift\n * glide (reveal decay: renderedΔ = −shiftΔ) and the pad retirement (the\n * floor sinks with the pad and the pin follows: renderedΔ = −padΔ). Only\n * the delta beyond BOTH is host motion worth compensating.\n */\n readonly shift: number\n readonly pad: number\n}\nconst followGuardAnchors = new WeakMap<HTMLElement, FollowGuardAnchor>()\n/**\n * Ports whose completion settle loop owns the follow. The settle drains the\n * reveal, retires the pad and guards the cascade; the swap that ends the\n * turn REMOUNTS the follower arms in the same frame cluster, and a freshly\n * mounted arm primes with a higher generation and would otherwise steal the\n * port mid-drain — its observers miss the cascade mutations (armed after\n * the fact) and its state initialization re-materializes engine space.\n * Ownership is released only when the settle finishes, the reader gestures,\n * or a genuinely NEW turn arrives (a user row joined since the handoff).\n */\nconst followCompletionSettle = new WeakSet<HTMLElement>()\n/** User-row count at handoff, for the new-turn check above. */\nconst followCompletionSettleRows = new WeakMap<HTMLElement, number>()\n\n/** User rows below the flow, or -1 when the host does not label rows with\n * `data-chat-flow-kind` (the engine's own audit benches): the new-turn\n * check is unsupported there and ownership guarding must stay OFF. */\nfunction countUserRows(port: HTMLElement): number {\n const flow = flowElementOf(port)\n if (flow === null) return -1\n let count = 0\n let sawKind = false\n for (const child of flow.children) {\n if (!(child instanceof HTMLElement)) continue\n const kind = child.getAttribute('data-chat-flow-kind')\n if (kind !== null) sawKind = true\n if (kind === 'user') count++\n }\n return sawKind ? count : -1\n}\n\n/** True while this port's completion settle owns the follow and no new turn\n * has arrived since the handoff. */\nfunction completionSettleGuardsPort(port: HTMLElement): boolean {\n if (!followCompletionSettle.has(port)) return false\n const baseline = followCompletionSettleRows.get(port) ?? -1\n const current = countUserRows(port)\n return baseline >= 0 && current >= 0 && current <= baseline\n}\n/**\n * Ports whose completion settle loop owns the follow. A settle loop drains,\n * retires the pad and guards the cascade; an arm that primes while this is\n * set with `active === false` (the settled-side static arm mounting in the\n * very swap frame) must NOT seize leadership — the swap re-renders the node\n * view, a fresh arm would otherwise steal the port mid-drain with\n * `reservePx = ownedBottomSpace` (the pad!), re-materialize an equal runway\n * through applyVisual, double-count the extent and fight the settle's own\n * guard for the rest of the window. A streaming arm (active === true, the\n * next turn) still takes over normally and the settle yields.\n */\n\nfunction readingAnchorOf(port: HTMLElement): HTMLElement | null {\n const flow = flowElementOf(port)\n if (flow === null) return null\n let anchor: HTMLElement | null = null\n for (const child of flow.children) {\n if (!(child instanceof HTMLElement)) continue\n if (child.getAttribute('data-chat-flow-kind') === 'assistant' || child.querySelector('[data-variant=\"think\"]') !== null) {\n anchor = child\n }\n }\n return anchor ?? shiftSurfacesOf(port).at(-1) ?? null\n}\n\n/**\n * Measure the reading surface's screen delta since the last guard pass.\n * Returns null when there is nothing comparable yet (first observation), or\n * when the anchor changed identity in a way that is NOT the in-place\n * live→settled replacement (a new turn's row joined — nothing jumped,\n * re-seed). Compensation sites must store the POST-compensation held\n * position via `holdGuardAnchor`, or the guard would read its own\n * correction as a fresh jump and oscillate.\n */\nfunction measureReadingAnchor(port: HTMLElement): { anchor: HTMLElement; index: number; top: number; delta: number } | null {\n const anchor = readingAnchorOf(port)\n if (anchor === null) {\n followGuardAnchors.delete(port)\n return null\n }\n const rect = anchor.getBoundingClientRect()\n // Unmeasurable geometry (jsdom's zero rects, a detached row): screen-space\n // comparison is meaningless — never seed or compensate from it.\n if (!(rect.width > 0 || rect.height > 0)) return null\n const top = rect.top\n const shift = currentShiftOf(anchor)\n const pad = flowPadOf(port)\n const scrollTop = port.scrollTop\n const scrollHeight = port.scrollHeight\n const flow = flowElementOf(port)\n const index = flow === null ? -1 : [...flow.children].indexOf(anchor)\n const stored = followGuardAnchors.get(port)\n if (stored === undefined) {\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n }\n // A host bottom-follow write is NOT a layout push. With extent unchanged, a\n // scrollTop change only moves the whole viewport; granting pad for it would\n // manufacture blank space and then require a second \"retirement\" motion.\n // Rebase both ledgers and let the writer keep its scroll position.\n if (\n Math.abs(scrollHeight - stored.scrollHeight) <= 0.5\n && Math.abs(scrollTop - stored.scrollTop) > 0.5\n ) {\n followScrollLedgers.set(port, scrollTop)\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n }\n // Host-caused motion only: the engine's own shift glide and floor changes\n // cancel out (renderedΔ = topΔ − shiftΔ + floorΔ).\n const delta = (top - stored.top) - (shift - stored.shift) + (pad - stored.pad)\n if (stored.element === anchor) {\n // Refresh the baseline to the current rendered position on every\n // measurement: between guard passes the viewport legitimately moves\n // (streaming pins, reveal glide), and a stale baseline would read the\n // accumulated motion as one giant host jump at the next commit.\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return { anchor, index, top, delta }\n }\n // Identity changed. An in-place replacement (same slot, old node detached)\n // is the live→settled swap: bridge it by holding the reading surface at\n // its pre-swap viewport position. Anything else (the next turn's row\n // joining below, a session swap) is new layout — re-seed, never hold.\n if (!stored.element.isConnected && stored.index === index) {\n return { anchor, index, top, delta }\n }\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n}\n\n/** Record the position the reader should keep seeing after a correction. */\nfunction holdGuardAnchor(\n port: HTMLElement,\n measured: { anchor: HTMLElement; index: number },\n heldTop: number,\n): void {\n followGuardAnchors.set(port, {\n element: measured.anchor,\n index: measured.index,\n top: heldTop,\n shift: currentShiftOf(measured.anchor),\n pad: flowPadOf(port),\n scrollTop: port.scrollTop,\n scrollHeight: port.scrollHeight,\n })\n}\n/** Last runway offset seen per port, to rebase the extent when the margin size changes. */\nconst followRunwayOffsetHistory = new WeakMap<HTMLElement, number>()\n/** Last observed scroll floor per port, for the slack→overflow runway re-measure. */\nconst followFloorHistory = new WeakMap<HTMLElement, number>()\n/** One-shot flag: the transition frame must paint the full runway as baseline. */\nconst followSlackTransition = new WeakSet<HTMLElement>()\n\n/**\n * Bottom padding a completed settle left BELOW the status row. The settle\n * retires the owned runway by moving it from the status's top margin (the\n * visible reserve gap) to the flow's bottom padding (space under the chrome):\n * scroll extent stays constant, so the floor — and therefore the pinned\n * scrollTop and every content pixel — never moves, while the status glides up\n * to meet the final line. The pad is reclaimed back into the next stream's\n * runway by `ensureRunway`, so completions never accumulate dead space.\n */\ninterface FollowSettlePad {\n readonly element: HTMLElement\n readonly original: string\n readonly px: number\n}\nconst followSettlePads = new WeakMap<HTMLElement, FollowSettlePad>()\n\n/**\n * Retired follower space lives as `padding-bottom` on the FLOW element — the\n * one node the engine already owns styles on (flow-fill min-height) and the\n * host never rewrites. Host completion commits routinely REPLACE row elements\n * (live→settled swap re-keys the assistant row, the status row unmounts), and\n * any engine space written on those rows dies with them, sinking the floor\n * and slamming the pinned transcript for a frame. The flow survives.\n */\nfunction flowPadOf(port: HTMLElement): number {\n return followSettlePads.get(port)?.px ?? 0\n}\n/**\n * After a loss is re-opened as pad, a registry entry whose element is no\n * longer connected claims extent that no longer exists; drop it so the next\n * `ensureRunway` re-measures fresh instead of double-counting.\n */\nfunction pruneDeadRunway(port: HTMLElement): boolean {\n const runway = followRunways.get(port)\n if (runway !== undefined && !runway.element.isConnected) {\n restoreRunway(port)\n return true\n }\n return false\n}\n\nfunction setFlowPad(port: HTMLElement, px: number): void {\n const flow = flowElementOf(port)\n if (flow === null) return\n const existing = followSettlePads.get(port)\n const original = existing?.original ?? flow.style.paddingBottom\n if (px <= FOLLOW_SETTLE_EPSILON_PX) {\n if (existing !== undefined) {\n flow.style.paddingBottom = existing.original\n followSettlePads.delete(port)\n }\n return\n }\n flow.style.paddingBottom = original === ''\n ? `${px}px`\n : `calc(${original} + ${px}px)`\n followSettlePads.set(port, { element: flow, original, px })\n}\n\n/** Extent the follower owns below the content: the live runway margin plus\n * the retired completion pad. At adopt the pad is reclaimed into the fresh\n * reservation (same frame, pre-paint), so the floor never steps. */\nfunction ownedBottomSpaceOf(port: HTMLElement): number {\n return runwayOffsetOf(port) + flowPadOf(port)\n}\n\n/**\n * Completion-window diagnostics. Armed when a follower hands off to its\n * settle loop; every engine decision and every externally-written scroll\n * position inside the window prints one compact console line, so a live\n * host session can be diffed against the lab without a debugger.\n */\nlet followTraceUntilMs = 0\nfunction traceActive(): boolean {\n // Completion/finalize paths arm short trace windows automatically. Keep the\n // code path in published bundles, but do not emit console noise unless the\n // user has explicitly turned on render diagnostics.\n return debugRuntime.isEnabled() && performance.now() < followTraceUntilMs\n}\nfunction followTrace(event: string, detail: Record<string, number | string | boolean>): void {\n if (!traceActive()) return\n console.log(`[dsh-follow] ${event}`, JSON.stringify(detail))\n}\nfunction hostShOf(port: HTMLElement): number {\n return port.scrollHeight\n}\n\nfunction invalidatePaintLimit(port: HTMLElement): void {\n followPaintLimits.delete(port)\n}\n\ninterface FollowMotionState {\n readonly capacityPx: number\n readonly constrained: boolean\n readonly extent: number\n readonly lagPx: number\n readonly reservePx: number\n readonly velocityPxPerSec: number\n}\n\n/** Logical position and velocity survive a React owner handoff and finish. */\nconst followMotionStates = new WeakMap<HTMLElement, FollowMotionState>()\n\n/**\n * Reader-release record that must survive an ownership handoff. A follower\n * closing at stream end (finish/drain arm swap, row lifecycle flip) destroys\n * the closure holding `following = false`, and the arm taking over would\n * otherwise read the held viewport as \"at bottom\" and hard-snap to the\n * floor. Presence in this map means the reader's unpin away from the floor\n * is still in effect; it is cleared when a follower re-pins at the floor.\n */\ninterface FollowReaderHold {\n readonly atMs: number\n}\nconst followReaderHolds = new WeakMap<HTMLElement, FollowReaderHold>()\n\n/**\n * Commit-time correction channel. A reveal commit that lands after this\n * frame's ResizeObserver delivery would otherwise paint one intermediate\n * frame — content grown, scrollTop/transform not yet compensated — before\n * the next tick fixes it. Reveal arms call {@link notifyFollowCommit} right\n * after their commit; the leading follower re-runs its geometry in the same\n * task, so the intermediate state never reaches a paint.\n */\nconst followCommitListeners = new WeakMap<HTMLElement, Set<() => void>>()\n\nexport function notifyFollowCommit(fromInsidePort: HTMLElement | null): void {\n if (fromInsidePort === null) return\n const port = fromInsidePort.closest<HTMLElement>('[data-conversation-scroll]')\n const listeners = port === null ? undefined : followCommitListeners.get(port)\n if (listeners === undefined) return\n for (const listener of [...listeners]) listener()\n}\n\nfunction subscribeFollowCommit(port: HTMLElement, fn: () => void): () => void {\n let listeners = followCommitListeners.get(port)\n if (listeners === undefined) {\n listeners = new Set()\n followCommitListeners.set(port, listeners)\n }\n listeners.add(fn)\n return () => { listeners!.delete(fn) }\n}\n\nfunction restoreRunway(port: HTMLElement): void {\n const runway = followRunways.get(port)\n if (runway === undefined) return\n runway.element.style[runway.property] = runway.original\n followRunways.delete(port)\n invalidatePaintLimit(port)\n}\n\nfunction isLegacyRunway(value: string): boolean {\n if (value === '') return false\n const terms = [...value.matchAll(/([\\d.]+)px/g)]\n if (terms.length === 0 || value.replaceAll(/calc|px|[\\d.+()\\s]/g, '') !== '') return false\n const values = terms.map(([, raw]) => Number(raw))\n if (values.some(px => !Number.isFinite(px))) return false\n return [LEGACY_RUNWAY_PX, FOLLOW_STATUS_RUNWAY_PX].some(unit => values.every(px => (\n px >= unit && Math.abs(px % unit) <= Number.EPSILON\n )))\n}\n\n/** Remove unowned runway residue written by v0.3.3 and earlier bundles. */\nfunction migrateLegacyRunway(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n status: HTMLElement | null,\n composer: HTMLElement | null,\n): boolean {\n if (followRunways.has(port)) return false\n let migrated = false\n if (status !== null && isLegacyRunway(status.style.marginTop)) {\n // Harness TurnStatus has no inline margin; exact 48px multiples here are\n // values emitted by the old runway writer, including reload accumulation.\n status.style.marginTop = ''\n migrated = true\n }\n const last = surfaces.at(-1)\n if (\n status === null\n && composer !== null\n && last !== undefined\n && isLegacyRunway(last.style.marginBottom)\n ) {\n // Without TurnStatus the old writer used the current final message as its\n // completion runway. Limit migration to that same target topology.\n last.style.marginBottom = ''\n migrated = true\n }\n if (migrated) invalidatePaintLimit(port)\n return migrated\n}\n\nfunction ensureRunway(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n): void {\n const status = turnStatusOf(port)\n const composer = port.querySelector<HTMLElement>('[data-composer-seat]')\n // Adopt one exact current runway before migration. Larger exact multiples\n // are accumulated residue from older bundles and must be stripped.\n if (status !== null && followRunways.get(port) === undefined) {\n const inlinePx = Number.parseFloat(status.style.marginTop ?? '') || 0\n if (Math.abs(inlinePx - FOLLOW_STATUS_RUNWAY_PX) <= 0.5) {\n followRunways.set(port, {\n element: status,\n offset: inlinePx,\n property: 'marginTop',\n original: '',\n requestedPx: inlinePx,\n })\n invalidatePaintLimit(port)\n }\n }\n const migratedLegacy = migrateLegacyRunway(port, surfaces, status, composer)\n // A runway is useful only after the natural conversation already has a\n // scroll floor for its equal message transform to ride. Before that point\n // applyVisual keeps every surface in normal flow, so adding status margin\n // would expose the whole runway as empty space below a short/early Think.\n const naturalHeight = Math.max(0, port.scrollHeight - runwayOffsetOf(port))\n const existing = followRunways.get(port)\n const requestedRunwayPx = migratedLegacy || existing?.normalizedLegacy === true\n ? FOLLOW_STATUS_RUNWAY_PX\n : runwayPx\n if (requestedRunwayPx <= 0 || port.clientHeight <= 0 || naturalHeight <= port.clientHeight) {\n restoreRunway(port)\n return\n }\n const target = status === null\n ? { element: composer === null ? undefined : surfaces.at(-1), property: 'marginBottom' as const }\n : { element: status, property: 'marginTop' as const }\n if (target.element === undefined) {\n restoreRunway(port)\n return\n }\n const element = target.element\n const current = followRunways.get(port)\n if (current?.element === element\n && current.property === target.property\n && current.requestedPx === requestedRunwayPx) return\n\n restoreRunway(port)\n const beforeHeight = port.scrollHeight\n const original = element.style[target.property]\n element.style[target.property] = original === ''\n ? `${requestedRunwayPx}px`\n : `calc(${original} + ${requestedRunwayPx}px)`\n const offset = Math.max(0, port.scrollHeight - beforeHeight)\n followRunways.set(port, {\n element,\n offset,\n property: target.property,\n original,\n requestedPx: requestedRunwayPx,\n normalizedLegacy: migratedLegacy || existing?.normalizedLegacy === true,\n })\n invalidatePaintLimit(port)\n}\n\nfunction runwayOffsetOf(port: HTMLElement): number {\n return followRunways.get(port)?.offset ?? 0\n}\n\n/**\n * Move owned runway margin into the persistent flow pad without changing the\n * scroll extent. Returns the actual layout pixels removed from the margin.\n */\nfunction transferRunwayToFlowPad(port: HTMLElement, requestedPx: number): number {\n const runway = followRunways.get(port)\n if (runway === undefined || requestedPx <= 0 || !runway.element.isConnected) return 0\n const nextRequestedPx = Math.max(0, runway.requestedPx - requestedPx)\n const beforeOffset = runway.offset\n const beforeHeight = port.scrollHeight\n runway.element.style[runway.property] = nextRequestedPx <= FOLLOW_SETTLE_EPSILON_PX\n ? runway.original\n : runway.original === ''\n ? `${nextRequestedPx}px`\n : `calc(${runway.original} + ${nextRequestedPx}px)`\n const nextOffset = Math.max(0, beforeOffset + port.scrollHeight - beforeHeight)\n const transferredPx = Math.max(0, beforeOffset - nextOffset)\n if (nextRequestedPx <= FOLLOW_SETTLE_EPSILON_PX || nextOffset <= FOLLOW_SETTLE_EPSILON_PX) {\n followRunways.delete(port)\n } else {\n followRunways.set(port, {\n ...runway,\n offset: nextOffset,\n requestedPx: nextRequestedPx,\n })\n }\n if (transferredPx > 0) {\n setFlowPad(port, flowPadOf(port) + transferredPx)\n invalidatePaintLimit(port)\n }\n return transferredPx\n}\n\n/** Available paint room below the last message before fixed conversation chrome. */\nfunction safeShiftLimit(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n): number {\n const last = surfaces.at(-1)\n if (last === undefined) return 0\n const status = turnStatusOf(port)\n const composer = port.querySelector<HTMLElement>('[data-composer-seat]')\n if (status !== null || composer !== null) followHadChrome.add(port)\n const cached = followPaintLimits.get(port)\n // Content growth alone cannot move the limit (measured at the floor, the\n // flow bottom rides the scrollport bottom), so the cache survives glyph\n // frames and only chrome/viewport changes or the TTL force a re-measure.\n if (\n cached !== undefined\n && performance.now() - cached.measuredAtMs <= FOLLOW_PAINT_LIMIT_TTL_MS\n && cached.clientHeight === port.clientHeight\n && cached.surface === last\n && cached.status === status\n && cached.composer === composer\n ) return cached.limit\n const ceiling = [status, composer]\n .filter((element): element is HTMLElement => element !== null)\n .map(element => ({ element, rect: element.getBoundingClientRect() }))\n // A detached or still-unmeasured sticky seat returns an all-zero rect.\n // It cannot constrain paint yet; a real seat at viewport top remains\n // valid because its bottom is still below its top.\n .filter(({ rect }) => Number.isFinite(rect.top) && Number.isFinite(rect.bottom) && rect.bottom > rect.top)\n .sort((first, second) => first.rect.top - second.rect.top)[0]\n if (ceiling === undefined) {\n // No conversation chrome means there is nothing to overlap. If chrome is\n // mounted but has not measured yet, permit only the runway zero-point\n // until ResizeObserver provides a real ceiling.\n return status === null && composer === null\n ? followHadChrome.has(port) ? 0 : Number.POSITIVE_INFINITY\n : runwayOffsetOf(port)\n }\n const ceilingTop = ceiling.rect.top - currentShiftOf(ceiling.element)\n const naturalBottom = last.getBoundingClientRect().bottom - currentShiftOf(last)\n const limit = Math.max(0, ceilingTop - naturalBottom - FOLLOW_PAINT_GUARD_PX)\n followPaintLimits.set(port, {\n clientHeight: port.clientHeight,\n limit,\n measuredAtMs: performance.now(),\n composer,\n status,\n surface: last,\n })\n return limit\n}\n\nfunction setFollowScrollTop(port: HTMLElement, nextTop: number): void {\n const ledger = followScrollLedgers.get(port)\n // Claim before the write so a Host ResizeObserver that runs in the same task\n // sees the owner instead of racing in with its own bottom-follow.\n if (port.getAttribute(FOLLOW_OWNED_ATTR) === null) {\n port.setAttribute(FOLLOW_OWNED_ATTR, 'active')\n }\n // Someone else wrote scrollTop since our last write (host floor-snap,\n // browser clamp, reader): surface it — a fight between the host's own\n // follow controller and this engine is the completion-jitter suspect.\n if (ledger !== undefined && traceActive() && Math.abs(port.scrollTop - ledger) > 1) {\n followTrace('external-scroll', { from: Math.round(port.scrollTop), to: Math.round(nextTop), ledger: Math.round(ledger) })\n }\n if (Math.abs(port.scrollTop - nextTop) > 0.01) port.scrollTop = nextTop\n followScrollLedgers.set(port, port.scrollTop)\n const ownedTop = String(port.scrollTop)\n if (port.getAttribute(FOLLOW_OWNED_ATTR) !== ownedTop) {\n port.setAttribute(FOLLOW_OWNED_ATTR, ownedTop)\n }\n}\n\n/**\n * Last scrollTop this engine wrote or accepted, per port. Reader intent is a\n * real upward delta from this ledger; a key press or touch while pinned\n * (typing in the composer) must not release the pin, because a released pin\n * can never re-acquire while content streams away from the reader position.\n */\nconst followScrollLedgers = new WeakMap<HTMLElement, number>()\nconst followActivityAt = new WeakMap<HTMLElement, number>()\ninterface FollowScrollOwnership {\n /** User-row count at handoff; a larger count means a genuinely new turn. */\n readonly userRows: number\n}\n/**\n * Scroll ownership must survive follower-arm remounts. Per-closure state let a\n * new text/tool arm reset the strike counter, so the same host write kept\n * triggering another engine write and repainting the visible up/down fight.\n */\nconst followHostScrollPorts = new WeakMap<HTMLElement, FollowScrollOwnership>()\n\n/** Clear host ownership only when a new user turn actually starts. */\nfunction resetHostScrollOwnershipForNewTurn(port: HTMLElement): void {\n const ownership = followHostScrollPorts.get(port)\n if (ownership === undefined) return\n const userRows = countUserRows(port)\n if (userRows >= 0 && userRows > ownership.userRows) followHostScrollPorts.delete(port)\n}\n\n/** Whether this port was owned recently enough to identify a closing tail row. */\nexport function hasRecentConversationFollow(port: HTMLElement, windowMs = 250): boolean {\n const last = followActivityAt.get(port)\n return last !== undefined && performance.now() - last <= windowMs\n}\n\nfunction readerScrolledUp(port: HTMLElement): boolean {\n return port.scrollTop < (followScrollLedgers.get(port) ?? 0) - FOLLOW_UNPIN_GESTURE_PX\n}\n\n/**\n * Paint a bounded visual lag and return the effective logical extent.\n *\n * This is the final geometry invariant, not merely an animation preference:\n * any lag beyond the real gap to status/composer chrome is caught up in the\n * same frame. Carrying that excess in `scrollTop` would move the transcript\n * toward fixed chrome and also make the host expose jump-to-bottom.\n */\nfunction applyVisual(\n port: HTMLElement,\n animatedH: number,\n reservePx: number,\n velocityPxPerSec = 0,\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n shiftCeilingPx = Number.POSITIVE_INFINITY,\n promoteAtRest = false,\n trajectoryShiftPx?: number,\n dtMs = 16.7,\n writeScrollTop = true,\n): number {\n const surfaces = shiftSurfacesOf(port)\n ensureFlowFillsPort(port)\n void runwayPx\n // A runway added while the column still fit the viewport was absorbed by\n // the host's bottom slack: its measured offset was zero, but once real\n // overflow begins the same margin costs scroll length. Detect that\n // transition BEFORE any geometry is read and re-add the margin so its\n // stored offset is measured against the true post-overflow layout.\n {\n const preFloor = Math.max(0, port.scrollHeight - port.clientHeight)\n const lastFloorSeen = followFloorHistory.get(port)\n if (lastFloorSeen !== undefined && lastFloorSeen === 0 && preFloor > 0 && followRunways.has(port)) {\n const owned = followRunways.get(port)\n restoreRunway(port)\n ensureRunway(port, surfaces, owned?.requestedPx ?? runwayPx)\n // This frame the margin materializes into scroll length AND lands in\n // the floor in the same write; painting the held reserve as baseline\n // would leave its px uncompensated on screen. Spend the full runway\n // as baseline for exactly this frame.\n followSlackTransition.add(port)\n }\n if (preFloor !== lastFloorSeen) {\n followFloorHistory.set(port, preFloor)\n }\n }\n ensureRunway(port, surfaces, reservePx)\n const contentHeight2 = Math.max(0, port.scrollHeight)\n const runwayOffset2 = runwayOffsetOf(port)\n // Rebase the spring extent onto the current offset domain. targetHeight\n // = contentHeight − offset AND animatedH live in the same space; when the\n // margin grows, targetHeight drops by the offset's growth, so animatedH\n // must drop in lockstep or the whole req (painted shift) is released as\n // an upward snap. Shifting both by the same delta leaves the painted\n // shift untouched.\n const prevOffset2 = followRunwayOffsetHistory.get(port)\n if (prevOffset2 !== undefined && runwayOffset2 !== prevOffset2) {\n animatedH = Math.max(0, animatedH - (runwayOffset2 - prevOffset2))\n }\n followRunwayOffsetHistory.set(port, runwayOffset2)\n const contentHeight = contentHeight2\n const runwayOffset = runwayOffset2\n const targetHeight = Math.max(0, contentHeight - runwayOffset)\n const floor = Math.max(0, contentHeight - port.clientHeight)\n const extent = Math.min(targetHeight, Math.max(0, animatedH))\n if (port.style.overflowAnchor !== 'none') port.style.overflowAnchor = 'none'\n if (port.style.scrollBehavior !== 'auto') port.style.scrollBehavior = 'auto'\n if (floor <= 0) {\n followRunwayOffsetHistory.set(port, 0)\n if (writeScrollTop) setFollowScrollTop(port, 0)\n followMotionStates.set(port, {\n capacityPx: Number.POSITIVE_INFINITY,\n constrained: false,\n extent: targetHeight,\n lagPx: 0,\n reservePx: 0,\n velocityPxPerSec: 0,\n })\n for (const surface of surfaces) setShift(surface, 0)\n followLastShiftPx.set(port, 0)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n return targetHeight\n }\n // The visible scroll position rides the spring's smooth extent so each newly\n // revealed line is approached at continuous velocity instead of snapping the\n // whole wrap into one frame (the residual \"不丝滑\" jump). `animatedH` advances\n // by the spring's bounded per-frame step; the newest ≤ `visibleReserve` lines\n // stay hidden below the fold in the runway while `scrollTop` glides up to\n // reveal them. Concretely: `scrollTop = floor − min(requestedLag, reserve)`,\n // so during fast typing scrollTop trails floor by at most one runway (≤ 2\n // lines) advancing smoothly at the spring cadence; when typing stops and lag\n // exhausts, scrollTop converges to the floor. The shift below still holds the\n // reserve so no per-wrap tail jump appears.\n const limit = safeShiftLimit(port, surfaces)\n followSlackTransition.delete(port)\n const visibleReserve = Math.min(runwayOffset, Math.max(0, reservePx))\n const baselineShift = runwayOffset - visibleReserve\n const requestedLag = Math.max(0, targetHeight - extent)\n // Steady-state tail pin: while the predictive reserve is held, paint the\n // shifted surfaces at a FIXED offset equal to the reserve, so the newest\n // revealed line rides at a constant viewport position and every wrap's reveal\n // lands below the fold inside that space — instead of translating the whole\n // message by the decaying per-reveal lag (which moved the newest line up/down\n // at reveal cadence = the residual \"轻微回弹来回\" jitter). The reserve is held\n // constant during streaming; only when it retires (entrance/settle) does the\n // shift glide with it. The spring still closes below the fold, and backpressure\n // reads the untranslated requestedLag so reveal pacing is unchanged.\n const availableShift = Math.min(\n Math.max(0, limit),\n Math.max(0, shiftCeilingPx),\n )\n const motionShift = Math.min(\n trajectoryShiftPx ?? baselineShift + requestedLag,\n availableShift,\n )\n const idlePromotion = promoteAtRest && motionShift <= 0.01 && availableShift > 0 ? 0.1 : 0\n let shift = Math.max(motionShift, idlePromotion)\n const previousShift = followLastShiftPx.get(port)\n // The per-frame decay bound paces the engine's OWN glide (the margin\n // transfer retires at well under 8px/frame, so the limiter never binds for\n // it). It must NOT cap the compensation for a floor the engine did not\n // choose: the host completion cascade (think auto-collapse, status swap)\n // collapses the extent tens of px in one frame, scrollTop follows the\n // floor 1:1, and a decay capped at 8px/frame leaves the unpainted\n // remainder on screen — the completion 回弹 (visible 14-26px/frame sink).\n // Widen the bound by the floor's drop so the shift can always repaint what\n // the extent took away; the retire glide is unaffected because its\n // motionShift never moves.\n const previousFloor = followLastFloorPx.get(port)\n const floorDropPx = Math.max(0, (previousFloor ?? floor) - floor)\n const maxDecayPx = Math.max(\n dtMs <= 0\n ? FOLLOW_PAINT_SHIFT_MAX_STEP_PX\n : Math.max(1, (FOLLOW_PAINT_SHIFT_MAX_STEP_PX / 16.67) * dtMs),\n floorDropPx,\n )\n followLastFloorPx.set(port, floor)\n if (previousShift !== undefined && shift < previousShift - maxDecayPx) {\n // Decay-only rate limit. Growth is a WRAP COMPENSATION: the floor already\n // jumped one line in the same layout pass and `scrollTop` followed it, so\n // the matching shift increase cancels that step exactly. Rate-limiting it\n // paints the uncovered remainder as a visible one-frame jump (the\n // \"换行 18px 跳变\"). Only the decay side — runway retirement and settle —\n // is a real animation and keeps its per-frame bound.\n shift = previousShift - maxDecayPx\n }\n // COMPLETION RISE FUNDING. In the completion window a shift rise is only\n // invisible when it cancels floor growth the reader actually gets. The\n // handoff re-opens the runway while the think disclosure is still\n // collapsing: a same-task paint funded on the measured extent growth\n // over-covers by whatever the transition retracts before the paint lands —\n // the drain-onset 回弹. Same-task painters are therefore ceiling-frozen\n // (see the observer and the handoff below) and this clamp funds the\n // settle's rAF-frame rise on the growth CONFIRMED since the previous\n // paint; a completion without a collapse covers the runway in full on the\n // first frame (the drain contract). The streaming path never enters this\n // branch — wrap compensation stays unlimited there.\n if (followCompletionSettle.has(port) && previousShift !== undefined && previousFloor !== undefined) {\n const confirmedGrowthPx = Math.max(0, floor - previousFloor)\n if (shift > previousShift + confirmedGrowthPx) shift = previousShift + confirmedGrowthPx\n }\n followLastShiftPx.set(port, shift)\n const requestedShift = trajectoryShiftPx ?? (baselineShift + requestedLag)\n const effectiveLag = Math.max(0, shift - baselineShift)\n const capacityPx = Math.max(0, limit - baselineShift)\n const effectiveExtent = targetHeight - effectiveLag\n const isConstrained = requestedShift > availableShift + FOLLOW_SETTLE_EPSILON_PX\n || (limit <= 0 && requestedShift > baselineShift)\n if (writeScrollTop) setFollowScrollTop(port, floor)\n followMotionStates.set(port, {\n capacityPx,\n constrained: isConstrained,\n extent: effectiveExtent,\n lagPx: effectiveLag,\n reservePx: visibleReserve,\n velocityPxPerSec,\n })\n for (const surface of surfaces) setShift(surface, shift)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n return effectiveExtent\n}\n\nfunction clearMotion(port: HTMLElement): void {\n port.removeAttribute(FOLLOW_OWNED_ATTR)\n port.style.overflowAnchor = ''\n port.style.scrollBehavior = ''\n for (const surface of shiftSurfacesOf(port)) setShift(surface, 0)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n}\n\nfunction clearVisual(port: HTMLElement): void {\n clearMotion(port)\n restoreRunway(port)\n followMotionStates.delete(port)\n followLastShiftPx.delete(port)\n followLastFloorPx.delete(port)\n invalidatePaintLimit(port)\n}\n\n/** Keep an already-promoted surface at zero until one stable final paint lands. */\nfunction holdCompositorAtRest(element: HTMLElement): void {\n element.style.transform = 'translate3d(0, 0px, 0)'\n element.style.willChange = 'transform'\n element.style.clipPath = ''\n}\n\n/** Remove equal offsets, land on the floor, then retire the compositor quietly. */\nfunction finishAtNaturalFloor(\n port: HTMLElement,\n retainCompositor = true,\n writeScrollTop = true,\n): void {\n followCompletionSettle.delete(port)\n followTraceUntilMs = Math.max(followTraceUntilMs, performance.now() + 10000)\n followTrace('finish-enter', { sh: hostShOf(port), st: Math.round(port.scrollTop), pad: Math.round(flowPadOf(port)), retain: retainCompositor })\n const surfaces = shiftSurfacesOf(port)\n const status = turnStatusOf(port)\n if (!retainCompositor) {\n restoreRunway(port)\n if (writeScrollTop) settleAtFloor(port)\n clearMotion(port)\n followMotionStates.delete(port)\n return\n }\n const promoted = [...surfaces, ...(status === null ? [] : [status])]\n .filter(element => element.style.transform !== '' || element.style.willChange === 'transform')\n const promotedSet = new Set(promoted)\n if (writeScrollTop) settleAtFloor(port)\n port.removeAttribute(FOLLOW_OWNED_ATTR)\n port.style.overflowAnchor = ''\n port.style.scrollBehavior = ''\n for (const surface of surfaces) {\n if (promotedSet.has(surface)) holdCompositorAtRest(surface)\n else setShift(surface, 0)\n }\n if (status !== null) {\n if (promotedSet.has(status)) holdCompositorAtRest(status)\n else setShift(status, 0)\n }\n followMotionStates.delete(port)\n if (promoted.length === 0) return\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n for (const element of promoted) {\n if (Math.abs(currentShiftOf(element)) <= 0.01) setShift(element, 0)\n }\n })\n })\n}\n\nfunction settleAtFloor(port: HTMLElement): void {\n const floor = Math.max(0, port.scrollHeight - port.clientHeight)\n setFollowScrollTop(port, floor)\n followReaderHolds.delete(port)\n}\n\ninterface FollowLeader {\n readonly generation: number\n readonly owner: object\n}\n\n/** Only the newest active follower may write one port's shared visual state. */\nconst followLeaders = new WeakMap<HTMLElement, FollowLeader>()\nlet followGeneration = 0\n/** Ports with a live streaming arm; completion guards must not fight them. */\nconst followActivePorts = new WeakSet<HTMLElement>()\n\n/**\n * Own the conversation scrollport's bottom-follow while `active` is true.\n *\n * @param rootRef - An element inside the conversation scrollport.\n * @param active - True while the reply is still revealing.\n * @param speedCpsRef - Live reveal-rate EMA from the smoother.\n * @param revealScaleRef - Optional backpressure control for text reveal.\n * @param predictive - Whether to reserve paint room ahead of growth.\n * @param entrance - Whether the first committed row height should glide in.\n * @param onEntranceSettled - Releases a one-shot entrance owner after catch-up.\n * @param predictiveRef - Optional live visibility gate for predictive runway.\n * @param entranceExtentRef - Optional measured growth delta for a generic row.\n * @param revealedCharsRef - Committed code-point count for feed-forward phase.\n * @param controlScroll - When false, leave the scrollport entirely to the Host.\n */\nexport function useConversationFollow(\n rootRef: RefObject<HTMLElement | null>,\n active: boolean,\n speedCpsRef: { current: number },\n revealScaleRef?: { current: number },\n predictive = true,\n entrance = false,\n onEntranceSettled?: () => void,\n predictiveRef?: { current: boolean },\n entranceExtentRef?: { current: number | null },\n revealedCharsRef?: { current: number },\n controlScroll = true,\n): void {\n const activeRef = useRef(active)\n const entranceRef = useRef(entrance)\n const onEntranceSettledRef = useRef(onEntranceSettled)\n entranceRef.current = entrance\n onEntranceSettledRef.current = onEntranceSettled\n activeRef.current = active\n const controlScrollRef = useRef(controlScroll)\n controlScrollRef.current = controlScroll\n\n useLayoutEffect(() => {\n if (!controlScroll) return\n if (!active) return\n const startedAsEntrance = entrance\n const owner = {}\n const generation = ++followGeneration\n let rafId = 0\n let last = performance.now()\n let following = true\n let primed = false\n let animatedH = 0\n let reservePx = 0\n let velocityPxPerSec = 0\n let interacting = false\n let readerGestureIntent = false\n let readerReleased = false\n let touchStartY: number | null = null\n let interactTimer: ReturnType<typeof setTimeout> | null = null\n let port: HTMLElement | null = null\n let resize: ResizeObserver | null = null\n let mutations: MutationObserver | null = null\n let observedTail: HTMLElement | null = null\n let statusWasPresent: boolean | null = null\n let lastStatusHeightPx = 0\n let trajectoryPositionPx: number | null = null\n let trajectoryVelocityPxPerMs = 0\n let trajectoryTargetVelocityPxPerMs = 0\n let trajectoryFloorPx: number | null = null\n let trajectoryGrowthAtMs: number | null = null\n let trajectoryAccumulatedGrowthPx = 0\n let trajectoryAccumulatedGrowthMs = 0\n let trajectoryGrowthSamples = 0\n let trajectoryWasActive = false\n const revealPhase = new FollowRevealPhaseTracker()\n let holding: HTMLElement | null = null\n let entrancePending = entranceRef.current\n\n const finishEntrance = (): void => {\n if (!entrancePending) return\n entrancePending = false\n onEntranceSettledRef.current?.()\n }\n\n const updateRevealScale = (next: HTMLElement, elapsedMs: number, urgent = false): void => {\n if (revealScaleRef === undefined) return\n const tuning = debugRuntime.activeTuning()\n const state = followMotionStates.get(next)\n const target = state === undefined\n ? 1\n : computeFollowRevealScale(state.lagPx, state.capacityPx, state.constrained, tuning)\n const current = Math.min(1, Math.max(tuning.backpressureMinScale, revealScaleRef.current))\n if (target < current || urgent) {\n // Slowing affects only future glyph commits, so it can react at once\n // without producing a visual discontinuity in the current frame.\n revealScaleRef.current = Math.min(current, target)\n return\n }\n const releaseStep = 1 - Math.exp(-Math.max(0, elapsedMs) / FOLLOW_BACKPRESSURE_RELEASE_MS)\n revealScaleRef.current = current + (target - current) * releaseStep\n }\n\n const releaseRevealScale = (): void => {\n if (revealScaleRef !== undefined) revealScaleRef.current = 1\n }\n\n const reportFollow = (next: HTMLElement, isActive: boolean): void => {\n const state = followMotionStates.get(next)\n debugRuntime.reportFollow(next, {\n // TEMP audit provenance: lagPx=-1 marks the fallback path (no motion\n // state owned by this reporter this frame).\n lagPx: state ? state.lagPx : -1,\n velocityPxPerSec: state?.velocityPxPerSec ?? 0,\n reservePx: state?.reservePx ?? 0,\n capacityPx: state ? state.capacityPx : -1,\n revealScale: revealScaleRef?.current ?? 1,\n following,\n constrained: state?.constrained ?? false,\n scrollTop: next.scrollTop,\n scrollHeight: next.scrollHeight,\n clientHeight: next.clientHeight,\n active: isActive,\n })\n }\n\n const isLeader = (next: HTMLElement): boolean => followLeaders.get(next)?.owner === owner\n\n const hold = (next: HTMLElement): void => {\n followActivityAt.set(next, performance.now())\n if (holding === next && isLeader(next)) return\n holding = next\n const leader = followLeaders.get(next)\n if ((leader === undefined || generation > leader.generation) && !completionSettleGuardsPort(next)) {\n followCompletionSettle.delete(next)\n followLeaders.set(next, { generation, owner })\n }\n }\n\n const yieldScrollOwnership = (next: HTMLElement, floor: number): void => {\n if (hostOwnsScroll) return\n hostOwnsScroll = true\n followHostScrollPorts.set(next, { userRows: countUserRows(next) })\n followTrace('yield-scroll', {\n from: Math.round(next.scrollTop),\n to: Math.round(floor),\n })\n // A host-owned port must be a clean host-owned render. Keeping the\n // engine's transform/reserve alive lets its decay fight the host's hard\n // bottom-follow; that is the visible up/down jitter after handoff.\n clearVisual(next)\n const naturalFloor = Math.max(0, next.scrollHeight - next.clientHeight)\n setFollowScrollTop(next, naturalFloor)\n next.removeAttribute(FOLLOW_OWNED_ATTR)\n followLeaders.delete(next)\n releaseRevealScale()\n debugRuntime.reportFollow(next, null)\n }\n\n const detectHostScroll = (next: HTMLElement, floor: number): void => {\n if (followHostScrollPorts.has(next)) {\n hostOwnsScroll = true\n return\n }\n const ledger = followScrollLedgers.get(next)\n if (ledger === undefined || Math.abs(next.scrollTop - ledger) <= 1) return\n // A write that lands on the current floor has the same semantics as our\n // own bottom-follow (including a manual jump-to-bottom or a shrink\n // clamp). Rebase and keep smoothing; treating it as a second writer\n // would permanently retire the effect for the rest of the turn.\n if (Math.abs(next.scrollTop - floor) <= 1) {\n followScrollLedgers.set(next, next.scrollTop)\n externalScrollStrikes = 0\n return\n }\n externalScrollStrikes += 1\n if (externalScrollStrikes >= 2) yieldScrollOwnership(next, floor)\n }\n\n const drop = (next: HTMLElement): void => {\n if (holding === next) holding = null\n if (isLeader(next)) {\n clearMotion(next)\n followMotionStates.delete(next)\n releaseRevealScale()\n debugRuntime.reportFollow(next, null)\n }\n }\n\n const handBackVisual = (next: HTMLElement): void => {\n const shift = currentShiftOf(shiftSurfacesOf(next).at(-1) ?? next)\n const transferableShift = shift > FOLLOW_SETTLE_EPSILON_PX ? shift : 0\n const visualTop = Math.max(0, next.scrollTop - transferableShift)\n // The predictive runway only has meaning while this follower owns the\n // floor. Remove it before choosing the reader's landing point; keeping\n // it through the release paints a transient natural gap + 48px blank\n // block until the next follow frame restores an equal transform.\n clearMotion(next)\n restoreRunway(next)\n const floor = Math.max(0, next.scrollHeight - next.clientHeight)\n // The host keeps its own bottom-follow bit while the reader remains in\n // its 25px slack band. Land one pixel beyond that band so even a light\n // wheel/trackpad/touch intent releases both owners on the same frame.\n next.scrollTop = Math.min(visualTop, Math.max(0, floor - FOLLOW_HOST_RELEASE_PX))\n followScrollLedgers.set(next, next.scrollTop)\n }\n\n const markGesture = (event: Event): void => {\n interacting = true\n if (event.type === 'wheel') {\n const deltaY = (event as WheelEvent).deltaY\n if (Number.isFinite(deltaY) && deltaY < 0) readerGestureIntent = true\n } else if (event.type === 'touchstart') {\n const touch = (event as TouchEvent).touches[0]\n touchStartY = touch?.clientY ?? null\n } else if (event.type === 'touchmove') {\n const touch = (event as TouchEvent).touches[0]\n if (touch !== undefined) {\n if (touchStartY === null) touchStartY = touch.clientY\n // A downward finger drag moves the transcript toward older content.\n if (touch.clientY - touchStartY > 1) readerGestureIntent = true\n }\n } else if (event.type === 'touchend' || event.type === 'touchcancel') {\n touchStartY = null\n }\n if (interactTimer !== null) clearTimeout(interactTimer)\n interactTimer = setTimeout(() => {\n interacting = false\n readerGestureIntent = false\n interactTimer = null\n }, FOLLOW_GESTURE_MS)\n }\n\n /**\n * Last observed scroll extent, shared by the pre-paint correction and the\n * settle loop so a host layout shrink is re-opened exactly once no matter\n * which observer sees it first. `-1` until the first owned observation.\n */\n let settleRetiring = false\n // The engine may lead streaming writes, but the host also owns a\n // bottom-follow controller. Ledger disagreement is harmless once; a\n // repeated disagreement is proof of a second writer. Hand the scrollport\n // to that writer immediately: the engine keeps compositor compensation but\n // never writes scrollTop again. This is the only way to avoid a ping-pong\n // fight when the host bundle does not consume `data-follow-owned`.\n let hostOwnsScroll = false\n let externalScrollStrikes = 0\n let lastReadingAnchorPullAtMs = Number.NEGATIVE_INFINITY\n let readingAnchorPullBudgetPx = 0\n // Set once this closure's completion handoff has armed its settle loop.\n // Only a handed-off arm's observers may guard a LEADERLESS port: mid-turn\n // arms that never handed off must keep standing down (entrance/steaming\n // successors own the port), while a handed-off arm whose settle loop was\n // killed by leadership churn is the only pre-paint guard left when the\n // completion cascade lands in the leaderless window.\n let handedOff = false\n /**\n * Bring the reading surface back down toward its held position after an\n * upward host push (clamp jump, live→settled swap): spend persistent pad\n * first — lowering the floor lets the pin carry the text back down —\n * then raise the compositor shift for whatever pad cannot cover, and\n * rebase the spring extent so the raise survives the next applyVisual\n * (which otherwise recomputes the shift from lag and undoes it).\n */\n const pullReadingAnchorBack = (\n host: HTMLElement,\n measured: { anchor: HTMLElement; index: number; top: number; delta: number },\n trace = false,\n ): void => {\n // Experimental no-rebound gate: an upward correction here has repeatedly\n // over/under-compensated against the settle loop's floor writes. Hold the\n // new position instead of issuing a reverse correction; the monotone\n // final retirement remains the only release path.\n holdGuardAnchor(host, measured, measured.top)\n return\n const need = -measured.delta\n // A large host shrink must not spend its whole pad in one paint. Keep\n // the screen anchored with an immediate shift, then hand the floor back\n // at the same bounded rate as the final retirement.\n const now = performance.now()\n const elapsedPx = lastReadingAnchorPullAtMs === Number.NEGATIVE_INFINITY\n ? FOLLOW_PAINT_SHIFT_MAX_STEP_PX\n : Math.min(24, Math.max(0, now - lastReadingAnchorPullAtMs) * (FOLLOW_PAINT_SHIFT_MAX_STEP_PX / 16.7))\n readingAnchorPullBudgetPx = Math.min(need, readingAnchorPullBudgetPx + elapsedPx)\n lastReadingAnchorPullAtMs = now\n const released = Math.min(flowPadOf(host), readingAnchorPullBudgetPx)\n readingAnchorPullBudgetPx -= released\n if (released > FOLLOW_SETTLE_EPSILON_PX) {\n if (trace) {\n followTrace('anchor-pull', { screenDelta: Math.round(measured.delta), released: Math.round(released), st: Math.round(host.scrollTop) })\n }\n setFlowPad(host, flowPadOf(host) - released)\n animatedH = Math.max(0, animatedH - released)\n }\n const remainder = need - released\n let raise = 0\n if (remainder > 0.5) {\n const surfaces = shiftSurfacesOf(host)\n const limit = safeShiftLimit(host, surfaces)\n const current = currentShiftOf(surfaces.at(-1) ?? host)\n const target = Math.min(current + remainder, Math.max(0, limit - FOLLOW_PAINT_GUARD_PX))\n raise = target - current\n if (raise > 0) {\n for (const surface of surfaces) setShift(surface, current + raise)\n followLastShiftPx.set(host, current + raise)\n animatedH = Math.max(0, animatedH - raise)\n }\n }\n holdGuardAnchor(host, measured, measured.top + released + raise)\n }\n /**\n * THE screen-space anchor hold, shared by every entry point: the\n * structural-observer path (pre-paint cascade correction), the settle\n * loop's per-frame poll, and the ACTIVE loop's per-frame poll. The\n * shift-excluded delta filters the engine's own motion (reveal glide,\n * wrap lockstep) to ~0, so a live poll may compensate safely — which is\n * what saves the completion swap: the settled-side arm primes in its\n * layout effect and steals leadership IN the cascade frame, its own\n * observers miss the mutations (armed after the fact), and only this\n * poll sees the jump while it can still be corrected before paint.\n * Returns the measured delta (null when nothing was comparable).\n */\n const enforceReadingAnchor = (host: HTMLElement, trace = false): number | null => {\n const measured = measureReadingAnchor(host)\n if (measured === null) return null\n if (measured.delta > 0.5) {\n if (trace) {\n followTrace('anchor-hold', { screenDelta: Math.round(measured.delta), st: Math.round(host.scrollTop) })\n }\n if (pruneDeadRunway(host)) reservePx = 0\n holdGuardAnchor(host, measured, measured.top)\n } else if (measured.delta < -0.5) {\n if (pruneDeadRunway(host)) reservePx = 0\n pullReadingAnchorBack(host, measured, trace)\n } else {\n holdGuardAnchor(host, measured, measured.top)\n }\n return measured.delta\n }\n /** Pre-paint correction (observers, commit subscription). */\n const restoreBeforePaint = (): void => {\n if (!following || port === null) return\n if (hostOwnsScroll || followHostScrollPorts.has(port)) {\n hostOwnsScroll = true\n followScrollLedgers.set(port, port.scrollTop)\n return\n }\n if (!activeRef.current) {\n detectHostScroll(port, Math.max(0, port.scrollHeight - port.clientHeight))\n }\n // Yield only to a LIVE owner. Block arms hand off leadership mid-turn\n // and each handoff kills the previous settle loop; the completion\n // cascade routinely lands in the leaderless window between that death\n // and the successor's first frame. Standing down whenever leadership is\n // merely absent left the cascade's clamp jump uncompensated. While\n // SOMEONE holds the port, the dead observers must not fight the live\n // guard; while NOBODY does, a handed-off arm's armed observer is the\n // only guard left, and the shared followGuardAnchors baseline keeps it\n // idempotent.\n const leaderless = !isLeader(port)\n if (!activeRef.current && followActivePorts.has(port)) return\n if (leaderless && (followLeaders.has(port) || !handedOff)) return\n // Leaderless window: this arm's closure state froze when its loop died.\n // Sync to the shared per-port motion ledger the last live loop wrote,\n // or the applyVisual below would replay stale extent/reserve into the\n // runway and pad ledgers while compensating the cascade.\n if (leaderless) {\n const sharedMotion = followMotionStates.get(port)\n if (sharedMotion !== undefined) {\n animatedH = Math.min(port.scrollHeight, Math.max(0, sharedMotion.extent))\n reservePx = sharedMotion.reservePx\n velocityPxPerSec = sharedMotion.velocityPxPerSec\n }\n }\n // A host keyed replacement can disconnect the element carrying our\n // margin before MutationObserver runs. Drop the stale registry entry;\n // banking it as pad preserves an extent that immediately becomes the\n // slow retirement rebound. The same-task ensureRunway / applyVisual path\n // reopens only the runway that is still needed.\n pruneDeadRunway(port)\n // HOST COMPLETION COMMITS under the pin must be corrected in THIS\n // pre-paint task: the settle loop's rAF guard runs after the host's own\n // follow effects, so a cascade commit (status swap, tail mount) would\n // otherwise paint one frame pinned to the sunk floor. The screen-space\n // anchor hold reads the shared per-port baseline (see\n // followGuardAnchors); it runs for structural commits only and stands\n // down while this settle's retirement glide runs (that motion is ours).\n if (!settleRetiring) {\n const measured = measureReadingAnchor(port)\n if (measured !== null && measured.delta > 0.5) {\n if (pruneDeadRunway(port)) reservePx = 0\n holdGuardAnchor(port, measured, measured.top)\n } else if (measured !== null && measured.delta < -0.5) {\n if (pruneDeadRunway(port)) reservePx = 0\n if (!activeRef.current) {\n // Completion window: pad first, then the shift raise absorbs\n // whatever pad cannot cover (the swap jump rides this path).\n pullReadingAnchorBack(port, measured)\n } else {\n // Live streaming: the original semantics — release only what the\n // pad holds and leave the remainder to the frame loop's own\n // lockstep. A shift raise here would cancel the reveal glide.\n const released = Math.min(flowPadOf(port), -measured.delta)\n if (released > FOLLOW_SETTLE_EPSILON_PX) {\n setFlowPad(port, flowPadOf(port) - released)\n animatedH = Math.max(0, animatedH - released)\n }\n holdGuardAnchor(port, measured, measured.top + released)\n }\n } else if (measured !== null) {\n holdGuardAnchor(port, measured, measured.top)\n }\n }\n // A reveal commit changes the measured tail, not the fixed chrome. Keep\n // the paint-limit TTL intact here; ResizeObserver and viewport/chrome\n // changes invalidate it when the cached geometry is no longer valid.\n // The same-task correction still runs, but ordinary glyph commits do not\n // force a fresh chrome rect read.\n const tuning = debugRuntime.activeTuning()\n const predictGrowth = predictiveRef?.current ?? predictive\n const floor = Math.max(0, port.scrollHeight - port.clientHeight)\n // A wrap or other layout growth changes the real floor and may change the\n // natural tail clearance. Re-measure that boundary; same-floor glyph\n // commits can continue using the cached chrome geometry.\n if (followFloorHistory.get(port) !== floor) invalidatePaintLimit(port)\n const isReasoningSurface = rootRef.current?.querySelector('[data-variant=\"think\"]') !== null\n const trajectoryShift = predictive\n && !isReasoningSurface\n && runwayOffsetOf(port) > 0\n && trajectoryPositionPx !== null\n ? floor - trajectoryPositionPx\n : undefined\n animatedH = applyVisual(\n port,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n // COMPLETION RISE FREEZE: this observer runs in the mutation's\n // microtask, but the paint lands one vsync later — extent a CSS\n // transition retracts in between makes any rise funded here\n // over-cover by exactly that retraction (the drain-onset 回弹).\n // Freeze rises same-task; the settle's rAF frame re-reads the floor\n // within its own paint tick and funds the confirmed growth there.\n activeRef.current\n ? Number.POSITIVE_INFINITY\n : (followLastShiftPx.get(port) ?? Number.POSITIVE_INFINITY),\n !predictGrowth,\n trajectoryShift,\n 0,\n activeRef.current && !hostOwnsScroll,\n )\n if (trajectoryShift !== undefined) {\n const currentShift = followLastShiftPx.get(port) ?? (floor - (trajectoryPositionPx ?? floor))\n trajectoryPositionPx = floor - currentShift\n }\n updateRevealScale(port, 0, true)\n reportFollow(port, activeRef.current)\n // Host ChatView ResizeObservers may run after this observer and hard-snap\n // to its floor. Re-apply the owned floating top in the same microtask,\n // before the browser's next paint, while scroll-event capture prevents a\n // programmatic write from changing the reader's at-bottom state.\n }\n\n // Same correction, run synchronously with a reveal commit (see\n // notifyFollowCommit above). Subscribed per-port in bindPort.\n let unsubscribeCommit: (() => void) | null = null\n\n const bindPort = (next: HTMLElement): void => {\n if (port === next) return\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n resize?.disconnect()\n mutations?.disconnect()\n }\n unsubscribeCommit?.()\n port = next\n invalidatePaintLimit(port)\n unsubscribeCommit = subscribeFollowCommit(port, () => { restoreBeforePaint() })\n for (const name of GESTURE_EVENTS) {\n port.addEventListener(name, markGesture, { passive: true })\n }\n if (typeof ResizeObserver !== 'undefined') {\n resize = new ResizeObserver(() => restoreBeforePaint())\n resize.observe(port)\n const proxy = resizeProxyOf(port)\n if (proxy !== null) resize.observe(proxy)\n }\n // Completion is chiefly a child-list transaction (status removal,\n // live-to-settled replacement, tail insertion). Because following\n // gives the flow a viewport min-height, those mutations can leave the\n // flow's border box unchanged and never notify ResizeObserver. Observe\n // the transaction itself so the anchor hold still runs before paint.\n if (typeof MutationObserver !== 'undefined') {\n const flow = flowElementOf(port)\n if (flow !== null) {\n mutations = new MutationObserver(() => { restoreBeforePaint() })\n mutations.observe(flow, { childList: true, subtree: true })\n }\n }\n }\n\n /**\n * Keep the observer on the flow's TAIL surface. A flow locked to the\n * viewport by min-height does not resize when content grows inside it —\n * only the last message row does, and missing that resize means missing\n * the pre-paint correction for that frame's wrap.\n */\n const observeTailSurface = (): void => {\n if (resize === null || port === null) return\n const tail = shiftSurfacesOf(port).at(-1) ?? null\n if (tail === observedTail) return\n if (observedTail !== null) resize.unobserve(observedTail)\n observedTail = tail\n if (tail !== null) resize.observe(tail)\n }\n\n const frame = (now: number) => {\n rafId = requestAnimationFrame(frame)\n // Spring time is clamped so one paint after a stall cannot teleport the\n // transcript. Runway response uses real elapsed time, otherwise long\n // frames would open paint room more slowly precisely when it is needed.\n const elapsedMs = Math.max(0.001, now - last)\n const dt = Math.min(FOLLOW_MAX_FRAME_MS, elapsedMs)\n const tuning = debugRuntime.activeTuning()\n last = now\n const root = rootRef.current\n if (root === null) return\n const nextPort = root.closest<HTMLElement>('[data-conversation-scroll]')\n if (nextPort === null) return\n bindPort(nextPort)\n observeTailSurface()\n resetHostScrollOwnershipForNewTurn(nextPort)\n hostOwnsScroll = followHostScrollPorts.has(nextPort)\n if (activeRef.current) followActivePorts.add(nextPort)\n else followActivePorts.delete(nextPort)\n // A hidden/unmeasured port has no meaningful floor yet. Keep this owner\n // unprimed and let the already-scheduled RAF initialize it after layout.\n if (nextPort.clientHeight <= 0) return\n\n const floor = Math.max(0, nextPort.scrollHeight - nextPort.clientHeight)\n const reportedLag = floor - nextPort.scrollTop\n const extent = Math.min(\n nextPort.scrollHeight,\n Math.max(0, nextPort.scrollHeight - reportedLag),\n )\n\n if (!primed) {\n // A completion settle owns this port (the swap remounted this arm in\n // the same frame cluster): stay a passive watcher. Taking over here\n // would zero the pad mid-retirement and re-inherit it as reserve —\n // double-counting the extent for one giant jump.\n if (completionSettleGuardsPort(nextPort)) {\n primed = true\n following = false\n return\n }\n const inherited = nextPort.hasAttribute(FOLLOW_OWNED_ATTR)\n ? followMotionStates.get(nextPort)\n : undefined\n if (inherited === undefined) {\n // A new Agent row is already part of scrollHeight on its first\n // frame. Start at the pre-insert extent so that initial Context and\n // Tool chrome enters through the same spring as later height growth.\n // The predictive runway starts pre-opened at the current reveal\n // pressure: it rides canceled by the equal transform, and waiting\n // out the response ramp would leave the first wraps unpinned.\n const entranceExtent = entrancePending\n ? entranceExtentRef?.current ?? entranceExtentOf(root)\n : 0\n const predictGrowth = predictiveRef?.current ?? predictive\n // Start the entrance at the pre-insert extent, not the raw reported\n // lag: holding the reader's small first-frame offset here would keep\n // the entrance lag above the settle epsilon for ~a second (the\n // spring's advance at single-digit lag is sub-pixel), leaving the\n // entrance arm alive past a settled swap and deferring the\n // completion settle until it finally closes.\n animatedH = entrancePending\n ? Math.max(0, nextPort.scrollHeight - entranceExtent)\n : nextPort.scrollHeight\n // Established before first paint; the matching margin below is\n // written in the same commit, so this held-and-canceled space\n // never moves a pixel.\n const hasStatus = turnStatusOf(nextPort) !== null\n // ZERO-DOWNWARD-REBOUND: the reservation must never land below the\n // margin this port already owns. base = margin − reservation is the\n // painted shift; a reservation smaller than the owned margin would\n // repaint the difference as an instant downward step on this arm's\n // first frame. The margin stays owned (see the growth-only rule in\n // the frame loop), so the reservation opens at least to match it.\n reservePx = Math.max(\n ownedBottomSpaceOf(nextPort),\n predictGrowth && (hasStatus || speedCpsRef.current > FOLLOW_RESERVE_MIN_CPS)\n ? computeFollowReserve(speedCpsRef.current, tuning.runwayPx)\n : 0,\n )\n // Adopt-time reclaim, exactly once and in this same pre-paint task:\n // the previous completion's pad becomes this stream's reserve gap,\n // so the extent — and the pinned floor — never steps between turns.\n // A completion settle still owning the port keeps its ledgers: the\n // swap's remounted arms must not zero the pad mid-retirement.\n if (!completionSettleGuardsPort(nextPort)) setFlowPad(nextPort, 0)\n statusWasPresent = hasStatus\n velocityPxPerSec = 0\n // The committed row/growth delta has already moved the new floor.\n // Decide ownership from READER INTENT EVIDENCE, not raw lag: an\n // upward move recorded past our own ledger is a pull-up; anything\n // else (content that mounted while the host had not re-pinned yet,\n // a completion clamp, first-frame geometry) must keep following,\n // otherwise the whole stream falls back to the host's hard snap.\n void reportedLag\n // A prior follower's reader-release record outranks ledger\n // evidence: its closure died with `following = false` after the\n // release already reset the ledger to the held position, so the\n // delta-based check alone can no longer see the unpin.\n following = !readerScrolledUp(nextPort)\n && !followReaderHolds.has(nextPort)\n } else {\n animatedH = Math.min(nextPort.scrollHeight, inherited.extent)\n reservePx = inherited.reservePx\n velocityPxPerSec = inherited.velocityPxPerSec\n following = true\n }\n if (following) {\n hold(nextPort)\n if (isLeader(nextPort)) {\n animatedH = applyVisual(\n nextPort,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n Number.POSITIVE_INFINITY,\n !(predictiveRef?.current ?? predictive),\n undefined,\n 0,\n !hostOwnsScroll,\n )\n if (\n predictive\n && root.querySelector('[data-variant=\"think\"]') === null\n && runwayOffsetOf(nextPort) > 0\n ) {\n const floor = Math.max(0, nextPort.scrollHeight - nextPort.clientHeight)\n const requestedMinLagPx = Math.max(\n FOLLOW_TRAJECTORY_MIN_LAG_PX,\n runwayOffsetOf(nextPort) - FOLLOW_TRAJECTORY_PHASE_PX,\n )\n const paintMaxLagPx = Math.max(0, safeShiftLimit(nextPort, shiftSurfacesOf(nextPort)) - FOLLOW_PAINT_GUARD_PX)\n const minLagPx = Math.min(requestedMinLagPx, paintMaxLagPx)\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n trajectoryPositionPx = floor - Math.min(paintMaxLagPx, Math.max(minLagPx, currentShift))\n trajectoryTargetVelocityPxPerMs = Math.max(0, speedCpsRef.current) * 0.4 / 1000\n trajectoryVelocityPxPerMs = trajectoryTargetVelocityPxPerMs\n trajectoryFloorPx = floor\n trajectoryGrowthAtMs = now\n trajectoryAccumulatedGrowthPx = 0\n trajectoryAccumulatedGrowthMs = 0\n trajectoryGrowthSamples = 0\n trajectoryWasActive = true\n }\n updateRevealScale(nextPort, elapsedMs)\n reportFollow(nextPort, activeRef.current)\n const runwayOffset = runwayOffsetOf(nextPort)\n const entranceLag = Math.max(0, nextPort.scrollHeight - animatedH - runwayOffset)\n if (entranceLag <= FOLLOW_SETTLE_EPSILON_PX) finishEntrance()\n } else {\n finishEntrance()\n }\n } else {\n finishEntrance()\n }\n primed = true\n return\n }\n\n const repinSlack = readerReleased ? FOLLOW_REPIN_PX : FOLLOW_SLACK_PX\n const returnedToFloor = readerReleased\n && !readerGestureIntent\n && reportedLag <= FOLLOW_REPIN_PX\n if (!following && (!interacting || returnedToFloor) && reportedLag <= repinSlack) {\n following = true\n readerReleased = false\n followReaderHolds.delete(nextPort)\n animatedH = extent\n reservePx = 0\n velocityPxPerSec = 0\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n hold(nextPort)\n } else if (following && interacting && (readerGestureIntent || readerScrolledUp(nextPort))) {\n // Directional wheel/touch intent is authoritative even when automatic\n // follow has already overwritten the small physical scroll delta.\n following = false\n readerGestureIntent = false\n readerReleased = true\n followReaderHolds.set(nextPort, { atMs: performance.now() })\n handBackVisual(nextPort)\n animatedH = nextPort.scrollHeight\n reservePx = 0\n velocityPxPerSec = 0\n drop(nextPort)\n finishEntrance()\n }\n\n if (!activeRef.current || !following) {\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n reportFollow(nextPort, activeRef.current)\n return\n }\n detectHostScroll(nextPort, floor)\n if (hostOwnsScroll) {\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n reportFollow(nextPort, false)\n return\n }\n hold(nextPort)\n if (!isLeader(nextPort)) {\n finishEntrance()\n return\n }\n // Runway and an equal transform cancel visually. It is the zero point,\n // not residual motion: decaying below it would scroll past the final\n // resting position and rebound when runway is removed.\n //\n // The reservation scales with reveal pressure — idle holds nothing,\n // because speculative space at rest is a visible defect on handback —\n // but the runway MARGIN tracks the reservation 1:1 in the same frame,\n // so their difference (the only part that can move pixels) stays\n // constant. Growing the reservation without the margin would glide the\n // whole column; growing both together is invisible.\n const predictGrowth = predictiveRef?.current ?? predictive\n const statusElement = turnStatusOf(nextPort)\n const hasStatus = statusElement !== null\n if (statusElement !== null) lastStatusHeightPx = statusElement.offsetHeight\n const statusJustRemoved = predictGrowth && statusWasPresent === true && !hasStatus\n if (statusJustRemoved) {\n // The dying status row takes its own layout height AND the margin\n // riding on it out of the scroll extent in one commit. Re-open the\n // margin on the next surface in the same frame, sized to cover both,\n // or the floor sinks by that height and the transcript slides down\n // under the pin before the replacement margin can land.\n reservePx = Math.max(reservePx, tuning.runwayPx) + lastStatusHeightPx\n }\n statusWasPresent = hasStatus\n const reserveEnabled = hasStatus\n || statusJustRemoved\n || reservePx > FOLLOW_SETTLE_EPSILON_PX\n || speedCpsRef.current > FOLLOW_RESERVE_MIN_CPS\n const pressureReserveTarget = predictGrowth && reserveEnabled\n ? computeFollowReserve(speedCpsRef.current, tuning.runwayPx)\n : 0\n // ZERO-DOWNWARD-REBOUND (root cause): while this follower owns the port\n // it pins scrollTop to the floor, and the floor rides the owned bottom\n // margin 1:1. Shrinking that margin under the pin clamps scrollTop\n // downward and slides the whole transcript down — the one motion this\n // module must never paint; no shift remains to release it because the\n // reservation already covers the margin (base = margin − reservation\n // stays flat). An owned margin therefore only GROWS here: prediction\n // shutdown and reveal-pressure drops freeze it at its current size, and\n // retirement is deferred to reader handback (a user-driven scroll) or\n // the next ownership. Growth stays invisible because the reservation\n // grows in the same frame and the baseline difference never moves.\n const effectiveReserveTarget = Math.max(reservePx, pressureReserveTarget)\n const reserveStep = 1 - Math.exp(-elapsedMs / tuning.reserveResponseMs)\n reservePx += (effectiveReserveTarget - reservePx) * reserveStep\n if (predictGrowth || runwayOffsetOf(nextPort) > 0.5) {\n ensureRunway(nextPort, shiftSurfacesOf(nextPort), reservePx)\n }\n const runwayOffset = runwayOffsetOf(nextPort)\n const contentHeight = nextPort.scrollHeight\n const floorNow = Math.max(0, contentHeight - nextPort.clientHeight)\n const trajectoryActive = predictive\n && root.querySelector('[data-variant=\"think\"]') === null\n && runwayOffset > 0\n let trajectoryShift: number | undefined\n if (trajectoryActive) {\n const requestedMinLagPx = Math.max(\n FOLLOW_TRAJECTORY_MIN_LAG_PX,\n runwayOffset - FOLLOW_TRAJECTORY_PHASE_PX,\n )\n // Phase-band upper bound comes from paint space, not a runway-derived\n // constant: `minLag + 39` can exceed the real gap to status/composer\n // chrome and get clipped into a hard catch-up exactly at the wrap\n // cadence the band exists to absorb (see docs §3.1).\n const paintLimit = safeShiftLimit(nextPort, shiftSurfacesOf(nextPort))\n const maxLagPx = Math.max(0, paintLimit - FOLLOW_PAINT_GUARD_PX)\n const minLagPx = Math.min(requestedMinLagPx, maxLagPx)\n if (trajectoryPositionPx === null || trajectoryFloorPx === null) {\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n trajectoryPositionPx = floorNow - Math.min(maxLagPx, Math.max(minLagPx, currentShift))\n trajectoryTargetVelocityPxPerMs = Math.max(0, speedCpsRef.current) * 0.4 / 1000\n trajectoryVelocityPxPerMs = trajectoryTargetVelocityPxPerMs\n trajectoryGrowthAtMs = now\n } else if (floorNow > trajectoryFloorPx + 0.5) {\n const intervalMs = Math.max(1, now - (trajectoryGrowthAtMs ?? now))\n if (trajectoryGrowthSamples > 0) {\n trajectoryAccumulatedGrowthPx += floorNow - trajectoryFloorPx\n trajectoryAccumulatedGrowthMs += intervalMs\n const measuredVelocity = trajectoryAccumulatedGrowthPx\n / trajectoryAccumulatedGrowthMs\n // A single wrap interval is quantized by layout and may also span a\n // dropped frame. Do not replace the trajectory target with that\n // staircase sample: low-pass it over a few wraps so the visual\n // velocity remains continuous when the host is busy or a retry row\n // changes the layout.\n const targetBlend = 1 - Math.exp(-intervalMs / 240)\n trajectoryTargetVelocityPxPerMs += (\n measuredVelocity - trajectoryTargetVelocityPxPerMs\n ) * targetBlend\n }\n trajectoryGrowthSamples += 1\n trajectoryGrowthAtMs = now\n } else if (floorNow < trajectoryFloorPx - 0.5) {\n trajectoryPositionPx = floorNow - minLagPx\n trajectoryGrowthAtMs = now\n trajectoryAccumulatedGrowthPx = 0\n trajectoryAccumulatedGrowthMs = 0\n trajectoryGrowthSamples = 0\n }\n trajectoryFloorPx = floorNow\n const phaseTarget = revealedCharsRef === undefined\n ? floorNow\n : revealPhase.advance(floorNow, revealedCharsRef.current).targetPx\n const trajectoryStep = computeFollowTrajectoryStep(elapsedMs, {\n positionPx: trajectoryPositionPx,\n velocityPxPerMs: trajectoryVelocityPxPerMs,\n targetPx: phaseTarget,\n targetVelocityPxPerMs: trajectoryTargetVelocityPxPerMs,\n minLagPx,\n maxLagPx,\n paintFloorPx: floorNow,\n })\n trajectoryPositionPx = trajectoryStep.positionPx\n trajectoryVelocityPxPerMs = trajectoryStep.velocityPxPerMs\n trajectoryShift = trajectoryStep.shiftPx\n trajectoryWasActive = true\n const baselineShift = runwayOffset - Math.min(runwayOffset, Math.max(0, reservePx))\n animatedH = contentHeight - runwayOffset - Math.max(0, trajectoryShift - baselineShift)\n velocityPxPerSec = trajectoryVelocityPxPerMs * 1000\n } else {\n if (trajectoryWasActive) {\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n animatedH = contentHeight - runwayOffset - Math.max(0, currentShift)\n velocityPxPerSec = trajectoryVelocityPxPerMs * 1000\n trajectoryPositionPx = null\n trajectoryWasActive = false\n }\n const lag = Math.max(0, contentHeight - animatedH - runwayOffset)\n const step = computeFollowStep(dt, {\n lag,\n speedEma: speedCpsRef.current,\n velocityPxPerSec,\n }, tuning)\n if (lag <= 0.1) {\n animatedH = contentHeight - runwayOffset\n velocityPxPerSec = 0\n } else {\n // ZERO-DOWNWARD-REBOUND: the reservation is NOT real lag. With the\n // steady-state tail pin it already rides as baseline-canceled gap\n // (shift = margin − reservation + reveal lag), so forcing the spring\n // to stop `reservePx` short of the natural floor — the pre-tail-pin\n // \"hold the reserve as lag\" semantic — would double-count it and\n // repaint the difference as an instant downward step the moment\n // prediction shuts off. The spring always drains to the natural\n // floor; the painted shift decays through the rate-limited release.\n animatedH = Math.min(\n contentHeight - runwayOffset,\n animatedH + step.advancePx,\n )\n velocityPxPerSec = step.velocityPxPerSec\n }\n }\n animatedH = applyVisual(\n nextPort,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n Number.POSITIVE_INFINITY,\n !predictGrowth,\n trajectoryShift,\n elapsedMs,\n !hostOwnsScroll,\n )\n if (trajectoryActive) {\n const currentShift = followLastShiftPx.get(nextPort) ?? (trajectoryShift ?? 0)\n trajectoryPositionPx = floorNow - currentShift\n }\n updateRevealScale(nextPort, elapsedMs)\n reportFollow(nextPort, true)\n // Keep the previous painted tail as the completion handoff baseline.\n // The active loop is the only place that sees the old surface before a\n // host live->settled replacement disconnects it.\n // Per-frame anchor hold — completion window only. During live\n // streaming the lockstep in this very frame's applyVisual already\n // cancels wraps; a guard running here fights it (its pad/raise writes\n // shift the next frame's lag bookkeeping) and visibly degrades the\n // reveal. The completion cascade is different: the settled-side arm\n // that primes IN the swap frame has active=false from mount, so ITS\n // first poll runs before paint and compensates the swap jump that the\n // older arms' observers were too late (or too unprivileged) to fix.\n // Track the reading surface's rendered position so the completion\n // guard inherits the exact last-painted baseline (never a stale or\n // already-jumped one) when the stream hands off. Compensation is NOT\n // done from this poll (a guard beside the active loop's own lockstep\n // fights it and degrades the reveal), and a NON-leader arm must not\n // even refresh the baseline: its measurement would store the very\n // jump the owning guard is about to correct and neutralize its next\n // pass.\n if (isLeader(nextPort)) {\n if (!activeRef.current) enforceReadingAnchor(nextPort)\n else measureReadingAnchor(nextPort)\n }\n const remainingEntranceLag = Math.max(\n 0,\n nextPort.scrollHeight - animatedH - runwayOffsetOf(nextPort),\n )\n if (remainingEntranceLag <= FOLLOW_SETTLE_EPSILON_PX) finishEntrance()\n }\n\n // Prime ownership and the final committed height in this layout phase.\n // A producer-complete text arm can mount and drain before the next RAF;\n // deferring this first pass would let it unmount unprimed after replacing\n // the previous owner, leaving a large final append at the old scrollTop.\n frame(performance.now())\n return () => {\n if (!controlScrollRef.current) {\n cancelAnimationFrame(rafId)\n if (port !== null) followActivePorts.delete(port)\n unsubscribeCommit?.()\n resize?.disconnect()\n mutations?.disconnect()\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n }\n if (interactTimer !== null) clearTimeout(interactTimer)\n const disabledHost = rootRef.current?.closest<HTMLElement>('[data-conversation-scroll]') ?? port\n if (disabledHost !== null) {\n clearVisual(disabledHost)\n followLeaders.delete(disabledHost)\n debugRuntime.reportFollow(disabledHost, null)\n }\n releaseRevealScale()\n return\n }\n cancelAnimationFrame(rafId)\n if (port !== null) followActivePorts.delete(port)\n unsubscribeCommit?.()\n if (interactTimer !== null) clearTimeout(interactTimer)\n resize?.disconnect()\n mutations?.disconnect()\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n }\n const root = rootRef.current\n const host = root?.closest<HTMLElement>('[data-conversation-scroll]') ?? port\n if (host === null) return\n holding = null\n if (!isLeader(host)) return\n const preserveReader = interacting && (readerGestureIntent || readerScrolledUp(host))\n if (!following || !primed) {\n if (!following && primed) {\n // A follower that already released the reader must carry that fact\n // across this closure's death: the draining arm mounting after this\n // cleanup would otherwise read the held viewport as its own\n // at-bottom state and hard-snap it to the floor.\n followReaderHolds.set(host, { atMs: performance.now() })\n }\n clearVisual(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n if (preserveReader) {\n handBackVisual(host)\n followReaderHolds.set(host, { atMs: performance.now() })\n clearVisual(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n\n // Completion can land the final Tool/command height in this same\n // commit. Preserve the logical extent and drain it after unmount instead\n // of clearing the compositor state before the first settled paint.\n // NOTE: do NOT clamp animatedH down by the held reserve here — the\n // reserve is canceled space (base = margin − reservation stays flat),\n // so treating it as real lag paints a whole runway-height step at the\n // exact moment leadership hands to the draining arm. The settle loop\n // caps animatedH against the shrinking extent directly.\n // Settle state (declared before the handoff so the completion paths can\n // measure the extent against it):\n let settleQuietMs = 0\n let settleSig = ''\n const lagBeforeCompletionPaint = Math.max(\n 0,\n host.scrollHeight - animatedH - runwayOffsetOf(host),\n )\n const currentRunway = runwayOffsetOf(host)\n const currentShift = Math.abs(currentShiftOf(shiftSurfacesOf(host).at(-1) ?? host))\n if (\n !activeRef.current\n && lagBeforeCompletionPaint <= FOLLOW_SLACK_PX\n && currentRunway <= FOLLOW_SETTLE_EPSILON_PX\n && currentShift <= FOLLOW_SETTLE_EPSILON_PX\n // A live completion pad must retire through the settle's glide first;\n // fast-finishing here would freeze it in place as visible bottom gap.\n && flowPadOf(host) <= FOLLOW_SETTLE_EPSILON_PX\n ) {\n followTraceUntilMs = Math.max(followTraceUntilMs, performance.now() + 10000)\n followTrace('fast-gate', { sh: host.scrollHeight, st: Math.round(host.scrollTop), pad: Math.round(flowPadOf(host)) })\n finishAtNaturalFloor(host, !startedAsEntrance)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n const completionShift = currentShiftOf(shiftSurfacesOf(host).at(-1) ?? host)\n // Freeze, never raise, in this same-task paint — same race as the\n // observer above; the settle's first rAF frame funds the re-open.\n // Entrance handoffs are mount transients with no collapse in flight:\n // their first cover must paint immediately (the soften contract).\n const completionShiftCeiling = startedAsEntrance && completionShift <= FOLLOW_SETTLE_EPSILON_PX\n ? Number.POSITIVE_INFINITY\n : completionShift\n if (hostOwnsScroll) {\n clearVisual(host)\n setFollowScrollTop(host, Math.max(0, host.scrollHeight - host.clientHeight))\n host.removeAttribute(FOLLOW_OWNED_ATTR)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n // The completion commit often REPLACES the last surface (live→settled\n // swap re-keys the row), and the owned margin written on the old element\n // dies with it in the same layout pass. Do NOT bank that loss as a flow\n // pad: the next ensureRunway opens the completion runway in this same\n // pre-paint task. Converting the dead margin to pad creates a second\n // owned extent that must later retire as the visible \"slow rebound\".\n followTraceUntilMs = performance.now() + 15000\n if (pruneDeadRunway(host)) {\n followTrace('cleanup-dead-margin', { sh: host.scrollHeight, st: Math.round(host.scrollTop), pad: Math.round(flowPadOf(host)) })\n reservePx = 0\n }\n // The completion handoff keeps at least one real runway open so the\n // final height has reserved paint room to drain through: with zero\n // margin the whole final height lands as shift in ONE paint (offset\n // space collapses to the paint limit), the exact teleport this drain\n // exists to prevent. The draining arm ramps its reserve from here.\n const completionTuning = debugRuntime.activeTuning()\n const previousCompletionRunway = runwayOffsetOf(host)\n // The completion pad already holds retired extent below the fold; the\n // handoff only opens the runway room the pad does not cover, or the\n // same pixels are added twice and the restored floor overshoots.\n ensureRunway(\n host,\n shiftSurfacesOf(host),\n Math.max(reservePx, Math.max(0, completionTuning.runwayPx - flowPadOf(host))),\n )\n const completionRunway = runwayOffsetOf(host)\n // The reading anchor's baseline is already live (the active loop\n // refreshed it every frame, and the guard observers keep it current);\n // only seed it here when this port somehow has none, so the first\n // completion commit has a real screen-space baseline to compare\n // against instead of silently adopting the jumped position.\n measureReadingAnchor(host)\n // Rebase the spring extent onto the new offset domain before the paint:\n // adding the margin drops targetHeight by the same amount, so animatedH\n // must drop in lockstep or the margin's px release as an instant shift.\n animatedH = Math.max(0, animatedH - (completionRunway - previousCompletionRunway))\n if (!hostOwnsScroll) settleAtFloor(host)\n animatedH = applyVisual(\n host,\n animatedH,\n reservePx,\n velocityPxPerSec,\n completionRunway,\n completionShiftCeiling,\n false,\n undefined,\n 0,\n !hostOwnsScroll,\n )\n reportFollow(host, false)\n const runwayOffset = runwayOffsetOf(host)\n const remainingLag = Math.max(0, host.scrollHeight - animatedH - runwayOffset)\n if (\n remainingLag <= FOLLOW_SETTLE_EPSILON_PX\n && runwayOffset <= FOLLOW_SETTLE_EPSILON_PX\n && reservePx <= FOLLOW_SETTLE_EPSILON_PX\n ) {\n finishAtNaturalFloor(host, !startedAsEntrance, !hostOwnsScroll)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n\n for (const name of GESTURE_EVENTS) {\n host.addEventListener(name, markGesture, { passive: true })\n }\n const stopSettleListeners = (): void => {\n for (const name of GESTURE_EVENTS) host.removeEventListener(name, markGesture)\n resize?.disconnect()\n mutations?.disconnect()\n if (interactTimer !== null) {\n clearTimeout(interactTimer)\n interactTimer = null\n }\n }\n // Re-arm pre-paint observation for the whole completion cascade. The\n // active effect's observers were disconnected above, but status/tail\n // commits continue while the detached settle loop owns the port.\n if (typeof ResizeObserver !== 'undefined') {\n resize = new ResizeObserver(() => restoreBeforePaint())\n resize.observe(host)\n const proxy = resizeProxyOf(host)\n if (proxy !== null) resize.observe(proxy)\n }\n if (typeof MutationObserver !== 'undefined') {\n const flow = flowElementOf(host)\n if (flow !== null) {\n mutations = new MutationObserver(() => { restoreBeforePaint() })\n mutations.observe(flow, { childList: true, subtree: true })\n }\n }\n // From here this closure's observers are the completion guard of last\n // resort (see `handedOff` above), and this settle OWNS the port until\n // it finishes.\n followCompletionSettle.add(host)\n followCompletionSettleRows.set(host, countUserRows(host))\n handedOff = true\n let settleLast = performance.now()\n // Settle-pad transfer state lives above the completion handoff; the\n // loop below only drives it frame by frame. `settleRetiring` marks the\n // final glide: the cascade has quieted, so the pad that kept every host\n // commit pixel-stable is handed back to the layout at the bounded\n // settle rate and the pinned viewport glides down to the natural\n // resting position against the composer.\n const settleFrame = (now: number): void => {\n if (!isLeader(host)) {\n stopSettleListeners()\n return\n }\n if (interacting && (readerGestureIntent || readerScrolledUp(host))) {\n readerGestureIntent = false\n handBackVisual(host)\n clearVisual(host)\n followCompletionSettle.delete(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n const dt = Math.min(FOLLOW_MAX_FRAME_MS, Math.max(0, now - settleLast))\n const tuning = debugRuntime.activeTuning()\n settleLast = now\n detectHostScroll(host, Math.max(0, host.scrollHeight - host.clientHeight))\n if (hostOwnsScroll) {\n clearVisual(host)\n setFollowScrollTop(host, Math.max(0, host.scrollHeight - host.clientHeight))\n host.removeAttribute(FOLLOW_OWNED_ATTR)\n followCompletionSettle.delete(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n // HOST COMPLETION CASCADE: around completion the host swaps the status\n // row for its process/tail rows, auto-collapses the think disclosure\n // and mounts the metrics tail — each a same-frame layout shrink under\n // the pinned floor. Re-open every lost pixel below the last surface\n // (out of sight; extent, floor and pinned scrollTop restored) and hold\n // ownership until the cascade has been quiet for\n // FOLLOW_SETTLE_QUIET_MS, so the host's own floor-snap never paints a\n // host action as a single-frame slam of the whole transcript.\n // ANCHOR SCREEN HOLD: the completion cascade moves the reading\n // anchor's viewport position (status swap, live→settled replacement,\n // clamp jumps). The reading-surface baseline lives in the shared\n // followGuardAnchors ledger; the shift-excluded delta filters the\n // engine's own glide, so the per-frame poll only answers real host\n // motion. While the pad retires, extent motion is OUR OWN glide —\n // the hold stands down.\n const guardDelta = !settleRetiring && !followActivePorts.has(host)\n ? enforceReadingAnchor(host, true)\n : null\n settleQuietMs = !settleRetiring && (guardDelta === null || Math.abs(guardDelta) <= 0.5) ? settleQuietMs + dt : 0\n // ZERO-DOWNWARD-REBOUND (root cause): scrollTop is pinned to the floor\n // and the floor rides the owned margin 1:1, so the settle must NOT\n // shrink the margin — that clamps scrollTop downward with no shift\n // left to release (the reservation covers the margin, so base = margin\n // − reservation never moves). Instead the margin MOVES below the\n // status row: marginTop −δ and marginBottom +δ in the same layout\n // pass keep the scroll extent constant, so the floor, the pinned\n // scrollTop and every content pixel stay put while the status glides\n // up to close the reserve gap — the completion 归位, with zero\n // downward motion.\n const settleStatus = turnStatusOf(host)\n const ownedRunwayPx = runwayOffsetOf(host)\n if (ownedRunwayPx > FOLLOW_SETTLE_EPSILON_PX) {\n const requestedTransferPx = settleStatus === null\n ? ownedRunwayPx\n : Math.min(\n reservePx,\n ((tuning.runwayPx || FOLLOW_STATUS_RUNWAY_PX) / FOLLOW_RUNWAY_RETIRE_MS) * dt,\n )\n const transferredPx = transferRunwayToFlowPad(host, requestedTransferPx)\n // Do not bank a completion pad. The margin release and pad removal\n // happen in one layout pass, so there is no extra extent to retire\n // later and no second slow rebound after the cascade quiets.\n if (transferredPx > 0) setFlowPad(host, Math.max(0, flowPadOf(host) - transferredPx))\n reservePx = Math.max(0, reservePx - transferredPx)\n // targetHeight = scrollHeight - runway. The equal margin-to-pad\n // transfer keeps scrollHeight fixed and lowers runway by δ, so the\n // logical extent rises by exactly δ (not 2δ). Both this rebase and\n // applyVisual's offset-history rebase are required: dropping either\n // one stalls the spring or leaks residual motion into the quiet\n // window (audit burst-gap/ramp quiescence-move).\n animatedH += transferredPx\n }\n const runwayOffset = runwayOffsetOf(host)\n const lag = Math.max(0, host.scrollHeight - animatedH - runwayOffset)\n // PAD RETIREMENT (the final glide of 收尾归位): cascade quiet, drain\n // closed — the pad that kept every host commit pixel-stable is handed\n // back to the layout at the bounded settle rate. The floor sinks with\n // it and the pinned viewport glides down to the natural resting\n // position against the composer; smooth and rate-limited, never the\n // single-frame slam the raw host snap paints.\n if (\n !settleRetiring\n && lag <= FOLLOW_SETTLE_EPSILON_PX\n && reservePx <= FOLLOW_SETTLE_EPSILON_PX\n && settleQuietMs >= FOLLOW_SETTLE_QUIET_MS\n && flowPadOf(host) > FOLLOW_SETTLE_EPSILON_PX\n ) {\n followTrace('retire-start', { pad: Math.round(flowPadOf(host)), sh: host.scrollHeight, st: Math.round(host.scrollTop) })\n settleRetiring = true\n }\n if (settleRetiring) {\n const padPx = flowPadOf(host)\n const retirePx = Math.min(\n padPx,\n ((tuning.runwayPx || FOLLOW_STATUS_RUNWAY_PX) / FOLLOW_RUNWAY_RETIRE_MS) * dt,\n )\n if (padPx - retirePx <= FOLLOW_SETTLE_EPSILON_PX) {\n setFlowPad(host, 0)\n settleRetiring = false\n } else {\n setFlowPad(host, padPx - retirePx)\n }\n }\n if (\n lag <= FOLLOW_SETTLE_EPSILON_PX\n && (reservePx <= FOLLOW_SETTLE_EPSILON_PX || settleStatus === null)\n && flowPadOf(host) <= FOLLOW_SETTLE_EPSILON_PX\n && settleQuietMs >= FOLLOW_SETTLE_QUIET_MS\n ) {\n followTrace('finish', { st: Math.round(host.scrollTop), sh: host.scrollHeight, pad: Math.round(flowPadOf(host)) })\n animatedH = host.scrollHeight\n velocityPxPerSec = 0\n finishAtNaturalFloor(host, !startedAsEntrance, !hostOwnsScroll)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n const step = computeFollowStep(dt, {\n lag,\n speedEma: speedCpsRef.current,\n velocityPxPerSec,\n }, tuning)\n animatedH = Math.min(\n host.scrollHeight - runwayOffset,\n animatedH + step.advancePx,\n )\n velocityPxPerSec = step.velocityPxPerSec\n if (!hostOwnsScroll) settleAtFloor(host)\n // Once the host has written, never write scrollTop again. The settle\n // still computes compositor shifts and rebases the spring; the host\n // owns the scrollport. A completion commit that GROWS the extent\n // changes the host floor; the host snaps while applyVisual answers\n // with the matching shift raise — the same lockstep the active loop\n // paints for a wrap.\n animatedH = applyVisual(\n host,\n animatedH,\n reservePx,\n velocityPxPerSec,\n runwayOffset,\n Number.POSITIVE_INFINITY,\n false,\n undefined,\n 0,\n !hostOwnsScroll,\n )\n if (traceActive()) {\n const sig = `${Math.round(host.scrollTop)}|${host.scrollHeight}|${Math.round(flowPadOf(host))}|${Math.round(reservePx)}|${settleRetiring}`\n if (sig !== settleSig) {\n followTrace('settle', { st: Math.round(host.scrollTop), sh: host.scrollHeight, pad: Math.round(flowPadOf(host)), reserve: Math.round(reservePx), lag: Math.round(lag * 10) / 10, retiring: settleRetiring })\n settleSig = sig\n }\n }\n reportFollow(host, false)\n requestAnimationFrame(settleFrame)\n }\n requestAnimationFrame(settleFrame)\n }\n }, [active, rootRef, speedCpsRef, revealScaleRef, predictive, predictiveRef, controlScroll])\n\n useLayoutEffect(() => {\n const host = rootRef.current?.closest<HTMLElement>('[data-conversation-scroll]') ?? null\n if (host !== null) {\n followFlowFillUsers.set(host, (followFlowFillUsers.get(host) ?? 0) + 1)\n }\n return () => {\n if (host === null) return\n const remaining = Math.max(0, (followFlowFillUsers.get(host) ?? 1) - 1)\n if (remaining > 0) {\n followFlowFillUsers.set(host, remaining)\n return\n }\n followFlowFillUsers.delete(host)\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (!followLeaders.has(host) && !followFlowFillUsers.has(host)) restoreFlowFill(host)\n })\n })\n }\n }, [rootRef])\n}\n","/**\n * Stream-smoothing reveal hook.\n *\n * Buffers the model's chunked text and reveals it at a cadence that tracks\n * the observed arrival rate, so a long reply never dumps whole paragraphs at\n * once and a fast stream never stutters. Port of lobe-ui's smoother: EMA\n * arrival cps + chunk size, backlog pressure, commit-interval widening with\n * tail length, and a flush-speed settle drain once the input idles. The\n * reveal decision is the pure {@link computeRevealStep} for unit tests.\n *\n * `shouldHoldBack` is the performance guard's veto: while it returns true the\n * loop keeps measuring but skips the DOM commit, so an offscreen reply never\n * competes with visible frames when the frame rate is degraded.\n */\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { DEFAULT_STREAM_DEBUG_TUNING, type StreamDebugTuning } from '../settings.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\nexport type StreamSmoothingPreset = 'realtime' | 'balanced' | 'silky'\n\nexport interface StreamSmoothingPresetConfig {\n readonly activeInputWindowMs: number\n readonly defaultCps: number\n readonly emaAlpha: number\n readonly flushCps: number\n readonly largeAppendChars: number\n readonly maxActiveCps: number\n readonly maxCps: number\n readonly maxFlushCps: number\n readonly minCps: number\n readonly settleAfterMs: number\n readonly settleDrainMaxMs: number\n readonly settleDrainMinMs: number\n readonly targetBufferMs: number\n}\n\nexport const PRESET_CONFIG: Record<StreamSmoothingPreset, StreamSmoothingPresetConfig> = {\n balanced: {\n activeInputWindowMs: 220,\n defaultCps: 80,\n emaAlpha: 0.35,\n flushCps: 180,\n largeAppendChars: 120,\n maxActiveCps: 360,\n maxCps: 240,\n maxFlushCps: 480,\n minCps: 24,\n settleAfterMs: 280,\n settleDrainMaxMs: 420,\n settleDrainMinMs: 120,\n targetBufferMs: 40,\n },\n realtime: {\n activeInputWindowMs: 140,\n defaultCps: 120,\n emaAlpha: 0.45,\n flushCps: 240,\n largeAppendChars: 180,\n maxActiveCps: 480,\n maxCps: 320,\n maxFlushCps: 640,\n minCps: 32,\n settleAfterMs: 200,\n settleDrainMaxMs: 280,\n settleDrainMinMs: 100,\n targetBufferMs: 24,\n },\n silky: {\n activeInputWindowMs: 280,\n defaultCps: 64,\n emaAlpha: 0.28,\n flushCps: 140,\n largeAppendChars: 100,\n maxActiveCps: 280,\n maxCps: 180,\n maxFlushCps: 400,\n minCps: 20,\n settleAfterMs: 360,\n settleDrainMaxMs: 520,\n settleDrainMinMs: 160,\n targetBufferMs: 56,\n },\n}\n\n/** Pressure curve from the reference stream renderer. */\nexport const QUEUE_BASE_SPEED_CPS = 90\nexport const QUEUE_ACCEL_EXPONENT = 1.25\nexport const QUEUE_PRESSURE_FACTOR = 0.85\nexport const QUEUE_MAX_SPEED_CPS = 600\n/** Hard cap on how far display may trail a live stream, in characters. */\nexport const LIVE_LAG_CHAR_CEILING = 32\nconst CATCHUP_SECONDS = 0.15\n\nexport const clamp = (value: number, min: number, max: number): number => {\n return Math.min(max, Math.max(min, value))\n}\n\n/**\n * Reference pressure-buffer reveal for a frame that starts without debt.\n * @param backlog - Unrevealed characters.\n * @param dtMs - Frame delta in ms.\n * @returns Characters to reveal this frame.\n */\nexport function computeQueueReveal(backlog: number, dtMs: number): number {\n if (backlog <= 0 || dtMs <= 0) return 0\n return computeAdaptiveQueueStep(backlog, dtMs, 0).revealChars\n}\n\nexport interface AdaptiveQueueStep {\n readonly revealChars: number\n readonly debt: number\n readonly speedCps: number\n}\n\n/** Float-debt queue integration from `ultimate_stream_physics_scroller.html`. */\nexport function computeAdaptiveQueueStep(\n backlog: number,\n dtMs: number,\n debt: number,\n revealScale = 1,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): AdaptiveQueueStep {\n if (backlog <= 0 || dtMs <= 0) return { revealChars: 0, debt: 0, speedCps: 0 }\n const speedCps = Math.min(\n tuning.maxRevealCps,\n QUEUE_BASE_SPEED_CPS + Math.pow(backlog, QUEUE_ACCEL_EXPONENT) * tuning.queuePressure,\n )\n const effectiveScale = clamp(revealScale * tuning.revealScale, 0.05, 2)\n const accumulated = Math.max(0, debt) + speedCps * effectiveScale * (dtMs / 1000)\n const revealChars = Math.min(backlog, Math.floor(accumulated))\n return { revealChars, debt: revealChars >= backlog ? 0 : accumulated - revealChars, speedCps }\n}\n\n/** Counts user-perceived characters (code points), not UTF-16 units. */\nexport const countChars = (text: string): number => {\n let count = 0\n for (const char of text) {\n void char\n count += 1\n }\n return count\n}\n\n/**\n * Drain rate for backlog beyond the tail-lag ceiling: the displayed text may\n * trail the stream by at most `backlogCharCeiling` characters for at most\n * `backlogSecondCeiling` seconds. The constants are a smoothness invariant\n * (bounded lag is the reason the reveal never stalls mid-reply), so they are\n * not config fields; the preset multiplier is how a deployment tunes them.\n */\nexport const BACKLOG_CHAR_CEILING = 300\nexport const BACKLOG_SECOND_CEILING = 2\n\nexport interface SettleDrainInput {\n readonly backlog: number\n readonly inputActive: boolean\n readonly settling: boolean\n}\n\n/** Pure settle-drain decision shared by the frame loop and its tests. */\nexport function computeSettleDrain(config: StreamSmoothingPresetConfig, input: SettleDrainInput): number {\n if (input.inputActive || !input.settling) return 0\n // A settled stream must drain fast enough to finish the reply promptly:\n // lag beyond the ceiling drains within the second ceiling.\n const overflow = Math.max(0, input.backlog - BACKLOG_CHAR_CEILING)\n const overflowCps = (overflow * 1000) / BACKLOG_SECOND_CEILING\n const drainTargetMs = clamp(input.backlog * 8, config.settleDrainMinMs, config.settleDrainMaxMs)\n const settleCps = (input.backlog * 1000) / drainTargetMs\n return clamp(Math.max(settleCps, overflowCps), config.flushCps, config.maxFlushCps)\n}\n\n/**\n * Fixed velocity that closes a producer-complete queue within its deadline.\n * This completion-only target may exceed the live-stream flush ceiling.\n */\nexport function computeCompletionDrain(\n config: StreamSmoothingPresetConfig,\n backlog: number,\n initialCps = 0,\n): number {\n if (backlog <= 0) return 0\n const drainTargetMs = clamp(backlog * 8, config.settleDrainMinMs, config.settleDrainMaxMs)\n const deadlineSeconds = drainTargetMs / 1000\n const rampAreaSeconds = SETTLE_RAMP_TAU_S * (1 - Math.exp(\n -deadlineSeconds / SETTLE_RAMP_TAU_S,\n ))\n const deadlineCps = (\n backlog - Math.max(0, initialCps) * rampAreaSeconds\n ) / Math.max(0.001, deadlineSeconds - rampAreaSeconds)\n return Math.max(\n deadlineCps,\n computeSettleDrain(config, { backlog, inputActive: false, settling: true }),\n )\n}\n\n/**\n * Drain rate multiplier once the input ends: leftover backlog reveals at\n * this multiple of the steady rate, so the end never drags.\n */\nexport const SETTLE_DRAIN_MULTIPLIER = 1.8\n/** Time constant for ramping the completion-drain velocity up from streaming pace. */\nexport const SETTLE_RAMP_TAU_S = 0.09\n\nexport interface RevealStepInput {\n readonly backlog: number\n readonly chunkSizeEma: number\n readonly arrivalCpsEma: number\n readonly emaCps: number\n readonly inputActive: boolean\n readonly settling: boolean\n /** Fixed reveal rate; overrides the arrival-tracking cadence entirely. */\n readonly steadyCps?: number | undefined\n}\n\nexport interface RevealStepResult {\n readonly revealChars: number\n readonly targetLagChars: number\n}\n\n/** Pure per-frame reveal decision shared by the loop and its tests. */\nexport function computeRevealStep(config: StreamSmoothingPresetConfig, input: RevealStepInput, dtSeconds: number): RevealStepResult {\n // Track the faster of the two EMAs and do not clamp to the old low maxCps\n // ceiling — that cap is why a fast model left hundreds of chars unrevealed.\n const trackedCps = Math.max(input.emaCps, input.arrivalCpsEma)\n const baseCps = clamp(trackedCps, config.minCps, config.maxFlushCps)\n const targetLagChars = input.inputActive\n ? Math.max(2, Math.round((baseCps * config.targetBufferMs) / 1000))\n : 0\n\n let currentCps: number\n if (input.steadyCps !== undefined) {\n currentCps = input.inputActive || input.settling\n ? clamp(\n input.steadyCps * (input.inputActive ? 1 : SETTLE_DRAIN_MULTIPLIER),\n config.minCps,\n config.maxFlushCps,\n )\n : 0\n } else if (input.inputActive) {\n const overflow = Math.max(0, input.backlog - LIVE_LAG_CHAR_CEILING)\n const catchup = overflow > 0 ? overflow / CATCHUP_SECONDS : 0\n currentCps = clamp(baseCps * 1.08 + catchup, config.minCps, config.maxFlushCps)\n } else if (input.settling) {\n currentCps = computeSettleDrain(config, input)\n } else {\n const idleFlushCps = Math.max(config.flushCps, baseCps * 1.8, input.arrivalCpsEma * 0.8)\n currentCps = clamp(idleFlushCps, config.flushCps, config.maxFlushCps)\n }\n\n const minRevealChars = input.inputActive ? 1 : 2\n return { revealChars: Math.max(minRevealChars, Math.round(currentCps * dtSeconds)), targetLagChars }\n}\n\nexport interface UseSmoothStreamContentOptions {\n enabled?: boolean\n /** The producer has completed; drain queued text without live backpressure. */\n inputComplete?: boolean\n preset?: StreamSmoothingPreset\n /** Performance guard veto: while true, reveal commits are held back. */\n shouldHoldBack?: (() => boolean) | undefined\n /**\n * Fixed reveal rate in chars/s. When set, the reveal runs at this steady\n * pace while the input streams (instead of tracking the arrival rate) and\n * drains an inferred idle backlog at {@link SETTLE_DRAIN_MULTIPLIER}.\n * Explicit producer completion still uses the bounded completion drain.\n */\n steadyCps?: number | undefined\n /**\n * Seed for the arrival-rate EMA. When omitted, the preset's `defaultCps`\n * is used. The live rate then tracks observed arrival; this is not a cap.\n */\n defaultCps?: number | undefined\n /** Written each commit with the live arrival-rate EMA for the follow lerp. */\n speedCpsRef?: { current: number } | undefined\n /** Cumulative code points that have actually committed to the display. */\n revealedCharsRef?: { current: number } | undefined\n /**\n * Called synchronously after each reveal commit lands in the DOM, so the\n * conversation follower can re-run its geometry inside the same task and\n * no intermediate (grown-but-uncompensated) frame can reach a paint.\n */\n onRevealCommit?: (() => void) | undefined\n /** Live multiplier from the follow spring when safe visual lag is filling. */\n revealScaleRef?: { current: number } | undefined\n}\n\n/**\n * Smooth a chunked content stream into a reveal-paced display string.\n *\n * @param content - The full accumulated input so far.\n * @param options - Preset, guard, and steady-rate wiring.\n * @returns The displayed content, revealed at the smoothed cadence.\n */\nexport function useSmoothStreamContent(\n content: string,\n {\n enabled = true,\n inputComplete = false,\n preset = 'balanced',\n shouldHoldBack,\n steadyCps,\n defaultCps,\n speedCpsRef,\n revealedCharsRef,\n revealScaleRef,\n onRevealCommit,\n }: UseSmoothStreamContentOptions = {},\n): string {\n const config = PRESET_CONFIG[preset]\n const seedCps = defaultCps ?? config.defaultCps\n // A fast provider can fill the first Host render with a large batch. Start\n // an enabled stream behind that batch so it still enters the reveal queue;\n // disabled (settled/history) content must remain immediate.\n const initialContent = enabled ? '' : content\n const [displayedContent, setDisplayedContent] = useState(initialContent)\n\n const displayedContentRef = useRef(initialContent)\n const displayedCountRef = useRef(countChars(initialContent))\n const targetContentRef = useRef(initialContent)\n const targetCharsRef = useRef([...initialContent])\n const targetCountRef = useRef(countChars(initialContent))\n\n const emaCpsRef = useRef(seedCps)\n const lastInputTsRef = useRef(0)\n const lastInputCountRef = useRef(countChars(initialContent))\n const chunkSizeEmaRef = useRef(1)\n const arrivalCpsEmaRef = useRef(seedCps)\n\n const rafRef = useRef<number | null>(null)\n const lastFrameTsRef = useRef<number | null>(null)\n const queueDebtRef = useRef(0)\n const settleCpsRef = useRef<number | null>(null)\n const lastDrainCpsRef = useRef(0)\n const holdBackRef = useRef(shouldHoldBack)\n const speedOutRef = useRef(speedCpsRef)\n speedOutRef.current = speedCpsRef\n const revealedCharsOutRef = useRef(revealedCharsRef)\n revealedCharsOutRef.current = revealedCharsRef\n const revealScaleOutRef = useRef(revealScaleRef)\n revealScaleOutRef.current = revealScaleRef\n const onRevealCommitOutRef = useRef(onRevealCommit)\n onRevealCommitOutRef.current = onRevealCommit\n const inputCompleteRef = useRef(inputComplete)\n inputCompleteRef.current = inputComplete\n const streamIdRef = useRef(`stream-${Math.random().toString(36).slice(2)}`)\n\n useEffect(() => {\n holdBackRef.current = shouldHoldBack\n }, [shouldHoldBack])\n\n const stopFrameLoop = useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n lastFrameTsRef.current = null\n }, [])\n\n const startFrameLoopRef = useRef<() => void>(() => {})\n\n const syncImmediate = useCallback(\n (nextContent: string) => {\n stopFrameLoop()\n const chars = [...nextContent]\n const now = performance.now()\n targetContentRef.current = nextContent\n targetCharsRef.current = chars\n targetCountRef.current = chars.length\n displayedContentRef.current = nextContent\n displayedCountRef.current = chars.length\n queueDebtRef.current = 0\n settleCpsRef.current = null\n lastDrainCpsRef.current = 0\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = seedCps\n setDisplayedContent(nextContent)\n emaCpsRef.current = seedCps\n chunkSizeEmaRef.current = 1\n arrivalCpsEmaRef.current = seedCps\n lastInputTsRef.current = now\n lastInputCountRef.current = chars.length\n },\n [seedCps, stopFrameLoop],\n )\n\n // Producer completion used to publish the accumulated source in one commit\n // here. That single commit is a visible teleport whenever a fast stream\n // ends with standing backlog — hundreds of chars become thousands of px in\n // one frame, exactly the end-of-render jerk this plugin fights. The frame\n // loop's producer-complete branch already drains the queue at a bounded\n // constant velocity (computeCompletionDrain), which finishes near its\n // configured deadline and glides every px through the spring. Nothing is left\n // \"typing\" after the Agent stops; the tail just closes at drain speed.\n //\n // Non-append-only edits and disabled streams still sync immediately below.\n\n const startFrameLoop = useCallback(() => {\n if (rafRef.current !== null) return\n\n const tick = (now: number) => {\n const targetCount = targetCountRef.current\n const displayedCount = displayedCountRef.current\n const backlog = targetCount - displayedCount\n\n if (backlog <= 0) {\n queueDebtRef.current = 0\n settleCpsRef.current = null\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = seedCps\n debugRuntime.reportStream(streamIdRef.current, null)\n stopFrameLoop()\n return\n }\n\n if (lastFrameTsRef.current === null) {\n lastFrameTsRef.current = now\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n const frameIntervalMs = Math.max(0, now - lastFrameTsRef.current)\n const dtSeconds = Math.max(0.001, Math.min(frameIntervalMs / 1000, 0.12))\n lastFrameTsRef.current = now\n\n const idleMs = now - lastInputTsRef.current\n const producerComplete = inputCompleteRef.current\n const debugTuning = debugRuntime.activeTuning()\n const inputActive = !producerComplete && idleMs <= config.activeInputWindowMs\n const settling = producerComplete || (!inputActive && idleMs >= config.settleAfterMs)\n if (!producerComplete) settleCpsRef.current = null\n\n let revealChars: number\n let revealSpeedCps: number\n let nextQueueDebt = 0\n if (producerComplete) {\n // Backpressure protects live layout. Once input has ended, retaining\n // that scale only makes a completed response keep typing onscreen.\n // Keep one TARGET velocity for the whole completion tail — recomputing\n // it from the shrinking backlog creates an exponential slow tail —\n // but RAMP the effective velocity up from the last reveal speed over\n // ~3 frames: an instant jump from streaming pace to max flush is\n // itself a visible jerk at exactly the moment the reader is watching\n // the reply finish.\n // The pre-drain reveal speed is the streaming EMA, not the debug seed.\n // Seeding the ramp from the 35cps default when the reply ran at the\n // max-flush ceiling stretched a 420ms tail past the 800ms announcer\n // step and the visible Markdown mutated across it.\n const previousCps = lastDrainCpsRef.current > 0\n ? lastDrainCpsRef.current\n : Math.max(config.minCps, emaCpsRef.current)\n const drainTargetCps = settleCpsRef.current\n ?? computeCompletionDrain(config, backlog, previousCps)\n settleCpsRef.current = drainTargetCps\n const rampedCps = previousCps\n + (drainTargetCps - previousCps) * (1 - Math.exp(-dtSeconds / SETTLE_RAMP_TAU_S))\n const settleCps = Math.min(drainTargetCps, Math.max(previousCps, rampedCps))\n lastDrainCpsRef.current = Math.min(drainTargetCps, rampedCps)\n const accumulated = Math.max(0, queueDebtRef.current) + settleCps * dtSeconds\n revealChars = Math.min(backlog, Math.floor(accumulated))\n revealSpeedCps = settleCps\n nextQueueDebt = revealChars >= backlog ? 0 : accumulated - revealChars\n if (revealChars >= backlog) lastDrainCpsRef.current = 0\n } else if (steadyCps !== undefined) {\n const step = computeRevealStep(\n config,\n {\n backlog,\n chunkSizeEma: chunkSizeEmaRef.current,\n arrivalCpsEma: arrivalCpsEmaRef.current,\n emaCps: emaCpsRef.current,\n inputActive,\n settling,\n steadyCps,\n },\n dtSeconds,\n )\n revealChars = Math.min(Math.round(step.revealChars * debugTuning.revealScale), backlog)\n revealSpeedCps = frameIntervalMs > 0 ? (revealChars * 1000) / frameIntervalMs : 0\n } else {\n const step = computeAdaptiveQueueStep(\n backlog,\n frameIntervalMs,\n queueDebtRef.current,\n revealScaleOutRef.current?.current ?? 1,\n debugTuning,\n )\n revealChars = step.revealChars\n revealSpeedCps = step.speedCps\n nextQueueDebt = step.debt\n }\n\n debugRuntime.reportStream(streamIdRef.current, {\n backlog,\n speedCps: revealSpeedCps,\n targetChars: targetCount,\n displayedChars: displayedCount,\n active: !producerComplete,\n })\n\n // Performance guard: while degraded and the reply is offscreen, skip\n // the DOM commit — the backlog keeps accumulating and flushes when the\n // guard clears or the reply scrolls into view.\n if (holdBackRef.current?.() === true) {\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n queueDebtRef.current = nextQueueDebt\n\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = revealSpeedCps\n\n if (revealChars <= 0) {\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n const nextCount = displayedCount + revealChars\n const segment = targetCharsRef.current.slice(displayedCount, nextCount).join('')\n if (segment) {\n const nextDisplayed = displayedContentRef.current + segment\n displayedContentRef.current = nextDisplayed\n displayedCountRef.current = nextCount\n setDisplayedContent(nextDisplayed)\n } else {\n displayedContentRef.current = targetContentRef.current\n displayedCountRef.current = targetCount\n setDisplayedContent(targetContentRef.current)\n }\n\n rafRef.current = requestAnimationFrame(tick)\n }\n\n rafRef.current = requestAnimationFrame(tick)\n }, [config, seedCps, stopFrameLoop, steadyCps])\n\n // Run AFTER the commit's DOM mutations, before paint: the follower's\n // same-task correction hook.\n useLayoutEffect(() => {\n const revealedCharsOut = revealedCharsOutRef.current\n if (revealedCharsOut !== undefined) revealedCharsOut.current = displayedCountRef.current\n if (displayedContent === '') return\n onRevealCommitOutRef.current?.()\n }, [displayedContent])\n\n useEffect(() => {\n startFrameLoopRef.current = startFrameLoop\n }, [startFrameLoop])\n\n useEffect(() => {\n if (!enabled) {\n syncImmediate(content)\n return\n }\n\n const prevTargetContent = targetContentRef.current\n if (content === prevTargetContent) return\n\n const now = performance.now()\n const appendOnly = content.startsWith(prevTargetContent)\n\n if (!appendOnly) {\n syncImmediate(content)\n return\n }\n\n const appended = content.slice(prevTargetContent.length)\n const appendedChars = [...appended]\n const appendedCount = appendedChars.length\n\n targetContentRef.current = content\n targetCharsRef.current.push(...appendedChars)\n targetCountRef.current += appendedCount\n settleCpsRef.current = null\n\n const hadSample = lastInputTsRef.current > 0\n const deltaChars = targetCountRef.current - lastInputCountRef.current\n const deltaMs = Math.max(1, now - lastInputTsRef.current)\n\n // Skip the first sample: lastInputTs starts at 0, so the interval would\n // be \"time since page load\" (or 1ms under fake timers) and poison the EMA.\n if (hadSample && deltaChars > 0) {\n const instantCps = (deltaChars * 1000) / deltaMs\n const normalizedInstantCps = clamp(instantCps, config.minCps, config.maxFlushCps * 3)\n const chunkEmaAlpha = 0.45\n chunkSizeEmaRef.current = chunkSizeEmaRef.current * (1 - chunkEmaAlpha) + appendedCount * chunkEmaAlpha\n arrivalCpsEmaRef.current = arrivalCpsEmaRef.current * (1 - chunkEmaAlpha) + normalizedInstantCps * chunkEmaAlpha\n emaCpsRef.current = emaCpsRef.current * (1 - config.emaAlpha) + normalizedInstantCps * config.emaAlpha\n }\n\n lastInputTsRef.current = now\n lastInputCountRef.current = targetCountRef.current\n\n startFrameLoop()\n }, [content, enabled, config, startFrameLoop, syncImmediate])\n\n useEffect(() => {\n return () => {\n stopFrameLoop()\n debugRuntime.reportStream(streamIdRef.current, null)\n }\n }, [stopFrameLoop])\n\n return displayedContent\n}\n","/**\n * Performance guard for the streaming reveal.\n *\n * Feeds an EMA-smoothed frame-rate monitor from a rAF loop while streaming\n * and tracks whether the reply is on-screen. The returned `shouldHoldBack`\n * predicate is true only while the frame rate is below the threshold AND the\n * reply is offscreen — exactly the spec's \"skip offscreen DOM updates when\n * FPS < 30\" rule. The smoother consumes the predicate as its commit veto.\n */\n\nimport { useCallback, useEffect, useRef } from 'react'\nimport { debugRuntime } from './debugRuntime.ts'\n\nconst FPS_THRESHOLD = 30\nconst FPS_ALPHA = 0.12\nconst RECOVER_FRAMES = 6\nconst MAX_FRAME_MS = 100\n\ninterface MutableFps {\n emaMs: number\n lastMs: number\n healthyRun: number\n degraded: boolean\n}\n\nexport function useFpsGuard(active: boolean): {\n ref: (element: HTMLElement | null) => void\n shouldHoldBack: () => boolean\n} {\n const fpsRef = useRef<MutableFps>({ emaMs: 0, lastMs: 0, healthyRun: 0, degraded: false })\n const visibleRef = useRef(true)\n const elementRef = useRef<HTMLElement | null>(null)\n\n useEffect(() => {\n if (!active) return\n let rafId = 0\n let lastDebugReport = 0\n const frame = (now: number) => {\n rafId = requestAnimationFrame(frame)\n const fps = fpsRef.current\n if (fps.lastMs === 0) {\n fps.lastMs = now\n return\n }\n const delta = Math.min(MAX_FRAME_MS, Math.max(1, now - fps.lastMs))\n fps.lastMs = now\n fps.emaMs = fps.emaMs === 0 ? delta : fps.emaMs + FPS_ALPHA * (delta - fps.emaMs)\n const currentFps = 1000 / fps.emaMs\n if (currentFps < FPS_THRESHOLD) {\n fps.healthyRun = 0\n fps.degraded = true\n } else if (fps.degraded) {\n fps.healthyRun += 1\n if (fps.healthyRun >= RECOVER_FRAMES) fps.degraded = false\n }\n if (now - lastDebugReport >= 100) {\n debugRuntime.reportFps(currentFps, fps.emaMs, fps.degraded)\n lastDebugReport = now\n }\n }\n rafId = requestAnimationFrame(frame)\n return () => {\n cancelAnimationFrame(rafId)\n fpsRef.current = { emaMs: 0, lastMs: 0, healthyRun: 0, degraded: false }\n debugRuntime.clearFps()\n }\n }, [active])\n\n const ref = useCallback((element: HTMLElement | null) => {\n elementRef.current = element\n }, [])\n\n useEffect(() => {\n const element = elementRef.current\n if (element === null || typeof IntersectionObserver === 'undefined') return\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) visibleRef.current = entry.isIntersecting\n },\n { rootMargin: '120px 0px' },\n )\n observer.observe(element)\n return () => observer.disconnect()\n })\n\n const shouldHoldBack = useCallback(() => {\n return active && fpsRef.current.degraded && !visibleRef.current\n }, [active])\n\n return { ref, shouldHoldBack }\n}\n","import { useEffect, useRef, type ReactNode } from 'react'\nimport { useConversationFollow } from './teleprompterGlide.ts'\nimport css from './TypewriterAssistantNodeView.module.css'\n\n/**\n * Document-flow host that owns conversation-port follow while `active`.\n * Shared by assistant blocks and every other Agent Chat row. `onGrowth` lets\n * generic wrapped renderers re-arm one glide when their DOM grows without\n * requiring a business-kind-specific lifecycle predicate.\n */\nexport function FollowHost({\n active,\n entrance = false,\n onEntranceSettled,\n onGrowth,\n entranceExtentRef,\n speedCpsRef,\n revealedCharsRef,\n revealScaleRef,\n predictive = true,\n predictiveRef,\n controlScroll = true,\n hostRef,\n className,\n entranceActive,\n children,\n}: {\n active: boolean\n entrance?: boolean\n onEntranceSettled?: (() => void) | undefined\n onGrowth?: ((deltaPx: number) => void) | undefined\n entranceExtentRef?: { current: number | null } | undefined\n speedCpsRef: { current: number }\n revealedCharsRef?: { current: number } | undefined\n revealScaleRef?: { current: number } | undefined\n predictive?: boolean\n predictiveRef?: { current: boolean } | undefined\n /** False leaves conversation bottom-follow to the Host. */\n controlScroll?: boolean\n hostRef?: { current: HTMLDivElement | null } | undefined\n children: ReactNode\n className?: string | undefined\n /** Optional marker for a generic row's one-shot entrance animation. */\n entranceActive?: boolean | undefined\n}) {\n const localRootRef = useRef<HTMLDivElement>(null)\n const rootRef = hostRef ?? localRootRef\n useConversationFollow(\n rootRef,\n active || entrance,\n speedCpsRef,\n revealScaleRef,\n predictive,\n entrance,\n onEntranceSettled,\n predictiveRef,\n entranceExtentRef,\n revealedCharsRef,\n controlScroll,\n )\n useEffect(() => {\n if (onGrowth === undefined || typeof ResizeObserver === 'undefined') return\n const root = rootRef.current\n if (root === null) return\n let previousHeight: number | null = null\n let pendingGrowth = 0\n let growthFrame: number | null = null\n const flushGrowth = (): void => {\n growthFrame = null\n if (pendingGrowth <= 0) return\n const delta = pendingGrowth\n pendingGrowth = 0\n onGrowth(delta)\n }\n const observer = new ResizeObserver(entries => {\n const measuredHeight = entries[0]?.contentRect.height\n if (measuredHeight === undefined || !Number.isFinite(measuredHeight)) return\n const nextHeight = measuredHeight\n if (previousHeight !== null && nextHeight > previousHeight + 0.5) {\n pendingGrowth += nextHeight - previousHeight\n if (growthFrame === null) growthFrame = requestAnimationFrame(flushGrowth)\n }\n previousHeight = nextHeight\n })\n observer.observe(root)\n return () => {\n observer.disconnect()\n if (growthFrame !== null) cancelAnimationFrame(growthFrame)\n }\n }, [onGrowth])\n return (\n <div\n ref={rootRef}\n className={className === undefined ? css.follow : `${css.follow} ${className}`}\n data-entrance={entranceActive === undefined ? undefined : entranceActive ? 'active' : 'idle'}\n >\n {children}\n </div>\n )\n}\n","/**\n * Shared plugin configuration contract. The Host half defines the\n * Schemastery schema over this shape (defaults live here so both halves stay\n * symmetric); the client half falls back to the same defaults when the Host\n * boot-config bridge is absent (client-only composition).\n */\n\nimport type { StreamSmoothingPreset } from './client/useSmoothStreamContent.ts'\n\n/** Legacy render-mode value retained so existing overlays remain valid. */\nexport type StreamMode = 'typewriter' | 'teleprompter'\n\n/** Plugin configuration validated by the Host schema and bridged to the browser half. */\nexport interface StreamConfig {\n /** Compatibility field; both values use the current adaptive reveal engine. */\n readonly mode: StreamMode\n /** Smoothing preset for the reveal cadence. */\n readonly preset: StreamSmoothingPreset\n /**\n * Unused at runtime; kept so existing overlays load. Live reveal tracks\n * observed arrival and ignores this seed.\n */\n readonly revealCharsPerSec: number\n /**\n * Unused at runtime; kept so existing overlays load. Follow is a\n * smooth-damp, not a cruise speed.\n */\n readonly scrollSpeedPxPerSec: number\n /** Unused at runtime; retained so existing overlays continue to load. */\n readonly maxScrollSpeedPxPerSec: number\n}\n\n/** Defaults shared by the Host schema and the client-side fallback. */\nexport const DEFAULT_STREAM_CONFIG: StreamConfig = {\n mode: 'typewriter',\n preset: 'balanced',\n revealCharsPerSec: 80,\n scrollSpeedPxPerSec: 48,\n maxScrollSpeedPxPerSec: 1000,\n}\n\n/**\n * Window global the Host writes into the served index HTML. The browser boot\n * graph carries no per-entry config, so this inline script is the only\n * Host-to-client configuration channel for a composed web plugin.\n */\nexport const STREAM_BOOT_GLOBAL = '__DSH_SMOOTH_STREAM_CONFIG__'\n","import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ComponentProps, type ReactNode, type RefObject } from 'react'\nimport { IconThinkOutline14, JsonBlock, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { ImageGallery, type ImageLoader, type MessageImageLabels } from '@deepseek-ai/dsh-client-ui-attachment'\nimport type { ChatNodeViewProps, TurnTailOwnerProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { AnimatedDisclosure } from './AnimatedDisclosure.tsx'\nimport { notifyFollowCommit } from './teleprompterGlide.ts'\nimport { useSmoothStreamContent, type StreamSmoothingPreset } from './useSmoothStreamContent.ts'\nimport { useFpsGuard } from './useFpsGuard.ts'\nimport { FollowHost } from './FollowHost.tsx'\nimport { DEFAULT_STREAM_CONFIG, type StreamMode } from '../config.ts'\nimport { DEFAULT_STREAM_SETTINGS, type StreamMotionPreference } from '../settings.ts'\nimport css from './TypewriterAssistantNodeView.module.css'\n\ntype AssistantProps = ChatNodeViewProps<'assistant-step'>\ntype MarkdownProps = Pick<ComponentProps<typeof MarkdownText>, 'labels' | 'fileMentions' | 'text'>\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(\n () => typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true,\n )\n useEffect(() => {\n if (typeof window === 'undefined' || window.matchMedia === undefined) return\n const query = window.matchMedia('(prefers-reduced-motion: reduce)')\n const onChange = () => setReduced(query.matches)\n query.addEventListener('change', onChange)\n return () => query.removeEventListener('change', onChange)\n }, [])\n return reduced\n}\n\n/**\n * Resolve whether the reveal engine should stay off for this view. The OS\n * preference wins only in `auto` mode: `force-smooth` keeps the engine on\n * machines where a system-wide reduce-motion switch (or a forced browser\n * flag) would otherwise silently bypass smoothing, and `force-reduced`\n * disables it even when the OS asks for motion. Credit: three-state design\n * proposed by @Zn-Dk in #21/#22.\n */\nfunction useMotionReduced(preference: StreamMotionPreference): boolean {\n const system = usePrefersReducedMotion()\n if (preference === 'force-smooth') return false\n if (preference === 'force-reduced') return true\n return system\n}\n\ninterface AnimatedMarkdownTextProps extends MarkdownProps {\n streaming: boolean\n /** Whether the resolved reduced-motion gate keeps the reveal engine off. */\n motionReduced: boolean\n /** True on the last text block: that block owns conversation follow. */\n ownFollow: boolean\n followSpeedCpsRef?: { current: number } | undefined\n followRevealedCharsRef?: { current: number } | undefined\n followRevealScaleRef?: { current: number } | undefined\n onPredictiveChange?: ((predictive: boolean) => void) | undefined\n preset: StreamSmoothingPreset\n shouldHoldBack: () => boolean\n controlScroll?: boolean\n}\n\n/** Conservative fallback before the streaming Markdown tail has geometry. */\nconst PREDICTIVE_WRAP_FALLBACK_CHARS = 32\nconst STREAM_ANNOUNCEMENT_INTERVAL_MS = 800\nconst STREAM_ANNOUNCEMENT_MAX_CHARS = 320\n\ninterface PendingTextGeometry {\n root: HTMLElement\n visibleText: string\n fontSize: number\n wrapThresholdWidth: number | null\n}\n\nfunction approximateInlineWidth(text: string, emPx: number): number {\n let width = 0\n for (const char of text) {\n if (/\\s/u.test(char)) width += emPx * 0.33\n else if (/^[\\x00-\\x7f]$/u.test(char)) width += emPx * 0.56\n else width += emPx\n }\n return width\n}\n\nfunction measurePendingTextGeometry(root: HTMLElement, visibleText: string): PendingTextGeometry {\n if (\n typeof document.createTreeWalker !== 'function'\n || typeof NodeFilter === 'undefined'\n ) {\n return { root, visibleText, fontSize: 14, wrapThresholdWidth: null }\n }\n const rootRect = root.getBoundingClientRect()\n const rootWidth = Math.max(0, rootRect.width, rootRect.right - rootRect.left, root.clientWidth)\n if (rootWidth <= 0) return { root, visibleText, fontSize: 14, wrapThresholdWidth: null }\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let tail: Text | null = null\n for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {\n if ((node.textContent ?? '').length > 0) tail = node as Text\n }\n const parent = tail?.parentElement ?? root\n const fontSize = Number.parseFloat(getComputedStyle(parent).fontSize) || 14\n if (tail === null || typeof document.createRange !== 'function') {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n\n try {\n const length = tail.textContent?.length ?? 0\n if (length <= 0) return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n const range = document.createRange()\n range.setStart(tail, Math.max(0, length - 1))\n range.setEnd(tail, length)\n const tailRect = range.getBoundingClientRect()\n const contentRight = rootRect.right\n if (!Number.isFinite(tailRect.right) || tailRect.right <= rootRect.left || contentRight <= rootRect.left) {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n const remainingWidth = Math.max(0, contentRight - tailRect.right)\n return {\n root,\n visibleText,\n fontSize,\n wrapThresholdWidth: remainingWidth + fontSize * 0.35,\n }\n } catch {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n}\n\n/** Whether buffered source can reach a new visual line before it drains. */\nfunction pendingTextCanGrow(\n root: HTMLElement | null,\n visibleText: string,\n pending: string,\n geometryRef: { current: PendingTextGeometry | null },\n): boolean {\n if (pending === '') return false\n if (/[\\r\\n]/u.test(pending)) return true\n const pendingChars = [...pending]\n if (root === null) return pendingChars.length >= PREDICTIVE_WRAP_FALLBACK_CHARS\n\n let geometry = geometryRef.current\n if (geometry?.root !== root || geometry.visibleText !== visibleText) {\n geometry = measurePendingTextGeometry(root, visibleText)\n geometryRef.current = geometry\n }\n if (geometry.wrapThresholdWidth === null) {\n return pendingChars.length >= PREDICTIVE_WRAP_FALLBACK_CHARS\n }\n return approximateInlineWidth(pending, geometry.fontSize) >= geometry.wrapThresholdWidth\n}\n\nfunction announcementChunkEnd(source: string, start: number): number {\n const hardEnd = Math.min(source.length, start + STREAM_ANNOUNCEMENT_MAX_CHARS)\n if (hardEnd === source.length) return hardEnd\n const softStart = start + Math.floor(STREAM_ANNOUNCEMENT_MAX_CHARS * 0.6)\n for (let index = hardEnd - 1; index >= softStart; index -= 1) {\n if (/[\\s.,;:!?]/u.test(source[index] ?? '')) return index + 1\n }\n return hardEnd\n}\n\n/** Pace screen-reader updates independently from visual reveal frames. */\ninterface StreamAnnouncementState {\n text: string\n revision: number\n present: boolean\n}\n\n/** A commit-driven live region isolated from the visible Markdown subtree. */\nconst StreamAnnouncement = memo(function StreamAnnouncement({\n text,\n active,\n}: {\n text: string\n active: boolean\n}) {\n const [announcement, setAnnouncement] = useState<StreamAnnouncementState>({\n text: '',\n revision: 0,\n present: active,\n })\n const sourceRef = useRef(text)\n const activeRef = useRef(active)\n const announcedOffsetRef = useRef(active ? 0 : text.length)\n const drainSourceRef = useRef<string | null>(null)\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(() => {\n const clearTimer = (): void => {\n if (timerRef.current === null) return\n clearTimeout(timerRef.current)\n timerRef.current = null\n }\n\n const publishNext = (source: string): boolean => {\n const start = Math.min(announcedOffsetRef.current, source.length)\n const end = announcementChunkEnd(source, start)\n if (end <= start) return false\n announcedOffsetRef.current = end\n setAnnouncement(previous => ({\n text: source.slice(start, end),\n revision: previous.revision + 1,\n present: true,\n }))\n return end < source.length\n }\n\n const hideAfterLinger = (): void => {\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (activeRef.current) return\n drainSourceRef.current = null\n setAnnouncement(previous => ({ ...previous, present: false }))\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const drainNext = (): void => {\n const source = drainSourceRef.current\n if (source === null) return\n if (!publishNext(source)) {\n hideAfterLinger()\n return\n }\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (activeRef.current) return\n drainNext()\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const scheduleLive = (): void => {\n if (timerRef.current !== null || announcedOffsetRef.current >= sourceRef.current.length) return\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (!activeRef.current) return\n const source = sourceRef.current\n if (publishNext(source)) scheduleLive()\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const wasActive = activeRef.current\n const previousSource = sourceRef.current\n const continuingDrain = !active && !wasActive && drainSourceRef.current !== null\n if (\n !continuingDrain\n && (!text.startsWith(previousSource) || announcedOffsetRef.current > text.length)\n ) {\n announcedOffsetRef.current = 0\n }\n sourceRef.current = text\n activeRef.current = active\n\n if (active) {\n if (!wasActive) {\n clearTimer()\n drainSourceRef.current = null\n setAnnouncement(previous => ({\n text: '',\n revision: previous.revision + 1,\n present: true,\n }))\n }\n scheduleLive()\n return\n }\n\n if (!wasActive) {\n if (drainSourceRef.current === null) announcedOffsetRef.current = text.length\n return\n }\n\n clearTimer()\n drainSourceRef.current = text\n drainNext()\n }, [active, text])\n\n useEffect(() => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current)\n timerRef.current = null\n }, [])\n\n if (!active && !announcement.present) return null\n const activating = active && !activeRef.current\n return (\n <span\n className={css.visuallyHidden}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n <span key={announcement.revision}>{activating ? '' : announcement.text}</span>\n </span>\n )\n})\n\n/**\n * Smooth streaming text arm. While the reply runs, the accumulated source is\n * revealed through the smoother at a rate that tracks the model's arrival\n * and rendered by the Harness `MarkdownText`\n * streaming arm (incremental parse, frozen non-tail blocks), so there is no\n * raw-text tail and no text-to-markdown swap: the tree stays markdown\n * throughout. The last text block owns conversation-port follow so wraps\n * glide instead of snapping. Once the stream closes and the reveal queue\n * drains, the settled full parse (KaTeX math, fence highlighting, file\n * mentions) swaps in exactly once.\n */\nfunction AnimatedMarkdownText({\n text,\n labels,\n fileMentions,\n streaming,\n motionReduced,\n ownFollow,\n followSpeedCpsRef,\n followRevealedCharsRef,\n followRevealScaleRef,\n onPredictiveChange,\n preset,\n shouldHoldBack,\n controlScroll = true,\n}: AnimatedMarkdownTextProps) {\n const reduced = motionReduced\n const [typing, setTyping] = useState(streaming)\n const localSpeedCpsRef = useRef(35)\n const followRootRef = useRef<HTMLDivElement>(null)\n const predictionSourceRef = useRef<string | null>(null)\n const predictionStateRef = useRef(false)\n const predictionGeometryRef = useRef<PendingTextGeometry | null>(null)\n const speedCpsRef = followSpeedCpsRef ?? localSpeedCpsRef\n const displayed = useSmoothStreamContent(text, {\n enabled: typing && !reduced,\n inputComplete: !streaming,\n preset,\n shouldHoldBack,\n speedCpsRef,\n revealedCharsRef: followRevealedCharsRef,\n revealScaleRef: followRevealScaleRef,\n onRevealCommit: () => { notifyFollowCommit(followRootRef.current) },\n })\n const shown = reduced ? text : displayed\n const live = typing && !reduced\n\n useEffect(() => {\n const root = followRootRef.current\n if (root === null || typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(() => {\n if (predictionGeometryRef.current?.root === root) predictionGeometryRef.current = null\n })\n observer.observe(root)\n return () => { observer.disconnect() }\n }, [])\n\n useLayoutEffect(() => {\n if (onPredictiveChange === undefined) return\n const pending = text.slice(shown.length)\n const sourceChanged = predictionSourceRef.current !== text\n const next = !live || !streaming || pending === ''\n ? false\n : sourceChanged\n ? pendingTextCanGrow(followRootRef.current, shown, pending, predictionGeometryRef)\n : predictionStateRef.current\n predictionSourceRef.current = text\n predictionStateRef.current = next\n onPredictiveChange(next)\n }, [live, onPredictiveChange, shown, streaming, text])\n\n // The stream closed: keep revealing the remaining queue, then swap to the\n // settled parse exactly once. The markdown tree stays mounted until then.\n useEffect(() => {\n if (typing && !streaming && shown.length === text.length) setTyping(false)\n }, [shown, streaming, text, typing])\n\n // A row can mount before the projection flips its assistant step to\n // `running`, which would freeze `typing` at false forever and leave the\n // reveal engine off for the whole reply. Re-arm on the rising edge so late\n // stream starts are still smoothed. (Adopted from #22 by @Zn-Dk.)\n useEffect(() => {\n if (streaming) setTyping(true)\n }, [streaming])\n\n return (\n <FollowHost\n active={live && ownFollow}\n speedCpsRef={speedCpsRef}\n revealedCharsRef={followRevealedCharsRef}\n revealScaleRef={followRevealScaleRef}\n predictive={streaming}\n controlScroll={controlScroll}\n hostRef={followRootRef}\n >\n <MarkdownText\n // `shown` stays authoritative through the completion drain: the\n // settled parse swaps in only when the queue has actually emptied.\n // Rendering `text` early bypasses the drain and teleports the tail.\n text={live ? shown : text}\n streaming={live}\n labels={labels}\n fileMentions={live ? undefined : fileMentions}\n />\n </FollowHost>\n )\n}\n\nfunction imageLabels(t: AssistantProps['t']): MessageImageLabels {\n return {\n image: t('image.label'),\n open: t('image.openOriginal'),\n openNamed: label => t('image.openOriginalLabel', { label }),\n loading: t('image.loading'),\n loadFailed: t('image.loadFailed'),\n lightbox: {\n dialog: t('image.preview'),\n close: t('image.closePreview'),\n },\n }\n}\n\n/**\n * Apply searchable hidden state without unmounting a stable subtree — the\n * Host's completion fold hides the answer-inline reasoning this way, so the\n * takeover renderer must reproduce it to stay inside the contract: the row\n * disappears into the Host's process summary and comes back on find-in-page.\n * (Mirrors the Harness chat kit's `useSearchableHidden`.)\n */\nfunction useSearchableHidden(\n hidden: boolean,\n reveal: () => void,\n): RefObject<HTMLDivElement> {\n const ref = useRef<HTMLDivElement>(null)\n useLayoutEffect(() => {\n const element = ref.current\n if (element === null) return\n if (hidden && element.contains(element.ownerDocument.activeElement)) {\n reveal()\n return\n }\n if (hidden) element.setAttribute('hidden', 'until-found')\n else element.removeAttribute('hidden')\n }, [hidden, reveal])\n useEffect(() => {\n const element = ref.current\n if (element === null) return\n element.addEventListener('beforematch', reveal)\n return () => { element.removeEventListener('beforematch', reveal) }\n }, [reveal])\n return ref\n}\n\n/**\n * One answer-inline reasoning block wrapped in the Host's fold contract. The\n * Host computes the fold decision (turn closed, compact transcript, this node\n * is the answer) and delivers it through the `turnProcess` owner prop; when\n * folded the block hides into the Host's \"thought\" summary row instead of\n * staying mounted above the answer.\n */\nfunction FoldableReasoning({\n hidden,\n reveal,\n children,\n}: {\n hidden: boolean\n reveal: () => void\n children: ReactNode\n}) {\n const ref = useSearchableHidden(hidden, reveal)\n return (\n <div ref={ref} data-turn-process-inline={hidden || undefined}>\n {children}\n </div>\n )\n}\n\nfunction firstLine(text: string): string {\n const newline = text.indexOf('\\n')\n return newline === -1 ? text : text.slice(0, newline)\n}\n\nfunction latestLine(text: string): string {\n const visible = text.trimEnd()\n const newline = visible.lastIndexOf('\\n')\n return newline === -1 ? visible : visible.slice(newline + 1)\n}\n\n/**\n * Built-in Think disclosure with a smoothed `text` feed. Chevron and row\n * click stay on the disclosure chrome, which the plugin's AnimatedDisclosure\n * renders with a height-animated body (the harness primitive would mount and\n * unmount it, which cannot glide). The row opens only while this block is\n * the streaming tail and closes as soon as thinking ends — a later block,\n * or the assistant node settling — not when the rest of the reply is\n * still streaming.\n */\nfunction AnimatedReasoning({\n text,\n running,\n preset,\n thinkAutoExpand,\n motionReduced,\n shouldHoldBack,\n followSpeedCpsRef,\n followRevealScaleRef,\n t,\n}: {\n text: string\n running: boolean\n preset: StreamSmoothingPreset\n thinkAutoExpand: boolean\n motionReduced: boolean\n shouldHoldBack: () => boolean\n followSpeedCpsRef?: { current: number } | undefined\n followRevealScaleRef?: { current: number } | undefined\n t: AssistantProps['t']\n}) {\n const reduced = motionReduced\n const [expanded, setExpanded] = useState(running && thinkAutoExpand)\n const [autoClosed, setAutoClosed] = useState(false)\n const summaryRef = useRef<HTMLSpanElement>(null)\n const commitAnchorRef = useRef<HTMLDivElement>(null)\n // The running→false flip is the AUTO-close: it collapses instantly and the\n // follower's settle spring absorbs the height step. A later manual toggle\n // keeps the CSS glide.\n const displayed = useSmoothStreamContent(text, {\n enabled: running && !reduced,\n preset,\n shouldHoldBack,\n speedCpsRef: followSpeedCpsRef,\n revealScaleRef: followRevealScaleRef,\n onRevealCommit: () => { notifyFollowCommit(commitAnchorRef.current) },\n })\n const shown = running && !reduced ? displayed : text\n const summary = running ? latestLine(shown) : firstLine(text)\n\n useLayoutEffect(() => {\n // Only the running state owns disclosure while auto-expand is on; with it\n // off, a manual toggle is never wrestled back by the stream.\n if (thinkAutoExpand) {\n setExpanded(running)\n setAutoClosed(!running)\n }\n // A commit that changes this block's height must hand the follower its\n // correction in the SAME task, before the grown-but-uncompensated frame\n // can reach a paint.\n notifyFollowCommit(commitAnchorRef.current)\n }, [running, thinkAutoExpand])\n\n useEffect(() => {\n const element = summaryRef.current\n if (element === null) return\n element.scrollLeft = running ? element.scrollWidth - element.clientWidth : 0\n }, [running, summary])\n\n // Preserve FollowHost's layout wrapper without mounting a second scroll owner.\n return (\n <div className={css.follow} ref={commitAnchorRef}>\n <div className={css.think} data-variant=\"think\" data-state={running ? 'running' : 'ok'}>\n {running && <span className={css.visuallyHidden}>{t('row.running')}</span>}\n <AnimatedDisclosure\n rowClassName={css.thinkRow}\n leadingClassName={css.thinkLeading}\n titleClassName={css.thinkTitle}\n chevronClassName={css.thinkChevron}\n icon={<IconThinkOutline14 size={14} />}\n title=\"Think\"\n open={expanded}\n onToggle={() => {\n setAutoClosed(false)\n setExpanded(value => !value)\n }}\n // The auto-close at stream end snaps (no grid-track animation): the\n // follower's settle spring absorbs the height step through the\n // compositor, so animating the track too would double-animate the\n // collapse. Manual toggles while streaming keep the glide.\n bodyTransition={!autoClosed}\n collapsedContent={(\n <>\n <span className={css.thinkSeparator} aria-hidden />\n <span ref={summaryRef} className={css.thinkSummary} data-follow-end={running || undefined}>{summary}</span>\n </>\n )}\n >\n <div className={css.thinkBody}>{shown}</div>\n </AnimatedDisclosure>\n </div>\n </div>\n )\n}\n\n/**\n * Assistant node renderer for the typewriter overlay. Text observed while\n * streaming is revealed by the smoother through the Harness Markdown\n * renderer at a rate that tracks arrival. Reasoning blocks keep the\n * built-in Think disclosure and only receive a smoothed text feed; the\n * outer node owns conversation-port follow while streaming; the final text\n * block keeps ownership while its settled reveal queue drains. The FPS guard\n * holds offscreen reveals when the frame rate is degraded. Settled text\n * renders with the full Markdown pipeline.\n */\nexport const TypewriterAssistantNodeView = memo(function TypewriterAssistantNodeView({\n mode: _mode = DEFAULT_STREAM_CONFIG.mode,\n preset = DEFAULT_STREAM_CONFIG.preset,\n revealCharsPerSec: _revealCharsPerSec = DEFAULT_STREAM_CONFIG.revealCharsPerSec,\n scrollSpeedPxPerSec: _scrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.scrollSpeedPxPerSec,\n maxScrollSpeedPxPerSec: _maxScrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.maxScrollSpeedPxPerSec,\n thinkAutoExpand = DEFAULT_STREAM_SETTINGS.thinkAutoExpand,\n controlScroll = true,\n motionPreference = DEFAULT_STREAM_SETTINGS.motionPreference,\n node,\n useTurnData,\n openFile,\n loadImage,\n fileMentions,\n turnProcess,\n t,\n}: AssistantProps & {\n mode?: StreamMode\n preset?: StreamSmoothingPreset\n revealCharsPerSec?: number\n scrollSpeedPxPerSec?: number\n maxScrollSpeedPxPerSec?: number\n thinkAutoExpand?: boolean\n controlScroll?: boolean\n motionPreference?: StreamMotionPreference\n}) {\n const data = node.data\n const streaming = data.status === 'running'\n const reduced = useMotionReduced(motionPreference)\n // The Host's completion-fold decision for THIS node's inline reasoning:\n // only the answer step folds, only in compact-transcript mode, and only\n // once the turn has closed (foldable implies it). Mirrors the built-in\n // assistant renderer so the takeover keeps the official behavior.\n const reasoningHidden = turnProcess !== undefined\n && turnProcess.foldable\n && turnProcess.spec.answerStep === data.step\n && turnProcess.spec.inlineReasoning\n && !turnProcess.open\n const revealProcess = useCallback(() => { turnProcess?.setOpen(true) }, [turnProcess])\n const { ref: guardRef, shouldHoldBack } = useFpsGuard(streaming)\n const rootSpeedRef = useRef(35)\n const rootRevealedCharsRef = useRef(0)\n const rootRevealScaleRef = useRef(1)\n const reasoningTailIndex = streaming && data.blocks[data.blocks.length - 1]?.kind === 'reasoning'\n ? data.blocks.length - 1\n : -1\n const reasoningOwnsSpeed = reasoningTailIndex !== -1\n const rootPredictiveRef = useRef(false)\n const previousReasoningTailRef = useRef(-1)\n if (reasoningTailIndex !== previousReasoningTailRef.current) {\n // Think growth is already paced by its own text reveal. Opening additional\n // speculative runway here exposes that runway as an empty gap above the\n // fixed turn status, especially when reasoning arrives in fast bursts.\n // The follower still smooths real height growth within the measured gap\n // and catches up any unsafe remainder in the same frame.\n rootPredictiveRef.current = false\n if (!reasoningOwnsSpeed) rootSpeedRef.current = 35\n previousReasoningTailRef.current = reasoningTailIndex\n }\n const updateTextPrediction = useMemo(\n () => (predictive: boolean): void => { rootPredictiveRef.current = predictive },\n [],\n )\n const turn = node.location.kind === 'turn' || node.location.kind === 'step'\n ? node.location.turn\n : undefined\n const tail = useTurnData('turn-tail')\n const owner = useMemo<TurnTailOwnerProps | undefined>(() => {\n if (turn?.status !== 'closed' || data.finalNode === undefined) return undefined\n if (tail?.closing?.finalNode.seq !== data.finalNode.seq) return undefined\n return { turn, seq: data.finalNode.seq, openFile }\n }, [data.finalNode, openFile, tail, turn])\n const mentions = useMemo(\n () => owner === undefined ? undefined : fileMentions(owner),\n [fileMentions, owner],\n )\n const markdownLabels = useMemo(() => ({\n code: { copyLabel: t('copy'), copiedLabel: t('copied') },\n footnotes: t('markdown.footnotes'),\n }), [t])\n const imageLoader: ImageLoader = loadImage ?? (async () => {\n throw new Error(t('image.serviceUnavailable'))\n })\n const hasVisible = streaming\n || data.status === 'interrupted'\n || data.blocks.some(block => block.kind !== 'tool-call')\n if (!hasVisible) return null\n const announcementText = data.blocks\n .filter(block => block.kind === 'text')\n .map(block => block.text)\n .join('\\n')\n\n const rendered: ReactNode[] = []\n const last = data.blocks.length - 1\n let lastFollow = -1\n for (let index = 0; index < data.blocks.length; index += 1) {\n const kind = data.blocks[index]?.kind\n if (kind === 'text' || kind === 'reasoning') lastFollow = index\n }\n for (let index = 0; index < data.blocks.length; index += 1) {\n const block = data.blocks[index]\n if (block === undefined) continue\n switch (block.kind) {\n case 'text':\n rendered.push(\n <AnimatedMarkdownText\n key={index}\n text={block.text}\n labels={markdownLabels}\n fileMentions={mentions}\n streaming={streaming}\n motionReduced={reduced}\n ownFollow={!streaming && index === lastFollow}\n followSpeedCpsRef={index === lastFollow ? rootSpeedRef : undefined}\n followRevealedCharsRef={index === lastFollow ? rootRevealedCharsRef : undefined}\n followRevealScaleRef={index === lastFollow ? rootRevealScaleRef : undefined}\n onPredictiveChange={index === lastFollow ? updateTextPrediction : undefined}\n preset={preset}\n shouldHoldBack={shouldHoldBack}\n controlScroll={controlScroll}\n />,\n )\n break\n case 'reasoning':\n rendered.push(\n <FoldableReasoning key={index} hidden={reasoningHidden} reveal={revealProcess}>\n <AnimatedReasoning\n text={block.text}\n running={streaming && index === last}\n preset={preset}\n thinkAutoExpand={thinkAutoExpand}\n motionReduced={reduced}\n shouldHoldBack={shouldHoldBack}\n followSpeedCpsRef={reasoningOwnsSpeed && index === last ? rootSpeedRef : undefined}\n followRevealScaleRef={reasoningOwnsSpeed && index === last ? rootRevealScaleRef : undefined}\n t={t}\n />\n </FoldableReasoning>,\n )\n break\n case 'image': {\n const start = index\n const group = [block]\n while (index + 1 < data.blocks.length) {\n const next = data.blocks[index + 1]\n if (next === undefined || next.kind !== 'image') break\n group.push(next)\n index += 1\n }\n rendered.push(\n <ImageGallery key={start} images={group} load={imageLoader} align=\"start\" labels={imageLabels(t)} />,\n )\n break\n }\n case 'tool-call':\n break\n case 'other':\n rendered.push(\n <JsonBlock\n key={index}\n label={t('message.unknownBlock')}\n payload={block.block}\n truncatedLabel={total => t('json.truncated', { total })}\n />,\n )\n break\n }\n }\n\n return (\n <div ref={guardRef} className={css.root} data-streaming={streaming || undefined}>\n <StreamAnnouncement text={announcementText} active={streaming && !reduced} />\n <FollowHost\n active={streaming && !reduced}\n speedCpsRef={rootSpeedRef}\n revealedCharsRef={rootRevealedCharsRef}\n revealScaleRef={rootRevealScaleRef}\n predictiveRef={rootPredictiveRef}\n controlScroll={controlScroll}\n >\n <div className={css.body}>\n {rendered}\n {data.status === 'interrupted' && <span className={css.stopped}>{t('message.stopped')}</span>}\n </div>\n </FollowHost>\n </div>\n )\n})\n","/**\n * Progressive text reveal for opaque Agent renderers.\n *\n * Slot renderers own arbitrary React trees, so the generic integration cannot\n * clone or classify their business components. This hook leaves that tree and\n * all of its event handlers in place, and only paces visible Text node data\n * while the row belongs to the live Agent turn. No clip, mask, overlay, or\n * duplicate accessibility tree is introduced.\n */\n\nimport { useLayoutEffect, type RefObject } from 'react'\nimport { computeAdaptiveQueueStep } from './useSmoothStreamContent.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\ninterface TextRevealRecord {\n chars: readonly string[]\n full: string\n shown: number\n}\n\n/** Last presented text per root, retained across follow lifecycle flips. */\nconst ledgerByRoot = new WeakMap<HTMLElement, Map<Text, TextRevealRecord>>()\n\nconst SKIP_TEXT_SELECTOR = [\n '[aria-hidden=\"true\"]',\n '[aria-live]',\n '[contenteditable=\"true\"]',\n 'script',\n 'style',\n 'textarea',\n].join(',')\n\nfunction revealable(node: Text, root: HTMLElement): boolean {\n if (node.data.trim() === '') return false\n const parent = node.parentElement\n return parent !== null\n && root.contains(parent)\n && parent.closest(SKIP_TEXT_SELECTOR) === null\n}\n\nfunction commonPrefix(left: readonly string[], right: readonly string[]): number {\n const limit = Math.min(left.length, right.length)\n let index = 0\n while (index < limit && left[index] === right[index]) index += 1\n return index\n}\n\n/**\n * Pace text inside a renderer whose React component is intentionally opaque.\n * Initial content is revealed only for a genuinely new row; later mutations\n * stay paced until `enabled` becomes false, at which point the full renderer\n * content is restored synchronously before paint.\n */\nexport function useProgressiveDomText(\n rootRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n revealInitial: boolean,\n speedCpsRef: { current: number },\n onSettled?: (() => void) | undefined,\n): void {\n useLayoutEffect(() => {\n const root = rootRef.current\n if (root === null || typeof document === 'undefined') return\n\n let records = ledgerByRoot.get(root)\n if (!enabled && records === undefined) return\n if (records === undefined) {\n records = new Map<Text, TextRevealRecord>()\n ledgerByRoot.set(root, records)\n }\n\n const forEachText = (from: Node, callback: (text: Text) => void): void => {\n if (from.nodeType === Node.TEXT_NODE) {\n callback(from as Text)\n return\n }\n const walker = document.createTreeWalker(from, NodeFilter.SHOW_TEXT)\n let current = walker.nextNode()\n while (current !== null) {\n callback(current as Text)\n current = walker.nextNode()\n }\n }\n\n const settle = (text: Text): void => {\n if (!revealable(text, root)) return\n const chars = [...text.data]\n records.set(text, { chars, full: text.data, shown: chars.length })\n }\n\n const snapshotVisible = (): void => {\n const current = new Set<Text>()\n forEachText(root, (text) => {\n if (!revealable(text, root)) return\n current.add(text)\n settle(text)\n })\n for (const text of records.keys()) {\n if (!current.has(text)) records.delete(text)\n }\n }\n\n if (!enabled) {\n snapshotVisible()\n const observer = typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver(snapshotVisible)\n observer?.observe(root, { childList: true, characterData: true, subtree: true })\n return () => {\n observer?.disconnect()\n }\n }\n\n const pending = new Set<Text>()\n const internalWrites = new WeakMap<Text, string>()\n let rafId = 0\n let lastFrame: number | null = null\n let debt = 0\n let stopped = false\n let announcedSettled = false\n const streamId = `dom-${Math.random().toString(36).slice(2)}`\n\n const announceSettled = (): void => {\n lastFrame = null\n debt = 0\n speedCpsRef.current = 35\n debugRuntime.reportStream(streamId, null)\n if (announcedSettled) return\n announcedSettled = true\n onSettled?.()\n }\n\n const write = (node: Text, value: string): void => {\n if (node.data === value) return\n internalWrites.set(node, value)\n node.data = value\n }\n\n const enqueue = (node: Text, full: string, preserve: TextRevealRecord | undefined): void => {\n if (!revealable(node, root)) return\n const chars = [...full]\n const preserved = preserve === undefined\n ? 0\n : Math.min(preserve.shown, commonPrefix(preserve.chars, chars))\n const record = { chars, full, shown: preserved }\n records.set(node, record)\n if (preserved < chars.length) {\n pending.add(node)\n announcedSettled = false\n } else {\n pending.delete(node)\n }\n write(node, chars.slice(0, preserved).join(''))\n }\n\n const visit = (from: Node, reveal: boolean): void => {\n forEachText(from, (text) => {\n if (!revealable(text, root)) return\n if (reveal) {\n enqueue(text, text.data, records.get(text))\n return\n }\n settle(text)\n })\n }\n\n const forget = (from: Node): void => {\n forEachText(from, (text) => {\n if (root.contains(text)) return\n records.delete(text)\n pending.delete(text)\n })\n }\n\n const scheduleFrame = (): void => {\n if (stopped || pending.size === 0 || rafId !== 0) return\n rafId = requestAnimationFrame(frame)\n }\n\n const frame = (now: number): void => {\n rafId = 0\n if (stopped) return\n if (pending.size === 0) {\n announceSettled()\n return\n }\n announcedSettled = false\n if (lastFrame === null) {\n lastFrame = now\n scheduleFrame()\n return\n }\n const elapsed = Math.max(0, now - lastFrame)\n lastFrame = now\n let backlog = 0\n for (const node of pending) {\n const record = records.get(node)\n if (record !== undefined) backlog += record.chars.length - record.shown\n }\n const step = computeAdaptiveQueueStep(backlog, elapsed, debt, 1, debugRuntime.activeTuning())\n debt = step.debt\n speedCpsRef.current = step.speedCps\n let remaining = step.revealChars\n for (const node of [...pending]) {\n if (remaining <= 0) break\n const record = records.get(node)\n if (record === undefined || !node.isConnected) {\n pending.delete(node)\n records.delete(node)\n continue\n }\n const amount = Math.min(remaining, record.chars.length - record.shown)\n const shown = record.shown + amount\n const next = { ...record, shown }\n records.set(node, next)\n write(node, next.chars.slice(0, shown).join(''))\n remaining -= amount\n if (shown >= next.chars.length) pending.delete(node)\n }\n let targetChars = 0\n let displayedChars = 0\n let nextBacklog = 0\n for (const [node, record] of records) {\n if (!node.isConnected) {\n records.delete(node)\n pending.delete(node)\n continue\n }\n targetChars += record.chars.length\n displayedChars += record.shown\n if (pending.has(node)) nextBacklog += record.chars.length - record.shown\n }\n debugRuntime.reportStream(streamId, {\n backlog: nextBacklog,\n speedCps: step.speedCps,\n targetChars,\n displayedChars,\n active: pending.size > 0,\n })\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n }\n\n visit(root, revealInitial)\n\n const observer = typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'characterData') {\n const node = mutation.target as Text\n const expected = internalWrites.get(node)\n if (expected === node.data) {\n internalWrites.delete(node)\n continue\n }\n enqueue(node, node.data, records.get(node))\n continue\n }\n for (const removed of mutation.removedNodes) forget(removed)\n for (const added of mutation.addedNodes) visit(added, true)\n }\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n })\n observer?.observe(root, { childList: true, characterData: true, subtree: true })\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n\n return () => {\n stopped = true\n cancelAnimationFrame(rafId)\n observer?.disconnect()\n for (const [node, record] of records) {\n const controlled = record.chars.slice(0, record.shown).join('')\n // React may have committed a terminal replacement in the same mutation\n // phase that disables this hook. Never overwrite that newer renderer\n // value with the previous controlled source during layout cleanup.\n if (node.isConnected && node.data === controlled) {\n write(node, record.full)\n }\n }\n pending.clear()\n speedCpsRef.current = 35\n debugRuntime.reportStream(streamId, null)\n }\n }, [enabled, onSettled, revealInitial, rootRef, speedCpsRef])\n}\n","import { createElement, useCallback, useEffect, useLayoutEffect, useRef, useState, type ComponentType } from 'react'\nimport { FollowHost } from './FollowHost.tsx'\nimport { useProgressiveDomText } from './useProgressiveDomText.ts'\nimport { hasRecentConversationFollow } from './teleprompterGlide.ts'\nimport entranceCss from './AgentRowEntrance.module.css'\n\n/** Props forwarded through a follow wrap; extra kit seats pass through. */\nexport type FollowWrapProps = {\n node?: unknown\n renderSlot?: unknown\n} & Record<string, unknown>\n\nfunction openAgentLocation(node: unknown): boolean {\n if (node === null || typeof node !== 'object' || !('location' in node)) return false\n const location = (node as { location: unknown }).location\n if (location === null || typeof location !== 'object' || !('kind' in location)) return false\n const kind = (location as { kind: unknown }).kind\n if (!('turn' in location)) return false\n const turn = (location as { turn: unknown }).turn\n if (turn === null || typeof turn !== 'object' || !('status' in turn)) return false\n if (kind === 'turn') return (turn as { status: unknown }).status === 'open'\n if (kind !== 'step' || !('step' in location)) return false\n const step = (location as { step: unknown }).step\n return step !== null\n && typeof step === 'object'\n && 'status' in step\n && (step as { status: unknown }).status === 'open'\n}\n\n/**\n * True while a Chat node has an explicitly unfinished lifecycle: an\n * assistant/workflow `status: 'running'` payload, a Tool root that has not\n * settled (`kind` absent), or a model-retry whose current attempt is still\n * `scheduled`. Open-but-otherwise-unknown rows are covered by\n * `isFollowableChatNode` below.\n * @param node - The Chat node's view `node` prop.\n * @returns whether this row should own conversation follow.\n */\nexport function isGrowingChatNode(node: unknown): boolean {\n if (node === null || typeof node !== 'object' || !('data' in node)) return false\n const data = (node as { data: unknown }).data\n if (data === null || typeof data !== 'object') return false\n if ('status' in data && (data as { status: unknown }).status === 'running') return true\n if (\n 'kind' in data\n && (data as { kind: unknown }).kind === 'command'\n && 'outcome' in data\n && (data as { outcome: unknown }).outcome === null\n ) return true\n if ('command' in data) {\n const command = (data as { command: unknown }).command\n if (\n command !== null\n && typeof command === 'object'\n && 'outcome' in command\n && (command as { outcome: unknown }).outcome === null\n ) return true\n }\n if ('root' in data) {\n const root = (data as { root: unknown }).root\n if (root !== null && typeof root === 'object' && !('kind' in root)) return true\n }\n if ('current' in data) {\n const current = (data as { current: unknown }).current\n if (\n current !== null\n && typeof current === 'object'\n && 'retryState' in current\n && (current as { retryState: unknown }).retryState === 'scheduled'\n ) return true\n }\n return false\n}\n\n/**\n * True for any Agent-owned Chat row in the currently open turn/step. This is\n * the extensibility boundary: a newly registered Context, Command, Tool, or\n * workflow renderer is followed without adding another kind-specific branch.\n */\nexport function isFollowableChatNode(node: unknown): boolean {\n return isGrowingChatNode(node) || openAgentLocation(node)\n}\n\n/**\n * True when a newly mounted Agent-owned row belongs to the current open\n * Turn/Step, or is itself an unresolved growing lifecycle.\n * @param node - The Chat node's view `node` prop.\n * @returns whether its initial height should enter through conversation follow.\n */\nexport function shouldAnimateChatNodeEntrance(node: unknown): boolean {\n return isFollowableChatNode(node)\n}\n\n/** Runtime-only fallback for unknown or terminal rows at the active flow tip. */\nfunction liveAgentTailMode(root: HTMLElement): 'turn' | 'handoff' | null {\n const port = root.closest<HTMLElement>('[data-conversation-scroll]')\n if (port === null) return null\n const row = root.closest<HTMLElement>('[data-chat-flow-key]')\n if (row !== null) {\n let sibling = row.nextElementSibling\n while (sibling !== null) {\n if (sibling instanceof HTMLElement && sibling.hasAttribute('data-chat-flow-key')) return null\n sibling = sibling.nextElementSibling\n }\n }\n const flow = root.closest<HTMLElement>('[data-chat-flow]')\n const hasTurnStatus = flow !== null && [...flow.children].some(child =>\n child instanceof HTMLElement\n && child.getAttribute('role') === 'status'\n && !child.hasAttribute('data-chat-flow-key'))\n if (hasTurnStatus) return 'turn'\n return hasRecentConversationFollow(port) ? 'handoff' : null\n}\n\n/**\n * Wrap a prior Agent Chat renderer so its entrance and later growth share\n * conversation follow. Presentation stays with the wrapped component; kit\n * seats (`renderSlot`, locale, inject) pass through unchanged.\n * @param Inner - The already-registered row component.\n * @returns A follow-hosted row.\n */\nexport function wrapFollowNodeView(\n Inner: ComponentType<FollowWrapProps>,\n useControlScroll?: () => boolean,\n) {\n return function TypewriterFollowNodeView(props: FollowWrapProps) {\n const controlScroll = useControlScroll?.() ?? true\n const speedCpsRef = useRef(35)\n const hostRef = useRef<HTMLDivElement>(null)\n const growing = isGrowingChatNode(props.node)\n const structurallyFollowable = isFollowableChatNode(props.node)\n const structuralRef = useRef(structurallyFollowable)\n const [runtimeFollowable, setRuntimeFollowable] = useState(false)\n const runtimePersistentRef = useRef(false)\n const runtimeHandledRef = useRef(false)\n const followable = structurallyFollowable || runtimeFollowable\n const revealInitialRef = useRef(true)\n const [entering, setEntering] = useState(() => shouldAnimateChatNodeEntrance(props.node))\n const [growthPulse, setGrowthPulse] = useState(false)\n const followableRef = useRef(false)\n const growingRef = useRef(growing)\n const entranceActiveRef = useRef(entering || growthPulse)\n const growthExtentRef = useRef<number | null>(null)\n const mountedRef = useRef(true)\n const pulseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n structuralRef.current = structurallyFollowable\n followableRef.current = followable\n growingRef.current = growing\n entranceActiveRef.current = entering || growthPulse\n const finishRuntimeReveal = useCallback(() => {\n if (structuralRef.current || runtimePersistentRef.current) return\n runtimeHandledRef.current = true\n setRuntimeFollowable(false)\n }, [])\n useProgressiveDomText(\n hostRef,\n followable,\n revealInitialRef.current,\n speedCpsRef,\n runtimeFollowable ? finishRuntimeReveal : undefined,\n )\n useLayoutEffect(() => {\n if (structurallyFollowable) return\n const root = hostRef.current\n if (root === null) return\n const mode = liveAgentTailMode(root)\n if (runtimeFollowable) {\n if (runtimePersistentRef.current && mode !== 'turn') {\n runtimePersistentRef.current = false\n runtimeHandledRef.current = true\n setRuntimeFollowable(false)\n }\n return\n }\n if (runtimeHandledRef.current || mode === null) return\n runtimePersistentRef.current = mode === 'turn'\n setRuntimeFollowable(true)\n setEntering(true)\n }, [runtimeFollowable, structurallyFollowable])\n const finishEntrance = useCallback(() => {\n growthExtentRef.current = null\n if (pulseTimerRef.current !== null) {\n clearTimeout(pulseTimerRef.current)\n pulseTimerRef.current = null\n }\n setEntering(false)\n setGrowthPulse(false)\n }, [])\n const onGrowth = useCallback((deltaPx: number) => {\n // A row with an explicit streaming lifecycle keeps its original owner\n // through completion. For every other Agent row, a pure layout increase\n // is enough evidence to glide it; renderer kind and payload shape are\n // intentionally irrelevant.\n if (\n !mountedRef.current\n || !followableRef.current\n || growingRef.current\n || entranceActiveRef.current\n ) return\n growthExtentRef.current = deltaPx\n setGrowthPulse(true)\n if (pulseTimerRef.current !== null) clearTimeout(pulseTimerRef.current)\n pulseTimerRef.current = setTimeout(() => {\n pulseTimerRef.current = null\n setGrowthPulse(false)\n }, 1200)\n }, [])\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n if (pulseTimerRef.current !== null) clearTimeout(pulseTimerRef.current)\n }\n }, [])\n return (\n <FollowHost\n active={growing}\n entrance={entering || growthPulse}\n onEntranceSettled={finishEntrance}\n onGrowth={followable ? onGrowth : undefined}\n entranceExtentRef={growthExtentRef}\n speedCpsRef={speedCpsRef}\n controlScroll={controlScroll}\n // Generic Agent rows reveal and spring their measured growth, but do\n // not continuously reserve space for a future Markdown line wrap.\n // Keeping that assistant-only prediction here creates an idle gap\n // above TurnStatus and a visible return when a short Tool row settles.\n predictive={false}\n hostRef={hostRef}\n className={entranceCss.surface}\n entranceActive={entering || growthPulse}\n >\n {createElement(Inner, props)}\n </FollowHost>\n )\n }\n}\n","/**\n * The smooth-stream plugin configuration card, rendered inside the Web\n * Settings \"plugin configuration\" page. Preferences are staged until the user\n * saves — the same shape as the Host-shipped cards, hand-drawn because the\n * Host cards' chrome is not exported for reuse.\n */\n\nimport { useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { IconChevronDownOutline14, IconRefreshOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { SmoothStreamCardFace } from './smooth-stream-card-controller.ts'\nimport css from './SmoothStreamCard.module.css'\n\n/** Props the renderer binds for the smooth-stream card. */\nexport type SmoothStreamCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'settings.smoothStream'>\n & InjectFace<SmoothStreamCardFace>\n\n/** Render the smooth-stream card independently of the core settings namespace allowlist. */\nexport function SmoothStreamCard(props: SmoothStreamCardProps) {\n const { t } = props\n const [open, setOpen] = useState(false)\n const state = props.useSmoothStreamCard(snapshot => snapshot)\n const blocked = !state.dirty || state.saving || state.status !== 'ready'\n const versionLabel = state.version === undefined\n ? null\n : t(state.installation === 'development' ? 'developmentVersion' : 'version')\n .replace('{version}', state.version)\n\n return (\n <li className={open ? `${css.card} ${css.cardOpen}` : css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {versionLabel === null ? null : <span className={css.version}>{versionLabel}</span>}\n {state.dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron} />\n </button>\n {open\n ? (\n <div className={css.body}>\n {state.status === 'loading' ? <p className={css.readOnly} role=\"status\">{t('loading')}</p> : null}\n {state.status === 'unavailable' ? (\n <div className={css.failure}>\n <p className={css.readOnly} role=\"status\">{t('unavailable')}</p>\n <button type=\"button\" className={css.discard} onClick={props.reload}>{t('retry')}</button>\n </div>\n ) : null}\n {state.status === 'ready' ? (\n <>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n <label className={css.field}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('enabled')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.enabled}\n disabled={!state.writable || state.saving}\n onChange={(event) => { props.edit({ enabled: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('enabledHint')}</span>\n </label>\n <label className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('controlScroll')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.controlScroll}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={(event) => { props.edit({ controlScroll: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('controlScrollHint')}</span>\n </label>\n {/* Motion preference is a radio group, so this row is a div:\n nesting the choice labels inside a field <label> would be\n illegal HTML (label within label) and browsers route the\n inner click away, so React never sees onChange. */}\n <div className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('motionPreference')}</span>\n </span>\n <span className={css.hint}>{t('motionPreferenceHint')}</span>\n <span className={css.choiceRow} role=\"radiogroup\" aria-label={t('motionPreference')}>\n {([\n ['auto', 'motionAuto', 'motionAutoHint'],\n ['force-smooth', 'motionForceSmooth', 'motionForceSmoothHint'],\n ['force-reduced', 'motionForceReduced', 'motionForceReducedHint'],\n ] as const).map(([value, label, hint]) => (\n <label key={value} className={css.choice} title={t(hint)}>\n <input\n type=\"radio\"\n className={css.choiceInput}\n name=\"smooth-stream-motion\"\n checked={state.motionPreference === value}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={() => { props.edit({ motionPreference: value }) }}\n />\n {t(label)}\n </label>\n ))}\n </span>\n </div>\n <label className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('thinkAutoExpand')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.thinkAutoExpand}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={(event) => { props.edit({ thinkAutoExpand: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('thinkAutoExpandHint')}</span>\n </label>\n <label className={state.debugAvailable ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('debugEnabled')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.debugEnabled}\n disabled={!state.debugAvailable || !state.writable || state.saving}\n onChange={(event) => { props.edit({ debugEnabled: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{state.debugAvailable ? t('debugEnabledHint') : t('debugUnavailable')}</span>\n </label>\n <div className={css.updateRow}>\n <span className={css.updateCopy}>\n <span className={css.label}>{t('updates')}</span>\n <span className={css.hint}>\n {state.restartRequired\n ? t('restartRequired')\n : state.installation === 'npm' ? t('updateHint')\n : state.installation === 'development' ? t('developmentBuild') : t('updateUnavailable')}\n </span>\n </span>\n <button\n type=\"button\"\n className={css.update}\n disabled={!state.canUpgrade || state.upgrading || state.restartRequired}\n title={state.canUpgrade ? undefined : t('updateUnavailable')}\n onClick={props.upgrade}\n >\n <span aria-hidden=\"true\"><IconRefreshOutline14 /></span>\n {t(state.upgrading ? 'updating' : 'update')}\n </button>\n </div>\n {state.upgradeFailed ? <p className={css.failed} role=\"status\">{t('updateFailed')}</p> : null}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{t('saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.discard}\n >\n {t('discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </button>\n </div>\n </>\n ) : null}\n </div>\n )\n : null}\n </li>\n )\n}\n","/** Staged form state for the plugin-owned smooth-stream settings RPC. */\n\nimport { createSnapshotStore, type SnapshotStore } from './clientStore.ts'\nimport {\n DEFAULT_STREAM_DEBUG_TUNING,\n DEFAULT_STREAM_SETTINGS,\n type StreamDebugTuning,\n type StreamMotionPreference,\n type StreamSettings,\n} from '../settings.ts'\nimport type {\n StreamDebugSettingsView,\n StreamInstallationKind,\n StreamSettingsView,\n} from '../settings-api.ts'\nimport type { SmoothStreamSettingsApi } from './smooth-stream-settings-api.ts'\n\n/** What the smooth-stream card renders. It remains visible while its Host RPC loads. */\nexport interface SmoothStreamCardState {\n status: 'loading' | 'ready' | 'unavailable'\n writable: boolean\n dirty: boolean\n saving: boolean\n failed: boolean\n enabled: boolean\n controlScroll: boolean\n motionPreference: StreamMotionPreference\n thinkAutoExpand: boolean\n debugEnabled: boolean\n debugTuning: StreamDebugTuning\n debugAvailable: boolean\n version: string | undefined\n installation: StreamInstallationKind\n canUpgrade: boolean\n upgrading: boolean\n upgradeFailed: boolean\n restartRequired: boolean\n}\n\n/** The registration-side face injected into the settings slot renderer. */\nexport interface SmoothStreamCardFace {\n hooks: {\n smoothStreamCard: SnapshotStore<SmoothStreamCardState>\n }\n edit: (patch: Partial<StreamSettings>) => void\n save: () => void\n discard: () => void\n reload: () => void\n upgrade: () => void\n}\n\n/** Bridges the plugin's protected Host interface onto a staged settings form. */\nexport class SmoothStreamCardController {\n private readonly store = createSnapshotStore<SmoothStreamCardState>(this.projection())\n private loaded: StreamSettingsView | undefined\n private loadedDebug: StreamDebugSettingsView | undefined\n private stagedBase: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand'> | undefined\n private stagedDebug: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'> | undefined\n private saving = false\n private failed = false\n private upgrading = false\n private upgradeFailed = false\n private restartRequired = false\n private loadGeneration = 0\n private loadStatus: 'loading' | 'ready' | 'unavailable' = 'loading'\n\n constructor(private readonly api: SmoothStreamSettingsApi) {}\n\n /** Begin the background read after the card has been registered. */\n start(): void {\n void this.load()\n }\n\n /** Ignore a late response after the surrounding optional services unload. */\n stop(): void {\n this.loadGeneration += 1\n }\n\n /** Current card snapshot, also consumed by the streaming preference cell. */\n getSnapshot(): SmoothStreamCardState {\n return this.store.getSnapshot()\n }\n\n /** Subscribe to state changes. */\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** Build the face consumed by the settings slot renderer. */\n inject(): SmoothStreamCardFace {\n return {\n hooks: { smoothStreamCard: this.store },\n edit: (patch) => {\n if (this.saving) return\n if (patch.enabled !== undefined || patch.controlScroll !== undefined || patch.motionPreference !== undefined || patch.thinkAutoExpand !== undefined) {\n this.stagedBase = {\n ...this.baseValues(),\n ...(patch.enabled === undefined ? {} : { enabled: patch.enabled }),\n ...(patch.controlScroll === undefined ? {} : { controlScroll: patch.controlScroll }),\n ...(patch.motionPreference === undefined ? {} : { motionPreference: patch.motionPreference }),\n ...(patch.thinkAutoExpand === undefined ? {} : { thinkAutoExpand: patch.thinkAutoExpand }),\n }\n }\n if (this.loadedDebug !== undefined && (patch.debugEnabled !== undefined || patch.debugTuning !== undefined)) {\n this.stagedDebug = {\n ...this.debugValues(),\n ...(patch.debugEnabled === undefined ? {} : { debugEnabled: patch.debugEnabled }),\n ...(patch.debugTuning === undefined ? {} : { debugTuning: { ...this.debugValues().debugTuning, ...patch.debugTuning } }),\n }\n }\n this.failed = false\n this.publish()\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.stagedBase === undefined && this.stagedDebug === undefined && !this.failed) return\n this.stagedBase = undefined\n this.stagedDebug = undefined\n this.failed = false\n this.publish()\n },\n reload: () => { void this.load() },\n upgrade: () => { void this.upgrade() },\n }\n }\n\n private projection(): SmoothStreamCardState {\n return {\n status: this.loadStatus,\n writable: this.loaded?.writable ?? false,\n dirty: this.stagedBase !== undefined || this.stagedDebug !== undefined,\n saving: this.saving,\n failed: this.failed,\n ...this.baseValues(),\n ...this.debugValues(),\n debugAvailable: this.loadedDebug !== undefined,\n version: this.loaded?.version,\n installation: this.loaded?.installation ?? 'unmanaged',\n canUpgrade: this.loaded?.canUpgrade ?? false,\n upgrading: this.upgrading,\n upgradeFailed: this.upgradeFailed,\n restartRequired: this.restartRequired,\n }\n }\n\n private baseValues(): Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand'> {\n return this.stagedBase ?? {\n enabled: this.loaded?.enabled ?? DEFAULT_STREAM_SETTINGS.enabled,\n controlScroll: this.loaded?.controlScroll ?? DEFAULT_STREAM_SETTINGS.controlScroll,\n motionPreference: this.loaded?.motionPreference ?? DEFAULT_STREAM_SETTINGS.motionPreference,\n thinkAutoExpand: this.loaded?.thinkAutoExpand ?? DEFAULT_STREAM_SETTINGS.thinkAutoExpand,\n }\n }\n\n private debugValues(): Pick<StreamSettings, 'debugEnabled' | 'debugTuning'> {\n return this.stagedDebug ?? {\n debugEnabled: this.loadedDebug?.debugEnabled ?? DEFAULT_STREAM_SETTINGS.debugEnabled,\n debugTuning: this.loadedDebug?.tuning ?? DEFAULT_STREAM_DEBUG_TUNING,\n }\n }\n\n /** Complete settings projection consumed by the live SettingsCell bridge. */\n values(): StreamSettings {\n return { ...this.baseValues(), ...this.debugValues() }\n }\n\n private async load(): Promise<void> {\n const generation = ++this.loadGeneration\n this.loadStatus = 'loading'\n this.loaded = undefined\n this.loadedDebug = undefined\n this.publish()\n try {\n const view = await this.api.read()\n if (generation !== this.loadGeneration) return\n this.loaded = view\n this.loadStatus = 'ready'\n this.publish()\n try {\n const debug = await this.api.readDebug()\n if (generation !== this.loadGeneration) return\n this.loadedDebug = debug\n } catch {\n if (generation !== this.loadGeneration) return\n // Older hosts expose the original settings endpoints only. Keep the\n // card usable and hide debug-only controls until the host is upgraded.\n this.loadedDebug = undefined\n }\n } catch {\n if (generation !== this.loadGeneration) return\n this.loaded = undefined\n this.loadedDebug = undefined\n this.loadStatus = 'unavailable'\n }\n this.publish()\n }\n\n private async save(): Promise<void> {\n if ((this.stagedBase === undefined && this.stagedDebug === undefined)\n || this.saving || this.loaded?.writable !== true) return\n const base = this.stagedBase\n const debug = this.stagedDebug\n this.saving = true\n this.failed = false\n this.publish()\n try {\n if (base !== undefined) {\n const combined = debug !== undefined && this.loadedDebug !== undefined\n this.loaded = await this.api.write(combined ? { ...base, ...debug } : base)\n this.stagedBase = undefined\n if (combined) {\n this.loadedDebug = {\n debugEnabled: debug.debugEnabled,\n tuning: { ...debug.debugTuning },\n }\n this.stagedDebug = undefined\n }\n }\n if (debug !== undefined && this.loadedDebug !== undefined && this.stagedDebug !== undefined) {\n this.loadedDebug = await this.api.writeDebug(debug)\n this.stagedDebug = undefined\n }\n } catch {\n this.failed = true\n }\n this.saving = false\n this.publish()\n }\n\n private async upgrade(): Promise<void> {\n if (this.loaded?.canUpgrade !== true || this.upgrading) return\n this.upgrading = true\n this.upgradeFailed = false\n this.restartRequired = false\n this.publish()\n try {\n const result = await this.api.upgrade()\n this.restartRequired = result.restartRequired\n } catch {\n this.upgradeFailed = true\n }\n this.upgrading = false\n this.publish()\n }\n\n private publish(): void {\n this.store.set(this.projection())\n }\n}\n","/** Shared wire vocabulary for the plugin-owned settings RPC channel. */\n\n/** Dedicated, loopback-only RPC channel registered by the Host half. */\nexport const STREAM_SETTINGS_RPC_CHANNEL = '/smooth-stream'\n\n/** Endpoints accepted by {@link STREAM_SETTINGS_RPC_CHANNEL}. */\nexport const STREAM_SETTINGS_RPC = {\n read: 'settings.read',\n write: 'settings.write',\n debugRead: 'debug.read',\n debugWrite: 'debug.write',\n upgrade: 'plugin.upgrade',\n} as const\n\n/** How the active profile supplied this plugin. */\nexport type StreamInstallationKind = 'npm' | 'development' | 'unmanaged'\n\n/** Redacted, plugin-owned configuration state returned to the browser. */\nexport interface StreamSettingsView {\n /** Version of the package currently running in the Host process. */\n version: string\n /** Source class of this package in the active profile. */\n installation: StreamInstallationKind\n /** Whether the Host settings provider permits a write. */\n writable: boolean\n /** Whether smooth-stream currently owns conversation rendering. */\n enabled: boolean\n /** Whether smooth-stream also owns conversation bottom-follow. */\n controlScroll: boolean\n /** How the reveal honors the OS reduced-motion preference. */\n motionPreference: import('./settings.ts').StreamMotionPreference\n /** Current resolved preference. */\n thinkAutoExpand: boolean\n /** Whether a fixed npm update command is safe to offer. */\n canUpgrade: boolean\n}\n\n/** Debug-only settings returned by the diagnostics RPC. */\nexport interface StreamDebugSettingsView {\n debugEnabled: boolean\n tuning: import('./settings.ts').StreamDebugTuning\n}\n\n/** Successful package update acknowledgement; loading the new code needs a restart. */\nexport interface StreamUpgradeView {\n restartRequired: true\n}\n","/** Browser adapter for the Host-owned smooth-stream settings RPC. */\n\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type { StreamDebugTuning, StreamSettings } from '../settings.ts'\nimport {\n STREAM_SETTINGS_RPC,\n STREAM_SETTINGS_RPC_CHANNEL,\n type StreamDebugSettingsView,\n type StreamSettingsView,\n type StreamUpgradeView,\n} from '../settings-api.ts'\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined\n}\n\nfunction settingsView(value: unknown): StreamSettingsView {\n const data = record(value)\n if (data === undefined\n || typeof data.version !== 'string'\n || !['npm', 'development', 'unmanaged'].includes(data.installation as string)\n || typeof data.writable !== 'boolean'\n || typeof data.enabled !== 'boolean'\n || typeof data.controlScroll !== 'boolean'\n || !['auto', 'force-smooth', 'force-reduced'].includes(data.motionPreference as string)\n || typeof data.thinkAutoExpand !== 'boolean'\n || typeof data.canUpgrade !== 'boolean') {\n throw new Error('dsh-smooth-stream: malformed settings response')\n }\n return data as unknown as StreamSettingsView\n}\n\nfunction upgradeView(value: unknown): StreamUpgradeView {\n const data = record(value)\n if (data?.restartRequired !== true) throw new Error('dsh-smooth-stream: malformed update response')\n return { restartRequired: true }\n}\n\nfunction debugSettingsView(value: unknown): StreamDebugSettingsView {\n const data = record(value)\n const tuning = record(data?.tuning)\n if (data === undefined\n || typeof data.debugEnabled !== 'boolean'\n || tuning === undefined\n || typeof tuning.revealScale !== 'number'\n || typeof tuning.queuePressure !== 'number'\n || typeof tuning.maxRevealCps !== 'number'\n || typeof tuning.springStiffness !== 'number'\n || typeof tuning.springDamping !== 'number'\n || typeof tuning.springMass !== 'number'\n || typeof tuning.runwayPx !== 'number'\n || typeof tuning.reserveResponseMs !== 'number'\n || typeof tuning.backpressureMinScale !== 'number') {\n throw new Error('dsh-smooth-stream: malformed debug settings response')\n }\n return {\n debugEnabled: data.debugEnabled,\n tuning: tuning as unknown as StreamDebugTuning,\n }\n}\n\nfunction accepted(result: Awaited<ReturnType<ConnectionHandle['rpc']['call']>>): unknown {\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n}\n\n/** Narrow client contract consumed by the staged settings-card controller. */\nexport interface SmoothStreamSettingsApi {\n read(): Promise<StreamSettingsView>\n write(settings: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand'> & Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>): Promise<StreamSettingsView>\n readDebug(): Promise<StreamDebugSettingsView>\n writeDebug(settings: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>): Promise<StreamDebugSettingsView>\n upgrade(): Promise<StreamUpgradeView>\n}\n\n/** Build the typed facade over the generic Connection RPC service. */\nexport function createSmoothStreamSettingsApi(connection: ConnectionHandle): SmoothStreamSettingsApi {\n return {\n async read(): Promise<StreamSettingsView> {\n return settingsView(accepted(await connection.rpc.call(STREAM_SETTINGS_RPC_CHANNEL, STREAM_SETTINGS_RPC.read, {})))\n },\n async write(settings: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand'> & Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>): Promise<StreamSettingsView> {\n return settingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.write,\n {\n enabled: settings.enabled,\n controlScroll: settings.controlScroll,\n motionPreference: settings.motionPreference,\n thinkAutoExpand: settings.thinkAutoExpand,\n ...(settings.debugEnabled === undefined || settings.debugTuning === undefined\n ? {}\n : { debugEnabled: settings.debugEnabled, debugTuning: settings.debugTuning }),\n },\n )))\n },\n async readDebug(): Promise<StreamDebugSettingsView> {\n return debugSettingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.debugRead,\n {},\n )))\n },\n async writeDebug(settings: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>): Promise<StreamDebugSettingsView> {\n return debugSettingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.debugWrite,\n { debugEnabled: settings.debugEnabled, tuning: settings.debugTuning },\n )))\n },\n async upgrade(): Promise<StreamUpgradeView> {\n return upgradeView(accepted(await connection.rpc.call(STREAM_SETTINGS_RPC_CHANNEL, STREAM_SETTINGS_RPC.upgrade, {})))\n },\n }\n}\n","import { useEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport {\n IconCloseOutline16,\n IconCodeOutline16,\n IconCopyOutline16,\n IconQuestionOutline14,\n IconRefreshOutline16,\n Tooltip,\n writeClipboard,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { StreamDebugTuning } from '../settings.ts'\nimport type { DebugPanelFace, DebugRuntimeState } from './debugRuntime.ts'\nimport type { NS } from './locales.ts'\nimport css from './DebugPanel.module.css'\n\nexport type DebugPanelProps =\n PropsRuntime<'conversation.session.header.utilities'>\n & PropsLocale<typeof NS>\n & InjectFace<DebugPanelFace>\n\ntype TuningKey = keyof StreamDebugTuning\n\ninterface TuningControl {\n key: TuningKey\n label: Parameters<DebugPanelProps['t']>[0]\n tip: Parameters<DebugPanelProps['t']>[0]\n min: number\n max: number\n step: number\n unit: string\n}\n\nconst REVEAL_CONTROLS: readonly TuningControl[] = [\n { key: 'revealScale', label: 'debugRevealMultiplier', tip: 'debugTipRevealMultiplier', min: 0.25, max: 2, step: 0.05, unit: 'x' },\n { key: 'queuePressure', label: 'debugQueuePressure', tip: 'debugTipQueuePressure', min: 0, max: 2, step: 0.05, unit: 'x' },\n { key: 'maxRevealCps', label: 'debugMaxReveal', tip: 'debugTipMaxReveal', min: 120, max: 1000, step: 10, unit: 'cps' },\n]\n\nconst FOLLOW_CONTROLS: readonly TuningControl[] = [\n { key: 'springStiffness', label: 'debugSpringStiffness', tip: 'debugTipSpringStiffness', min: 40, max: 320, step: 5, unit: '' },\n { key: 'springDamping', label: 'debugSpringDamping', tip: 'debugTipSpringDamping', min: 8, max: 80, step: 1, unit: '' },\n { key: 'springMass', label: 'debugSpringMass', tip: 'debugTipSpringMass', min: 0.5, max: 3, step: 0.05, unit: '' },\n { key: 'runwayPx', label: 'debugRunway', tip: 'debugTipRunway', min: 0, max: 120, step: 2, unit: 'px' },\n { key: 'reserveResponseMs', label: 'debugReserveResponse', tip: 'debugTipReserveResponse', min: 60, max: 600, step: 10, unit: 'ms' },\n { key: 'backpressureMinScale', label: 'debugBackpressureMin', tip: 'debugTipBackpressureMin', min: 0.25, max: 1, step: 0.05, unit: 'x' },\n]\n\nfunction fixed(value: number | null, digits = 1): string {\n return value === null || !Number.isFinite(value) ? '-' : value.toFixed(digits)\n}\n\nfunction Metric({ label, value, tone }: { label: string; value: string; tone?: 'good' | 'warn' | undefined }) {\n return (\n <div className={css.metric}>\n <dt>{label}</dt>\n <dd data-tone={tone}>{value}</dd>\n </div>\n )\n}\n\nfunction TuningField({\n control,\n state,\n edit,\n label,\n t,\n}: {\n control: TuningControl\n state: DebugRuntimeState\n edit: DebugPanelFace['edit']\n label: string\n t: DebugPanelProps['t']\n}) {\n const value = state.tuning[control.key]\n const labelId = `smooth-stream-debug-${control.key}`\n const update = (next: number) => {\n if (!Number.isFinite(next)) return\n const clamped = Math.min(control.max, Math.max(control.min, next))\n edit({ debugTuning: { ...state.tuning, [control.key]: clamped } })\n }\n return (\n <div className={css.control}>\n <span className={css.controlHead}>\n <span className={css.controlLabel}>\n <span id={labelId}>{label}</span>\n <Tooltip label={t(control.tip)} side=\"right\" maxWidth={300}>\n <button\n className={css.infoButton}\n type=\"button\"\n aria-label={label}\n title={t(control.tip)}\n >\n <IconQuestionOutline14 />\n </button>\n </Tooltip>\n </span>\n <span className={css.numberWrap}>\n <input\n className={css.number}\n type=\"number\"\n aria-labelledby={labelId}\n min={control.min}\n max={control.max}\n step={control.step}\n value={value}\n disabled={!state.writable}\n onChange={event => { update(event.currentTarget.valueAsNumber) }}\n />\n {control.unit === '' ? null : <span className={css.unit}>{control.unit}</span>}\n </span>\n </span>\n <input\n className={css.range}\n type=\"range\"\n aria-labelledby={labelId}\n min={control.min}\n max={control.max}\n step={control.step}\n value={value}\n disabled={!state.writable}\n onChange={event => { update(event.currentTarget.valueAsNumber) }}\n />\n </div>\n )\n}\n\nexport function DebugPanel(props: DebugPanelProps) {\n const { t } = props\n const state = props.useDebugRuntime(snapshot => snapshot)\n const [open, setOpen] = useState(true)\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n if (!copied) return\n const timer = setTimeout(() => { setCopied(false) }, 1400)\n return () => { clearTimeout(timer) }\n }, [copied])\n\n useEffect(() => {\n if (state.enabled) setOpen(true)\n }, [state.enabled])\n\n if (!state.available || !state.enabled || !open) return null\n const metrics = state.metrics\n const live = metrics.streamActive || metrics.followActive\n const progress = metrics.streamTargetChars <= 0\n ? '-'\n : `${String(metrics.streamDisplayedChars)} / ${String(metrics.streamTargetChars)}`\n const copyDiagnostics = async () => {\n const accepted = await writeClipboard(JSON.stringify({\n tuning: state.tuning,\n metrics: state.metrics,\n }, null, 2))\n if (accepted) setCopied(true)\n }\n\n const panel = !state.enabled || !open ? null : (\n <aside className={css.panel} role=\"complementary\" aria-label={t('debugPanelTitle')}>\n <header className={css.panelHeader}>\n <span className={live ? `${css.statusDot} ${css.statusLive}` : css.statusDot} aria-hidden />\n <span className={css.title}>{t('debugPanelTitle')}</span>\n <span className={css.state}>{t(live ? 'debugLive' : 'debugIdle')}</span>\n {state.dirty ? <span className={css.unsaved}>{t('debugUnsaved')}</span> : null}\n <button className={css.iconButton} type=\"button\" title={t('debugCopy')} aria-label={t('debugCopy')} onClick={() => { void copyDiagnostics() }}>\n <IconCopyOutline16 />\n </button>\n <button\n className={css.iconButton}\n type=\"button\"\n title={t('debugPanelClose')}\n aria-label={t('debugPanelClose')}\n disabled={!state.writable}\n onClick={() => {\n setOpen(false)\n props.edit({ debugEnabled: false })\n props.save()\n }}\n >\n <IconCloseOutline16 />\n </button>\n <span className={css.visuallyHidden} aria-live=\"polite\">{copied ? t('debugCopied') : ''}</span>\n </header>\n\n <div className={css.scrollArea}>\n <p className={css.guide}>{t('debugGuide')}</p>\n <section className={css.section} aria-labelledby=\"smooth-stream-live-heading\">\n <h2 id=\"smooth-stream-live-heading\">{t('debugSectionLive')}</h2>\n <dl className={css.metrics}>\n <Metric label={t('debugFps')} value={fixed(metrics.fps, 0)} tone={(metrics.fps ?? 60) < 45 ? 'warn' : 'good'} />\n <Metric label={t('debugFrameTime')} value={`${fixed(metrics.frameMs)} ms`} />\n <Metric label={t('debugBacklog')} value={String(metrics.streamBacklog)} tone={metrics.streamBacklog > 32 ? 'warn' : undefined} />\n <Metric label={t('debugRevealSpeed')} value={`${fixed(metrics.streamSpeedCps, 0)} cps`} />\n <Metric label={t('debugProgress')} value={progress} />\n <Metric label={t('debugFollowState')} value={t(metrics.followFollowing ? 'debugFollowing' : 'debugReleased')} />\n <Metric label={t('debugLag')} value={`${fixed(metrics.followLagPx)} px`} tone={metrics.followConstrained ? 'warn' : undefined} />\n <Metric label={t('debugVelocity')} value={`${fixed(metrics.followVelocityPxPerSec, 0)} px/s`} />\n <Metric label={t('debugReserve')} value={`${fixed(metrics.followReservePx)} px`} />\n <Metric label={t('debugCapacity')} value={`${fixed(metrics.followCapacityPx)} px`} />\n <Metric label={t('debugAppliedScale')} value={`${fixed(metrics.followRevealScale, 2)}x`} />\n </dl>\n </section>\n\n <section className={css.section} aria-labelledby=\"smooth-stream-reveal-heading\">\n <h2 id=\"smooth-stream-reveal-heading\">{t('debugSectionReveal')}</h2>\n {REVEAL_CONTROLS.map(control => (\n <TuningField key={control.key} control={control} state={state} edit={props.edit} label={t(control.label)} t={t} />\n ))}\n </section>\n\n <section className={css.section} aria-labelledby=\"smooth-stream-follow-heading\">\n <h2 id=\"smooth-stream-follow-heading\">{t('debugSectionFollow')}</h2>\n {FOLLOW_CONTROLS.map(control => (\n <TuningField key={control.key} control={control} state={state} edit={props.edit} label={t(control.label)} t={t} />\n ))}\n </section>\n </div>\n\n <footer className={css.footer}>\n <button className={css.secondaryButton} type=\"button\" disabled={!state.writable} onClick={props.reset}>\n <IconRefreshOutline16 />\n {t('debugReset')}\n </button>\n <span className={css.footerSpacer} />\n <button className={css.secondaryButton} type=\"button\" disabled={!state.writable || !state.dirty} onClick={props.discard}>{t('debugDiscard')}</button>\n <button className={css.primaryButton} type=\"button\" disabled={!state.writable || !state.dirty} onClick={props.save}>{t('debugSave')}</button>\n </footer>\n </aside>\n )\n\n return (\n <>\n <button\n type=\"button\"\n className={state.enabled && open ? `${css.trigger} ${css.triggerActive}` : css.trigger}\n aria-expanded={state.enabled && open}\n aria-label={t('debugPanelToggle')}\n title={t('debugPanelToggle')}\n onClick={() => { setOpen(current => !current) }}\n >\n <IconCodeOutline16 />\n </button>\n {typeof document === 'undefined' || panel === null ? null : createPortal(panel, document.body)}\n </>\n )\n}\n","/** Locale bundles for the smooth-stream plugin configuration card. */\n\n/** Dictionary namespace owned by this plugin's settings card. */\nexport const NS = 'settings.smoothStream'\n\n/** Locale keys the card renders. */\nexport type SmoothStreamLocaleKey =\n | 'title' | 'description'\n | 'enabled' | 'enabledHint'\n | 'controlScroll' | 'controlScrollHint'\n | 'motionPreference' | 'motionPreferenceHint'\n | 'motionAuto' | 'motionAutoHint'\n | 'motionForceSmooth' | 'motionForceSmoothHint'\n | 'motionForceReduced' | 'motionForceReducedHint'\n | 'thinkAutoExpand' | 'thinkAutoExpandHint'\n | 'debugEnabled' | 'debugEnabledHint' | 'debugUnavailable'\n | 'debugPanelTitle' | 'debugPanelToggle' | 'debugPanelClose' | 'debugGuide'\n | 'debugLive' | 'debugIdle' | 'debugUnsaved'\n | 'debugSave' | 'debugDiscard' | 'debugReset' | 'debugCopy' | 'debugCopied'\n | 'debugSectionLive' | 'debugSectionReveal' | 'debugSectionFollow'\n | 'debugFps' | 'debugFrameTime' | 'debugBacklog' | 'debugRevealSpeed' | 'debugProgress'\n | 'debugFollowState' | 'debugFollowing' | 'debugReleased'\n | 'debugLag' | 'debugVelocity' | 'debugReserve' | 'debugCapacity' | 'debugAppliedScale'\n | 'debugRevealMultiplier' | 'debugQueuePressure' | 'debugMaxReveal'\n | 'debugSpringStiffness' | 'debugSpringDamping' | 'debugSpringMass'\n | 'debugRunway' | 'debugReserveResponse' | 'debugBackpressureMin'\n | 'debugTipRevealMultiplier' | 'debugTipQueuePressure' | 'debugTipMaxReveal'\n | 'debugTipSpringStiffness' | 'debugTipSpringDamping' | 'debugTipSpringMass'\n | 'debugTipRunway' | 'debugTipReserveResponse' | 'debugTipBackpressureMin'\n | 'readOnly' | 'loading' | 'unavailable' | 'retry'\n | 'version' | 'developmentVersion'\n | 'updates' | 'updateHint' | 'developmentBuild' | 'updateUnavailable'\n | 'update' | 'updating' | 'restartRequired' | 'updateFailed'\n | 'save' | 'saving' | 'discard' | 'unsaved' | 'saveFailed'\n\n/** English copy. */\nexport const en: Record<SmoothStreamLocaleKey, string> = {\n title: 'Smooth stream',\n description: 'How replies are revealed while they stream.',\n enabled: 'Enable smooth streaming',\n enabledHint: 'Let this plugin render and follow streaming replies. Turn off to use the built-in Harness renderer.',\n controlScroll: 'Take over scrolling',\n controlScrollHint: 'On by default; smooth-stream writes the conversation scroll position. Turn off to leave bottom-follow to Harness.',\n motionPreference: 'Motion',\n motionPreferenceHint: 'How streaming responds to the system reduce-motion setting.',\n motionAuto: 'Follow system',\n motionAutoHint: 'Reduced-motion systems get raw text (accessibility first).',\n motionForceSmooth: 'Always smooth',\n motionForceSmoothHint: 'Keep the smoothing engine even when the system asks for reduced motion.',\n motionForceReduced: 'Always raw',\n motionForceReducedHint: 'Render raw text even when the system allows motion.',\n thinkAutoExpand: 'Auto-expand thinking',\n thinkAutoExpandHint: 'Open the thinking block while it streams. Turn off to keep it collapsed.',\n debugEnabled: 'Show render diagnostics',\n debugEnabledHint: 'Show live streaming and scroll metrics on the right side of the chat. Tune values there, then save them here.',\n debugUnavailable: 'Live diagnostics require a newer plugin Host.',\n debugPanelTitle: 'Render diagnostics',\n debugPanelToggle: 'Toggle render diagnostics',\n debugPanelClose: 'Hide diagnostics panel',\n debugGuide: 'Tune one value at a time while a reply streams. Keep FPS stable and backlog near zero. If text lags, raise the reveal multiplier, queue pressure, or maximum reveal; if a blank gap appears, reduce Predictive runway. Increase damping when the scroll feels springy. Save only after the behavior is stable; Reset restores the production defaults.',\n debugLive: 'Streaming',\n debugIdle: 'Idle',\n debugUnsaved: 'Unsaved tuning',\n debugSave: 'Save tuning',\n debugDiscard: 'Discard changes',\n debugReset: 'Reset tuning',\n debugCopy: 'Copy diagnostics',\n debugCopied: 'Copied',\n debugSectionLive: 'Live renderer',\n debugSectionReveal: 'Reveal tuning',\n debugSectionFollow: 'Scroll tuning',\n debugFps: 'FPS',\n debugFrameTime: 'Frame',\n debugBacklog: 'Backlog',\n debugRevealSpeed: 'Reveal',\n debugProgress: 'Progress',\n debugFollowState: 'Follow',\n debugFollowing: 'Pinned',\n debugReleased: 'Released',\n debugLag: 'Visual lag',\n debugVelocity: 'Velocity',\n debugReserve: 'Reserve',\n debugCapacity: 'Capacity',\n debugAppliedScale: 'Applied scale',\n debugRevealMultiplier: 'Reveal multiplier',\n debugQueuePressure: 'Queue pressure',\n debugMaxReveal: 'Maximum reveal',\n debugSpringStiffness: 'Spring stiffness',\n debugSpringDamping: 'Spring damping',\n debugSpringMass: 'Spring mass',\n debugRunway: 'Predictive runway',\n debugReserveResponse: 'Runway response',\n debugBackpressureMin: 'Minimum backpressure',\n debugTipRevealMultiplier: 'Overall reveal speed multiplier. Higher reveals text faster and clears backlog sooner, but can feel jumpy. Lower is smoother but takes longer to finish.',\n debugTipQueuePressure: 'Backlog acceleration strength. Higher catches up to a growing queue more aggressively; lower keeps speed steadier but may leave backlog.',\n debugTipMaxReveal: 'Hard cap for reveal speed in characters per second. Higher allows faster catch-up; lower limits bursts and keeps motion calmer.',\n debugTipSpringStiffness: 'Scroll spring strength. Higher closes visual lag faster but can feel sharp; lower feels softer but follows more slowly.',\n debugTipSpringDamping: 'Scroll energy damping. Higher suppresses overshoot and jitter but feels heavier; lower feels livelier but may oscillate.',\n debugTipSpringMass: 'Scroll inertia. Higher makes movement slower and heavier; lower makes it react faster but can feel abrupt.',\n debugTipRunway: 'Predictive blank space reserved while content grows. Higher absorbs growth and protects the bottom follow, but can create a larger visible gap; lower reduces blank space but leaves less room to absorb lag.',\n debugTipReserveResponse: 'How quickly the reserved runway opens or closes. Higher changes more gradually; lower reacts faster but can look abrupt.',\n debugTipBackpressureMin: 'Slowest reveal multiplier under scroll pressure. Higher keeps text moving but may increase visual lag; lower slows text more to protect smooth following.',\n readOnly: 'This deployment stores settings read-only.',\n loading: 'Loading plugin settings…',\n unavailable: 'Plugin settings are unavailable in this connection.',\n retry: 'Retry',\n version: 'Version {version}',\n developmentVersion: 'Development version {version}',\n updates: 'Updates',\n updateHint: 'Install the newest npm version, then restart Harness.',\n developmentBuild: 'Linked source; updates are managed in the checkout.',\n updateUnavailable: 'Updates are available only for an npm profile installation.',\n update: 'Update',\n updating: 'Updating…',\n restartRequired: 'Updated. Restart Harness to load the new version.',\n updateFailed: 'The package update failed; your current version is unchanged.',\n save: 'Save',\n saving: 'Saving…',\n discard: 'Discard',\n unsaved: 'Unsaved',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n}\n\n/** Simplified Chinese copy. */\nexport const zh: Record<SmoothStreamLocaleKey, string> = {\n title: '丝滑流式',\n description: '回复在流式输出时如何逐字展现。',\n enabled: '启用丝滑流式渲染',\n enabledHint: '由本插件渲染并跟随流式回复;关闭后使用 Harness 内置渲染。',\n controlScroll: '接管滚动',\n controlScrollHint: '默认开启,由丝滑流式写入会话滚动位置;关闭后贴底滚动交给 Harness。',\n motionPreference: '动效偏好',\n motionPreferenceHint: '流式渲染如何响应系统的「减少动态效果」设置。',\n motionAuto: '跟随系统',\n motionAutoHint: '系统开启减少动态效果时直接呈现原始文本(优先无障碍)。',\n motionForceSmooth: '始终平滑',\n motionForceSmoothHint: '即使系统要求减少动态效果,仍保持平滑流式渲染。',\n motionForceReduced: '始终原始',\n motionForceReducedHint: '即使系统允许动效,也直接呈现原始文本。',\n thinkAutoExpand: '自动展开思考',\n thinkAutoExpandHint: '思考块在流式时自动展开;关闭后保持折叠,可手动展开。',\n debugEnabled: '显示渲染调试面板',\n debugEnabledHint: '在聊天右侧显示流式渲染和滚动的实时参数,可在面板中调节并在这里保存。',\n debugUnavailable: '当前 Host 版本不支持实时调试,请先更新插件 Host。',\n debugPanelTitle: '渲染诊断',\n debugPanelToggle: '显示或隐藏渲染诊断',\n debugPanelClose: '收起诊断面板',\n debugGuide: '流式输出时一次只调一个参数,观察帧率、积压和视觉滞后。优先保持帧率稳定、积压接近 0;如果文字滞后,提高揭示倍率、队列压力或最大揭示速度;如果底部出现空白,降低“预测预留空间”。滚动有回弹或抖动时提高阻尼。确认表现稳定后再保存;“恢复默认参数”会回到生产默认值。',\n debugLive: '正在流式输出',\n debugIdle: '空闲',\n debugUnsaved: '参数尚未保存',\n debugSave: '保存参数',\n debugDiscard: '放弃修改',\n debugReset: '恢复默认参数',\n debugCopy: '复制诊断数据',\n debugCopied: '已复制',\n debugSectionLive: '实时渲染',\n debugSectionReveal: '流式参数',\n debugSectionFollow: '滚动参数',\n debugFps: '帧率',\n debugFrameTime: '帧耗时',\n debugBacklog: '积压字符',\n debugRevealSpeed: '揭示速度',\n debugProgress: '渲染进度',\n debugFollowState: '跟随状态',\n debugFollowing: '跟随底部',\n debugReleased: '用户已释放',\n debugLag: '视觉滞后',\n debugVelocity: '滚动速度',\n debugReserve: '预留空间',\n debugCapacity: '安全容量',\n debugAppliedScale: '实际倍率',\n debugRevealMultiplier: '揭示倍率',\n debugQueuePressure: '队列压力',\n debugMaxReveal: '最大揭示速度',\n debugSpringStiffness: '弹簧刚度',\n debugSpringDamping: '弹簧阻尼',\n debugSpringMass: '弹簧质量',\n debugRunway: '预测预留空间',\n debugReserveResponse: '预留响应时间',\n debugBackpressureMin: '最小背压倍率',\n debugTipRevealMultiplier: '整体文字揭示速度倍率。调大能更快清空积压,但可能显得跳;调小更平滑,但完成回复需要更久。',\n debugTipQueuePressure: '积压对加速的影响强度。调大能更积极追赶增长中的队列;调小速度更稳定,但积压可能持续。',\n debugTipMaxReveal: '每秒揭示字符数上限。调大允许更快追赶;调小限制突发速度,让动作更平稳。',\n debugTipSpringStiffness: '滚动弹簧刚度。调大更快收拢视觉滞后,但感觉更硬;调小更柔和,但跟随更慢。',\n debugTipSpringDamping: '滚动能量阻尼。调大能抑制过冲和抖动,但感觉更沉;调小更灵活,但可能回弹。',\n debugTipSpringMass: '滚动惯性。调大移动更慢更沉;调小反应更快,但可能显得突兀。',\n debugTipRunway: '内容增长时预留的预测空白。调大更能吸收增长、保护底部跟随,但可能产生更大的可见空区;调小能减少空白,但可吸收滞后的空间也更少。',\n debugTipReserveResponse: '预留空间打开或关闭的响应时间。调大变化更渐进;调小反应更快,但可能显得突变。',\n debugTipBackpressureMin: '滚动压力下允许的最低揭示倍率。调大文字仍会较快前进,但视觉滞后可能增加;调小会更积极减速,以保护跟随平滑。',\n readOnly: '本部署的设置为只读。',\n loading: '正在加载插件设置…',\n unavailable: '当前连接无法访问插件设置。',\n retry: '重试',\n version: '版本 {version}',\n developmentVersion: '开发版本 {version}',\n updates: '更新',\n updateHint: '安装最新 npm 版本后重启 Harness。',\n developmentBuild: '当前为本地链接版本,请在源码目录管理更新。',\n updateUnavailable: '只有 profile 使用 npm 包时才能更新。',\n update: '更新',\n updating: '更新中…',\n restartRequired: '已更新;重启 Harness 后加载新版本。',\n updateFailed: '包更新失败,当前版本未改变。',\n save: '保存',\n saving: '保存中…',\n discard: '放弃修改',\n unsaved: '未保存',\n saveFailed: '本部署没有接受这些值,已保留供你修改。',\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.smoothStream': SmoothStreamLocaleKey\n }\n}\n","import { createElement, useSyncExternalStore, type ComponentType } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: the connection Context merge and the plugins section's SlotMap\n// entry ('settings.plugin.item').\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { TypewriterAssistantNodeView } from './TypewriterAssistantNodeView.tsx'\nimport { wrapFollowNodeView, type FollowWrapProps } from './TypewriterToolNodeView.tsx'\nimport { SmoothStreamCard } from './SmoothStreamCard.tsx'\nimport { SmoothStreamCardController } from './smooth-stream-card-controller.ts'\nimport { createSmoothStreamSettingsApi } from './smooth-stream-settings-api.ts'\nimport { DebugPanel } from './DebugPanel.tsx'\nimport { debugRuntime } from './debugRuntime.ts'\nimport { NS as SETTINGS_NS, en, zh } from './locales.ts'\nimport { DEFAULT_STREAM_CONFIG, STREAM_BOOT_GLOBAL, type StreamConfig } from '../config.ts'\nimport { DEFAULT_STREAM_SETTINGS, STREAM_SETTINGS_NS, type StreamSettings } from '../settings.ts'\n\n/**\n * Cordis services required by the browser half. Only `slots` is load-bearing\n * for the stream itself; locale and Connection power the configuration card\n * and are wired through `ctx.inject` below so a deployment without them still\n * streams with defaults.\n */\nexport const inject = ['slots']\n\ntype AssistantProps = ChatNodeViewProps<'assistant-step'>\n\nconst STREAM_MODES: readonly string[] = ['typewriter', 'teleprompter']\nconst STREAM_PRESETS: readonly string[] = ['realtime', 'balanced', 'silky']\n\n/**\n * The assistant renderer owns its own character queue and conversation\n * follower, so wrapping it again would create two scroll owners. Human input\n * stays immediate; every Agent-owned output renderer goes through the same\n * generic follow boundary. This is deliberately keyed by the owner that\n * provides the renderer, not by individual tool names, so new Context,\n * Command, and Tool rows are covered automatically.\n */\nconst SKIP_WRAP = new Set(['assistant-step', 'user', 'steering', 'command-input'])\n\n/** React function/class or an exotic component such as memo/forwardRef/lazy. */\nfunction isWrappableComponent(value: unknown): value is ComponentType<FollowWrapProps> {\n return typeof value === 'function'\n || (value !== null && typeof value === 'object' && '$$typeof' in value)\n}\n\n/**\n * Read the Host-bridged boot config. The inline script is produced by this\n * plugin's Host half from a schema-validated value, so only the structural\n * guarantees that could break between the two halves are re-checked: the\n * global is absent when the client runs without its Host entry (defaults\n * apply), and any present-but-malformed value fails loudly instead of\n * rendering a half-configured view.\n * @returns The resolved configuration for the assistant node view.\n */\nfunction readBootConfig(): StreamConfig {\n const raw = (globalThis as Record<string, unknown>)[STREAM_BOOT_GLOBAL]\n if (raw === undefined) {\n console.info('[dsh-smooth-stream] no host config bridge; using defaults')\n return DEFAULT_STREAM_CONFIG\n }\n if (\n typeof raw !== 'object' || raw === null\n || !STREAM_MODES.includes((raw as StreamConfig).mode)\n || !STREAM_PRESETS.includes((raw as StreamConfig).preset)\n || typeof (raw as StreamConfig).revealCharsPerSec !== 'number'\n || typeof (raw as StreamConfig).scrollSpeedPxPerSec !== 'number'\n || typeof (raw as StreamConfig).maxScrollSpeedPxPerSec !== 'number'\n ) {\n throw new Error(`[dsh-smooth-stream] malformed ${STREAM_BOOT_GLOBAL} boot global: ${JSON.stringify(raw)}`)\n }\n return raw as StreamConfig\n}\n\n/**\n * Wrap every Agent-owned keyed Chat row except the assistant renderer in\n * place. A second\n * register with the same `children` table throws because the child slot is\n * already declared, and only the winning entry receives `renderSlot`;\n * swapping `entry.component` keeps the original children, locale, and inject\n * seats. `assistant-step` is replaced below so text and Think use the\n * typewriter reveal. The wrapper owns only the shared layout-growth/follow\n * lifecycle; the Harness keeps each renderer's controls, disclosures, and\n * cards intact.\n * @param ctx - Browser context carrying the slot registry.\n * @returns Restorer that puts the original components back.\n */\nfunction wrapAgentChatRows(\n ctx: ClientContext,\n useControlScroll: () => boolean,\n): () => void {\n const restores: Array<() => void> = []\n const wrapped = new WeakSet<object>()\n\n const wrapAll = (): void => {\n for (const entry of ctx.slots.entries('conversation.chat.node')) {\n const key = entry.options.key\n if (key === undefined || SKIP_WRAP.has(key)) continue\n const current = entry.component\n if (!isWrappableComponent(current) || wrapped.has(current)) continue\n const inner = current as ComponentType<FollowWrapProps>\n const next = wrapFollowNodeView(inner, useControlScroll)\n wrapped.add(next)\n entry.component = next\n restores.push(() => {\n if (entry.component === next) entry.component = inner\n })\n }\n }\n\n wrapAll()\n const off = ctx.on('slots/changed', (key: string) => {\n if (key === 'conversation.chat.node') wrapAll()\n })\n return () => {\n off()\n for (const restore of restores) restore()\n }\n}\n\n/**\n * A live settings cell shared by the renderer lifecycle and React views. It\n * starts on the shared defaults and follows the plugin-owned controller once\n * the optional settings services arrive.\n */\nclass SettingsCell {\n private readonly listeners = new Set<() => void>()\n private card: SmoothStreamCardController | undefined\n private value: StreamSettings = DEFAULT_STREAM_SETTINGS\n private pending = false\n\n /** Re-point the cell at the plugin-owned settings controller. */\n attach(card: SmoothStreamCardController): () => void {\n this.card = card\n this.refresh()\n const unsubscribe = card.subscribe(() => { this.refresh() })\n return () => {\n unsubscribe()\n if (this.card !== card) return\n this.card = undefined\n this.refresh()\n }\n }\n\n private read(): StreamSettings {\n const snapshot = this.card?.getSnapshot()\n if (snapshot === undefined || snapshot.status !== 'ready') return this.value\n return this.card?.values() ?? this.value\n }\n\n private refresh(): void {\n const next = this.read()\n const pending = this.card?.getSnapshot().status === 'loading'\n if (\n pending === this.pending\n && next.enabled === this.value.enabled\n && next.controlScroll === this.value.controlScroll\n && next.motionPreference === this.value.motionPreference\n && next.thinkAutoExpand === this.value.thinkAutoExpand\n && next.debugEnabled === this.value.debugEnabled\n && next.debugTuning === this.value.debugTuning\n ) return\n this.pending = pending\n this.value = next\n for (const listener of this.listeners) listener()\n }\n\n /** False while an available settings service is resolving its authority. */\n takeoverEnabled(): boolean {\n return !this.pending && this.value.enabled\n }\n\n readonly getSnapshot = (): StreamSettings => this.value\n\n readonly subscribe = (listener: () => void): () => void => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n}\n\n/**\n * Register the typewriter renderer after the conversation package declares the\n * keyed Chat node seat. A lower priority shadows the built-in assistant row;\n * every other keyed renderer is wrapped in place so Context, commands, Tool\n * cards, retries, and workflow runs share one extensible follow boundary. The\n * Host-bridged configuration\n * selects the render direction, smoothing preset, and glide speed; the\n * plugin-owned settings RPC supplies the live auto-expand preference when the\n * settings surface is composed.\n * @param ctx - Browser context carrying the shared slot registry.\n */\nexport function apply(ctx: ClientContext): void {\n const config = readBootConfig()\n const settings = new SettingsCell()\n const useControlScroll = (): boolean => useSyncExternalStore(\n settings.subscribe,\n () => settings.getSnapshot().controlScroll,\n () => settings.getSnapshot().controlScroll,\n )\n\n // The card talks to the plugin-owned loopback RPC, so the core settings\n // namespace allowlist cannot make it disappear. The stream still applies\n // with defaults when the optional Settings UI or Connection is absent.\n ctx.inject(['slots', 'locale', 'connection'], (settingsCtx) => {\n const card = new SmoothStreamCardController(\n // The shared Context augmentation also carries the Host-side Connection\n // shape. This browser entry runs after the client provider installs its\n // handle, so narrow through unknown to its client contract here.\n createSmoothStreamSettingsApi(settingsCtx.get('connection') as unknown as ConnectionHandle),\n )\n const detachSettings = settings.attach(card)\n const syncDebug = (): void => {\n const snapshot = card.getSnapshot()\n debugRuntime.syncSettings({\n available: snapshot.debugAvailable,\n enabled: snapshot.debugEnabled,\n writable: snapshot.writable && !snapshot.saving,\n dirty: snapshot.dirty,\n status: snapshot.status,\n tuning: snapshot.debugTuning,\n })\n }\n const detachBinding = debugRuntime.bindSettings({\n edit: patch => { card.inject().edit(patch) },\n save: () => { card.inject().save() },\n discard: () => { card.inject().discard() },\n })\n const detachDebug = card.subscribe(syncDebug)\n syncDebug()\n card.start()\n settingsCtx.effect(() => settingsCtx.locale.register(SETTINGS_NS, { zh, en }), 'dsh-smooth-stream: settings dictionaries')\n settingsCtx.slots.inject('settings.plugin.item', () => settingsCtx.slots.register({\n name: 'settings.plugin.item',\n id: 'smooth-stream',\n key: STREAM_SETTINGS_NS,\n order: 30,\n locale: SETTINGS_NS,\n inject: () => card.inject(),\n // Older Harness declares this slot as a list (`id`); newer Harness uses a\n // keyed slot filtered by the Host settings namespace (`key`).\n } as never, SmoothStreamCard))\n settingsCtx.slots.inject('conversation.session.header.utilities', () => settingsCtx.slots.register({\n name: 'conversation.session.header.utilities',\n id: 'smooth-stream-debug',\n order: 40,\n locale: SETTINGS_NS,\n inject: () => debugRuntime.panelFace(),\n }, DebugPanel))\n return () => {\n card.stop()\n detachDebug()\n detachSettings()\n detachBinding()\n }\n })\n\n const configured = function StreamConfiguredView(props: AssistantProps) {\n const preferences = useSyncExternalStore(\n settings.subscribe,\n settings.getSnapshot,\n settings.getSnapshot,\n )\n return createElement(TypewriterAssistantNodeView, {\n ...props,\n mode: config.mode,\n preset: config.preset,\n revealCharsPerSec: config.revealCharsPerSec,\n scrollSpeedPxPerSec: config.scrollSpeedPxPerSec,\n maxScrollSpeedPxPerSec: config.maxScrollSpeedPxPerSec,\n thinkAutoExpand: preferences.thinkAutoExpand,\n controlScroll: preferences.controlScroll,\n motionPreference: preferences.motionPreference,\n })\n }\n ctx.slots.inject('conversation.chat.node', () => {\n let releaseTakeover: (() => void) | undefined\n\n const syncTakeover = (): void => {\n if (!settings.takeoverEnabled()) {\n releaseTakeover?.()\n releaseTakeover = undefined\n return\n }\n if (releaseTakeover !== undefined) return\n const unwrap = wrapAgentChatRows(ctx, useControlScroll)\n const unshadow = ctx.slots.register({\n name: 'conversation.chat.node',\n key: 'assistant-step',\n priority: -100,\n locale: 'conversation',\n registrant: 'dsh-smooth-stream',\n }, configured)\n releaseTakeover = () => {\n // Stop observing slot changes before the shadow entry is removed.\n unwrap()\n unshadow()\n }\n }\n\n const unsubscribe = settings.subscribe(syncTakeover)\n syncTakeover()\n return () => {\n unsubscribe()\n releaseTakeover?.()\n }\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["css","IconChevronDownOutline14","useRef","useState","useRef","useCallback","useRef","useCallback","css","useRef","useRef","css","useState","memo","useRef","css","MarkdownText","IconThinkOutline14","useCallback","useMemo","ImageGallery","JsonBlock","useRef","useState","useCallback","entranceCss","createElement","useState","css","IconChevronDownOutline14","IconRefreshOutline14","css","Tooltip","IconQuestionOutline14","useState","writeClipboard","IconCopyOutline16","IconCloseOutline16","IconRefreshOutline16","IconCodeOutline16","createPortal","useSyncExternalStore","SETTINGS_NS","createElement"],"sources":["../src/client/AnimatedDisclosure.tsx","../src/settings.ts","../src/client/clientStore.ts","../src/client/debugRuntime.ts","../src/client/teleprompterGlide.ts","../src/client/useSmoothStreamContent.ts","../src/client/useFpsGuard.ts","../src/client/useLogarithmicFade.ts","../src/client/FollowHost.tsx","../src/config.ts","../src/client/TypewriterAssistantNodeView.tsx","../src/client/useProgressiveDomText.ts","../src/client/TypewriterToolNodeView.tsx","../src/client/SmoothStreamCard.tsx","../src/client/smooth-stream-card-controller.ts","../src/settings-api.ts","../src/client/smooth-stream-settings-api.ts","../src/client/DebugPanel.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["// AnimatedDisclosure: the harness DisclosureRow chrome (24px row, hover\n// chevron preview, whole-row click/Enter/Space toggle) with one deliberate\n// difference - the expanded body stays mounted while collapsed and animates\n// between 0fr and 1fr grid tracks, so expand/collapse glides instead of\n// snapping. The harness primitive unmounts closed children (`{open &&\n// children}`) and a plugin cannot change that in place, so this fork mirrors\n// its DOM shape and `data-disclosure-row` contract: host styling keyed on the\n// row attribute and the Think chrome keep working unchanged.\n\nimport { type KeyboardEvent, type ReactNode } from 'react'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './TypewriterAssistantNodeView.module.css'\n\n/** Class-name join for optional overlay classes over the chrome defaults. */\nfunction cx(...parts: Array<string | undefined>): string {\n return parts.filter(part => part !== undefined && part !== '').join(' ')\n}\n\nexport interface AnimatedDisclosureProps {\n icon: ReactNode\n title: string\n open: boolean\n onToggle: () => void\n collapsedContent?: ReactNode\n children?: ReactNode\n rowClassName?: string | undefined\n leadingClassName?: string | undefined\n titleClassName?: string | undefined\n chevronClassName?: string | undefined\n /**\n * When false the body snaps between states with no grid-track transition.\n * The auto-close at stream end uses this: the conversation follower's\n * settle spring absorbs the height step through the compositor instead,\n * which glides identically without twelve frames of layout animation.\n */\n bodyTransition?: boolean\n}\n\n/**\n * Render one disclosure header whose expanded body is height-animated.\n * @param props - Visual content, controlled open state, and the toggle\n * callback fired by row click and Enter/Space.\n * @returns the animated disclosure row.\n */\nexport function AnimatedDisclosure({\n icon,\n title,\n open,\n onToggle,\n collapsedContent,\n children,\n rowClassName,\n leadingClassName,\n titleClassName,\n chevronClassName,\n bodyTransition = true,\n}: AnimatedDisclosureProps) {\n const toggleFromKeyboard = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Enter' && event.key !== ' ') return\n event.preventDefault()\n onToggle()\n }\n return (\n <div className={css.disclosureRoot} data-open={open || undefined}>\n <div\n className={cx(css.disclosureRow, rowClassName)}\n data-disclosure-row\n data-expandable=\"\"\n role=\"button\"\n tabIndex={0}\n aria-expanded={open}\n onClick={onToggle}\n onKeyDown={toggleFromKeyboard}\n >\n <span className={cx(css.disclosureLeading, leadingClassName)}>\n {open\n ? <IconChevronDownOutline14 className={chevronClassName} />\n : (\n <>\n <span className={css.disclosureIconIdle}>{icon}</span>\n <IconChevronDownOutline14 className={cx(chevronClassName, css.disclosureChevronHover)} />\n </>\n )}\n </span>\n <span className={cx(css.disclosureTitle, titleClassName)}>{title}</span>\n {!open && collapsedContent}\n </div>\n <div\n className={css.disclosureContent}\n data-disclosure-content\n data-collapsed={open ? undefined : ''}\n data-no-transition={bodyTransition ? undefined : ''}\n >\n {children}\n </div>\n </div>\n )\n}\n","/**\n * User-owned settings for the smooth-stream plugin, exposed to the Host\n * settings service and edited from the Web Settings \"plugin configuration\"\n * page. This is the runtime-editable complement to {@link StreamConfig}: that\n * contract is composed at load and bridged once through the boot global, while\n * these preferences live in the durable user-settings document and take effect\n * live.\n */\n\n/** Settings namespace registered by the Host and served through the plugin RPC. */\nexport const STREAM_SETTINGS_NS = 'smooth-stream'\n\n/** Runtime knobs exposed only while the diagnostics switch is enabled. */\nexport interface StreamDebugTuning {\n /** Multiplier applied to the reveal cadence (1 = preset default). */\n revealScale: number\n /** Multiplier for backlog pressure in the adaptive reveal queue. */\n queuePressure: number\n /** Upper bound for reveal cadence, in characters per second. */\n maxRevealCps: number\n /** Spring stiffness used by the conversation follower. */\n springStiffness: number\n /** Spring damping used by the conversation follower. */\n springDamping: number\n /** Spring mass used by the conversation follower. */\n springMass: number\n /** Predictive runway before the fixed conversation chrome, in pixels. */\n runwayPx: number\n /** Response time for opening/closing the predictive runway, in ms. */\n reserveResponseMs: number\n /** Lowest reveal multiplier when visual lag fills the safe paint room. */\n backpressureMinScale: number\n}\n\n/** Defaults preserve the production engine exactly. */\nexport const DEFAULT_STREAM_DEBUG_TUNING: StreamDebugTuning = {\n revealScale: 1,\n queuePressure: 0.85,\n maxRevealCps: 600,\n springStiffness: 130,\n springDamping: 24,\n springMass: 1,\n runwayPx: 72,\n reserveResponseMs: 180,\n backpressureMinScale: 0.55,\n}\n\n/**\n * How the typewriter reveal responds to the OS reduced-motion preference.\n * Credit: three-state design proposed by @Zn-Dk in #21/#22.\n */\nexport type StreamMotionPreference =\n /** Follow the OS preference: reduced-motion users get raw text (accessibility first). */\n | 'auto'\n /** Always run the smoothing engine, ignoring the OS preference. */\n | 'force-smooth'\n /** Always render raw text, ignoring the OS preference. */\n | 'force-reduced'\n\n/**\n * Preferences a user may set. Deliberately separate from {@link StreamConfig}\n * because the two change at different times: composition-time values go\n * through the boot global, a live UI edit goes through the protected plugin RPC.\n */\nexport interface StreamSettings {\n /**\n * Whether this plugin replaces and wraps Harness conversation renderers.\n * Off returns all rendering ownership to the built-in UI.\n */\n enabled: boolean\n /**\n * Whether this plugin also takes over conversation bottom-follow. Off leaves\n * scroll ownership to the Harness; text reveal still runs.\n */\n controlScroll: boolean\n /**\n * How the reveal honors the OS reduced-motion preference. `auto` preserves\n * the accessibility-first default; `force-smooth` keeps the engine on\n * machines where a system-wide reduce-motion switch (performance tooling,\n * RDP sessions, forced browser flags) would otherwise bypass it silently.\n */\n motionPreference: StreamMotionPreference\n /**\n * Whether a reasoning (\"Think\") block auto-expands while it is the\n * streaming tail. Off keeps the block collapsed — the user can still open\n * it by hand — and stops the running state from re-owning the disclosure.\n */\n thinkAutoExpand: boolean\n /** Logarithmic text fade for the answer and expanded thinking body. */\n logarithmicFade: boolean\n /** Whether the live renderer diagnostics panel is enabled. */\n debugEnabled: boolean\n /** Values edited by the diagnostics panel. */\n debugTuning: StreamDebugTuning\n}\n\n/** Defaults shared by the Host schema and the client-side fallback. */\nexport const DEFAULT_STREAM_SETTINGS: StreamSettings = {\n enabled: true,\n controlScroll: true,\n motionPreference: 'auto',\n thinkAutoExpand: true,\n logarithmicFade: true,\n debugEnabled: false,\n debugTuning: DEFAULT_STREAM_DEBUG_TUNING,\n}\n","/**\n * Kernel compatibility for the client store engine.\n *\n * DSH 0.1.2 split the snapshot store out of `@deepseek-ai/dsh-client-runtime`\n * into a bare `@deepseek-ai/dsh-client-store` module-table seed, while ≤ 0.1.1\n * kernels keep it on the client-runtime client face. The client module table\n * only answers what the booting kernel actually ships, so the face must be\n * probed at runtime: a static require of either specifier kills the whole\n * loader tree on the other generation (issue #17: a top-level\n * `require(\"@deepseek-ai/dsh-client-runtime/client\")` took down the web UI on\n * DSH Desktop 2.0.4 / kernel 0.1.2-alpha.1).\n */\n\ntype ClientRuntimeClient = typeof import('@deepseek-ai/dsh-client-runtime/client')\n\nexport interface SnapshotStoreLike<T> {\n getSnapshot(): T\n subscribe(listener: (state: T) => void): () => void\n update(mutator: (draft: T) => void): void\n set(next: T): void\n}\n\nfunction fallbackSnapshotStore<T extends object>(init: T): SnapshotStoreLike<T> {\n let state = init\n const listeners = new Set<(state: T) => void>()\n return {\n getSnapshot: () => state,\n subscribe: listener => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n update: mutator => {\n const draft = Object.create(\n Object.getPrototypeOf(state),\n Object.getOwnPropertyDescriptors(state),\n ) as T\n mutator(draft)\n state = draft\n for (const listener of [...listeners]) listener(state)\n },\n set: next => {\n state = next\n for (const listener of [...listeners]) listener(state)\n },\n }\n}\n\n/**\n * Runtime require: the module-loader factory scopes its own resolver over the\n * booting kernel's table; under Node (vitest) there is no global require, so\n * fall back to `createRequire`.\n */\nfunction pickRequire(): NodeRequire | null {\n if (typeof require === 'function') {\n try {\n return require\n } catch {\n return null\n }\n }\n if (typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function') {\n try {\n const { createRequire } = process.getBuiltinModule('node:module')\n return createRequire(process.cwd() + '/package.json')\n } catch {\n return null\n }\n }\n return null\n}\n\nlet clientStore: Partial<ClientRuntimeClient> | undefined\n\ntry {\n const req = pickRequire()\n if (req !== null) {\n try {\n // 0.1.2+ seeds the split store package directly into the module table.\n clientStore = req('@deepseek-ai/dsh-client-store') as ClientRuntimeClient\n } catch {\n try {\n // ≤ 0.1.1 owns the store engine on the client-runtime client face.\n clientStore = req('@deepseek-ai/dsh-client-runtime/client') as ClientRuntimeClient\n } catch {\n // Fallback below\n }\n }\n }\n} catch {\n // Fallback below\n}\n\nexport interface SnapshotStore<T> {\n getSnapshot(): T\n subscribe(listener: () => void): () => void\n update(mutator: (draft: T) => void): void\n set(next: T): void\n}\n\nexport const createSnapshotStore = (clientStore?.createSnapshotStore ?? fallbackSnapshotStore) as <T extends object>(init: T) => SnapshotStore<T>\n","/**\n * Shared browser-side diagnostics state.\n *\n * The settings card owns persistence. This module is the live bridge used by\n * the renderer and the chat-side panel: renderer loops publish measurements,\n * while panel edits are staged through the settings-card controller.\n */\n\nimport { createSnapshotStore, type SnapshotStore } from './clientStore.ts'\nimport {\n DEFAULT_STREAM_DEBUG_TUNING,\n type StreamDebugTuning,\n type StreamSettings,\n} from '../settings.ts'\n\nexport interface DebugMetrics {\n fps: number | null\n frameMs: number | null\n fpsDegraded: boolean\n streamActive: boolean\n streamBacklog: number\n streamSpeedCps: number\n streamTargetChars: number\n streamDisplayedChars: number\n followActive: boolean\n followLagPx: number\n followVelocityPxPerSec: number\n followReservePx: number\n followCapacityPx: number\n followRevealScale: number\n followFollowing: boolean\n followConstrained: boolean\n scrollTop: number | null\n scrollHeight: number | null\n clientHeight: number | null\n lastUpdatedMs: number | null\n}\n\nexport interface DebugRuntimeState {\n available: boolean\n enabled: boolean\n writable: boolean\n dirty: boolean\n status: 'loading' | 'ready' | 'unavailable'\n tuning: StreamDebugTuning\n metrics: DebugMetrics\n}\n\nexport type DebugSettingsPatch = Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>\n\nexport interface DebugPanelFace {\n hooks: {\n debugRuntime: SnapshotStore<DebugRuntimeState>\n }\n edit: (patch: DebugSettingsPatch) => void\n save: () => void\n discard: () => void\n reset: () => void\n}\n\ninterface DebugSettingsActions {\n edit: (patch: DebugSettingsPatch) => void\n save: () => void\n discard: () => void\n}\n\ninterface StreamMetric {\n backlog: number\n speedCps: number\n targetChars: number\n displayedChars: number\n active: boolean\n updatedAt: number\n}\n\ninterface FollowMetric {\n lagPx: number\n velocityPxPerSec: number\n reservePx: number\n capacityPx: number\n revealScale: number\n following: boolean\n constrained: boolean\n scrollTop: number\n scrollHeight: number\n clientHeight: number\n active: boolean\n updatedAt: number\n}\n\nconst EMPTY_METRICS: DebugMetrics = {\n fps: null,\n frameMs: null,\n fpsDegraded: false,\n streamActive: false,\n streamBacklog: 0,\n streamSpeedCps: 0,\n streamTargetChars: 0,\n streamDisplayedChars: 0,\n followActive: false,\n followLagPx: 0,\n followVelocityPxPerSec: 0,\n followReservePx: 0,\n followCapacityPx: 0,\n followRevealScale: 1,\n followFollowing: false,\n followConstrained: false,\n scrollTop: null,\n scrollHeight: null,\n clientHeight: null,\n lastUpdatedMs: null,\n}\n\nconst INITIAL_STATE: DebugRuntimeState = {\n available: false,\n enabled: false,\n writable: false,\n dirty: false,\n status: 'loading',\n tuning: { ...DEFAULT_STREAM_DEBUG_TUNING },\n metrics: EMPTY_METRICS,\n}\n\nconst store = createSnapshotStore<DebugRuntimeState>(INITIAL_STATE)\nconst streamMetrics = new Map<string, StreamMetric>()\nconst followMetrics = new Map<HTMLElement, FollowMetric>()\nlet actions: DebugSettingsActions | undefined\nlet lastMetricPublish = 0\n\nfunction resetMetrics(): void {\n streamMetrics.clear()\n followMetrics.clear()\n lastMetricPublish = 0\n}\n\nfunction resetRuntime(): void {\n actions = undefined\n resetMetrics()\n store.set({ ...INITIAL_STATE, metrics: EMPTY_METRICS })\n}\n\nfunction now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n}\n\nfunction sameTuning(left: StreamDebugTuning, right: StreamDebugTuning): boolean {\n return left.revealScale === right.revealScale\n && left.queuePressure === right.queuePressure\n && left.maxRevealCps === right.maxRevealCps\n && left.springStiffness === right.springStiffness\n && left.springDamping === right.springDamping\n && left.springMass === right.springMass\n && left.runwayPx === right.runwayPx\n && left.reserveResponseMs === right.reserveResponseMs\n && left.backpressureMinScale === right.backpressureMinScale\n}\n\nfunction currentMetrics(timestamp: number): DebugMetrics {\n let stream: StreamMetric | undefined\n for (const candidate of streamMetrics.values()) {\n if (stream === undefined || candidate.updatedAt > stream.updatedAt) stream = candidate\n }\n let follow: FollowMetric | undefined\n for (const candidate of followMetrics.values()) {\n if (follow === undefined || candidate.updatedAt > follow.updatedAt) follow = candidate\n }\n return {\n fps: store.getSnapshot().metrics.fps,\n frameMs: store.getSnapshot().metrics.frameMs,\n fpsDegraded: store.getSnapshot().metrics.fpsDegraded,\n streamActive: stream?.active ?? false,\n streamBacklog: stream?.backlog ?? 0,\n streamSpeedCps: stream?.speedCps ?? 0,\n streamTargetChars: stream?.targetChars ?? 0,\n streamDisplayedChars: stream?.displayedChars ?? 0,\n followActive: follow?.active ?? false,\n followLagPx: follow?.lagPx ?? 0,\n followVelocityPxPerSec: follow?.velocityPxPerSec ?? 0,\n followReservePx: follow?.reservePx ?? 0,\n followCapacityPx: follow?.capacityPx ?? 0,\n followRevealScale: follow?.revealScale ?? 1,\n followFollowing: follow?.following ?? false,\n followConstrained: follow?.constrained ?? false,\n scrollTop: follow?.scrollTop ?? null,\n scrollHeight: follow?.scrollHeight ?? null,\n clientHeight: follow?.clientHeight ?? null,\n lastUpdatedMs: timestamp,\n }\n}\n\nfunction publishMetrics(force = false): void {\n const timestamp = now()\n if (!force && timestamp - lastMetricPublish < 80) return\n lastMetricPublish = timestamp\n store.set({ ...store.getSnapshot(), metrics: currentMetrics(timestamp) })\n}\n\nexport const debugRuntime = {\n store,\n\n getSnapshot(): DebugRuntimeState {\n return store.getSnapshot()\n },\n\n subscribe(listener: () => void): () => void {\n return store.subscribe(listener)\n },\n\n /** Whether hot-path instrumentation should do any work. */\n isEnabled(): boolean {\n return store.getSnapshot().enabled\n },\n\n tuning(): StreamDebugTuning {\n return store.getSnapshot().tuning\n },\n\n /** Production values remain untouched until the user explicitly enables diagnostics. */\n activeTuning(): StreamDebugTuning {\n return store.getSnapshot().enabled ? store.getSnapshot().tuning : DEFAULT_STREAM_DEBUG_TUNING\n },\n\n bindSettings(nextActions: DebugSettingsActions | undefined): () => void {\n actions = nextActions\n return () => {\n if (actions !== nextActions) return\n resetRuntime()\n }\n },\n\n syncSettings(input: {\n available?: boolean\n enabled: boolean\n writable: boolean\n dirty: boolean\n status: DebugRuntimeState['status']\n tuning?: StreamDebugTuning\n }): void {\n const current = store.getSnapshot()\n // Callers predating the Host capability flag are local diagnostics tests\n // and renderer probes; preserve their enabled behavior unless the wiring\n // explicitly reports that the RPC is unavailable.\n const available = input.available ?? true\n const enabled = available && input.enabled\n const availabilityChanged = current.available !== available\n const enabledChanged = current.enabled !== enabled\n if (availabilityChanged || enabledChanged) resetMetrics()\n const tuning = input.tuning === undefined\n ? current.tuning\n : { ...DEFAULT_STREAM_DEBUG_TUNING, ...input.tuning }\n if (\n current.available === available\n && current.enabled === enabled\n && current.writable === input.writable\n && current.dirty === input.dirty\n && current.status === input.status\n && sameTuning(current.tuning, tuning)\n ) return\n store.set({\n ...current,\n available,\n enabled,\n writable: input.writable,\n dirty: input.dirty,\n status: input.status,\n tuning,\n metrics: availabilityChanged || enabledChanged || !enabled ? EMPTY_METRICS : current.metrics,\n })\n },\n\n edit(patch: DebugSettingsPatch): void {\n const current = store.getSnapshot()\n const enabled = patch.debugEnabled ?? current.enabled\n const enabledChanged = current.enabled !== enabled\n if (enabledChanged) resetMetrics()\n const tuning = patch.debugTuning === undefined\n ? current.tuning\n : { ...current.tuning, ...patch.debugTuning }\n store.set({\n ...current,\n enabled,\n dirty: true,\n tuning,\n metrics: enabledChanged || !enabled ? EMPTY_METRICS : current.metrics,\n })\n actions?.edit({\n ...(patch.debugEnabled === undefined ? {} : { debugEnabled: patch.debugEnabled }),\n ...(patch.debugTuning === undefined ? {} : { debugTuning: tuning }),\n })\n },\n\n save(): void {\n actions?.save()\n },\n\n discard(): void {\n actions?.discard()\n },\n\n reset(): void {\n this.edit({ debugTuning: { ...DEFAULT_STREAM_DEBUG_TUNING } })\n },\n\n reportStream(id: string, metric: Omit<StreamMetric, 'updatedAt'> | null): void {\n if (!this.isEnabled()) return\n if (metric === null) streamMetrics.delete(id)\n else streamMetrics.set(id, { ...metric, updatedAt: now() })\n publishMetrics(metric === null)\n },\n\n reportFollow(port: HTMLElement, metric: Omit<FollowMetric, 'updatedAt'> | null): void {\n if (!this.isEnabled()) return\n if (metric === null) followMetrics.delete(port)\n else followMetrics.set(port, { ...metric, updatedAt: now() })\n publishMetrics(metric === null)\n },\n\n reportFps(fps: number, frameMs: number, degraded: boolean): void {\n if (!this.isEnabled()) return\n const current = store.getSnapshot()\n store.set({\n ...current,\n metrics: { ...current.metrics, fps, frameMs, fpsDegraded: degraded, lastUpdatedMs: now() },\n })\n },\n\n clearFps(): void {\n if (!this.isEnabled()) return\n const current = store.getSnapshot()\n store.set({\n ...current,\n metrics: {\n ...current.metrics,\n fps: null,\n frameMs: null,\n fpsDegraded: false,\n lastUpdatedMs: now(),\n },\n })\n },\n\n panelFace(): DebugPanelFace {\n return {\n hooks: { debugRuntime: store },\n edit: patch => { this.edit(patch) },\n save: () => { this.save() },\n discard: () => { this.discard() },\n reset: () => { this.reset() },\n }\n },\n\n resetRuntime(): void {\n resetRuntime()\n },\n}\n","/**\n * Conversation-port follow while an assistant reply streams.\n *\n * A sub-stepped spring physics engine drives a float `animatedH`, rather\n * than restarting native smooth-scroll animations as every glyph lands.\n * Remaining lag rides a small compositor transform while the real scrollport\n * stays at its floor. The transform is bounded by the measured paint gap\n * before conversation chrome. This follower:\n *\n * - marks programmatic writes via `data-follow-owned` for compatible hosts;\n * - sets `overflow-anchor: none` so CSS scroll-anchoring does not snap;\n * - restores `animatedH` in a ResizeObserver (before paint) so a layout\n * pass cannot flash a snapped frame;\n * - expresses safe lag as a compositor transform on message rows;\n * - opens a speed-adaptive layout runway before fast output wraps, preserving\n * the reference spring constants at every reveal speed;\n * - catches up any lag that cannot fit before turn status / composer chrome,\n * so fixed chrome never has to counter-shift and the host stays at-bottom;\n * - never clips or overlays streamed text.\n *\n * A real reader gesture receives the effective visual position before the\n * transform clears. Lifecycle completion instead settles at the floor.\n *\n * Directional wheel/touch intent unpins immediately; pointer/key input falls\n * back to an upward scroll delta from the engine's own written position. A\n * reader release re-acquires only after returning to the real floor.\n */\n\nimport { useLayoutEffect, useRef, type RefObject } from 'react'\nimport { DEFAULT_STREAM_DEBUG_TUNING, type StreamDebugTuning } from '../settings.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\n/**\n * Programmatic follow marker retained for hosts that recognize external\n * scroll ownership. Current Harness also sees the write land at the floor.\n */\nconst FOLLOW_OWNED_ATTR = 'data-follow-owned'\n\n/** Physics parameters from `ultimate_stream_physics_scroller.html`. */\nexport const FOLLOW_SPRING_STIFFNESS = 130\nexport const FOLLOW_SPRING_DAMPING = 24\nexport const FOLLOW_SPRING_MASS = 1\nexport const FOLLOW_SPRING_SUBSTEPS = 4\nexport const FOLLOW_SPRING_MAX_STEP_MS = 32\n\n/** Minimum visible room for one ordinary line-wrap impulse. */\nexport const FOLLOW_RESERVE_MIN_PX = 31\n\n/** Reveal speeds at or below this are idle; no predictive room is held. */\nexport const FOLLOW_RESERVE_IDLE_CPS = 20\n\n/** Reveal-speed range produced by the pressure-buffer typewriter. */\n/** Retained for consumers that tune the old pressure threshold. */\nexport const FOLLOW_RESERVE_MIN_CPS = 90\nexport const FOLLOW_RESERVE_MAX_CPS = 600\n\n/** Time constant for opening/closing predictive paint room. */\nexport const FOLLOW_RESERVE_RESPONSE_MS = 180\n\n/**\n * The reference engine clamps physical time to one 32ms visual interval.\n * Replaying a 250ms main-thread stall in one paint teleports the transcript;\n * leaving the remaining distance in the spring makes the next frames catch up\n * smoothly instead.\n */\nexport const FOLLOW_MAX_FRAME_MS = 32\n\n/** Retained as the neutral reveal-speed seed for follow hosts. */\nexport const FOLLOW_SPEED_REF_CPS = 35\n\n/** Reader-return / still-pinned boundary, matching ChatView + the demo. */\nexport const FOLLOW_SLACK_PX = 25\n\n/**\n * Fallback upward scroll distance that releases the pin when the browser does\n * not expose a directional wheel/touch event. Directional intent releases\n * immediately even if the follow write erases the small physical delta.\n */\nexport const FOLLOW_UNPIN_GESTURE_PX = 8\n\n/** A reader-released follow only re-acquires at the actual floor. */\nexport const FOLLOW_REPIN_PX = 1\n\n/** ChatView's <=25px bottom band remains host-pinned; release beyond it. */\nexport const FOLLOW_HOST_RELEASE_PX = FOLLOW_SLACK_PX + 1\n\n/** Sub-pixel paint guard before status/composer chrome. */\nexport const FOLLOW_PAINT_GUARD_PX = 1\n\n/**\n * Maximum predictive paint room before status/composer chrome. The\n * feed-forward phase leads the real floor by up to one wrapped line, so the\n * runway must hold steady lag + one line + guard (35 + 26 + 8 ≈ 72) or the\n * leading shift gets clipped against chrome at the wrap cadence.\n */\nexport const FOLLOW_STATUS_RUNWAY_PX = 72\n\n/**\n * Duration of completion runway retirement. The final pad is visible motion:\n * its shrinking floor brings the transcript down to its natural resting\n * position. 1.5s keeps the default 72px runway at 48px/s (0.8px per 60Hz\n * frame), matching the configured default reading-follow velocity instead of\n * the old 160ms / 450px/s staircase that looked like repeated completion\n * jumps.\n */\nexport const FOLLOW_RUNWAY_RETIRE_MS = 1500\n\n/** How long a gesture keeps `isUserInteracting` so the next scroll can unpin. */\nexport const FOLLOW_GESTURE_MS = 800\n\n/** Sub-pixel settle threshold; clearing below this cannot produce a visible rebound. */\nexport const FOLLOW_SETTLE_EPSILON_PX = 0.25\n\n/**\n * How long the completion settle waits for the HOST's completion cascade —\n * status-row swap, think auto-collapse, metrics-tail mount — to stop moving\n * the scroll extent before the follower releases the port. Releasing earlier\n * hands a still-changing layout to the host's hard floor-snap, which paints\n * each host action as a single-frame slam of the whole transcript.\n */\nexport const FOLLOW_SETTLE_QUIET_MS = 240\n\n/**\n * Ceiling for the flow's completion pad. The pad backs the floor so the\n * pinned viewport can follow the reading anchor through host completion\n * commits (row swaps/insertions); capping it bounds the below-fold blank\n * space a long conversation accumulates.\n */\nexport const FOLLOW_SETTLE_PAD_CAP_PX = 2 * FOLLOW_STATUS_RUNWAY_PX\n\n/** Retained visual-motion budget for compatibility with diagnostics/tests. */\nexport const FOLLOW_CATCHUP_MAX_STEP_PX = 8\n\n/**\n * Max painted-shift change per frame, in px. A line-wrap adds one line height\n * (24-28px) to the floor in a single layout pass; letting the shift follow it\n * instantly paints that whole step as a hard jump of the newest line. Capping\n * the shift's per-frame change spreads the step across a few frames so the\n * line glides in (slow start) instead of snapping.\n */\n/**\n * Per-frame bound on the DECAY side of the painted shift (runway retirement\n * and settle), widened by any same-frame floor drop so extent collapses are\n * always fully repainted — see the clamp site in `applyVisual`. The growth\n * side stays unlimited: it is wrap compensation locked to the same-frame\n * floor step.\n */\nexport const FOLLOW_PAINT_SHIFT_MAX_STEP_PX = 8\n\n/** Runway size emitted by bundles before the 72px predictive runway. */\nconst LEGACY_RUNWAY_PX = 48\n\n/** Lowest reveal rate retained while the spring is short on paint room. */\nexport const FOLLOW_REVEAL_MIN_SCALE = 0.55\n\n/** Safe-lag occupancy band over which reveal pressure is progressively reduced. */\nexport const FOLLOW_BACKPRESSURE_START_RATIO = 0.1\nexport const FOLLOW_BACKPRESSURE_FULL_RATIO = 0.75\n\n/** Slow release prevents the reveal rate from oscillating around each wrap. */\nexport const FOLLOW_BACKPRESSURE_RELEASE_MS = 240\n\n/** Effective-scroll acceleration budget, in px/ms². */\nexport const FOLLOW_TRAJECTORY_ACCELERATION = 0.00022\n\n/** Leave one line of phase range inside the visible runway. */\nexport const FOLLOW_TRAJECTORY_PHASE_PX = 32\n\n/** Keep adaptive runway retirement from exposing an oversized chrome gap. */\nexport const FOLLOW_TRAJECTORY_MIN_LAG_PX = 20\n\n/** Phase-centering response; slow enough to preserve continuous velocity. */\nexport const FOLLOW_TRAJECTORY_CENTERING_MS = 120\n\nconst GESTURE_EVENTS = [\n 'wheel',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'pointerdown',\n 'keydown',\n] as const\n\n/** Visible runway needed for the current reveal pressure. */\nexport function computeFollowReserve(\n speedCps: number,\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n): number {\n const available = Math.max(0, runwayPx)\n if (available <= 0) return 0\n if (speedCps <= FOLLOW_RESERVE_IDLE_CPS) return 0\n const normalized = Math.min(1, Math.max(0, (\n speedCps - FOLLOW_RESERVE_IDLE_CPS\n ) / (FOLLOW_RESERVE_MAX_CPS - FOLLOW_RESERVE_IDLE_CPS)))\n const minimum = Math.min(available, FOLLOW_RESERVE_MIN_PX)\n return minimum + normalized * (available - minimum)\n}\n\nexport interface FollowTrajectoryInput {\n readonly positionPx: number\n readonly velocityPxPerMs: number\n readonly targetPx: number\n readonly targetVelocityPxPerMs: number\n readonly minLagPx: number\n readonly maxLagPx: number\n /** Real scroll floor used to turn logical position into a painted shift. */\n readonly paintFloorPx?: number\n}\n\nexport interface FollowRevealPhaseOptions {\n readonly seedCharsPerLine?: number\n readonly seedLineHeightPx?: number\n}\n\nexport interface FollowRevealPhase {\n readonly targetPx: number\n readonly phase: number\n readonly charsPerLine: number\n readonly lineHeightPx: number\n}\n\n/**\n * Character-domain feed-forward for the stepped layout floor. Callers only\n * provide committed reveal progress and the measured floor; wrap capacity and\n * line height stay local to this module and adapt when a real wrap lands.\n */\nexport class FollowRevealPhaseTracker {\n private charsPerLine: number\n private lineHeightPx: number\n private floorPx: number | null = null\n private wrapRevealCount = 0\n private lastRevealCount = 0\n\n constructor({\n seedCharsPerLine = 50,\n seedLineHeightPx = 26,\n }: FollowRevealPhaseOptions = {}) {\n this.charsPerLine = Math.max(1, seedCharsPerLine)\n this.lineHeightPx = Math.max(1, seedLineHeightPx)\n }\n\n advance(floorPx: number, revealedChars: number): FollowRevealPhase {\n const nextFloor = Math.max(0, floorPx)\n const nextRevealCount = Math.max(0, revealedChars)\n if (this.floorPx === null || nextRevealCount < this.lastRevealCount) {\n this.floorPx = nextFloor\n this.wrapRevealCount = nextRevealCount\n this.lastRevealCount = nextRevealCount\n return this.snapshot(nextFloor, 0)\n }\n\n const floorDelta = nextFloor - this.floorPx\n const lineStepThreshold = Math.max(4, this.lineHeightPx * 0.5)\n if (floorDelta >= lineStepThreshold) {\n const wrappedLines = Math.max(1, Math.round(floorDelta / this.lineHeightPx))\n const sampledLineHeight = floorDelta / wrappedLines\n const revealedSinceWrap = nextRevealCount - this.wrapRevealCount\n if (revealedSinceWrap >= this.charsPerLine * 0.5) {\n const sampledCharsPerLine = revealedSinceWrap / wrappedLines\n const alpha = 0.25\n this.charsPerLine += (sampledCharsPerLine - this.charsPerLine) * alpha\n this.lineHeightPx += (sampledLineHeight - this.lineHeightPx) * alpha\n this.wrapRevealCount = nextRevealCount\n } else {\n // A flow sibling can grow without the text arm committing a glyph.\n // Treat that as an unrelated layout event so its height is not folded\n // into the next text-wrap capacity sample.\n this.wrapRevealCount = nextRevealCount\n }\n } else if (floorDelta <= -lineStepThreshold) {\n this.wrapRevealCount = nextRevealCount\n }\n\n this.floorPx = nextFloor\n this.lastRevealCount = nextRevealCount\n const phase = Math.min(1, Math.max(\n 0,\n (nextRevealCount - this.wrapRevealCount) / this.charsPerLine,\n ))\n return this.snapshot(nextFloor, phase)\n }\n\n private snapshot(floorPx: number, phase: number): FollowRevealPhase {\n return {\n targetPx: floorPx + this.lineHeightPx * phase,\n phase,\n charsPerLine: this.charsPerLine,\n lineHeightPx: this.lineHeightPx,\n }\n }\n}\n\n/** Advance a continuous effective scroll position behind a stepped floor. */\nexport function computeFollowTrajectoryStep(\n dtMs: number,\n input: FollowTrajectoryInput,\n): { positionPx: number, shiftPx: number, velocityPxPerMs: number } {\n if (dtMs <= 0) {\n return {\n positionPx: input.positionPx,\n shiftPx: Math.max(0, (input.paintFloorPx ?? input.targetPx) - input.positionPx),\n velocityPxPerMs: input.velocityPxPerMs,\n }\n }\n const elapsedMs = Math.min(FOLLOW_MAX_FRAME_MS, dtMs)\n const currentLagPx = input.targetPx - input.positionPx\n const maxLagPx = Math.max(0, input.maxLagPx)\n const minLagPx = Math.min(Math.max(0, input.minLagPx), maxLagPx)\n const centerLagPx = (minLagPx + maxLagPx) / 2\n const desiredVelocity = Math.max(\n 0,\n input.targetVelocityPxPerMs\n + (currentLagPx - centerLagPx) / FOLLOW_TRAJECTORY_CENTERING_MS,\n )\n const maxVelocityChange = FOLLOW_TRAJECTORY_ACCELERATION * elapsedMs\n const velocityPxPerMs = desiredVelocity >= input.velocityPxPerMs\n ? Math.min(desiredVelocity, input.velocityPxPerMs + maxVelocityChange)\n : Math.max(desiredVelocity, input.velocityPxPerMs - maxVelocityChange)\n const minPosition = input.targetPx - maxLagPx\n const maxPosition = input.targetPx - minLagPx\n // The frame budget follows controlled velocity rather than a refresh-rate\n // dependent pixel constant. `elapsedMs` is already capped at 32ms, so a\n // stalled browser cannot replay an unbounded jump when it catches up.\n const frameAdvancePx = velocityPxPerMs * elapsedMs\n const boundedPositionPx = Math.min(\n maxPosition,\n Math.max(minPosition, input.positionPx + frameAdvancePx),\n )\n const positionPx = Math.max(input.positionPx, boundedPositionPx)\n return {\n positionPx,\n shiftPx: Math.max(0, (input.paintFloorPx ?? input.targetPx) - positionPx),\n velocityPxPerMs,\n }\n}\n\n/**\n * Reveal-rate multiplier needed to retain one-wrap headroom for the spring.\n * Throttling starts only after a quarter of the safe transform is occupied;\n * a constrained paint lands at the minimum immediately so the next reveal\n * commit cannot keep feeding an already-full visual buffer.\n */\nexport function computeFollowRevealScale(\n lagPx: number,\n capacityPx: number,\n constrained = false,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): number {\n if (constrained) return tuning.backpressureMinScale\n if (!Number.isFinite(capacityPx)) return 1\n if (capacityPx <= 0) return lagPx > 0 ? tuning.backpressureMinScale : 1\n const ratio = Math.min(1, Math.max(0, lagPx / capacityPx))\n if (ratio >= FOLLOW_BACKPRESSURE_FULL_RATIO) return tuning.backpressureMinScale\n const progress = Math.min(1, Math.max(0, (\n ratio - FOLLOW_BACKPRESSURE_START_RATIO\n ) / (FOLLOW_BACKPRESSURE_FULL_RATIO - FOLLOW_BACKPRESSURE_START_RATIO)))\n const eased = progress * progress * (3 - 2 * progress)\n return 1 - (1 - tuning.backpressureMinScale) * eased\n}\n\nexport interface FollowGlideInput {\n /** How far the interpolated top trails the floor, in px. */\n readonly lag: number\n /** Observed reveal rate, retained for the public follow-step contract. */\n readonly speedEma: number\n /** Physics velocity carried from the previous frame, in px/s. */\n readonly velocityPxPerSec?: number\n}\n\nexport interface FollowGlideStep {\n /** Pixels to advance the floating content extent this frame. */\n readonly advancePx: number\n /** Applied lerp fraction, for tests. */\n readonly lerpStep: number\n /** Physics velocity to carry into the next frame, in px/s. */\n readonly velocityPxPerSec: number\n}\n\n/** Semi-implicit spring integration with four substeps per <=32ms slice. */\nexport function computeFollowStep(\n dtMs: number,\n input: FollowGlideInput,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): FollowGlideStep {\n if (input.lag <= 0.1 || dtMs <= 0) {\n return { advancePx: 0, lerpStep: 0, velocityPxPerSec: 0 }\n }\n let lag = input.lag\n let velocity = Math.max(0, input.velocityPxPerSec ?? 0)\n const elapsedMs = Math.min(FOLLOW_MAX_FRAME_MS, dtMs)\n const slices = Math.max(1, Math.ceil(elapsedMs / FOLLOW_SPRING_MAX_STEP_MS))\n const subDt = elapsedMs / 1000 / slices / FOLLOW_SPRING_SUBSTEPS\n for (let slice = 0; slice < slices; slice += 1) {\n for (let substep = 0; substep < FOLLOW_SPRING_SUBSTEPS; substep += 1) {\n const acceleration = (\n tuning.springStiffness * lag - tuning.springDamping * velocity\n ) / tuning.springMass\n velocity = Math.max(0, velocity + acceleration * subDt)\n const advance = velocity * subDt\n if (advance >= lag) return { advancePx: input.lag, lerpStep: 1, velocityPxPerSec: 0 }\n lag -= advance\n }\n }\n const advancePx = input.lag - lag\n return { advancePx, lerpStep: advancePx / input.lag, velocityPxPerSec: velocity }\n}\n\n/** Element whose resize signals flow growth for the before-paint restore. */\nfunction resizeProxyOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector('[data-chat-transcript]') ?? port.querySelector('[data-chat-flow]')\n}\n\n/**\n * Outermost message surfaces; nested tool rows ride their parent.\n *\n * Another plugin may insert its own element as a flow sibling of the Chat rows\n * (meow-memory's fold bar is one).\n * Such a row carries no `data-chat-anchor-key`, so selecting only anchored\n * rows would shift the conversation while leaving the foreign row at its\n * natural offset, letting the shifted rows paint over it. Every direct flow\n * child therefore rides the same transform, keeping the visual order of the\n * column intact.\n */\nexport function shiftSurfacesOf(port: HTMLElement): HTMLElement[] {\n const transcript = port.querySelector<HTMLElement>('[data-chat-transcript]')\n if (transcript !== null) return [transcript]\n const anchored = [...port.querySelectorAll<HTMLElement>('[data-chat-anchor-key]')]\n .filter(row => row.parentElement?.closest('[data-chat-anchor-key]') === null)\n const flow = port.querySelector<HTMLElement>('[data-chat-flow]')\n if (flow === null) return anchored\n const status = turnStatusOf(port)\n const anchoredSet = new Set(anchored)\n // One document-order pass: an anchored row, or a foreign child that contains\n // no anchored row of its own (a wrapper around real rows would double-shift\n // the rows inside it).\n return [...flow.children].filter((child): child is HTMLElement =>\n child instanceof HTMLElement\n && child !== status\n && (anchoredSet.has(child) || child.querySelector('[data-chat-anchor-key]') === null))\n}\n\nfunction currentShiftOf(element: HTMLElement): number {\n return Number(\n /translate3d\\(0(?:px)?,\\s*(-?[\\d.]+)px,\\s*0(?:px)?\\)/.exec(element.style.transform)?.[1] ?? 0,\n )\n}\n\n/* An open fixed tooltip (role=\"tooltip\") inside a surface is the only reason a\n * naive translate would misalign content during the follow shift: the applied\n * transform turns the surface into the tooltip's containing block and drags\n * the bubble off its anchor. Rather than re-derive viewport coordinates every\n * frame (a fragile engine that needed four follow-up fixes), hold the affected\n * surface untransformed while a tooltip is open. A tooltip exists in the DOM\n * only during hover, so the transient un-shifted row is invisible to a reader\n * and matches the release 0.4.0 feel; the shift resumes on the next frame once\n * it closes. */\n\nfunction setDirectShift(element: HTMLElement, px: number): void {\n if (Math.abs(px) > 0.01) {\n if (\n Math.abs(currentShiftOf(element) - px) <= 0.01\n && element.style.willChange === 'transform'\n && element.style.clipPath === ''\n ) return\n element.style.transform = `translate3d(0, ${px}px, 0)`\n element.style.willChange = 'transform'\n } else {\n if (element.style.transform === '' && element.style.willChange === '' && element.style.clipPath === '') return\n element.style.transform = ''\n element.style.willChange = ''\n }\n element.style.clipPath = ''\n}\n\nfunction setShift(element: HTMLElement, px: number): void {\n // Guard: while an open fixed tooltip lives on the surface, hold it\n // untransformed (see the comment above). When the shift is zero the tooltip\n // cannot detach, so skip the subtree scan entirely and keep the fast path.\n if (Math.abs(px) > 0.01 && element.querySelector('[role=\"tooltip\"]') !== null) {\n setDirectShift(element, 0)\n return\n }\n setDirectShift(element, px)\n}\n\nfunction turnStatusOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector<HTMLElement>(\n '[data-chat-turn-status], [data-chat-flow] > [role=\"status\"]',\n )\n}\n\n/**\n * Bottom-anchored hosts (ChatView packs the flow with `justify-content:\n * flex-end`) translate every pre-overflow growth into an instant upward step\n * of the whole column — a line lands and everything on screen hops up by one\n * line-height. No scroll-domain engine can smooth that, because\n * `scrollHeight` does not move while the host slack absorbs the growth.\n *\n * Owning `min-height` on the flow removes the slack instead: the column\n * always fills the scrollport, content grows downward where it is visible,\n * and real overflow — which the spring does model — begins with the very\n * first wrapped line. The style is owned in a page-realm registry so a\n * re-injected bundle adopts it rather than fighting it.\n *\n * The fill targets the VISIBLE client box, not the raw `clientHeight`.\n * Imposing `min-height: clientHeight` inflates `scrollHeight` by whatever\n * the scroller holds beyond the flow (its own padding-bottom, adjacent\n * chrome); with short content the engine then sees a phantom floor equal to\n * that padding and scrolls the conversation up — top edge off-screen while\n * blank padding sits at the bottom. The overshoot is measured once per port\n * and subtracted, so short content reaches `scrollHeight == clientHeight`\n * and the floor is exactly zero.\n */\ninterface FollowFlowFill {\n readonly element: HTMLElement\n readonly original: string\n /** Scroller height held by padding/chrome above the flow, px. */\n readonly overshootPx: number\n}\nconst FOLLOW_FLOW_FILL_SYMBOL = Symbol.for('dsh-smooth-stream.follow-flow-fill')\nconst followFlowFillHost = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, FollowFlowFill> | undefined\n}\nconst followFlowFills = followFlowFillHost[FOLLOW_FLOW_FILL_SYMBOL]\n ?? new WeakMap<HTMLElement, FollowFlowFill>()\nfollowFlowFillHost[FOLLOW_FLOW_FILL_SYMBOL] = followFlowFills\nconst FOLLOW_FLOW_FILL_USERS_SYMBOL = Symbol.for('dsh-smooth-stream.follow-flow-fill-users')\nconst followFlowFillUsersHost = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, number> | undefined\n}\nconst followFlowFillUsers = followFlowFillUsersHost[FOLLOW_FLOW_FILL_USERS_SYMBOL]\n ?? new WeakMap<HTMLElement, number>()\nfollowFlowFillUsersHost[FOLLOW_FLOW_FILL_USERS_SYMBOL] = followFlowFillUsers\n\nfunction flowElementOf(port: HTMLElement): HTMLElement | null {\n return port.querySelector<HTMLElement>('[data-chat-transcript]')\n ?? port.querySelector<HTMLElement>('[data-chat-flow]')\n}\n\nfunction ensureFlowFillsPort(port: HTMLElement): void {\n const element = flowElementOf(port)\n const owned = followFlowFills.get(port)\n if (element === null) {\n if (owned !== undefined) restoreFlowFill(port)\n return\n }\n const client = Math.max(0, port.clientHeight)\n let overshoot = owned?.overshootPx\n if (overshoot === undefined) {\n // Measure once per port: impose the full fill, read the scrollHeight\n // excess (scroller padding / chrome), then restore the natural state.\n const pendingOriginal = element.style.minHeight\n element.style.minHeight = `${client}px`\n overshoot = Math.max(0, port.scrollHeight - client)\n element.style.minHeight = pendingOriginal\n if (owned !== undefined) restoreFlowFill(port)\n }\n const target = `${Math.max(0, client - overshoot)}px`\n if (owned !== undefined) {\n if (owned.element === element && owned.overshootPx === overshoot && element.style.minHeight === target) return\n restoreFlowFill(port)\n }\n const original = element.style.minHeight\n element.style.minHeight = target\n followFlowFills.set(port, { element, original, overshootPx: overshoot })\n}\n\nfunction restoreFlowFill(port: HTMLElement): void {\n const owned = followFlowFills.get(port)\n if (owned === undefined) return\n owned.element.style.minHeight = owned.original\n followFlowFills.delete(port)\n}\n\n/** Height committed by one newly mounted Chat row, including its flex gap. */\nfunction entranceExtentOf(root: HTMLElement): number {\n const row = root.closest<HTMLElement>('[data-chat-flow-key]') ?? root\n const rect = row.getBoundingClientRect()\n const height = Math.max(0, rect.height, rect.bottom - rect.top, row.offsetHeight)\n let previous = row.previousElementSibling\n while (previous instanceof HTMLElement) {\n const previousRect = previous.getBoundingClientRect()\n if (previousRect.height > 0 || previousRect.bottom > previousRect.top) {\n return Math.max(height, rect.bottom - previousRect.bottom)\n }\n previous = previous.previousElementSibling\n }\n return height\n}\n\ninterface FollowRunway {\n readonly element: HTMLElement\n readonly offset: number\n readonly original: string\n readonly property: 'marginBottom' | 'marginTop'\n readonly requestedPx: number\n readonly normalizedLegacy?: boolean\n}\n\n/**\n * The plugin can be reinjected without replacing the conversation DOM. Keep\n * runway ownership in the page realm so a fresh bundle adopts the existing\n * margin instead of treating it as host layout and adding another 48px.\n */\nconst FOLLOW_RUNWAYS_SYMBOL = Symbol.for('dsh-smooth-stream.follow-runways')\nconst followRunwayRegistry = globalThis as typeof globalThis & {\n [key: symbol]: WeakMap<HTMLElement, FollowRunway> | undefined\n}\nconst followRunways = followRunwayRegistry[FOLLOW_RUNWAYS_SYMBOL]\n ?? new WeakMap<HTMLElement, FollowRunway>()\nfollowRunwayRegistry[FOLLOW_RUNWAYS_SYMBOL] = followRunways\n\ninterface FollowPaintLimit {\n readonly clientHeight: number\n readonly limit: number\n readonly measuredAtMs: number\n readonly composer: HTMLElement | null\n readonly status: HTMLElement | null\n readonly surface: HTMLElement | undefined\n}\n\n/**\n * A rect read can force a layout flush. At the floor the flow bottom sits on\n * the scrollport bottom, so while content streams the paint limit (chrome top\n * minus flow bottom) is constant; it only truly changes when the viewport or\n * conversation chrome changes. A measured limit therefore stays trusted for\n * this long even as contentHeight grows, so ordinary glyph frames never pay\n * a forced layout.\n */\nexport const FOLLOW_PAINT_LIMIT_TTL_MS = 250\n\nconst followPaintLimits = new WeakMap<HTMLElement, FollowPaintLimit>()\nconst followHadChrome = new WeakSet<HTMLElement>()\n/** Last painted shift per port, to spread a wrap's one-line step over frames. */\nconst followLastShiftPx = new WeakMap<HTMLElement, number>()\n/** Last settled floor per port, to size the shift decay bound against extent collapse. */\nconst followLastFloorPx = new WeakMap<HTMLElement, number>()\n/**\n * Screen-space completion anchor per port, SHARED by every follower arm and\n * the settle loop. Per-arm closures made the guard incoherent across the\n * completion cascade: block arms hand off leadership mid-turn, each new\n * settle loop re-seeded its own baseline at the already-jumped position, and\n * the cascade's one-frame clamp jump painted uncompensated. One baseline per\n * port also makes concurrent guards idempotent — whoever compensates first\n * restores the anchor, so the second measure reads ~0 and grants nothing.\n *\n * The anchor is the READING surface (the current turn's assistant row), not\n * the bottom-most shift surface: the cascade mounts/unmounts rows at the\n * column's bottom (process/tail mount, status swap), which switches\n * `at(-1)`'s identity mid-guard. Measuring across that switch reads a newly\n * mounted tail row as a >1000px \"content moved down\" push and floods the\n * pad, while the reading surface's real clamp jump goes uncompensated.\n */\ninterface FollowGuardAnchor {\n readonly element: HTMLElement\n /** Held viewport top — the position the reader should keep seeing. */\n readonly top: number\n /** Flow-child index, to tell an in-place replacement from a new turn. */\n readonly index: number\n /** Scroll geometry at store time, to identify an extent-neutral scroll. */\n readonly scrollTop: number\n readonly scrollHeight: number\n /**\n * Compositor shift and owned pad at store time. The engine moves the\n * rendered anchor between guard passes through TWO channels — the shift\n * glide (reveal decay: renderedΔ = −shiftΔ) and the pad retirement (the\n * floor sinks with the pad and the pin follows: renderedΔ = −padΔ). Only\n * the delta beyond BOTH is host motion worth compensating.\n */\n readonly shift: number\n readonly pad: number\n}\nconst followGuardAnchors = new WeakMap<HTMLElement, FollowGuardAnchor>()\n/**\n * Ports whose completion settle loop owns the follow. The settle drains the\n * reveal, retires the pad and guards the cascade; the swap that ends the\n * turn REMOUNTS the follower arms in the same frame cluster, and a freshly\n * mounted arm primes with a higher generation and would otherwise steal the\n * port mid-drain — its observers miss the cascade mutations (armed after\n * the fact) and its state initialization re-materializes engine space.\n * Ownership is released only when the settle finishes, the reader gestures,\n * or a genuinely NEW turn arrives (a user row joined since the handoff).\n */\nconst followCompletionSettle = new WeakSet<HTMLElement>()\n/** User-row count at handoff, for the new-turn check above. */\nconst followCompletionSettleRows = new WeakMap<HTMLElement, number>()\n\n/** User rows below the flow, or -1 when the host does not label rows with\n * `data-chat-flow-kind` (the engine's own audit benches): the new-turn\n * check is unsupported there and ownership guarding must stay OFF. */\nfunction countUserRows(port: HTMLElement): number {\n const flow = flowElementOf(port)\n if (flow === null) return -1\n let count = 0\n let sawKind = false\n for (const child of flow.children) {\n if (!(child instanceof HTMLElement)) continue\n const kind = child.getAttribute('data-chat-flow-kind')\n if (kind !== null) sawKind = true\n if (kind === 'user') count++\n }\n return sawKind ? count : -1\n}\n\n/** True while this port's completion settle owns the follow and no new turn\n * has arrived since the handoff. */\nfunction completionSettleGuardsPort(port: HTMLElement): boolean {\n if (!followCompletionSettle.has(port)) return false\n const baseline = followCompletionSettleRows.get(port) ?? -1\n const current = countUserRows(port)\n return baseline >= 0 && current >= 0 && current <= baseline\n}\n/**\n * Ports whose completion settle loop owns the follow. A settle loop drains,\n * retires the pad and guards the cascade; an arm that primes while this is\n * set with `active === false` (the settled-side static arm mounting in the\n * very swap frame) must NOT seize leadership — the swap re-renders the node\n * view, a fresh arm would otherwise steal the port mid-drain with\n * `reservePx = ownedBottomSpace` (the pad!), re-materialize an equal runway\n * through applyVisual, double-count the extent and fight the settle's own\n * guard for the rest of the window. A streaming arm (active === true, the\n * next turn) still takes over normally and the settle yields.\n */\n\nfunction readingAnchorOf(port: HTMLElement): HTMLElement | null {\n const flow = flowElementOf(port)\n if (flow === null) return null\n let anchor: HTMLElement | null = null\n for (const child of flow.children) {\n if (!(child instanceof HTMLElement)) continue\n if (child.getAttribute('data-chat-flow-kind') === 'assistant' || child.querySelector('[data-variant=\"think\"]') !== null) {\n anchor = child\n }\n }\n return anchor ?? shiftSurfacesOf(port).at(-1) ?? null\n}\n\n/**\n * Measure the reading surface's screen delta since the last guard pass.\n * Returns null when there is nothing comparable yet (first observation), or\n * when the anchor changed identity in a way that is NOT the in-place\n * live→settled replacement (a new turn's row joined — nothing jumped,\n * re-seed). Compensation sites must store the POST-compensation held\n * position via `holdGuardAnchor`, or the guard would read its own\n * correction as a fresh jump and oscillate.\n */\nfunction measureReadingAnchor(port: HTMLElement): { anchor: HTMLElement; index: number; top: number; delta: number } | null {\n const anchor = readingAnchorOf(port)\n if (anchor === null) {\n followGuardAnchors.delete(port)\n return null\n }\n const rect = anchor.getBoundingClientRect()\n // Unmeasurable geometry (jsdom's zero rects, a detached row): screen-space\n // comparison is meaningless — never seed or compensate from it.\n if (!(rect.width > 0 || rect.height > 0)) return null\n const top = rect.top\n const shift = currentShiftOf(anchor)\n const pad = flowPadOf(port)\n const scrollTop = port.scrollTop\n const scrollHeight = port.scrollHeight\n const flow = flowElementOf(port)\n const index = flow === null ? -1 : [...flow.children].indexOf(anchor)\n const stored = followGuardAnchors.get(port)\n if (stored === undefined) {\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n }\n // A host bottom-follow write is NOT a layout push. With extent unchanged, a\n // scrollTop change only moves the whole viewport; granting pad for it would\n // manufacture blank space and then require a second \"retirement\" motion.\n // Rebase both ledgers and let the writer keep its scroll position.\n if (\n Math.abs(scrollHeight - stored.scrollHeight) <= 0.5\n && Math.abs(scrollTop - stored.scrollTop) > 0.5\n ) {\n followScrollLedgers.set(port, scrollTop)\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n }\n // Host-caused motion only: the engine's own shift glide and floor changes\n // cancel out (renderedΔ = topΔ + scrollΔ − shiftΔ + padΔ).\n const scrollDelta = scrollTop - stored.scrollTop\n const delta = (top - stored.top) + scrollDelta - (shift - stored.shift) + (pad - stored.pad)\n if (stored.element === anchor) {\n // Refresh the baseline to the current rendered position on every\n // measurement: between guard passes the viewport legitimately moves\n // (streaming pins, reveal glide), and a stale baseline would read the\n // accumulated motion as one giant host jump at the next commit.\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return { anchor, index, top, delta }\n }\n // Identity changed. An in-place replacement (same slot, old node detached)\n // is the live→settled swap: bridge it by holding the reading surface at\n // its pre-swap viewport position. Anything else (the next turn's row\n // joining below, a session swap) is new layout — re-seed, never hold.\n if (!stored.element.isConnected && stored.index === index) {\n return { anchor, index, top, delta }\n }\n followGuardAnchors.set(port, { element: anchor, top, index, shift, pad, scrollTop, scrollHeight })\n return null\n}\n\n/** Record the position the reader should keep seeing after a correction. */\nfunction holdGuardAnchor(\n port: HTMLElement,\n measured: { anchor: HTMLElement; index: number },\n heldTop: number,\n): void {\n followGuardAnchors.set(port, {\n element: measured.anchor,\n index: measured.index,\n top: heldTop,\n shift: currentShiftOf(measured.anchor),\n pad: flowPadOf(port),\n scrollTop: port.scrollTop,\n scrollHeight: port.scrollHeight,\n })\n}\n/** Last runway offset seen per port, to rebase the extent when the margin size changes. */\nconst followRunwayOffsetHistory = new WeakMap<HTMLElement, number>()\n/** Last observed scroll floor per port, for the slack→overflow runway re-measure. */\nconst followFloorHistory = new WeakMap<HTMLElement, number>()\n/** One-shot flag: the transition frame must paint the full runway as baseline. */\nconst followSlackTransition = new WeakSet<HTMLElement>()\n\n/**\n * Bottom padding a completed settle left BELOW the status row. The settle\n * retires the owned runway by moving it from the status's top margin (the\n * visible reserve gap) to the flow's bottom padding (space under the chrome):\n * scroll extent stays constant, so the floor — and therefore the pinned\n * scrollTop and every content pixel — never moves, while the status glides up\n * to meet the final line. The pad is reclaimed back into the next stream's\n * runway by `ensureRunway`, so completions never accumulate dead space.\n */\ninterface FollowSettlePad {\n readonly element: HTMLElement\n readonly original: string\n readonly px: number\n}\nconst followSettlePads = new WeakMap<HTMLElement, FollowSettlePad>()\n\n/**\n * Retired follower space lives as `padding-bottom` on the FLOW element — the\n * one node the engine already owns styles on (flow-fill min-height) and the\n * host never rewrites. Host completion commits routinely REPLACE row elements\n * (live→settled swap re-keys the assistant row, the status row unmounts), and\n * any engine space written on those rows dies with them, sinking the floor\n * and slamming the pinned transcript for a frame. The flow survives.\n */\nfunction flowPadOf(port: HTMLElement): number {\n return followSettlePads.get(port)?.px ?? 0\n}\n/**\n * After a loss is re-opened as pad, a registry entry whose element is no\n * longer connected claims extent that no longer exists; drop it so the next\n * `ensureRunway` re-measures fresh instead of double-counting.\n */\nfunction pruneDeadRunway(port: HTMLElement): boolean {\n const runway = followRunways.get(port)\n if (runway !== undefined && !runway.element.isConnected) {\n restoreRunway(port)\n return true\n }\n return false\n}\n\nfunction setFlowPad(port: HTMLElement, px: number): void {\n const flow = flowElementOf(port)\n if (flow === null) return\n const existing = followSettlePads.get(port)\n const original = existing?.original ?? flow.style.paddingBottom\n if (px <= FOLLOW_SETTLE_EPSILON_PX) {\n if (existing !== undefined) {\n flow.style.paddingBottom = existing.original\n followSettlePads.delete(port)\n }\n return\n }\n flow.style.paddingBottom = original === ''\n ? `${px}px`\n : `calc(${original} + ${px}px)`\n followSettlePads.set(port, { element: flow, original, px })\n}\n\n/** Extent the follower owns below the content: the live runway margin plus\n * the retired completion pad. At adopt the pad is reclaimed into the fresh\n * reservation (same frame, pre-paint), so the floor never steps. */\nfunction ownedBottomSpaceOf(port: HTMLElement): number {\n return runwayOffsetOf(port) + flowPadOf(port)\n}\n\n/**\n * Completion-window diagnostics. Armed when a follower hands off to its\n * settle loop; every engine decision and every externally-written scroll\n * position inside the window prints one compact console line, so a live\n * host session can be diffed against the lab without a debugger.\n */\nlet followTraceUntilMs = 0\nfunction traceActive(): boolean {\n // Completion/finalize paths arm short trace windows automatically. Keep the\n // code path in published bundles, but do not emit console noise unless the\n // user has explicitly turned on render diagnostics.\n return debugRuntime.isEnabled() && performance.now() < followTraceUntilMs\n}\nfunction followTrace(event: string, detail: Record<string, number | string | boolean>): void {\n if (!traceActive()) return\n console.log(`[dsh-follow] ${event}`, JSON.stringify(detail))\n}\nfunction hostShOf(port: HTMLElement): number {\n return port.scrollHeight\n}\n\nfunction invalidatePaintLimit(port: HTMLElement): void {\n followPaintLimits.delete(port)\n}\n\ninterface FollowMotionState {\n readonly capacityPx: number\n readonly constrained: boolean\n readonly extent: number\n readonly lagPx: number\n readonly reservePx: number\n readonly velocityPxPerSec: number\n}\n\n/** Logical position and velocity survive a React owner handoff and finish. */\nconst followMotionStates = new WeakMap<HTMLElement, FollowMotionState>()\n\n/**\n * Reader-release record that must survive an ownership handoff. A follower\n * closing at stream end (finish/drain arm swap, row lifecycle flip) destroys\n * the closure holding `following = false`, and the arm taking over would\n * otherwise read the held viewport as \"at bottom\" and hard-snap to the\n * floor. Presence in this map means the reader's unpin away from the floor\n * is still in effect; it is cleared when a follower re-pins at the floor.\n */\ninterface FollowReaderHold {\n readonly atMs: number\n}\nconst followReaderHolds = new WeakMap<HTMLElement, FollowReaderHold>()\n\n/**\n * Commit-time correction channel. A reveal commit that lands after this\n * frame's ResizeObserver delivery would otherwise paint one intermediate\n * frame — content grown, scrollTop/transform not yet compensated — before\n * the next tick fixes it. Reveal arms call {@link notifyFollowCommit} right\n * after their commit; the leading follower re-runs its geometry in the same\n * task, so the intermediate state never reaches a paint.\n */\nconst followCommitListeners = new WeakMap<HTMLElement, Set<() => void>>()\n\nexport function notifyFollowCommit(fromInsidePort: HTMLElement | null): void {\n if (fromInsidePort === null) return\n const port = fromInsidePort.closest<HTMLElement>('[data-conversation-scroll]')\n const listeners = port === null ? undefined : followCommitListeners.get(port)\n if (listeners === undefined) return\n for (const listener of [...listeners]) listener()\n}\n\nfunction subscribeFollowCommit(port: HTMLElement, fn: () => void): () => void {\n let listeners = followCommitListeners.get(port)\n if (listeners === undefined) {\n listeners = new Set()\n followCommitListeners.set(port, listeners)\n }\n listeners.add(fn)\n return () => { listeners!.delete(fn) }\n}\n\nfunction restoreRunway(port: HTMLElement): void {\n const runway = followRunways.get(port)\n if (runway === undefined) return\n runway.element.style[runway.property] = runway.original\n followRunways.delete(port)\n invalidatePaintLimit(port)\n}\n\nfunction isLegacyRunway(value: string): boolean {\n if (value === '') return false\n const terms = [...value.matchAll(/([\\d.]+)px/g)]\n if (terms.length === 0 || value.replaceAll(/calc|px|[\\d.+()\\s]/g, '') !== '') return false\n const values = terms.map(([, raw]) => Number(raw))\n if (values.some(px => !Number.isFinite(px))) return false\n return [LEGACY_RUNWAY_PX, FOLLOW_STATUS_RUNWAY_PX].some(unit => values.every(px => (\n px >= unit && Math.abs(px % unit) <= Number.EPSILON\n )))\n}\n\n/** Remove unowned runway residue written by v0.3.3 and earlier bundles. */\nfunction migrateLegacyRunway(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n status: HTMLElement | null,\n composer: HTMLElement | null,\n): boolean {\n if (followRunways.has(port)) return false\n let migrated = false\n if (status !== null && isLegacyRunway(status.style.marginTop)) {\n // Harness TurnStatus has no inline margin; exact 48px multiples here are\n // values emitted by the old runway writer, including reload accumulation.\n status.style.marginTop = ''\n migrated = true\n }\n const last = surfaces.at(-1)\n if (\n status === null\n && composer !== null\n && last !== undefined\n && isLegacyRunway(last.style.marginBottom)\n ) {\n // Without TurnStatus the old writer used the current final message as its\n // completion runway. Limit migration to that same target topology.\n last.style.marginBottom = ''\n migrated = true\n }\n if (migrated) invalidatePaintLimit(port)\n return migrated\n}\n\nfunction ensureRunway(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n): void {\n const status = turnStatusOf(port)\n const composer = port.querySelector<HTMLElement>('[data-composer-seat]')\n // Adopt one exact current runway before migration. Larger exact multiples\n // are accumulated residue from older bundles and must be stripped.\n if (status !== null && followRunways.get(port) === undefined) {\n const inlinePx = Number.parseFloat(status.style.marginTop ?? '') || 0\n if (Math.abs(inlinePx - FOLLOW_STATUS_RUNWAY_PX) <= 0.5) {\n followRunways.set(port, {\n element: status,\n offset: inlinePx,\n property: 'marginTop',\n original: '',\n requestedPx: inlinePx,\n })\n invalidatePaintLimit(port)\n }\n }\n const migratedLegacy = migrateLegacyRunway(port, surfaces, status, composer)\n // A runway is useful only after the natural conversation already has a\n // scroll floor for its equal message transform to ride. Before that point\n // applyVisual keeps every surface in normal flow, so adding status margin\n // would expose the whole runway as empty space below a short/early Think.\n const naturalHeight = Math.max(0, port.scrollHeight - runwayOffsetOf(port))\n const existing = followRunways.get(port)\n const requestedRunwayPx = migratedLegacy || existing?.normalizedLegacy === true\n ? FOLLOW_STATUS_RUNWAY_PX\n : runwayPx\n if (requestedRunwayPx <= 0 || port.clientHeight <= 0 || naturalHeight <= port.clientHeight) {\n restoreRunway(port)\n return\n }\n const target = status === null\n ? { element: composer === null ? undefined : surfaces.at(-1), property: 'marginBottom' as const }\n : { element: status, property: 'marginTop' as const }\n if (target.element === undefined) {\n restoreRunway(port)\n return\n }\n const element = target.element\n const current = followRunways.get(port)\n if (current?.element === element\n && current.property === target.property\n && current.requestedPx === requestedRunwayPx) return\n\n restoreRunway(port)\n const beforeHeight = port.scrollHeight\n const original = element.style[target.property]\n element.style[target.property] = original === ''\n ? `${requestedRunwayPx}px`\n : `calc(${original} + ${requestedRunwayPx}px)`\n const offset = Math.max(0, port.scrollHeight - beforeHeight)\n followRunways.set(port, {\n element,\n offset,\n property: target.property,\n original,\n requestedPx: requestedRunwayPx,\n normalizedLegacy: migratedLegacy || existing?.normalizedLegacy === true,\n })\n invalidatePaintLimit(port)\n}\n\nfunction runwayOffsetOf(port: HTMLElement): number {\n return followRunways.get(port)?.offset ?? 0\n}\n\n/**\n * Move owned runway margin into the persistent flow pad without changing the\n * scroll extent. Returns the actual layout pixels removed from the margin.\n */\nfunction transferRunwayToFlowPad(port: HTMLElement, requestedPx: number): number {\n const runway = followRunways.get(port)\n if (runway === undefined || requestedPx <= 0 || !runway.element.isConnected) return 0\n const nextRequestedPx = Math.max(0, runway.requestedPx - requestedPx)\n const beforeOffset = runway.offset\n const beforeHeight = port.scrollHeight\n runway.element.style[runway.property] = nextRequestedPx <= FOLLOW_SETTLE_EPSILON_PX\n ? runway.original\n : runway.original === ''\n ? `${nextRequestedPx}px`\n : `calc(${runway.original} + ${nextRequestedPx}px)`\n const nextOffset = Math.max(0, beforeOffset + port.scrollHeight - beforeHeight)\n const transferredPx = Math.max(0, beforeOffset - nextOffset)\n if (nextRequestedPx <= FOLLOW_SETTLE_EPSILON_PX || nextOffset <= FOLLOW_SETTLE_EPSILON_PX) {\n followRunways.delete(port)\n } else {\n followRunways.set(port, {\n ...runway,\n offset: nextOffset,\n requestedPx: nextRequestedPx,\n })\n }\n if (transferredPx > 0) {\n setFlowPad(port, flowPadOf(port) + transferredPx)\n invalidatePaintLimit(port)\n }\n return transferredPx\n}\n\n/** Available paint room below the last message before fixed conversation chrome. */\nfunction safeShiftLimit(\n port: HTMLElement,\n surfaces: readonly HTMLElement[],\n): number {\n const last = surfaces.at(-1)\n if (last === undefined) return 0\n const status = turnStatusOf(port)\n const composer = port.querySelector<HTMLElement>('[data-composer-seat]')\n if (status !== null || composer !== null) followHadChrome.add(port)\n const cached = followPaintLimits.get(port)\n // Content growth alone cannot move the limit (measured at the floor, the\n // flow bottom rides the scrollport bottom), so the cache survives glyph\n // frames and only chrome/viewport changes or the TTL force a re-measure.\n if (\n cached !== undefined\n && performance.now() - cached.measuredAtMs <= FOLLOW_PAINT_LIMIT_TTL_MS\n && cached.clientHeight === port.clientHeight\n && cached.surface === last\n && cached.status === status\n && cached.composer === composer\n ) return cached.limit\n const ceiling = [status, composer]\n .filter((element): element is HTMLElement => element !== null)\n .map(element => ({ element, rect: element.getBoundingClientRect() }))\n // A detached or still-unmeasured sticky seat returns an all-zero rect.\n // It cannot constrain paint yet; a real seat at viewport top remains\n // valid because its bottom is still below its top.\n .filter(({ rect }) => Number.isFinite(rect.top) && Number.isFinite(rect.bottom) && rect.bottom > rect.top)\n .sort((first, second) => first.rect.top - second.rect.top)[0]\n if (ceiling === undefined) {\n // No conversation chrome means there is nothing to overlap. If chrome is\n // mounted but has not measured yet, permit only the runway zero-point\n // until ResizeObserver provides a real ceiling.\n return status === null && composer === null\n ? followHadChrome.has(port) ? 0 : Number.POSITIVE_INFINITY\n : runwayOffsetOf(port)\n }\n const ceilingTop = ceiling.rect.top - currentShiftOf(ceiling.element)\n const naturalBottom = last.getBoundingClientRect().bottom - currentShiftOf(last)\n const limit = Math.max(0, ceilingTop - naturalBottom - FOLLOW_PAINT_GUARD_PX)\n followPaintLimits.set(port, {\n clientHeight: port.clientHeight,\n limit,\n measuredAtMs: performance.now(),\n composer,\n status,\n surface: last,\n })\n return limit\n}\n\nfunction setFollowScrollTop(port: HTMLElement, nextTop: number): void {\n const ledger = followScrollLedgers.get(port)\n // Claim before the write so a Host ResizeObserver that runs in the same task\n // sees the owner instead of racing in with its own bottom-follow.\n if (port.getAttribute(FOLLOW_OWNED_ATTR) === null) {\n port.setAttribute(FOLLOW_OWNED_ATTR, 'active')\n }\n // Someone else wrote scrollTop since our last write (host floor-snap,\n // browser clamp, reader): surface it — a fight between the host's own\n // follow controller and this engine is the completion-jitter suspect.\n if (ledger !== undefined && traceActive() && Math.abs(port.scrollTop - ledger) > 1) {\n followTrace('external-scroll', { from: Math.round(port.scrollTop), to: Math.round(nextTop), ledger: Math.round(ledger) })\n }\n if (Math.abs(port.scrollTop - nextTop) > 0.01) port.scrollTop = nextTop\n followScrollLedgers.set(port, port.scrollTop)\n const ownedTop = String(port.scrollTop)\n if (port.getAttribute(FOLLOW_OWNED_ATTR) !== ownedTop) {\n port.setAttribute(FOLLOW_OWNED_ATTR, ownedTop)\n }\n}\n\n/**\n * Last scrollTop this engine wrote or accepted, per port. Reader intent is a\n * real upward delta from this ledger; a key press or touch while pinned\n * (typing in the composer) must not release the pin, because a released pin\n * can never re-acquire while content streams away from the reader position.\n */\nconst followScrollLedgers = new WeakMap<HTMLElement, number>()\nconst followActivityAt = new WeakMap<HTMLElement, number>()\ninterface FollowScrollOwnership {\n /** User-row count at handoff; a larger count means a genuinely new turn. */\n readonly userRows: number\n}\n/**\n * Scroll ownership must survive follower-arm remounts. Per-closure state let a\n * new text/tool arm reset the strike counter, so the same host write kept\n * triggering another engine write and repainting the visible up/down fight.\n */\nconst followHostScrollPorts = new WeakMap<HTMLElement, FollowScrollOwnership>()\n\n/** Clear host ownership only when a new user turn actually starts. */\nfunction resetHostScrollOwnershipForNewTurn(port: HTMLElement): void {\n const ownership = followHostScrollPorts.get(port)\n if (ownership === undefined) return\n const userRows = countUserRows(port)\n if (userRows >= 0 && userRows > ownership.userRows) followHostScrollPorts.delete(port)\n}\n\n/** Whether this port was owned recently enough to identify a closing tail row. */\nexport function hasRecentConversationFollow(port: HTMLElement, windowMs = 250): boolean {\n const last = followActivityAt.get(port)\n return last !== undefined && performance.now() - last <= windowMs\n}\n\nfunction readerScrolledUp(port: HTMLElement): boolean {\n return port.scrollTop < (followScrollLedgers.get(port) ?? 0) - FOLLOW_UNPIN_GESTURE_PX\n}\n\n/**\n * Paint a bounded visual lag and return the effective logical extent.\n *\n * This is the final geometry invariant, not merely an animation preference:\n * any lag beyond the real gap to status/composer chrome is caught up in the\n * same frame. Carrying that excess in `scrollTop` would move the transcript\n * toward fixed chrome and also make the host expose jump-to-bottom.\n */\nfunction applyVisual(\n port: HTMLElement,\n animatedH: number,\n reservePx: number,\n velocityPxPerSec = 0,\n runwayPx = FOLLOW_STATUS_RUNWAY_PX,\n shiftCeilingPx = Number.POSITIVE_INFINITY,\n promoteAtRest = false,\n trajectoryShiftPx?: number,\n dtMs = 16.7,\n writeScrollTop = true,\n): number {\n const surfaces = shiftSurfacesOf(port)\n ensureFlowFillsPort(port)\n void runwayPx\n // A runway added while the column still fit the viewport was absorbed by\n // the host's bottom slack: its measured offset was zero, but once real\n // overflow begins the same margin costs scroll length. Detect that\n // transition BEFORE any geometry is read and re-add the margin so its\n // stored offset is measured against the true post-overflow layout.\n {\n const preFloor = Math.max(0, port.scrollHeight - port.clientHeight)\n const lastFloorSeen = followFloorHistory.get(port)\n if (lastFloorSeen !== undefined && lastFloorSeen === 0 && preFloor > 0 && followRunways.has(port)) {\n const owned = followRunways.get(port)\n restoreRunway(port)\n ensureRunway(port, surfaces, owned?.requestedPx ?? runwayPx)\n // This frame the margin materializes into scroll length AND lands in\n // the floor in the same write; painting the held reserve as baseline\n // would leave its px uncompensated on screen. Spend the full runway\n // as baseline for exactly this frame.\n followSlackTransition.add(port)\n }\n if (preFloor !== lastFloorSeen) {\n followFloorHistory.set(port, preFloor)\n }\n }\n ensureRunway(port, surfaces, reservePx)\n const contentHeight2 = Math.max(0, port.scrollHeight)\n const runwayOffset2 = runwayOffsetOf(port)\n // Rebase the spring extent onto the current offset domain. targetHeight\n // = contentHeight − offset AND animatedH live in the same space; when the\n // margin grows, targetHeight drops by the offset's growth, so animatedH\n // must drop in lockstep or the whole req (painted shift) is released as\n // an upward snap. Shifting both by the same delta leaves the painted\n // shift untouched.\n const prevOffset2 = followRunwayOffsetHistory.get(port)\n if (prevOffset2 !== undefined && runwayOffset2 !== prevOffset2) {\n animatedH = Math.max(0, animatedH - (runwayOffset2 - prevOffset2))\n }\n followRunwayOffsetHistory.set(port, runwayOffset2)\n const contentHeight = contentHeight2\n const runwayOffset = runwayOffset2\n const targetHeight = Math.max(0, contentHeight - runwayOffset)\n const floor = Math.max(0, contentHeight - port.clientHeight)\n const extent = Math.min(targetHeight, Math.max(0, animatedH))\n if (port.style.overflowAnchor !== 'none') port.style.overflowAnchor = 'none'\n if (port.style.scrollBehavior !== 'auto') port.style.scrollBehavior = 'auto'\n if (floor <= 0) {\n followRunwayOffsetHistory.set(port, 0)\n if (writeScrollTop) setFollowScrollTop(port, 0)\n followMotionStates.set(port, {\n capacityPx: Number.POSITIVE_INFINITY,\n constrained: false,\n extent: targetHeight,\n lagPx: 0,\n reservePx: 0,\n velocityPxPerSec: 0,\n })\n for (const surface of surfaces) setShift(surface, 0)\n followLastShiftPx.set(port, 0)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n return targetHeight\n }\n // The visible scroll position rides the spring's smooth extent so each newly\n // revealed line is approached at continuous velocity instead of snapping the\n // whole wrap into one frame (the residual \"不丝滑\" jump). `animatedH` advances\n // by the spring's bounded per-frame step; the newest ≤ `visibleReserve` lines\n // stay hidden below the fold in the runway while `scrollTop` glides up to\n // reveal them. Concretely: `scrollTop = floor − min(requestedLag, reserve)`,\n // so during fast typing scrollTop trails floor by at most one runway (≤ 2\n // lines) advancing smoothly at the spring cadence; when typing stops and lag\n // exhausts, scrollTop converges to the floor. The shift below still holds the\n // reserve so no per-wrap tail jump appears.\n const limit = safeShiftLimit(port, surfaces)\n followSlackTransition.delete(port)\n const visibleReserve = Math.min(runwayOffset, Math.max(0, reservePx))\n const baselineShift = runwayOffset - visibleReserve\n const requestedLag = Math.max(0, targetHeight - extent)\n // Steady-state tail pin: while the predictive reserve is held, paint the\n // shifted surfaces at a FIXED offset equal to the reserve, so the newest\n // revealed line rides at a constant viewport position and every wrap's reveal\n // lands below the fold inside that space — instead of translating the whole\n // message by the decaying per-reveal lag (which moved the newest line up/down\n // at reveal cadence = the residual \"轻微回弹来回\" jitter). The reserve is held\n // constant during streaming; only when it retires (entrance/settle) does the\n // shift glide with it. The spring still closes below the fold, and backpressure\n // reads the untranslated requestedLag so reveal pacing is unchanged.\n const availableShift = Math.min(\n Math.max(0, limit),\n Math.max(0, shiftCeilingPx),\n )\n const motionShift = Math.min(\n trajectoryShiftPx ?? baselineShift + requestedLag,\n availableShift,\n )\n const idlePromotion = promoteAtRest && motionShift <= 0.01 && availableShift > 0 ? 0.1 : 0\n let shift = Math.max(motionShift, idlePromotion)\n const previousShift = followLastShiftPx.get(port)\n // The per-frame decay bound paces the engine's OWN glide (the margin\n // transfer retires at well under 8px/frame, so the limiter never binds for\n // it). It must NOT cap the compensation for a floor the engine did not\n // choose: the host completion cascade (think auto-collapse, status swap)\n // collapses the extent tens of px in one frame, scrollTop follows the\n // floor 1:1, and a decay capped at 8px/frame leaves the unpainted\n // remainder on screen — the completion 回弹 (visible 14-26px/frame sink).\n // Widen the bound by the floor's drop so the shift can always repaint what\n // the extent took away; the retire glide is unaffected because its\n // motionShift never moves.\n const previousFloor = followLastFloorPx.get(port)\n const floorDropPx = Math.max(0, (previousFloor ?? floor) - floor)\n const maxDecayPx = Math.max(\n dtMs <= 0\n ? FOLLOW_PAINT_SHIFT_MAX_STEP_PX\n : Math.max(1, (FOLLOW_PAINT_SHIFT_MAX_STEP_PX / 16.67) * dtMs),\n floorDropPx,\n )\n followLastFloorPx.set(port, floor)\n if (previousShift !== undefined && shift < previousShift - maxDecayPx) {\n // Decay-only rate limit. Growth is a WRAP COMPENSATION: the floor already\n // jumped one line in the same layout pass and `scrollTop` followed it, so\n // the matching shift increase cancels that step exactly. Rate-limiting it\n // paints the uncovered remainder as a visible one-frame jump (the\n // \"换行 18px 跳变\"). Only the decay side — runway retirement and settle —\n // is a real animation and keeps its per-frame bound.\n shift = previousShift - maxDecayPx\n }\n // COMPLETION RISE FUNDING. In the completion window a shift rise is only\n // invisible when it cancels floor growth the reader actually gets. The\n // handoff re-opens the runway while the think disclosure is still\n // collapsing: a same-task paint funded on the measured extent growth\n // over-covers by whatever the transition retracts before the paint lands —\n // the drain-onset 回弹. Same-task painters are therefore ceiling-frozen\n // (see the observer and the handoff below) and this clamp funds the\n // settle's rAF-frame rise on the growth CONFIRMED since the previous\n // paint; a completion without a collapse covers the runway in full on the\n // first frame (the drain contract). The streaming path never enters this\n // branch — wrap compensation stays unlimited there.\n if (followCompletionSettle.has(port) && previousShift !== undefined && previousFloor !== undefined) {\n const confirmedGrowthPx = Math.max(0, floor - previousFloor)\n if (shift > previousShift + confirmedGrowthPx) shift = previousShift + confirmedGrowthPx\n }\n followLastShiftPx.set(port, shift)\n const requestedShift = trajectoryShiftPx ?? (baselineShift + requestedLag)\n const effectiveLag = Math.max(0, shift - baselineShift)\n const capacityPx = Math.max(0, limit - baselineShift)\n const effectiveExtent = targetHeight - effectiveLag\n const isConstrained = requestedShift > availableShift + FOLLOW_SETTLE_EPSILON_PX\n || (limit <= 0 && requestedShift > baselineShift)\n if (writeScrollTop) setFollowScrollTop(port, floor)\n followMotionStates.set(port, {\n capacityPx,\n constrained: isConstrained,\n extent: effectiveExtent,\n lagPx: effectiveLag,\n reservePx: visibleReserve,\n velocityPxPerSec,\n })\n for (const surface of surfaces) setShift(surface, shift)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n return effectiveExtent\n}\n\nfunction clearMotion(port: HTMLElement): void {\n port.removeAttribute(FOLLOW_OWNED_ATTR)\n port.style.overflowAnchor = ''\n port.style.scrollBehavior = ''\n for (const surface of shiftSurfacesOf(port)) setShift(surface, 0)\n const status = turnStatusOf(port)\n if (status !== null) setShift(status, 0)\n}\n\nfunction clearVisual(port: HTMLElement): void {\n clearMotion(port)\n restoreRunway(port)\n followMotionStates.delete(port)\n followLastShiftPx.delete(port)\n followLastFloorPx.delete(port)\n invalidatePaintLimit(port)\n}\n\n/** Keep an already-promoted surface at zero until one stable final paint lands. */\nfunction holdCompositorAtRest(element: HTMLElement): void {\n element.style.transform = 'translate3d(0, 0px, 0)'\n element.style.willChange = 'transform'\n element.style.clipPath = ''\n}\n\n/** Remove equal offsets, land on the floor, then retire the compositor quietly. */\nfunction finishAtNaturalFloor(\n port: HTMLElement,\n retainCompositor = true,\n writeScrollTop = true,\n): void {\n followCompletionSettle.delete(port)\n followTraceUntilMs = Math.max(followTraceUntilMs, performance.now() + 10000)\n followTrace('finish-enter', { sh: hostShOf(port), st: Math.round(port.scrollTop), pad: Math.round(flowPadOf(port)), retain: retainCompositor })\n const surfaces = shiftSurfacesOf(port)\n const status = turnStatusOf(port)\n if (!retainCompositor) {\n restoreRunway(port)\n if (writeScrollTop) settleAtFloor(port)\n clearMotion(port)\n followMotionStates.delete(port)\n return\n }\n const promoted = [...surfaces, ...(status === null ? [] : [status])]\n .filter(element => element.style.transform !== '' || element.style.willChange === 'transform')\n const promotedSet = new Set(promoted)\n if (writeScrollTop) settleAtFloor(port)\n port.removeAttribute(FOLLOW_OWNED_ATTR)\n port.style.overflowAnchor = ''\n port.style.scrollBehavior = ''\n for (const surface of surfaces) {\n if (promotedSet.has(surface)) holdCompositorAtRest(surface)\n else setShift(surface, 0)\n }\n if (status !== null) {\n if (promotedSet.has(status)) holdCompositorAtRest(status)\n else setShift(status, 0)\n }\n followMotionStates.delete(port)\n if (promoted.length === 0) return\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n for (const element of promoted) {\n if (Math.abs(currentShiftOf(element)) <= 0.01) setShift(element, 0)\n }\n })\n })\n}\n\nfunction settleAtFloor(port: HTMLElement): void {\n const floor = Math.max(0, port.scrollHeight - port.clientHeight)\n setFollowScrollTop(port, floor)\n followReaderHolds.delete(port)\n}\n\ninterface FollowLeader {\n readonly generation: number\n readonly owner: object\n}\n\n/** Only the newest active follower may write one port's shared visual state. */\nconst followLeaders = new WeakMap<HTMLElement, FollowLeader>()\nlet followGeneration = 0\n/** Ports with a live streaming arm; completion guards must not fight them. */\nconst followActivePorts = new WeakSet<HTMLElement>()\n\n/**\n * Own the conversation scrollport's bottom-follow while `active` is true.\n *\n * @param rootRef - An element inside the conversation scrollport.\n * @param active - True while the reply is still revealing.\n * @param speedCpsRef - Live reveal-rate EMA from the smoother.\n * @param revealScaleRef - Optional backpressure control for text reveal.\n * @param predictive - Whether to reserve paint room ahead of growth.\n * @param entrance - Whether the first committed row height should glide in.\n * @param onEntranceSettled - Releases a one-shot entrance owner after catch-up.\n * @param predictiveRef - Optional live visibility gate for predictive runway.\n * @param entranceExtentRef - Optional measured growth delta for a generic row.\n * @param revealedCharsRef - Committed code-point count for feed-forward phase.\n * @param controlScroll - When false, leave the scrollport entirely to the Host.\n */\nexport function useConversationFollow(\n rootRef: RefObject<HTMLElement | null>,\n active: boolean,\n speedCpsRef: { current: number },\n revealScaleRef?: { current: number },\n predictive = true,\n entrance = false,\n onEntranceSettled?: () => void,\n predictiveRef?: { current: boolean },\n entranceExtentRef?: { current: number | null },\n revealedCharsRef?: { current: number },\n controlScroll = true,\n): void {\n const activeRef = useRef(active)\n const entranceRef = useRef(entrance)\n const onEntranceSettledRef = useRef(onEntranceSettled)\n entranceRef.current = entrance\n onEntranceSettledRef.current = onEntranceSettled\n activeRef.current = active\n const controlScrollRef = useRef(controlScroll)\n controlScrollRef.current = controlScroll\n\n useLayoutEffect(() => {\n if (!controlScroll) return\n if (!active) return\n const startedAsEntrance = entrance\n const owner = {}\n const generation = ++followGeneration\n let rafId = 0\n let last = performance.now()\n let following = true\n let primed = false\n let animatedH = 0\n let reservePx = 0\n let velocityPxPerSec = 0\n let interacting = false\n let readerGestureIntent = false\n let readerReleased = false\n let touchStartY: number | null = null\n let interactTimer: ReturnType<typeof setTimeout> | null = null\n let port: HTMLElement | null = null\n let resize: ResizeObserver | null = null\n let mutations: MutationObserver | null = null\n let observedTail: HTMLElement | null = null\n let statusWasPresent: boolean | null = null\n let lastStatusHeightPx = 0\n let trajectoryPositionPx: number | null = null\n let trajectoryVelocityPxPerMs = 0\n let trajectoryTargetVelocityPxPerMs = 0\n let trajectoryFloorPx: number | null = null\n let trajectoryGrowthAtMs: number | null = null\n let trajectoryAccumulatedGrowthPx = 0\n let trajectoryAccumulatedGrowthMs = 0\n let trajectoryGrowthSamples = 0\n let trajectoryWasActive = false\n const revealPhase = new FollowRevealPhaseTracker()\n let holding: HTMLElement | null = null\n let entrancePending = entranceRef.current\n\n const finishEntrance = (): void => {\n if (!entrancePending) return\n entrancePending = false\n onEntranceSettledRef.current?.()\n }\n\n const updateRevealScale = (next: HTMLElement, elapsedMs: number, urgent = false): void => {\n if (revealScaleRef === undefined) return\n const tuning = debugRuntime.activeTuning()\n const state = followMotionStates.get(next)\n const target = state === undefined\n ? 1\n : computeFollowRevealScale(state.lagPx, state.capacityPx, state.constrained, tuning)\n const current = Math.min(1, Math.max(tuning.backpressureMinScale, revealScaleRef.current))\n if (target < current || urgent) {\n // Slowing affects only future glyph commits, so it can react at once\n // without producing a visual discontinuity in the current frame.\n revealScaleRef.current = Math.min(current, target)\n return\n }\n const releaseStep = 1 - Math.exp(-Math.max(0, elapsedMs) / FOLLOW_BACKPRESSURE_RELEASE_MS)\n revealScaleRef.current = current + (target - current) * releaseStep\n }\n\n const releaseRevealScale = (): void => {\n if (revealScaleRef !== undefined) revealScaleRef.current = 1\n }\n\n const reportFollow = (next: HTMLElement, isActive: boolean): void => {\n const state = followMotionStates.get(next)\n debugRuntime.reportFollow(next, {\n // TEMP audit provenance: lagPx=-1 marks the fallback path (no motion\n // state owned by this reporter this frame).\n lagPx: state ? state.lagPx : -1,\n velocityPxPerSec: state?.velocityPxPerSec ?? 0,\n reservePx: state?.reservePx ?? 0,\n capacityPx: state ? state.capacityPx : -1,\n revealScale: revealScaleRef?.current ?? 1,\n following,\n constrained: state?.constrained ?? false,\n scrollTop: next.scrollTop,\n scrollHeight: next.scrollHeight,\n clientHeight: next.clientHeight,\n active: isActive,\n })\n }\n\n const isLeader = (next: HTMLElement): boolean => followLeaders.get(next)?.owner === owner\n\n const hold = (next: HTMLElement): void => {\n followActivityAt.set(next, performance.now())\n if (holding === next && isLeader(next)) return\n holding = next\n const leader = followLeaders.get(next)\n if ((leader === undefined || generation > leader.generation) && !completionSettleGuardsPort(next)) {\n followCompletionSettle.delete(next)\n followLeaders.set(next, { generation, owner })\n }\n }\n\n const yieldScrollOwnership = (next: HTMLElement, floor: number): void => {\n if (hostOwnsScroll) return\n hostOwnsScroll = true\n followHostScrollPorts.set(next, { userRows: countUserRows(next) })\n followTrace('yield-scroll', {\n from: Math.round(next.scrollTop),\n to: Math.round(floor),\n })\n // A host-owned port must be a clean host-owned render. Keeping the\n // engine's transform/reserve alive lets its decay fight the host's hard\n // bottom-follow; that is the visible up/down jitter after handoff.\n clearVisual(next)\n const naturalFloor = Math.max(0, next.scrollHeight - next.clientHeight)\n setFollowScrollTop(next, naturalFloor)\n next.removeAttribute(FOLLOW_OWNED_ATTR)\n followLeaders.delete(next)\n releaseRevealScale()\n debugRuntime.reportFollow(next, null)\n }\n\n const detectHostScroll = (next: HTMLElement, floor: number): void => {\n if (followHostScrollPorts.has(next)) {\n hostOwnsScroll = true\n return\n }\n const ledger = followScrollLedgers.get(next)\n if (ledger === undefined || Math.abs(next.scrollTop - ledger) <= 1) return\n // A write that lands on the current floor has the same semantics as our\n // own bottom-follow (including a manual jump-to-bottom or a shrink\n // clamp). Rebase and keep smoothing; treating it as a second writer\n // would permanently retire the effect for the rest of the turn.\n if (Math.abs(next.scrollTop - floor) <= 1) {\n followScrollLedgers.set(next, next.scrollTop)\n externalScrollStrikes = 0\n return\n }\n externalScrollStrikes += 1\n if (externalScrollStrikes >= 2) yieldScrollOwnership(next, floor)\n }\n\n const drop = (next: HTMLElement): void => {\n if (holding === next) holding = null\n if (isLeader(next)) {\n clearMotion(next)\n followMotionStates.delete(next)\n releaseRevealScale()\n debugRuntime.reportFollow(next, null)\n }\n }\n\n const handBackVisual = (next: HTMLElement): void => {\n const shift = currentShiftOf(shiftSurfacesOf(next).at(-1) ?? next)\n const transferableShift = shift > FOLLOW_SETTLE_EPSILON_PX ? shift : 0\n const visualTop = Math.max(0, next.scrollTop - transferableShift)\n // The predictive runway only has meaning while this follower owns the\n // floor. Remove it before choosing the reader's landing point; keeping\n // it through the release paints a transient natural gap + 48px blank\n // block until the next follow frame restores an equal transform.\n clearMotion(next)\n restoreRunway(next)\n const floor = Math.max(0, next.scrollHeight - next.clientHeight)\n // The host keeps its own bottom-follow bit while the reader remains in\n // its 25px slack band. Land one pixel beyond that band so even a light\n // wheel/trackpad/touch intent releases both owners on the same frame.\n next.scrollTop = Math.min(visualTop, Math.max(0, floor - FOLLOW_HOST_RELEASE_PX))\n followScrollLedgers.set(next, next.scrollTop)\n }\n\n const markGesture = (event: Event): void => {\n interacting = true\n if (event.type === 'wheel') {\n const deltaY = (event as WheelEvent).deltaY\n if (Number.isFinite(deltaY) && deltaY < 0) readerGestureIntent = true\n } else if (event.type === 'touchstart') {\n const touch = (event as TouchEvent).touches[0]\n touchStartY = touch?.clientY ?? null\n } else if (event.type === 'touchmove') {\n const touch = (event as TouchEvent).touches[0]\n if (touch !== undefined) {\n if (touchStartY === null) touchStartY = touch.clientY\n // A downward finger drag moves the transcript toward older content.\n if (touch.clientY - touchStartY > 1) readerGestureIntent = true\n }\n } else if (event.type === 'touchend' || event.type === 'touchcancel') {\n touchStartY = null\n }\n if (interactTimer !== null) clearTimeout(interactTimer)\n interactTimer = setTimeout(() => {\n interacting = false\n readerGestureIntent = false\n interactTimer = null\n }, FOLLOW_GESTURE_MS)\n }\n\n /**\n * Last observed scroll extent, shared by the pre-paint correction and the\n * settle loop so a host layout shrink is re-opened exactly once no matter\n * which observer sees it first. `-1` until the first owned observation.\n */\n let settleRetiring = false\n // The engine may lead streaming writes, but the host also owns a\n // bottom-follow controller. Ledger disagreement is harmless once; a\n // repeated disagreement is proof of a second writer. Hand the scrollport\n // to that writer immediately: the engine keeps compositor compensation but\n // never writes scrollTop again. This is the only way to avoid a ping-pong\n // fight when the host bundle does not consume `data-follow-owned`.\n let hostOwnsScroll = false\n let externalScrollStrikes = 0\n let lastReadingAnchorPullAtMs = Number.NEGATIVE_INFINITY\n let readingAnchorPullBudgetPx = 0\n // Set once this closure's completion handoff has armed its settle loop.\n // Only a handed-off arm's observers may guard a LEADERLESS port: mid-turn\n // arms that never handed off must keep standing down (entrance/steaming\n // successors own the port), while a handed-off arm whose settle loop was\n // killed by leadership churn is the only pre-paint guard left when the\n // completion cascade lands in the leaderless window.\n let handedOff = false\n /**\n * Bring the reading surface back down toward its held position after an\n * upward host push (clamp jump, live→settled swap): spend persistent pad\n * first — lowering the floor lets the pin carry the text back down —\n * then raise the compositor shift for whatever pad cannot cover, and\n * rebase the spring extent so the raise survives the next applyVisual\n * (which otherwise recomputes the shift from lag and undoes it).\n */\n const pullReadingAnchorBack = (\n host: HTMLElement,\n measured: { anchor: HTMLElement; index: number; top: number; delta: number },\n trace = false,\n ): void => {\n // Experimental no-rebound gate: an upward correction here has repeatedly\n // over/under-compensated against the settle loop's floor writes. Hold the\n // new position instead of issuing a reverse correction; the monotone\n // final retirement remains the only release path.\n holdGuardAnchor(host, measured, measured.top)\n return\n const need = -measured.delta\n // A large host shrink must not spend its whole pad in one paint. Keep\n // the screen anchored with an immediate shift, then hand the floor back\n // at the same bounded rate as the final retirement.\n const now = performance.now()\n const elapsedPx = lastReadingAnchorPullAtMs === Number.NEGATIVE_INFINITY\n ? FOLLOW_PAINT_SHIFT_MAX_STEP_PX\n : Math.min(24, Math.max(0, now - lastReadingAnchorPullAtMs) * (FOLLOW_PAINT_SHIFT_MAX_STEP_PX / 16.7))\n readingAnchorPullBudgetPx = Math.min(need, readingAnchorPullBudgetPx + elapsedPx)\n lastReadingAnchorPullAtMs = now\n const released = Math.min(flowPadOf(host), readingAnchorPullBudgetPx)\n readingAnchorPullBudgetPx -= released\n if (released > FOLLOW_SETTLE_EPSILON_PX) {\n if (trace) {\n followTrace('anchor-pull', { screenDelta: Math.round(measured.delta), released: Math.round(released), st: Math.round(host.scrollTop) })\n }\n setFlowPad(host, flowPadOf(host) - released)\n animatedH = Math.max(0, animatedH - released)\n }\n const remainder = need - released\n let raise = 0\n if (remainder > 0.5) {\n const surfaces = shiftSurfacesOf(host)\n const limit = safeShiftLimit(host, surfaces)\n const current = currentShiftOf(surfaces.at(-1) ?? host)\n const target = Math.min(current + remainder, Math.max(0, limit - FOLLOW_PAINT_GUARD_PX))\n raise = target - current\n if (raise > 0) {\n for (const surface of surfaces) setShift(surface, current + raise)\n followLastShiftPx.set(host, current + raise)\n animatedH = Math.max(0, animatedH - raise)\n }\n }\n holdGuardAnchor(host, measured, measured.top + released + raise)\n }\n /**\n * THE screen-space anchor hold, shared by every entry point: the\n * structural-observer path (pre-paint cascade correction), the settle\n * loop's per-frame poll, and the ACTIVE loop's per-frame poll. The\n * shift-excluded delta filters the engine's own motion (reveal glide,\n * wrap lockstep) to ~0, so a live poll may compensate safely — which is\n * what saves the completion swap: the settled-side arm primes in its\n * layout effect and steals leadership IN the cascade frame, its own\n * observers miss the mutations (armed after the fact), and only this\n * poll sees the jump while it can still be corrected before paint.\n * Returns the measured delta (null when nothing was comparable).\n */\n const enforceReadingAnchor = (host: HTMLElement, trace = false): number | null => {\n const measured = measureReadingAnchor(host)\n if (measured === null) return null\n if (measured.delta > 0.5) {\n if (trace) {\n followTrace('anchor-hold', { screenDelta: Math.round(measured.delta), st: Math.round(host.scrollTop) })\n }\n if (pruneDeadRunway(host)) reservePx = 0\n holdGuardAnchor(host, measured, measured.top)\n } else if (measured.delta < -0.5) {\n if (pruneDeadRunway(host)) reservePx = 0\n pullReadingAnchorBack(host, measured, trace)\n } else {\n holdGuardAnchor(host, measured, measured.top)\n }\n return measured.delta\n }\n /** Pre-paint correction (observers, commit subscription). */\n const restoreBeforePaint = (): void => {\n if (!following || port === null) return\n if (hostOwnsScroll || followHostScrollPorts.has(port)) {\n hostOwnsScroll = true\n followScrollLedgers.set(port, port.scrollTop)\n return\n }\n if (!activeRef.current) {\n detectHostScroll(port, Math.max(0, port.scrollHeight - port.clientHeight))\n }\n // Yield only to a LIVE owner. Block arms hand off leadership mid-turn\n // and each handoff kills the previous settle loop; the completion\n // cascade routinely lands in the leaderless window between that death\n // and the successor's first frame. Standing down whenever leadership is\n // merely absent left the cascade's clamp jump uncompensated. While\n // SOMEONE holds the port, the dead observers must not fight the live\n // guard; while NOBODY does, a handed-off arm's armed observer is the\n // only guard left, and the shared followGuardAnchors baseline keeps it\n // idempotent.\n const leaderless = !isLeader(port)\n if (!activeRef.current && followActivePorts.has(port)) return\n if (leaderless && (followLeaders.has(port) || !handedOff)) return\n // Leaderless window: this arm's closure state froze when its loop died.\n // Sync to the shared per-port motion ledger the last live loop wrote,\n // or the applyVisual below would replay stale extent/reserve into the\n // runway and pad ledgers while compensating the cascade.\n if (leaderless) {\n const sharedMotion = followMotionStates.get(port)\n if (sharedMotion !== undefined) {\n animatedH = Math.min(port.scrollHeight, Math.max(0, sharedMotion.extent))\n reservePx = sharedMotion.reservePx\n velocityPxPerSec = sharedMotion.velocityPxPerSec\n }\n }\n // A host keyed replacement can disconnect the element carrying our\n // margin before MutationObserver runs. Drop the stale registry entry;\n // banking it as pad preserves an extent that immediately becomes the\n // slow retirement rebound. The same-task ensureRunway / applyVisual path\n // reopens only the runway that is still needed.\n pruneDeadRunway(port)\n // HOST COMPLETION COMMITS under the pin must be corrected in THIS\n // pre-paint task: the settle loop's rAF guard runs after the host's own\n // follow effects, so a cascade commit (status swap, tail mount) would\n // otherwise paint one frame pinned to the sunk floor. The screen-space\n // anchor hold reads the shared per-port baseline (see\n // followGuardAnchors); it runs for structural commits only and stands\n // down while this settle's retirement glide runs (that motion is ours).\n if (!settleRetiring) {\n const measured = measureReadingAnchor(port)\n if (measured !== null && measured.delta > 0.5) {\n if (pruneDeadRunway(port)) reservePx = 0\n holdGuardAnchor(port, measured, measured.top)\n } else if (measured !== null && measured.delta < -0.5) {\n if (pruneDeadRunway(port)) reservePx = 0\n if (!activeRef.current) {\n // Completion window: pad first, then the shift raise absorbs\n // whatever pad cannot cover (the swap jump rides this path).\n pullReadingAnchorBack(port, measured)\n } else {\n // Live streaming: the original semantics — release only what the\n // pad holds and leave the remainder to the frame loop's own\n // lockstep. A shift raise here would cancel the reveal glide.\n const released = Math.min(flowPadOf(port), -measured.delta)\n if (released > FOLLOW_SETTLE_EPSILON_PX) {\n setFlowPad(port, flowPadOf(port) - released)\n animatedH = Math.max(0, animatedH - released)\n }\n holdGuardAnchor(port, measured, measured.top + released)\n }\n } else if (measured !== null) {\n holdGuardAnchor(port, measured, measured.top)\n }\n }\n // A reveal commit changes the measured tail, not the fixed chrome. Keep\n // the paint-limit TTL intact here; ResizeObserver and viewport/chrome\n // changes invalidate it when the cached geometry is no longer valid.\n // The same-task correction still runs, but ordinary glyph commits do not\n // force a fresh chrome rect read.\n const tuning = debugRuntime.activeTuning()\n const predictGrowth = predictiveRef?.current ?? predictive\n const floor = Math.max(0, port.scrollHeight - port.clientHeight)\n // A wrap or other layout growth changes the real floor and may change the\n // natural tail clearance. Re-measure that boundary; same-floor glyph\n // commits can continue using the cached chrome geometry.\n if (followFloorHistory.get(port) !== floor) invalidatePaintLimit(port)\n const isReasoningSurface = rootRef.current?.querySelector('[data-variant=\"think\"]') !== null\n const trajectoryShift = predictive\n && !isReasoningSurface\n && runwayOffsetOf(port) > 0\n && trajectoryPositionPx !== null\n ? floor - trajectoryPositionPx\n : undefined\n animatedH = applyVisual(\n port,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n // COMPLETION RISE FREEZE: this observer runs in the mutation's\n // microtask, but the paint lands one vsync later — extent a CSS\n // transition retracts in between makes any rise funded here\n // over-cover by exactly that retraction (the drain-onset 回弹).\n // Freeze rises same-task; the settle's rAF frame re-reads the floor\n // within its own paint tick and funds the confirmed growth there.\n activeRef.current\n ? Number.POSITIVE_INFINITY\n : (followLastShiftPx.get(port) ?? Number.POSITIVE_INFINITY),\n !predictGrowth,\n trajectoryShift,\n 0,\n activeRef.current && !hostOwnsScroll,\n )\n if (trajectoryShift !== undefined) {\n const currentShift = followLastShiftPx.get(port) ?? (floor - (trajectoryPositionPx ?? floor))\n trajectoryPositionPx = floor - currentShift\n }\n updateRevealScale(port, 0, true)\n reportFollow(port, activeRef.current)\n // Host ChatView ResizeObservers may run after this observer and hard-snap\n // to its floor. Re-apply the owned floating top in the same microtask,\n // before the browser's next paint, while scroll-event capture prevents a\n // programmatic write from changing the reader's at-bottom state.\n }\n\n // Same correction, run synchronously with a reveal commit (see\n // notifyFollowCommit above). Subscribed per-port in bindPort.\n let unsubscribeCommit: (() => void) | null = null\n\n const bindPort = (next: HTMLElement): void => {\n if (port === next) return\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n resize?.disconnect()\n mutations?.disconnect()\n }\n unsubscribeCommit?.()\n port = next\n invalidatePaintLimit(port)\n unsubscribeCommit = subscribeFollowCommit(port, () => { restoreBeforePaint() })\n for (const name of GESTURE_EVENTS) {\n port.addEventListener(name, markGesture, { passive: true })\n }\n if (typeof ResizeObserver !== 'undefined') {\n resize = new ResizeObserver(() => restoreBeforePaint())\n resize.observe(port)\n const proxy = resizeProxyOf(port)\n if (proxy !== null) resize.observe(proxy)\n }\n // Completion is chiefly a child-list transaction (status removal,\n // live-to-settled replacement, tail insertion). Because following\n // gives the flow a viewport min-height, those mutations can leave the\n // flow's border box unchanged and never notify ResizeObserver. Observe\n // the transaction itself so the anchor hold still runs before paint.\n if (typeof MutationObserver !== 'undefined') {\n const flow = flowElementOf(port)\n if (flow !== null) {\n mutations = new MutationObserver(() => { restoreBeforePaint() })\n mutations.observe(flow, { childList: true, subtree: true })\n }\n }\n }\n\n /**\n * Keep the observer on the flow's TAIL surface. A flow locked to the\n * viewport by min-height does not resize when content grows inside it —\n * only the last message row does, and missing that resize means missing\n * the pre-paint correction for that frame's wrap.\n */\n const observeTailSurface = (): void => {\n if (resize === null || port === null) return\n const tail = shiftSurfacesOf(port).at(-1) ?? null\n if (tail === observedTail) return\n if (observedTail !== null) resize.unobserve(observedTail)\n observedTail = tail\n if (tail !== null) resize.observe(tail)\n }\n\n const frame = (now: number) => {\n rafId = requestAnimationFrame(frame)\n // Spring time is clamped so one paint after a stall cannot teleport the\n // transcript. Runway response uses real elapsed time, otherwise long\n // frames would open paint room more slowly precisely when it is needed.\n const elapsedMs = Math.max(0.001, now - last)\n const dt = Math.min(FOLLOW_MAX_FRAME_MS, elapsedMs)\n const tuning = debugRuntime.activeTuning()\n last = now\n const root = rootRef.current\n if (root === null) return\n const nextPort = root.closest<HTMLElement>('[data-conversation-scroll]')\n if (nextPort === null) return\n bindPort(nextPort)\n observeTailSurface()\n resetHostScrollOwnershipForNewTurn(nextPort)\n hostOwnsScroll = followHostScrollPorts.has(nextPort)\n if (activeRef.current) followActivePorts.add(nextPort)\n else followActivePorts.delete(nextPort)\n // A hidden/unmeasured port has no meaningful floor yet. Keep this owner\n // unprimed and let the already-scheduled RAF initialize it after layout.\n if (nextPort.clientHeight <= 0) return\n\n const floor = Math.max(0, nextPort.scrollHeight - nextPort.clientHeight)\n const reportedLag = floor - nextPort.scrollTop\n const extent = Math.min(\n nextPort.scrollHeight,\n Math.max(0, nextPort.scrollHeight - reportedLag),\n )\n\n if (!primed) {\n // A completion settle owns this port (the swap remounted this arm in\n // the same frame cluster): stay a passive watcher. Taking over here\n // would zero the pad mid-retirement and re-inherit it as reserve —\n // double-counting the extent for one giant jump.\n if (completionSettleGuardsPort(nextPort)) {\n primed = true\n following = false\n return\n }\n const inherited = nextPort.hasAttribute(FOLLOW_OWNED_ATTR)\n ? followMotionStates.get(nextPort)\n : undefined\n if (inherited === undefined) {\n // A new Agent row is already part of scrollHeight on its first\n // frame. Start at the pre-insert extent so that initial Context and\n // Tool chrome enters through the same spring as later height growth.\n // The predictive runway starts pre-opened at the current reveal\n // pressure: it rides canceled by the equal transform, and waiting\n // out the response ramp would leave the first wraps unpinned.\n const entranceExtent = entrancePending\n ? entranceExtentRef?.current ?? entranceExtentOf(root)\n : 0\n const predictGrowth = predictiveRef?.current ?? predictive\n // Start the entrance at the pre-insert extent, not the raw reported\n // lag: holding the reader's small first-frame offset here would keep\n // the entrance lag above the settle epsilon for ~a second (the\n // spring's advance at single-digit lag is sub-pixel), leaving the\n // entrance arm alive past a settled swap and deferring the\n // completion settle until it finally closes.\n animatedH = entrancePending\n ? Math.max(0, nextPort.scrollHeight - entranceExtent)\n : nextPort.scrollHeight\n // Established before first paint; the matching margin below is\n // written in the same commit, so this held-and-canceled space\n // never moves a pixel.\n const hasStatus = turnStatusOf(nextPort) !== null\n // ZERO-DOWNWARD-REBOUND: the reservation must never land below the\n // margin this port already owns. base = margin − reservation is the\n // painted shift; a reservation smaller than the owned margin would\n // repaint the difference as an instant downward step on this arm's\n // first frame. The margin stays owned (see the growth-only rule in\n // the frame loop), so the reservation opens at least to match it.\n reservePx = Math.max(\n ownedBottomSpaceOf(nextPort),\n predictGrowth && (hasStatus || speedCpsRef.current > FOLLOW_RESERVE_MIN_CPS)\n ? computeFollowReserve(speedCpsRef.current, tuning.runwayPx)\n : 0,\n )\n // Adopt-time reclaim, exactly once and in this same pre-paint task:\n // the previous completion's pad becomes this stream's reserve gap,\n // so the extent — and the pinned floor — never steps between turns.\n // A completion settle still owning the port keeps its ledgers: the\n // swap's remounted arms must not zero the pad mid-retirement.\n if (!completionSettleGuardsPort(nextPort)) setFlowPad(nextPort, 0)\n statusWasPresent = hasStatus\n velocityPxPerSec = 0\n // The committed row/growth delta has already moved the new floor.\n // Decide ownership from READER INTENT EVIDENCE, not raw lag: an\n // upward move recorded past our own ledger is a pull-up; anything\n // else (content that mounted while the host had not re-pinned yet,\n // a completion clamp, first-frame geometry) must keep following,\n // otherwise the whole stream falls back to the host's hard snap.\n void reportedLag\n // A prior follower's reader-release record outranks ledger\n // evidence: its closure died with `following = false` after the\n // release already reset the ledger to the held position, so the\n // delta-based check alone can no longer see the unpin.\n following = !readerScrolledUp(nextPort)\n && !followReaderHolds.has(nextPort)\n } else {\n animatedH = Math.min(nextPort.scrollHeight, inherited.extent)\n reservePx = inherited.reservePx\n velocityPxPerSec = inherited.velocityPxPerSec\n following = true\n }\n if (following) {\n hold(nextPort)\n if (isLeader(nextPort)) {\n animatedH = applyVisual(\n nextPort,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n Number.POSITIVE_INFINITY,\n !(predictiveRef?.current ?? predictive),\n undefined,\n 0,\n !hostOwnsScroll,\n )\n if (\n predictive\n && root.querySelector('[data-variant=\"think\"]') === null\n && runwayOffsetOf(nextPort) > 0\n ) {\n const floor = Math.max(0, nextPort.scrollHeight - nextPort.clientHeight)\n const requestedMinLagPx = Math.max(\n FOLLOW_TRAJECTORY_MIN_LAG_PX,\n runwayOffsetOf(nextPort) - FOLLOW_TRAJECTORY_PHASE_PX,\n )\n const paintMaxLagPx = Math.max(0, safeShiftLimit(nextPort, shiftSurfacesOf(nextPort)) - FOLLOW_PAINT_GUARD_PX)\n const minLagPx = Math.min(requestedMinLagPx, paintMaxLagPx)\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n trajectoryPositionPx = floor - Math.min(paintMaxLagPx, Math.max(minLagPx, currentShift))\n trajectoryTargetVelocityPxPerMs = Math.max(0, speedCpsRef.current) * 0.4 / 1000\n trajectoryVelocityPxPerMs = trajectoryTargetVelocityPxPerMs\n trajectoryFloorPx = floor\n trajectoryGrowthAtMs = now\n trajectoryAccumulatedGrowthPx = 0\n trajectoryAccumulatedGrowthMs = 0\n trajectoryGrowthSamples = 0\n trajectoryWasActive = true\n }\n updateRevealScale(nextPort, elapsedMs)\n reportFollow(nextPort, activeRef.current)\n const runwayOffset = runwayOffsetOf(nextPort)\n const entranceLag = Math.max(0, nextPort.scrollHeight - animatedH - runwayOffset)\n if (entranceLag <= FOLLOW_SETTLE_EPSILON_PX) finishEntrance()\n } else {\n finishEntrance()\n }\n } else {\n finishEntrance()\n }\n primed = true\n return\n }\n\n const repinSlack = readerReleased ? FOLLOW_REPIN_PX : FOLLOW_SLACK_PX\n const returnedToFloor = readerReleased\n && !readerGestureIntent\n && reportedLag <= FOLLOW_REPIN_PX\n if (!following && (!interacting || returnedToFloor) && reportedLag <= repinSlack) {\n following = true\n readerReleased = false\n followReaderHolds.delete(nextPort)\n animatedH = extent\n reservePx = 0\n velocityPxPerSec = 0\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n hold(nextPort)\n } else if (following && interacting && (readerGestureIntent || readerScrolledUp(nextPort))) {\n // Directional wheel/touch intent is authoritative even when automatic\n // follow has already overwritten the small physical scroll delta.\n following = false\n readerGestureIntent = false\n readerReleased = true\n followReaderHolds.set(nextPort, { atMs: performance.now() })\n handBackVisual(nextPort)\n animatedH = nextPort.scrollHeight\n reservePx = 0\n velocityPxPerSec = 0\n drop(nextPort)\n finishEntrance()\n }\n\n if (!activeRef.current || !following) {\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n reportFollow(nextPort, activeRef.current)\n return\n }\n detectHostScroll(nextPort, floor)\n if (hostOwnsScroll) {\n followScrollLedgers.set(nextPort, nextPort.scrollTop)\n reportFollow(nextPort, false)\n return\n }\n hold(nextPort)\n if (!isLeader(nextPort)) {\n finishEntrance()\n return\n }\n // Runway and an equal transform cancel visually. It is the zero point,\n // not residual motion: decaying below it would scroll past the final\n // resting position and rebound when runway is removed.\n //\n // The reservation scales with reveal pressure — idle holds nothing,\n // because speculative space at rest is a visible defect on handback —\n // but the runway MARGIN tracks the reservation 1:1 in the same frame,\n // so their difference (the only part that can move pixels) stays\n // constant. Growing the reservation without the margin would glide the\n // whole column; growing both together is invisible.\n const predictGrowth = predictiveRef?.current ?? predictive\n const statusElement = turnStatusOf(nextPort)\n const hasStatus = statusElement !== null\n if (statusElement !== null) lastStatusHeightPx = statusElement.offsetHeight\n const statusJustRemoved = predictGrowth && statusWasPresent === true && !hasStatus\n if (statusJustRemoved) {\n // The dying status row takes its own layout height AND the margin\n // riding on it out of the scroll extent in one commit. Re-open the\n // margin on the next surface in the same frame, sized to cover both,\n // or the floor sinks by that height and the transcript slides down\n // under the pin before the replacement margin can land.\n reservePx = Math.max(reservePx, tuning.runwayPx) + lastStatusHeightPx\n }\n statusWasPresent = hasStatus\n const reserveEnabled = hasStatus\n || statusJustRemoved\n || reservePx > FOLLOW_SETTLE_EPSILON_PX\n || speedCpsRef.current > FOLLOW_RESERVE_MIN_CPS\n const pressureReserveTarget = predictGrowth && reserveEnabled\n ? computeFollowReserve(speedCpsRef.current, tuning.runwayPx)\n : 0\n // ZERO-DOWNWARD-REBOUND (root cause): while this follower owns the port\n // it pins scrollTop to the floor, and the floor rides the owned bottom\n // margin 1:1. Shrinking that margin under the pin clamps scrollTop\n // downward and slides the whole transcript down — the one motion this\n // module must never paint; no shift remains to release it because the\n // reservation already covers the margin (base = margin − reservation\n // stays flat). An owned margin therefore only GROWS here: prediction\n // shutdown and reveal-pressure drops freeze it at its current size, and\n // retirement is deferred to reader handback (a user-driven scroll) or\n // the next ownership. Growth stays invisible because the reservation\n // grows in the same frame and the baseline difference never moves.\n const effectiveReserveTarget = Math.max(reservePx, pressureReserveTarget)\n const reserveStep = 1 - Math.exp(-elapsedMs / tuning.reserveResponseMs)\n reservePx += (effectiveReserveTarget - reservePx) * reserveStep\n if (predictGrowth || runwayOffsetOf(nextPort) > 0.5) {\n ensureRunway(nextPort, shiftSurfacesOf(nextPort), reservePx)\n }\n const runwayOffset = runwayOffsetOf(nextPort)\n const contentHeight = nextPort.scrollHeight\n const floorNow = Math.max(0, contentHeight - nextPort.clientHeight)\n const trajectoryActive = predictive\n && root.querySelector('[data-variant=\"think\"]') === null\n && runwayOffset > 0\n let trajectoryShift: number | undefined\n if (trajectoryActive) {\n const requestedMinLagPx = Math.max(\n FOLLOW_TRAJECTORY_MIN_LAG_PX,\n runwayOffset - FOLLOW_TRAJECTORY_PHASE_PX,\n )\n // Phase-band upper bound comes from paint space, not a runway-derived\n // constant: `minLag + 39` can exceed the real gap to status/composer\n // chrome and get clipped into a hard catch-up exactly at the wrap\n // cadence the band exists to absorb (see docs §3.1).\n const paintLimit = safeShiftLimit(nextPort, shiftSurfacesOf(nextPort))\n const maxLagPx = Math.max(0, paintLimit - FOLLOW_PAINT_GUARD_PX)\n const minLagPx = Math.min(requestedMinLagPx, maxLagPx)\n if (trajectoryPositionPx === null || trajectoryFloorPx === null) {\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n trajectoryPositionPx = floorNow - Math.min(maxLagPx, Math.max(minLagPx, currentShift))\n trajectoryTargetVelocityPxPerMs = Math.max(0, speedCpsRef.current) * 0.4 / 1000\n trajectoryVelocityPxPerMs = trajectoryTargetVelocityPxPerMs\n trajectoryGrowthAtMs = now\n } else if (floorNow > trajectoryFloorPx + 0.5) {\n const intervalMs = Math.max(1, now - (trajectoryGrowthAtMs ?? now))\n if (trajectoryGrowthSamples > 0) {\n trajectoryAccumulatedGrowthPx += floorNow - trajectoryFloorPx\n trajectoryAccumulatedGrowthMs += intervalMs\n const measuredVelocity = trajectoryAccumulatedGrowthPx\n / trajectoryAccumulatedGrowthMs\n // A single wrap interval is quantized by layout and may also span a\n // dropped frame. Do not replace the trajectory target with that\n // staircase sample: low-pass it over a few wraps so the visual\n // velocity remains continuous when the host is busy or a retry row\n // changes the layout.\n const targetBlend = 1 - Math.exp(-intervalMs / 240)\n trajectoryTargetVelocityPxPerMs += (\n measuredVelocity - trajectoryTargetVelocityPxPerMs\n ) * targetBlend\n }\n trajectoryGrowthSamples += 1\n trajectoryGrowthAtMs = now\n } else if (floorNow < trajectoryFloorPx - 0.5) {\n trajectoryPositionPx = floorNow - minLagPx\n trajectoryGrowthAtMs = now\n trajectoryAccumulatedGrowthPx = 0\n trajectoryAccumulatedGrowthMs = 0\n trajectoryGrowthSamples = 0\n }\n trajectoryFloorPx = floorNow\n const phaseTarget = revealedCharsRef === undefined\n ? floorNow\n : revealPhase.advance(floorNow, revealedCharsRef.current).targetPx\n const trajectoryStep = computeFollowTrajectoryStep(elapsedMs, {\n positionPx: trajectoryPositionPx,\n velocityPxPerMs: trajectoryVelocityPxPerMs,\n targetPx: phaseTarget,\n targetVelocityPxPerMs: trajectoryTargetVelocityPxPerMs,\n minLagPx,\n maxLagPx,\n paintFloorPx: floorNow,\n })\n trajectoryPositionPx = trajectoryStep.positionPx\n trajectoryVelocityPxPerMs = trajectoryStep.velocityPxPerMs\n trajectoryShift = trajectoryStep.shiftPx\n trajectoryWasActive = true\n const baselineShift = runwayOffset - Math.min(runwayOffset, Math.max(0, reservePx))\n animatedH = contentHeight - runwayOffset - Math.max(0, trajectoryShift - baselineShift)\n velocityPxPerSec = trajectoryVelocityPxPerMs * 1000\n } else {\n if (trajectoryWasActive) {\n const currentShift = currentShiftOf(shiftSurfacesOf(nextPort).at(-1) ?? nextPort)\n animatedH = contentHeight - runwayOffset - Math.max(0, currentShift)\n velocityPxPerSec = trajectoryVelocityPxPerMs * 1000\n trajectoryPositionPx = null\n trajectoryWasActive = false\n }\n const lag = Math.max(0, contentHeight - animatedH - runwayOffset)\n const step = computeFollowStep(dt, {\n lag,\n speedEma: speedCpsRef.current,\n velocityPxPerSec,\n }, tuning)\n if (lag <= 0.1) {\n animatedH = contentHeight - runwayOffset\n velocityPxPerSec = 0\n } else {\n // ZERO-DOWNWARD-REBOUND: the reservation is NOT real lag. With the\n // steady-state tail pin it already rides as baseline-canceled gap\n // (shift = margin − reservation + reveal lag), so forcing the spring\n // to stop `reservePx` short of the natural floor — the pre-tail-pin\n // \"hold the reserve as lag\" semantic — would double-count it and\n // repaint the difference as an instant downward step the moment\n // prediction shuts off. The spring always drains to the natural\n // floor; the painted shift decays through the rate-limited release.\n animatedH = Math.min(\n contentHeight - runwayOffset,\n animatedH + step.advancePx,\n )\n velocityPxPerSec = step.velocityPxPerSec\n }\n }\n animatedH = applyVisual(\n nextPort,\n animatedH,\n reservePx,\n velocityPxPerSec,\n tuning.runwayPx,\n Number.POSITIVE_INFINITY,\n !predictGrowth,\n trajectoryShift,\n elapsedMs,\n !hostOwnsScroll,\n )\n if (trajectoryActive) {\n const currentShift = followLastShiftPx.get(nextPort) ?? (trajectoryShift ?? 0)\n trajectoryPositionPx = floorNow - currentShift\n }\n updateRevealScale(nextPort, elapsedMs)\n reportFollow(nextPort, true)\n // Keep the previous painted tail as the completion handoff baseline.\n // The active loop is the only place that sees the old surface before a\n // host live->settled replacement disconnects it.\n // Per-frame anchor hold — completion window only. During live\n // streaming the lockstep in this very frame's applyVisual already\n // cancels wraps; a guard running here fights it (its pad/raise writes\n // shift the next frame's lag bookkeeping) and visibly degrades the\n // reveal. The completion cascade is different: the settled-side arm\n // that primes IN the swap frame has active=false from mount, so ITS\n // first poll runs before paint and compensates the swap jump that the\n // older arms' observers were too late (or too unprivileged) to fix.\n // Track the reading surface's rendered position so the completion\n // guard inherits the exact last-painted baseline (never a stale or\n // already-jumped one) when the stream hands off. Compensation is NOT\n // done from this poll (a guard beside the active loop's own lockstep\n // fights it and degrades the reveal), and a NON-leader arm must not\n // even refresh the baseline: its measurement would store the very\n // jump the owning guard is about to correct and neutralize its next\n // pass.\n if (isLeader(nextPort)) {\n if (!activeRef.current) enforceReadingAnchor(nextPort)\n else measureReadingAnchor(nextPort)\n }\n const remainingEntranceLag = Math.max(\n 0,\n nextPort.scrollHeight - animatedH - runwayOffsetOf(nextPort),\n )\n if (remainingEntranceLag <= FOLLOW_SETTLE_EPSILON_PX) finishEntrance()\n }\n\n // Prime ownership and the final committed height in this layout phase.\n // A producer-complete text arm can mount and drain before the next RAF;\n // deferring this first pass would let it unmount unprimed after replacing\n // the previous owner, leaving a large final append at the old scrollTop.\n frame(performance.now())\n return () => {\n if (!controlScrollRef.current) {\n cancelAnimationFrame(rafId)\n if (port !== null) followActivePorts.delete(port)\n unsubscribeCommit?.()\n resize?.disconnect()\n mutations?.disconnect()\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n }\n if (interactTimer !== null) clearTimeout(interactTimer)\n const disabledHost = rootRef.current?.closest<HTMLElement>('[data-conversation-scroll]') ?? port\n if (disabledHost !== null) {\n clearVisual(disabledHost)\n followLeaders.delete(disabledHost)\n debugRuntime.reportFollow(disabledHost, null)\n }\n releaseRevealScale()\n return\n }\n cancelAnimationFrame(rafId)\n if (port !== null) followActivePorts.delete(port)\n unsubscribeCommit?.()\n if (interactTimer !== null) clearTimeout(interactTimer)\n resize?.disconnect()\n mutations?.disconnect()\n if (port !== null) {\n for (const name of GESTURE_EVENTS) port.removeEventListener(name, markGesture)\n }\n const root = rootRef.current\n const host = root?.closest<HTMLElement>('[data-conversation-scroll]') ?? port\n if (host === null) return\n holding = null\n if (!isLeader(host)) return\n const preserveReader = interacting && (readerGestureIntent || readerScrolledUp(host))\n if (!following || !primed) {\n if (!following && primed) {\n // A follower that already released the reader must carry that fact\n // across this closure's death: the draining arm mounting after this\n // cleanup would otherwise read the held viewport as its own\n // at-bottom state and hard-snap it to the floor.\n followReaderHolds.set(host, { atMs: performance.now() })\n }\n clearVisual(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n if (preserveReader) {\n handBackVisual(host)\n followReaderHolds.set(host, { atMs: performance.now() })\n clearVisual(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n\n // Completion can land the final Tool/command height in this same\n // commit. Preserve the logical extent and drain it after unmount instead\n // of clearing the compositor state before the first settled paint.\n // NOTE: do NOT clamp animatedH down by the held reserve here — the\n // reserve is canceled space (base = margin − reservation stays flat),\n // so treating it as real lag paints a whole runway-height step at the\n // exact moment leadership hands to the draining arm. The settle loop\n // caps animatedH against the shrinking extent directly.\n // Settle state (declared before the handoff so the completion paths can\n // measure the extent against it):\n let settleQuietMs = 0\n let settleSig = ''\n if (!activeRef.current) {\n followTraceUntilMs = Math.max(followTraceUntilMs, performance.now() + 10000)\n followTrace('fast-gate', { sh: host.scrollHeight, st: Math.round(host.scrollTop), pad: Math.round(flowPadOf(host)) })\n restoreRunway(host)\n setFlowPad(host, 0)\n finishAtNaturalFloor(host, !startedAsEntrance, true)\n followLeaders.delete(host)\n followCompletionSettle.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n const completionShift = currentShiftOf(shiftSurfacesOf(host).at(-1) ?? host)\n // Freeze, never raise, in this same-task paint — same race as the\n // observer above; the settle's first rAF frame funds the re-open.\n // Entrance handoffs are mount transients with no collapse in flight:\n // their first cover must paint immediately (the soften contract).\n const completionShiftCeiling = startedAsEntrance && completionShift <= FOLLOW_SETTLE_EPSILON_PX\n ? Number.POSITIVE_INFINITY\n : completionShift\n if (hostOwnsScroll) {\n clearVisual(host)\n setFollowScrollTop(host, Math.max(0, host.scrollHeight - host.clientHeight))\n host.removeAttribute(FOLLOW_OWNED_ATTR)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n // The completion commit often REPLACES the last surface (live→settled\n // swap re-keys the row), and the owned margin written on the old element\n // dies with it in the same layout pass. Do NOT bank that loss as a flow\n // pad: the next ensureRunway opens the completion runway in this same\n // pre-paint task. Converting the dead margin to pad creates a second\n // owned extent that must later retire as the visible \"slow rebound\".\n followTraceUntilMs = performance.now() + 15000\n if (pruneDeadRunway(host)) {\n followTrace('cleanup-dead-margin', { sh: host.scrollHeight, st: Math.round(host.scrollTop), pad: Math.round(flowPadOf(host)) })\n reservePx = 0\n }\n // The completion handoff keeps at least one real runway open so the\n // final height has reserved paint room to drain through: with zero\n // margin the whole final height lands as shift in ONE paint (offset\n // space collapses to the paint limit), the exact teleport this drain\n // exists to prevent. The draining arm ramps its reserve from here.\n const completionTuning = debugRuntime.activeTuning()\n const previousCompletionRunway = runwayOffsetOf(host)\n // The completion pad already holds retired extent below the fold; the\n // handoff only opens the runway room the pad does not cover, or the\n // same pixels are added twice and the restored floor overshoots.\n ensureRunway(\n host,\n shiftSurfacesOf(host),\n Math.max(reservePx, Math.max(0, completionTuning.runwayPx - flowPadOf(host))),\n )\n const completionRunway = runwayOffsetOf(host)\n // The reading anchor's baseline is already live (the active loop\n // refreshed it every frame, and the guard observers keep it current);\n // only seed it here when this port somehow has none, so the first\n // completion commit has a real screen-space baseline to compare\n // against instead of silently adopting the jumped position.\n measureReadingAnchor(host)\n // Rebase the spring extent onto the new offset domain before the paint:\n // adding the margin drops targetHeight by the same amount, so animatedH\n // must drop in lockstep or the margin's px release as an instant shift.\n animatedH = Math.max(0, animatedH - (completionRunway - previousCompletionRunway))\n if (!hostOwnsScroll) settleAtFloor(host)\n animatedH = applyVisual(\n host,\n animatedH,\n reservePx,\n velocityPxPerSec,\n completionRunway,\n completionShiftCeiling,\n false,\n undefined,\n 0,\n !hostOwnsScroll,\n )\n reportFollow(host, false)\n const runwayOffset = runwayOffsetOf(host)\n const remainingLag = Math.max(0, host.scrollHeight - animatedH - runwayOffset)\n if (\n remainingLag <= FOLLOW_SETTLE_EPSILON_PX\n && runwayOffset <= FOLLOW_SETTLE_EPSILON_PX\n && reservePx <= FOLLOW_SETTLE_EPSILON_PX\n ) {\n finishAtNaturalFloor(host, !startedAsEntrance, !hostOwnsScroll)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n return\n }\n\n for (const name of GESTURE_EVENTS) {\n host.addEventListener(name, markGesture, { passive: true })\n }\n const stopSettleListeners = (): void => {\n for (const name of GESTURE_EVENTS) host.removeEventListener(name, markGesture)\n resize?.disconnect()\n mutations?.disconnect()\n if (interactTimer !== null) {\n clearTimeout(interactTimer)\n interactTimer = null\n }\n }\n // Re-arm pre-paint observation for the whole completion cascade. The\n // active effect's observers were disconnected above, but status/tail\n // commits continue while the detached settle loop owns the port.\n if (typeof ResizeObserver !== 'undefined') {\n resize = new ResizeObserver(() => restoreBeforePaint())\n resize.observe(host)\n const proxy = resizeProxyOf(host)\n if (proxy !== null) resize.observe(proxy)\n }\n if (typeof MutationObserver !== 'undefined') {\n const flow = flowElementOf(host)\n if (flow !== null) {\n mutations = new MutationObserver(() => { restoreBeforePaint() })\n mutations.observe(flow, { childList: true, subtree: true })\n }\n }\n // From here this closure's observers are the completion guard of last\n // resort (see `handedOff` above), and this settle OWNS the port until\n // it finishes.\n followCompletionSettle.add(host)\n followCompletionSettleRows.set(host, countUserRows(host))\n handedOff = true\n let settleLast = performance.now()\n // Settle-pad transfer state lives above the completion handoff; the\n // loop below only drives it frame by frame. `settleRetiring` marks the\n // final glide: the cascade has quieted, so the pad that kept every host\n // commit pixel-stable is handed back to the layout at the bounded\n // settle rate and the pinned viewport glides down to the natural\n // resting position against the composer.\n const settleFrame = (now: number): void => {\n if (!isLeader(host)) {\n stopSettleListeners()\n return\n }\n if (interacting && (readerGestureIntent || readerScrolledUp(host))) {\n readerGestureIntent = false\n handBackVisual(host)\n clearVisual(host)\n followCompletionSettle.delete(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n const dt = Math.min(FOLLOW_MAX_FRAME_MS, Math.max(0, now - settleLast))\n const tuning = debugRuntime.activeTuning()\n settleLast = now\n detectHostScroll(host, Math.max(0, host.scrollHeight - host.clientHeight))\n if (hostOwnsScroll) {\n clearVisual(host)\n setFollowScrollTop(host, Math.max(0, host.scrollHeight - host.clientHeight))\n host.removeAttribute(FOLLOW_OWNED_ATTR)\n followCompletionSettle.delete(host)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n // HOST COMPLETION CASCADE: around completion the host swaps the status\n // row for its process/tail rows, auto-collapses the think disclosure\n // and mounts the metrics tail — each a same-frame layout shrink under\n // the pinned floor. Re-open every lost pixel below the last surface\n // (out of sight; extent, floor and pinned scrollTop restored) and hold\n // ownership until the cascade has been quiet for\n // FOLLOW_SETTLE_QUIET_MS, so the host's own floor-snap never paints a\n // host action as a single-frame slam of the whole transcript.\n // ANCHOR SCREEN HOLD: the completion cascade moves the reading\n // anchor's viewport position (status swap, live→settled replacement,\n // clamp jumps). The reading-surface baseline lives in the shared\n // followGuardAnchors ledger; the shift-excluded delta filters the\n // engine's own glide, so the per-frame poll only answers real host\n // motion. While the pad retires, extent motion is OUR OWN glide —\n // the hold stands down.\n const guardDelta = !settleRetiring && !followActivePorts.has(host)\n ? enforceReadingAnchor(host, true)\n : null\n settleQuietMs = !settleRetiring && (guardDelta === null || Math.abs(guardDelta) <= 0.5) ? settleQuietMs + dt : 0\n // ZERO-DOWNWARD-REBOUND (root cause): scrollTop is pinned to the floor\n // and the floor rides the owned margin 1:1, so the settle must NOT\n // shrink the margin — that clamps scrollTop downward with no shift\n // left to release (the reservation covers the margin, so base = margin\n // − reservation never moves). Instead the margin MOVES below the\n // status row: marginTop −δ and marginBottom +δ in the same layout\n // pass keep the scroll extent constant, so the floor, the pinned\n // scrollTop and every content pixel stay put while the status glides\n // up to close the reserve gap — the completion 归位, with zero\n // downward motion.\n const settleStatus = turnStatusOf(host)\n const ownedRunwayPx = runwayOffsetOf(host)\n if (ownedRunwayPx > FOLLOW_SETTLE_EPSILON_PX) {\n const requestedTransferPx = settleStatus === null\n ? ownedRunwayPx\n : Math.min(\n reservePx,\n ((tuning.runwayPx || FOLLOW_STATUS_RUNWAY_PX) / FOLLOW_RUNWAY_RETIRE_MS) * dt,\n )\n const transferredPx = transferRunwayToFlowPad(host, requestedTransferPx)\n // Do not bank a completion pad. The margin release and pad removal\n // happen in one layout pass, so there is no extra extent to retire\n // later and no second slow rebound after the cascade quiets.\n if (transferredPx > 0) setFlowPad(host, Math.max(0, flowPadOf(host) - transferredPx))\n reservePx = Math.max(0, reservePx - transferredPx)\n // targetHeight = scrollHeight - runway. The equal margin-to-pad\n // transfer keeps scrollHeight fixed and lowers runway by δ, so the\n // logical extent rises by exactly δ (not 2δ). Both this rebase and\n // applyVisual's offset-history rebase are required: dropping either\n // one stalls the spring or leaks residual motion into the quiet\n // window (audit burst-gap/ramp quiescence-move).\n animatedH += transferredPx\n }\n const runwayOffset = runwayOffsetOf(host)\n const lag = Math.max(0, host.scrollHeight - animatedH - runwayOffset)\n // PAD RETIREMENT (the final glide of 收尾归位): cascade quiet, drain\n // closed — the pad that kept every host commit pixel-stable is handed\n // back to the layout at the bounded settle rate. The floor sinks with\n // it and the pinned viewport glides down to the natural resting\n // position against the composer; smooth and rate-limited, never the\n // single-frame slam the raw host snap paints.\n if (\n !settleRetiring\n && lag <= FOLLOW_SETTLE_EPSILON_PX\n && reservePx <= FOLLOW_SETTLE_EPSILON_PX\n && settleQuietMs >= FOLLOW_SETTLE_QUIET_MS\n && flowPadOf(host) > FOLLOW_SETTLE_EPSILON_PX\n ) {\n followTrace('retire-start', { pad: Math.round(flowPadOf(host)), sh: host.scrollHeight, st: Math.round(host.scrollTop) })\n settleRetiring = true\n }\n if (settleRetiring) {\n const padPx = flowPadOf(host)\n const retirePx = Math.min(\n padPx,\n ((tuning.runwayPx || FOLLOW_STATUS_RUNWAY_PX) / FOLLOW_RUNWAY_RETIRE_MS) * dt,\n )\n if (padPx - retirePx <= FOLLOW_SETTLE_EPSILON_PX) {\n setFlowPad(host, 0)\n settleRetiring = false\n } else {\n setFlowPad(host, padPx - retirePx)\n }\n }\n if (\n lag <= FOLLOW_SETTLE_EPSILON_PX\n && (reservePx <= FOLLOW_SETTLE_EPSILON_PX || settleStatus === null)\n && flowPadOf(host) <= FOLLOW_SETTLE_EPSILON_PX\n && settleQuietMs >= FOLLOW_SETTLE_QUIET_MS\n ) {\n followTrace('finish', { st: Math.round(host.scrollTop), sh: host.scrollHeight, pad: Math.round(flowPadOf(host)) })\n animatedH = host.scrollHeight\n velocityPxPerSec = 0\n finishAtNaturalFloor(host, !startedAsEntrance, !hostOwnsScroll)\n followLeaders.delete(host)\n releaseRevealScale()\n debugRuntime.reportFollow(host, null)\n stopSettleListeners()\n return\n }\n const step = computeFollowStep(dt, {\n lag,\n speedEma: speedCpsRef.current,\n velocityPxPerSec,\n }, tuning)\n animatedH = Math.min(\n host.scrollHeight - runwayOffset,\n animatedH + step.advancePx,\n )\n velocityPxPerSec = step.velocityPxPerSec\n if (!hostOwnsScroll) settleAtFloor(host)\n // Once the host has written, never write scrollTop again. The settle\n // still computes compositor shifts and rebases the spring; the host\n // owns the scrollport. A completion commit that GROWS the extent\n // changes the host floor; the host snaps while applyVisual answers\n // with the matching shift raise — the same lockstep the active loop\n // paints for a wrap.\n animatedH = applyVisual(\n host,\n animatedH,\n reservePx,\n velocityPxPerSec,\n runwayOffset,\n Number.POSITIVE_INFINITY,\n false,\n undefined,\n 0,\n !hostOwnsScroll,\n )\n if (traceActive()) {\n const sig = `${Math.round(host.scrollTop)}|${host.scrollHeight}|${Math.round(flowPadOf(host))}|${Math.round(reservePx)}|${settleRetiring}`\n if (sig !== settleSig) {\n followTrace('settle', { st: Math.round(host.scrollTop), sh: host.scrollHeight, pad: Math.round(flowPadOf(host)), reserve: Math.round(reservePx), lag: Math.round(lag * 10) / 10, retiring: settleRetiring })\n settleSig = sig\n }\n }\n reportFollow(host, false)\n requestAnimationFrame(settleFrame)\n }\n requestAnimationFrame(settleFrame)\n }\n }, [active, rootRef, speedCpsRef, revealScaleRef, predictive, predictiveRef, controlScroll])\n\n useLayoutEffect(() => {\n const host = rootRef.current?.closest<HTMLElement>('[data-conversation-scroll]') ?? null\n if (host !== null) {\n followFlowFillUsers.set(host, (followFlowFillUsers.get(host) ?? 0) + 1)\n }\n return () => {\n if (host === null) return\n const remaining = Math.max(0, (followFlowFillUsers.get(host) ?? 1) - 1)\n if (remaining > 0) {\n followFlowFillUsers.set(host, remaining)\n return\n }\n followFlowFillUsers.delete(host)\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (!followLeaders.has(host) && !followFlowFillUsers.has(host)) restoreFlowFill(host)\n })\n })\n }\n }, [rootRef])\n}\n","/**\n * Stream-smoothing reveal hook.\n *\n * Buffers the model's chunked text and reveals it at a cadence that tracks\n * the observed arrival rate, so a long reply never dumps whole paragraphs at\n * once and a fast stream never stutters. Port of lobe-ui's smoother: EMA\n * arrival cps + chunk size, backlog pressure, commit-interval widening with\n * tail length, and a flush-speed settle drain once the input idles. The\n * reveal decision is the pure {@link computeRevealStep} for unit tests.\n *\n * `shouldHoldBack` is the performance guard's veto: while it returns true the\n * loop keeps measuring but skips the DOM commit, so an offscreen reply never\n * competes with visible frames when the frame rate is degraded.\n */\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { DEFAULT_STREAM_DEBUG_TUNING, type StreamDebugTuning } from '../settings.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\nexport type StreamSmoothingPreset = 'realtime' | 'balanced' | 'silky'\n\nexport interface StreamSmoothingPresetConfig {\n readonly activeInputWindowMs: number\n readonly defaultCps: number\n readonly emaAlpha: number\n readonly flushCps: number\n readonly largeAppendChars: number\n readonly maxActiveCps: number\n readonly maxCps: number\n readonly maxFlushCps: number\n readonly minCps: number\n readonly settleAfterMs: number\n readonly settleDrainMaxMs: number\n readonly settleDrainMinMs: number\n readonly targetBufferMs: number\n}\n\nexport const PRESET_CONFIG: Record<StreamSmoothingPreset, StreamSmoothingPresetConfig> = {\n balanced: {\n activeInputWindowMs: 220,\n defaultCps: 80,\n emaAlpha: 0.35,\n flushCps: 180,\n largeAppendChars: 120,\n maxActiveCps: 360,\n maxCps: 240,\n maxFlushCps: 480,\n minCps: 24,\n settleAfterMs: 280,\n settleDrainMaxMs: 420,\n settleDrainMinMs: 120,\n targetBufferMs: 40,\n },\n realtime: {\n activeInputWindowMs: 140,\n defaultCps: 120,\n emaAlpha: 0.45,\n flushCps: 240,\n largeAppendChars: 180,\n maxActiveCps: 480,\n maxCps: 320,\n maxFlushCps: 640,\n minCps: 32,\n settleAfterMs: 200,\n settleDrainMaxMs: 280,\n settleDrainMinMs: 100,\n targetBufferMs: 24,\n },\n silky: {\n activeInputWindowMs: 280,\n defaultCps: 64,\n emaAlpha: 0.28,\n flushCps: 140,\n largeAppendChars: 100,\n maxActiveCps: 280,\n maxCps: 180,\n maxFlushCps: 400,\n minCps: 20,\n settleAfterMs: 360,\n settleDrainMaxMs: 520,\n settleDrainMinMs: 160,\n targetBufferMs: 56,\n },\n}\n\n/** Pressure curve from the reference stream renderer. */\nexport const QUEUE_BASE_SPEED_CPS = 90\nexport const QUEUE_ACCEL_EXPONENT = 1.25\nexport const QUEUE_PRESSURE_FACTOR = 0.85\nexport const QUEUE_MAX_SPEED_CPS = 600\n/** Hard cap on how far display may trail a live stream, in characters. */\nexport const LIVE_LAG_CHAR_CEILING = 32\nconst CATCHUP_SECONDS = 0.15\n\nexport const clamp = (value: number, min: number, max: number): number => {\n return Math.min(max, Math.max(min, value))\n}\n\n/**\n * Reference pressure-buffer reveal for a frame that starts without debt.\n * @param backlog - Unrevealed characters.\n * @param dtMs - Frame delta in ms.\n * @returns Characters to reveal this frame.\n */\nexport function computeQueueReveal(backlog: number, dtMs: number): number {\n if (backlog <= 0 || dtMs <= 0) return 0\n return computeAdaptiveQueueStep(backlog, dtMs, 0).revealChars\n}\n\nexport interface AdaptiveQueueStep {\n readonly revealChars: number\n readonly debt: number\n readonly speedCps: number\n}\n\n/** Float-debt queue integration from `ultimate_stream_physics_scroller.html`. */\nexport function computeAdaptiveQueueStep(\n backlog: number,\n dtMs: number,\n debt: number,\n revealScale = 1,\n tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,\n): AdaptiveQueueStep {\n if (backlog <= 0 || dtMs <= 0) return { revealChars: 0, debt: 0, speedCps: 0 }\n const speedCps = Math.min(\n tuning.maxRevealCps,\n QUEUE_BASE_SPEED_CPS + Math.pow(backlog, QUEUE_ACCEL_EXPONENT) * tuning.queuePressure,\n )\n const effectiveScale = clamp(revealScale * tuning.revealScale, 0.05, 2)\n const accumulated = Math.max(0, debt) + speedCps * effectiveScale * (dtMs / 1000)\n const revealChars = Math.min(backlog, Math.floor(accumulated))\n return { revealChars, debt: revealChars >= backlog ? 0 : accumulated - revealChars, speedCps }\n}\n\n/** Counts user-perceived characters (code points), not UTF-16 units. */\nexport const countChars = (text: string): number => {\n let count = 0\n for (const char of text) {\n void char\n count += 1\n }\n return count\n}\n\n/**\n * Drain rate for backlog beyond the tail-lag ceiling: the displayed text may\n * trail the stream by at most `backlogCharCeiling` characters for at most\n * `backlogSecondCeiling` seconds. The constants are a smoothness invariant\n * (bounded lag is the reason the reveal never stalls mid-reply), so they are\n * not config fields; the preset multiplier is how a deployment tunes them.\n */\nexport const BACKLOG_CHAR_CEILING = 300\nexport const BACKLOG_SECOND_CEILING = 2\n\nexport interface SettleDrainInput {\n readonly backlog: number\n readonly inputActive: boolean\n readonly settling: boolean\n}\n\n/** Pure settle-drain decision shared by the frame loop and its tests. */\nexport function computeSettleDrain(config: StreamSmoothingPresetConfig, input: SettleDrainInput): number {\n if (input.inputActive || !input.settling) return 0\n // A settled stream must drain fast enough to finish the reply promptly:\n // lag beyond the ceiling drains within the second ceiling.\n const overflow = Math.max(0, input.backlog - BACKLOG_CHAR_CEILING)\n const overflowCps = (overflow * 1000) / BACKLOG_SECOND_CEILING\n const drainTargetMs = clamp(input.backlog * 8, config.settleDrainMinMs, config.settleDrainMaxMs)\n const settleCps = (input.backlog * 1000) / drainTargetMs\n return clamp(Math.max(settleCps, overflowCps), config.flushCps, config.maxFlushCps)\n}\n\n/**\n * Fixed velocity that closes a producer-complete queue within its deadline.\n * This completion-only target may exceed the live-stream flush ceiling.\n */\nexport function computeCompletionDrain(\n config: StreamSmoothingPresetConfig,\n backlog: number,\n initialCps = 0,\n): number {\n if (backlog <= 0) return 0\n const drainTargetMs = clamp(backlog * 8, config.settleDrainMinMs, config.settleDrainMaxMs)\n const deadlineSeconds = drainTargetMs / 1000\n const rampAreaSeconds = SETTLE_RAMP_TAU_S * (1 - Math.exp(\n -deadlineSeconds / SETTLE_RAMP_TAU_S,\n ))\n const deadlineCps = (\n backlog - Math.max(0, initialCps) * rampAreaSeconds\n ) / Math.max(0.001, deadlineSeconds - rampAreaSeconds)\n return Math.max(\n deadlineCps,\n computeSettleDrain(config, { backlog, inputActive: false, settling: true }),\n )\n}\n\n/**\n * Drain rate multiplier once the input ends: leftover backlog reveals at\n * this multiple of the steady rate, so the end never drags.\n */\nexport const SETTLE_DRAIN_MULTIPLIER = 1.8\n/** Time constant for ramping the completion-drain velocity up from streaming pace. */\nexport const SETTLE_RAMP_TAU_S = 0.09\n\nexport interface RevealStepInput {\n readonly backlog: number\n readonly chunkSizeEma: number\n readonly arrivalCpsEma: number\n readonly emaCps: number\n readonly inputActive: boolean\n readonly settling: boolean\n /** Fixed reveal rate; overrides the arrival-tracking cadence entirely. */\n readonly steadyCps?: number | undefined\n}\n\nexport interface RevealStepResult {\n readonly revealChars: number\n readonly targetLagChars: number\n}\n\n/** Pure per-frame reveal decision shared by the loop and its tests. */\nexport function computeRevealStep(config: StreamSmoothingPresetConfig, input: RevealStepInput, dtSeconds: number): RevealStepResult {\n // Track the faster of the two EMAs and do not clamp to the old low maxCps\n // ceiling — that cap is why a fast model left hundreds of chars unrevealed.\n const trackedCps = Math.max(input.emaCps, input.arrivalCpsEma)\n const baseCps = clamp(trackedCps, config.minCps, config.maxFlushCps)\n const targetLagChars = input.inputActive\n ? Math.max(2, Math.round((baseCps * config.targetBufferMs) / 1000))\n : 0\n\n let currentCps: number\n if (input.steadyCps !== undefined) {\n currentCps = input.inputActive || input.settling\n ? clamp(\n input.steadyCps * (input.inputActive ? 1 : SETTLE_DRAIN_MULTIPLIER),\n config.minCps,\n config.maxFlushCps,\n )\n : 0\n } else if (input.inputActive) {\n const overflow = Math.max(0, input.backlog - LIVE_LAG_CHAR_CEILING)\n const catchup = overflow > 0 ? overflow / CATCHUP_SECONDS : 0\n currentCps = clamp(baseCps * 1.08 + catchup, config.minCps, config.maxFlushCps)\n } else if (input.settling) {\n currentCps = computeSettleDrain(config, input)\n } else {\n const idleFlushCps = Math.max(config.flushCps, baseCps * 1.8, input.arrivalCpsEma * 0.8)\n currentCps = clamp(idleFlushCps, config.flushCps, config.maxFlushCps)\n }\n\n const minRevealChars = input.inputActive ? 1 : 2\n return { revealChars: Math.max(minRevealChars, Math.round(currentCps * dtSeconds)), targetLagChars }\n}\n\nexport interface UseSmoothStreamContentOptions {\n enabled?: boolean\n /** The producer has completed; drain queued text without live backpressure. */\n inputComplete?: boolean\n preset?: StreamSmoothingPreset\n /** Performance guard veto: while true, reveal commits are held back. */\n shouldHoldBack?: (() => boolean) | undefined\n /**\n * Fixed reveal rate in chars/s. When set, the reveal runs at this steady\n * pace while the input streams (instead of tracking the arrival rate) and\n * drains an inferred idle backlog at {@link SETTLE_DRAIN_MULTIPLIER}.\n * Explicit producer completion still uses the bounded completion drain.\n */\n steadyCps?: number | undefined\n /**\n * Seed for the arrival-rate EMA. When omitted, the preset's `defaultCps`\n * is used. The live rate then tracks observed arrival; this is not a cap.\n */\n defaultCps?: number | undefined\n /** Written each commit with the live arrival-rate EMA for the follow lerp. */\n speedCpsRef?: { current: number } | undefined\n /** Cumulative code points that have actually committed to the display. */\n revealedCharsRef?: { current: number } | undefined\n /**\n * Called synchronously after each reveal commit lands in the DOM, so the\n * conversation follower can re-run its geometry inside the same task and\n * no intermediate (grown-but-uncompensated) frame can reach a paint.\n */\n onRevealCommit?: (() => void) | undefined\n /** Live multiplier from the follow spring when safe visual lag is filling. */\n revealScaleRef?: { current: number } | undefined\n}\n\n/**\n * Smooth a chunked content stream into a reveal-paced display string.\n *\n * @param content - The full accumulated input so far.\n * @param options - Preset, guard, and steady-rate wiring.\n * @returns The displayed content, revealed at the smoothed cadence.\n */\nexport function useSmoothStreamContent(\n content: string,\n {\n enabled = true,\n inputComplete = false,\n preset = 'balanced',\n shouldHoldBack,\n steadyCps,\n defaultCps,\n speedCpsRef,\n revealedCharsRef,\n revealScaleRef,\n onRevealCommit,\n }: UseSmoothStreamContentOptions = {},\n): string {\n const config = PRESET_CONFIG[preset]\n const seedCps = defaultCps ?? config.defaultCps\n // A fast provider can fill the first Host render with a large batch. Start\n // an enabled stream behind that batch so it still enters the reveal queue;\n // disabled (settled/history) content must remain immediate.\n const initialContent = enabled ? '' : content\n const [displayedContent, setDisplayedContent] = useState(initialContent)\n\n const displayedContentRef = useRef(initialContent)\n const displayedCountRef = useRef(countChars(initialContent))\n const targetContentRef = useRef(initialContent)\n const targetCharsRef = useRef([...initialContent])\n const targetCountRef = useRef(countChars(initialContent))\n\n const emaCpsRef = useRef(seedCps)\n const lastInputTsRef = useRef(0)\n const lastInputCountRef = useRef(countChars(initialContent))\n const chunkSizeEmaRef = useRef(1)\n const arrivalCpsEmaRef = useRef(seedCps)\n\n const rafRef = useRef<number | null>(null)\n const lastFrameTsRef = useRef<number | null>(null)\n const queueDebtRef = useRef(0)\n const settleCpsRef = useRef<number | null>(null)\n const lastDrainCpsRef = useRef(0)\n const holdBackRef = useRef(shouldHoldBack)\n const speedOutRef = useRef(speedCpsRef)\n speedOutRef.current = speedCpsRef\n const revealedCharsOutRef = useRef(revealedCharsRef)\n revealedCharsOutRef.current = revealedCharsRef\n const revealScaleOutRef = useRef(revealScaleRef)\n revealScaleOutRef.current = revealScaleRef\n const onRevealCommitOutRef = useRef(onRevealCommit)\n onRevealCommitOutRef.current = onRevealCommit\n const inputCompleteRef = useRef(inputComplete)\n inputCompleteRef.current = inputComplete\n const streamIdRef = useRef(`stream-${Math.random().toString(36).slice(2)}`)\n\n useEffect(() => {\n holdBackRef.current = shouldHoldBack\n }, [shouldHoldBack])\n\n const stopFrameLoop = useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n lastFrameTsRef.current = null\n }, [])\n\n const startFrameLoopRef = useRef<() => void>(() => {})\n\n const syncImmediate = useCallback(\n (nextContent: string) => {\n stopFrameLoop()\n const chars = [...nextContent]\n const now = performance.now()\n targetContentRef.current = nextContent\n targetCharsRef.current = chars\n targetCountRef.current = chars.length\n displayedContentRef.current = nextContent\n displayedCountRef.current = chars.length\n queueDebtRef.current = 0\n settleCpsRef.current = null\n lastDrainCpsRef.current = 0\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = seedCps\n setDisplayedContent(nextContent)\n emaCpsRef.current = seedCps\n chunkSizeEmaRef.current = 1\n arrivalCpsEmaRef.current = seedCps\n lastInputTsRef.current = now\n lastInputCountRef.current = chars.length\n },\n [seedCps, stopFrameLoop],\n )\n\n // Producer completion used to publish the accumulated source in one commit\n // here. That single commit is a visible teleport whenever a fast stream\n // ends with standing backlog — hundreds of chars become thousands of px in\n // one frame, exactly the end-of-render jerk this plugin fights. The frame\n // loop's producer-complete branch already drains the queue at a bounded\n // constant velocity (computeCompletionDrain), which finishes near its\n // configured deadline and glides every px through the spring. Nothing is left\n // \"typing\" after the Agent stops; the tail just closes at drain speed.\n //\n // Non-append-only edits and disabled streams still sync immediately below.\n\n const startFrameLoop = useCallback(() => {\n if (rafRef.current !== null) return\n\n const tick = (now: number) => {\n const targetCount = targetCountRef.current\n const displayedCount = displayedCountRef.current\n const backlog = targetCount - displayedCount\n\n if (backlog <= 0) {\n queueDebtRef.current = 0\n settleCpsRef.current = null\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = seedCps\n debugRuntime.reportStream(streamIdRef.current, null)\n stopFrameLoop()\n return\n }\n\n if (lastFrameTsRef.current === null) {\n lastFrameTsRef.current = now\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n const frameIntervalMs = Math.max(0, now - lastFrameTsRef.current)\n const dtSeconds = Math.max(0.001, Math.min(frameIntervalMs / 1000, 0.12))\n lastFrameTsRef.current = now\n\n const idleMs = now - lastInputTsRef.current\n const producerComplete = inputCompleteRef.current\n const debugTuning = debugRuntime.activeTuning()\n const inputActive = !producerComplete && idleMs <= config.activeInputWindowMs\n const settling = producerComplete || (!inputActive && idleMs >= config.settleAfterMs)\n if (!producerComplete) settleCpsRef.current = null\n\n let revealChars: number\n let revealSpeedCps: number\n let nextQueueDebt = 0\n if (producerComplete) {\n // Backpressure protects live layout. Once input has ended, retaining\n // that scale only makes a completed response keep typing onscreen.\n // Keep one TARGET velocity for the whole completion tail — recomputing\n // it from the shrinking backlog creates an exponential slow tail —\n // but RAMP the effective velocity up from the last reveal speed over\n // ~3 frames: an instant jump from streaming pace to max flush is\n // itself a visible jerk at exactly the moment the reader is watching\n // the reply finish.\n // The pre-drain reveal speed is the streaming EMA, not the debug seed.\n // Seeding the ramp from the 35cps default when the reply ran at the\n // max-flush ceiling stretched a 420ms tail past the 800ms announcer\n // step and the visible Markdown mutated across it.\n const previousCps = lastDrainCpsRef.current > 0\n ? lastDrainCpsRef.current\n : Math.max(config.minCps, emaCpsRef.current)\n const drainTargetCps = settleCpsRef.current\n ?? computeCompletionDrain(config, backlog, previousCps)\n settleCpsRef.current = drainTargetCps\n const rampedCps = previousCps\n + (drainTargetCps - previousCps) * (1 - Math.exp(-dtSeconds / SETTLE_RAMP_TAU_S))\n const settleCps = Math.min(drainTargetCps, Math.max(previousCps, rampedCps))\n lastDrainCpsRef.current = Math.min(drainTargetCps, rampedCps)\n const accumulated = Math.max(0, queueDebtRef.current) + settleCps * dtSeconds\n revealChars = Math.min(backlog, Math.floor(accumulated))\n revealSpeedCps = settleCps\n nextQueueDebt = revealChars >= backlog ? 0 : accumulated - revealChars\n if (revealChars >= backlog) lastDrainCpsRef.current = 0\n } else if (steadyCps !== undefined) {\n const step = computeRevealStep(\n config,\n {\n backlog,\n chunkSizeEma: chunkSizeEmaRef.current,\n arrivalCpsEma: arrivalCpsEmaRef.current,\n emaCps: emaCpsRef.current,\n inputActive,\n settling,\n steadyCps,\n },\n dtSeconds,\n )\n revealChars = Math.min(Math.round(step.revealChars * debugTuning.revealScale), backlog)\n revealSpeedCps = frameIntervalMs > 0 ? (revealChars * 1000) / frameIntervalMs : 0\n } else {\n const step = computeAdaptiveQueueStep(\n backlog,\n frameIntervalMs,\n queueDebtRef.current,\n revealScaleOutRef.current?.current ?? 1,\n debugTuning,\n )\n revealChars = step.revealChars\n revealSpeedCps = step.speedCps\n nextQueueDebt = step.debt\n }\n\n debugRuntime.reportStream(streamIdRef.current, {\n backlog,\n speedCps: revealSpeedCps,\n targetChars: targetCount,\n displayedChars: displayedCount,\n active: !producerComplete,\n })\n\n // Performance guard: while degraded and the reply is offscreen, skip\n // the DOM commit — the backlog keeps accumulating and flushes when the\n // guard clears or the reply scrolls into view.\n if (holdBackRef.current?.() === true) {\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n queueDebtRef.current = nextQueueDebt\n\n const speedOut = speedOutRef.current\n if (speedOut !== undefined) speedOut.current = revealSpeedCps\n\n if (revealChars <= 0) {\n rafRef.current = requestAnimationFrame(tick)\n return\n }\n\n const nextCount = displayedCount + revealChars\n const segment = targetCharsRef.current.slice(displayedCount, nextCount).join('')\n if (segment) {\n const nextDisplayed = displayedContentRef.current + segment\n displayedContentRef.current = nextDisplayed\n displayedCountRef.current = nextCount\n setDisplayedContent(nextDisplayed)\n } else {\n displayedContentRef.current = targetContentRef.current\n displayedCountRef.current = targetCount\n setDisplayedContent(targetContentRef.current)\n }\n\n rafRef.current = requestAnimationFrame(tick)\n }\n\n rafRef.current = requestAnimationFrame(tick)\n }, [config, seedCps, stopFrameLoop, steadyCps])\n\n // Run AFTER the commit's DOM mutations, before paint: the follower's\n // same-task correction hook.\n useLayoutEffect(() => {\n const revealedCharsOut = revealedCharsOutRef.current\n if (revealedCharsOut !== undefined) revealedCharsOut.current = displayedCountRef.current\n if (displayedContent === '') return\n onRevealCommitOutRef.current?.()\n }, [displayedContent])\n\n useEffect(() => {\n startFrameLoopRef.current = startFrameLoop\n }, [startFrameLoop])\n\n useEffect(() => {\n if (!enabled) {\n syncImmediate(content)\n return\n }\n\n const prevTargetContent = targetContentRef.current\n if (content === prevTargetContent) return\n\n const now = performance.now()\n const appendOnly = content.startsWith(prevTargetContent)\n\n if (!appendOnly) {\n syncImmediate(content)\n return\n }\n\n const appended = content.slice(prevTargetContent.length)\n const appendedChars = [...appended]\n const appendedCount = appendedChars.length\n\n targetContentRef.current = content\n targetCharsRef.current.push(...appendedChars)\n targetCountRef.current += appendedCount\n settleCpsRef.current = null\n\n const hadSample = lastInputTsRef.current > 0\n const deltaChars = targetCountRef.current - lastInputCountRef.current\n const deltaMs = Math.max(1, now - lastInputTsRef.current)\n\n // Skip the first sample: lastInputTs starts at 0, so the interval would\n // be \"time since page load\" (or 1ms under fake timers) and poison the EMA.\n if (hadSample && deltaChars > 0) {\n const instantCps = (deltaChars * 1000) / deltaMs\n const normalizedInstantCps = clamp(instantCps, config.minCps, config.maxFlushCps * 3)\n const chunkEmaAlpha = 0.45\n chunkSizeEmaRef.current = chunkSizeEmaRef.current * (1 - chunkEmaAlpha) + appendedCount * chunkEmaAlpha\n arrivalCpsEmaRef.current = arrivalCpsEmaRef.current * (1 - chunkEmaAlpha) + normalizedInstantCps * chunkEmaAlpha\n emaCpsRef.current = emaCpsRef.current * (1 - config.emaAlpha) + normalizedInstantCps * config.emaAlpha\n }\n\n lastInputTsRef.current = now\n lastInputCountRef.current = targetCountRef.current\n\n startFrameLoop()\n }, [content, enabled, config, startFrameLoop, syncImmediate])\n\n useEffect(() => {\n return () => {\n stopFrameLoop()\n debugRuntime.reportStream(streamIdRef.current, null)\n }\n }, [stopFrameLoop])\n\n return displayedContent\n}\n","/**\n * Performance guard for the streaming reveal.\n *\n * Feeds an EMA-smoothed frame-rate monitor from a rAF loop while streaming\n * and tracks whether the reply is on-screen. The returned `shouldHoldBack`\n * predicate is true only while the frame rate is below the threshold AND the\n * reply is offscreen — exactly the spec's \"skip offscreen DOM updates when\n * FPS < 30\" rule. The smoother consumes the predicate as its commit veto.\n */\n\nimport { useCallback, useEffect, useRef } from 'react'\nimport { debugRuntime } from './debugRuntime.ts'\n\nconst FPS_THRESHOLD = 30\nconst FPS_ALPHA = 0.12\nconst RECOVER_FRAMES = 6\nconst MAX_FRAME_MS = 100\n\ninterface MutableFps {\n emaMs: number\n lastMs: number\n healthyRun: number\n degraded: boolean\n}\n\nexport function useFpsGuard(active: boolean): {\n ref: (element: HTMLElement | null) => void\n shouldHoldBack: () => boolean\n} {\n const fpsRef = useRef<MutableFps>({ emaMs: 0, lastMs: 0, healthyRun: 0, degraded: false })\n const visibleRef = useRef(true)\n const elementRef = useRef<HTMLElement | null>(null)\n\n useEffect(() => {\n if (!active) return\n let rafId = 0\n let lastDebugReport = 0\n const frame = (now: number) => {\n rafId = requestAnimationFrame(frame)\n const fps = fpsRef.current\n if (fps.lastMs === 0) {\n fps.lastMs = now\n return\n }\n const delta = Math.min(MAX_FRAME_MS, Math.max(1, now - fps.lastMs))\n fps.lastMs = now\n fps.emaMs = fps.emaMs === 0 ? delta : fps.emaMs + FPS_ALPHA * (delta - fps.emaMs)\n const currentFps = 1000 / fps.emaMs\n if (currentFps < FPS_THRESHOLD) {\n fps.healthyRun = 0\n fps.degraded = true\n } else if (fps.degraded) {\n fps.healthyRun += 1\n if (fps.healthyRun >= RECOVER_FRAMES) fps.degraded = false\n }\n if (now - lastDebugReport >= 100) {\n debugRuntime.reportFps(currentFps, fps.emaMs, fps.degraded)\n lastDebugReport = now\n }\n }\n rafId = requestAnimationFrame(frame)\n return () => {\n cancelAnimationFrame(rafId)\n fpsRef.current = { emaMs: 0, lastMs: 0, healthyRun: 0, degraded: false }\n debugRuntime.clearFps()\n }\n }, [active])\n\n const ref = useCallback((element: HTMLElement | null) => {\n elementRef.current = element\n }, [])\n\n useEffect(() => {\n const element = elementRef.current\n if (element === null || typeof IntersectionObserver === 'undefined') return\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) visibleRef.current = entry.isIntersecting\n },\n { rootMargin: '120px 0px' },\n )\n observer.observe(element)\n return () => observer.disconnect()\n })\n\n const shouldHoldBack = useCallback(() => {\n return active && fpsRef.current.degraded && !visibleRef.current\n }, [active])\n\n return { ref, shouldHoldBack }\n}\n","import { useLayoutEffect, useRef, type RefObject } from 'react'\nimport css from './LogarithmicFade.module.css'\n\nexport const FADE_DURATION_MS = 240\nexport const FADE_TAIL_SIZE = 24\nexport const FADE_MAX_TAIL_SIZE = 160\nexport const FADE_MIN_OPACITY = 0\nconst FADE_STEPS = 32\nconst PREFIX = 'dsh-smooth-stream-log-fade-'\nconst COLOR_PROPERTY = '--dsh-smooth-stream-fade-color'\n// Lightning CSS scopes highlight identifiers as well as class names.\nconst highlightName = (index: number): string => css[`${PREFIX}${index}`] ?? `${PREFIX}${index}`\nconst EXCLUDED = 'pre,code,math,.katex,.katex-display,mjx-container,svg,script,style,textarea,input,button,select,[role=\"button\"],[contenteditable],[hidden],[aria-hidden=\"true\"],[aria-live]'\n\nexport function logarithmicOpacity(progress: number): number {\n const p = Number.isFinite(progress) ? Math.max(0, Math.min(1, progress)) : 1\n // Reverse the log easing: preserve translucency early, then settle to ink.\n return FADE_MIN_OPACITY + (1 - FADE_MIN_OPACITY) * (1 - Math.log1p(5 * (1 - p)) / Math.log(6))\n}\n\nexport function fadeTailSize(speedCps: number): number {\n const speed = Number.isFinite(speedCps) ? Math.max(0, speedCps) : 0\n return Math.min(FADE_MAX_TAIL_SIZE, Math.max(FADE_TAIL_SIZE, Math.ceil(speed * FADE_DURATION_MS / 1000)))\n}\n\ninterface FadeCharacter {\n start: number\n end: number\n born: number\n range: Range\n bucket: number\n}\n\ninterface Scheduler {\n highlights: Highlight[]\n clients: Set<LogarithmicFadeController>\n pending: Set<LogarithmicFadeController>\n frame: number\n registry: HighlightRegistry\n window: Window\n}\n\nconst schedulers = new WeakMap<Document, Scheduler>()\nconst segmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n\nfunction schedule(scheduler: Scheduler): void {\n if (scheduler.frame !== 0 || scheduler.pending.size === 0) return\n scheduler.frame = scheduler.window.requestAnimationFrame((now) => {\n scheduler.frame = 0\n for (const client of scheduler.pending) {\n if (!client.paint(now)) scheduler.pending.delete(client)\n }\n schedule(scheduler)\n })\n}\n\nfunction schedulerFor(root: HTMLElement): Scheduler | null {\n const doc = root.ownerDocument\n const win = doc.defaultView\n if (win === null) return null\n // Use the root's realm, including when a renderer lives in another document.\n const realm = win as Window & typeof globalThis\n if (typeof realm.Highlight !== 'function' || !realm.CSS?.highlights\n || !realm.CSS.supports('color', 'color-mix(in srgb, currentColor 15%, transparent)')) return null\n let scheduler = schedulers.get(doc)\n if (scheduler === undefined) {\n const highlights = Array.from({ length: FADE_STEPS }, () => new realm.Highlight())\n for (const [index, highlight] of highlights.entries()) realm.CSS.highlights.set(highlightName(index), highlight)\n scheduler = {\n highlights,\n clients: new Set(),\n pending: new Set(),\n frame: 0,\n registry: realm.CSS.highlights,\n window: win,\n }\n schedulers.set(doc, scheduler)\n }\n return scheduler\n}\n\n/** Owns ranges only: React retains ownership of every element and Text node. */\nexport class LogarithmicFadeController {\n private previous = ''\n private characters: FadeCharacter[] = []\n private colors = new Map<HTMLElement, { value: string, priority: string }>()\n private enabled = false\n private active = false\n private speedCps = 100\n private pausedAt: number | null = null\n private disposed = false\n private readonly observer: MutationObserver\n\n private constructor(private readonly root: HTMLElement, private readonly scheduler: Scheduler) {\n scheduler.clients.add(this)\n const win = root.ownerDocument.defaultView as Window & typeof globalThis\n this.observer = new win.MutationObserver(() => { this.reconcile() })\n this.observer.observe(root, { subtree: true, childList: true, characterData: true })\n }\n\n static create(root: HTMLElement): LogarithmicFadeController | null {\n const scheduler = schedulerFor(root)\n return scheduler === null ? null : new LogarithmicFadeController(root, scheduler)\n }\n\n update(enabled: boolean, active: boolean, speedCps = 100, paused = false): void {\n const now = this.scheduler.window.performance.now()\n if (paused && this.pausedAt === null) this.pausedAt = now\n if (!paused && this.pausedAt !== null) {\n const pauseDuration = now - this.pausedAt\n for (const character of this.characters) character.born += pauseDuration\n this.pausedAt = null\n }\n this.enabled = enabled\n this.active = active\n this.speedCps = speedCps\n this.reconcile()\n }\n\n private clearRanges(): void {\n for (const character of this.characters) {\n this.scheduler.highlights[character.bucket]?.delete(character.range)\n }\n this.characters = []\n this.restoreColors()\n }\n\n private restoreColors(): void {\n for (const [element, original] of this.colors) {\n if (original.value === '') element.style.removeProperty(COLOR_PROPERTY)\n else element.style.setProperty(COLOR_PROPERTY, original.value, original.priority)\n }\n this.colors.clear()\n }\n\n private preserveColor(element: HTMLElement): void {\n if (this.colors.has(element)) return\n const color = this.scheduler.window.getComputedStyle(element).color\n this.colors.set(element, {\n value: element.style.getPropertyValue(COLOR_PROPERTY),\n priority: element.style.getPropertyPriority(COLOR_PROPERTY),\n })\n // An explicit source color prevents highlight inheritance from multiplying\n // alpha through nested Markdown elements (root → paragraph → strong).\n element.style.setProperty(COLOR_PROPERTY, color)\n }\n\n private reconcile(): void {\n if (this.disposed) return\n const text = this.root.textContent ?? ''\n const previous = this.previous\n this.previous = text\n const old = this.characters\n this.clearRanges()\n if (!this.enabled) {\n this.root.classList.remove(css.scope!)\n this.scheduler.pending.delete(this)\n this.stopIfIdle()\n return\n }\n this.root.classList.add(css.scope!)\n const now = this.pausedAt ?? this.scheduler.window.performance.now()\n // A parser rewrite must not replay already readable content. Retain only\n // the unchanged prefix; future appends resume the effect normally.\n let prefix = 0\n while (prefix < previous.length && prefix < text.length && previous[prefix] === text[prefix]) prefix += 1\n const appended = text.startsWith(previous)\n const nodes: { node: Text, start: number, end: number, eligible: boolean }[] = []\n const walker = this.root.ownerDocument.createTreeWalker(this.root, NodeFilter.SHOW_TEXT)\n let offset = 0\n for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {\n const end = offset + (node.textContent?.length ?? 0)\n nodes.push({ node: node as Text, start: offset, end, eligible: node.parentElement?.closest(EXCLUDED) === null })\n offset = end\n }\n // containing() walks backwards by grapheme without segmenting the entire\n // answer into an array. Offsets still refer to the original DOM text.\n const segments = segmenter.segment(text)\n // Keep existing characters alive when the engine resets its speed during\n // completion. A shrinking window must not abruptly darken the old tail.\n const tailSize = fadeTailSize(this.speedCps)\n const oldestLiveStart = old.reduce((start, character) => (\n now - character.born < FADE_DURATION_MS && character.end <= prefix\n ? Math.min(start, character.start)\n : start\n ), Infinity)\n let end = text.length\n for (let count = 0; count < FADE_MAX_TAIL_SIZE && end > 0 && (count < tailSize || end > oldestLiveStart); count += 1) {\n const segment = segments.containing(end - 1)\n if (segment === undefined) break\n const start = segment.index\n const parts = nodes.filter(node => node.end > start && node.start < end)\n const retained = old.find(character => character.start === start && character.end === end && end <= prefix)\n const born = retained?.born ?? (this.active && appended && start >= previous.length ? now : null)\n if (born !== null && now - born < FADE_DURATION_MS && segment.segment.trim() !== ''\n && parts.length > 0 && parts.every(part => part.eligible)) {\n const first = parts[0]!\n const last = parts[parts.length - 1]!\n const range = this.root.ownerDocument.createRange()\n range.setStart(first.node, start - first.start)\n range.setEnd(last.node, end - last.start)\n for (const part of parts) this.preserveColor(part.node.parentElement!)\n this.characters.push({ start, end, born, range, bucket: -1 })\n }\n end = start\n }\n if (this.paint(now)) {\n if (this.pausedAt === null) {\n this.scheduler.pending.add(this)\n schedule(this.scheduler)\n } else {\n this.scheduler.pending.delete(this)\n this.stopIfIdle()\n }\n } else {\n this.scheduler.pending.delete(this)\n this.stopIfIdle()\n }\n }\n\n paint(now: number): boolean {\n this.characters = this.characters.filter((character) => {\n const progress = (now - character.born) / FADE_DURATION_MS\n if (progress >= 1 || !this.root.isConnected || !this.root.contains(character.range.startContainer)) {\n this.scheduler.highlights[character.bucket]?.delete(character.range)\n return false\n }\n const bucket = Math.min(FADE_STEPS - 1, Math.round((logarithmicOpacity(progress) - FADE_MIN_OPACITY) / (1 - FADE_MIN_OPACITY) * (FADE_STEPS - 1)))\n if (bucket !== character.bucket) {\n this.scheduler.highlights[character.bucket]?.delete(character.range)\n this.scheduler.highlights[bucket]!.add(character.range)\n character.bucket = bucket\n }\n return true\n })\n if (this.characters.length === 0) this.restoreColors()\n return this.characters.length > 0\n }\n\n private stopIfIdle(): void {\n if (this.scheduler.pending.size !== 0) return\n this.scheduler.window.cancelAnimationFrame(this.scheduler.frame)\n this.scheduler.frame = 0\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.observer.disconnect()\n this.clearRanges()\n this.root.classList.remove(css.scope!)\n this.scheduler.pending.delete(this)\n this.scheduler.clients.delete(this)\n this.stopIfIdle()\n if (this.scheduler.clients.size === 0) {\n for (const [index, highlight] of this.scheduler.highlights.entries()) {\n const name = highlightName(index)\n if (this.scheduler.registry.get(name) === highlight) this.scheduler.registry.delete(name)\n }\n schedulers.delete(this.root.ownerDocument)\n }\n }\n}\n\n/** active admits new characters; enabled=false also cancels completion linger. */\nexport function useLogarithmicFade(\n rootRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n active: boolean,\n speedCpsRef?: { current: number },\n paused = false,\n): void {\n const controller = useRef<LogarithmicFadeController | null>(null)\n const committed = useRef(false)\n useLayoutEffect(() => {\n return () => {\n controller.current?.dispose()\n controller.current = null\n }\n }, [rootRef])\n // Deliberately commit-driven, including Markdown updates with unchanged source.\n useLayoutEffect(() => {\n const root = rootRef.current\n // Settled history allocates neither observers nor highlight buckets.\n if (controller.current === null && root !== null && enabled && active) {\n controller.current = LogarithmicFadeController.create(root)\n // Enabling midway through a message must not replay readable text.\n if (committed.current) controller.current?.update(false, false)\n }\n controller.current?.update(enabled, active, speedCpsRef?.current, paused)\n committed.current = true\n })\n}\n","import { useEffect, useRef, type ReactNode } from 'react'\nimport { useConversationFollow } from './teleprompterGlide.ts'\nimport css from './TypewriterAssistantNodeView.module.css'\n\n/**\n * Document-flow host that owns conversation-port follow while `active`.\n * Shared by assistant blocks and every other Agent Chat row. `onGrowth` lets\n * generic wrapped renderers re-arm one glide when their DOM grows without\n * requiring a business-kind-specific lifecycle predicate.\n */\nexport function FollowHost({\n active,\n entrance = false,\n onEntranceSettled,\n onGrowth,\n entranceExtentRef,\n speedCpsRef,\n revealedCharsRef,\n revealScaleRef,\n predictive = true,\n predictiveRef,\n controlScroll = true,\n hostRef,\n className,\n entranceActive,\n children,\n}: {\n active: boolean\n entrance?: boolean\n onEntranceSettled?: (() => void) | undefined\n onGrowth?: ((deltaPx: number) => void) | undefined\n entranceExtentRef?: { current: number | null } | undefined\n speedCpsRef: { current: number }\n revealedCharsRef?: { current: number } | undefined\n revealScaleRef?: { current: number } | undefined\n predictive?: boolean\n predictiveRef?: { current: boolean } | undefined\n /** False leaves conversation bottom-follow to the Host. */\n controlScroll?: boolean\n hostRef?: { current: HTMLDivElement | null } | undefined\n children: ReactNode\n className?: string | undefined\n /** Optional marker for a generic row's one-shot entrance animation. */\n entranceActive?: boolean | undefined\n}) {\n const localRootRef = useRef<HTMLDivElement>(null)\n const rootRef = hostRef ?? localRootRef\n useConversationFollow(\n rootRef,\n active || entrance,\n speedCpsRef,\n revealScaleRef,\n predictive,\n entrance,\n onEntranceSettled,\n predictiveRef,\n entranceExtentRef,\n revealedCharsRef,\n controlScroll,\n )\n useEffect(() => {\n if (onGrowth === undefined || typeof ResizeObserver === 'undefined') return\n const root = rootRef.current\n if (root === null) return\n let previousHeight: number | null = null\n let pendingGrowth = 0\n let growthFrame: number | null = null\n const flushGrowth = (): void => {\n growthFrame = null\n if (pendingGrowth <= 0) return\n const delta = pendingGrowth\n pendingGrowth = 0\n onGrowth(delta)\n }\n const observer = new ResizeObserver(entries => {\n const measuredHeight = entries[0]?.contentRect.height\n if (measuredHeight === undefined || !Number.isFinite(measuredHeight)) return\n const nextHeight = measuredHeight\n if (previousHeight !== null && nextHeight > previousHeight + 0.5) {\n pendingGrowth += nextHeight - previousHeight\n if (growthFrame === null) growthFrame = requestAnimationFrame(flushGrowth)\n }\n previousHeight = nextHeight\n })\n observer.observe(root)\n return () => {\n observer.disconnect()\n if (growthFrame !== null) cancelAnimationFrame(growthFrame)\n }\n }, [onGrowth])\n return (\n <div\n ref={rootRef}\n className={className === undefined ? css.follow : `${css.follow} ${className}`}\n data-entrance={entranceActive === undefined ? undefined : entranceActive ? 'active' : 'idle'}\n >\n {children}\n </div>\n )\n}\n","/**\n * Shared plugin configuration contract. The Host half defines the\n * Schemastery schema over this shape (defaults live here so both halves stay\n * symmetric); the client half falls back to the same defaults when the Host\n * boot-config bridge is absent (client-only composition).\n */\n\nimport type { StreamSmoothingPreset } from './client/useSmoothStreamContent.ts'\n\n/** Legacy render-mode value retained so existing overlays remain valid. */\nexport type StreamMode = 'typewriter' | 'teleprompter'\n\n/** Plugin configuration validated by the Host schema and bridged to the browser half. */\nexport interface StreamConfig {\n /** Compatibility field; both values use the current adaptive reveal engine. */\n readonly mode: StreamMode\n /** Smoothing preset for the reveal cadence. */\n readonly preset: StreamSmoothingPreset\n /**\n * Unused at runtime; kept so existing overlays load. Live reveal tracks\n * observed arrival and ignores this seed.\n */\n readonly revealCharsPerSec: number\n /**\n * Unused at runtime; kept so existing overlays load. Follow is a\n * smooth-damp, not a cruise speed.\n */\n readonly scrollSpeedPxPerSec: number\n /** Unused at runtime; retained so existing overlays continue to load. */\n readonly maxScrollSpeedPxPerSec: number\n}\n\n/** Defaults shared by the Host schema and the client-side fallback. */\nexport const DEFAULT_STREAM_CONFIG: StreamConfig = {\n mode: 'typewriter',\n preset: 'balanced',\n revealCharsPerSec: 80,\n scrollSpeedPxPerSec: 48,\n maxScrollSpeedPxPerSec: 1000,\n}\n\n/**\n * Window global the Host writes into the served index HTML. The browser boot\n * graph carries no per-entry config, so this inline script is the only\n * Host-to-client configuration channel for a composed web plugin.\n */\nexport const STREAM_BOOT_GLOBAL = '__DSH_SMOOTH_STREAM_CONFIG__'\n","import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ComponentProps, type ReactNode, type RefObject } from 'react'\nimport { IconThinkOutline14, JsonBlock, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { ImageGallery, type ImageLoader, type MessageImageLabels } from '@deepseek-ai/dsh-client-ui-attachment'\nimport type { ChatNodeViewProps, TurnTailOwnerProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { AnimatedDisclosure } from './AnimatedDisclosure.tsx'\nimport { notifyFollowCommit } from './teleprompterGlide.ts'\nimport { useSmoothStreamContent, type StreamSmoothingPreset } from './useSmoothStreamContent.ts'\nimport { useFpsGuard } from './useFpsGuard.ts'\nimport { useLogarithmicFade } from './useLogarithmicFade.ts'\nimport { FollowHost } from './FollowHost.tsx'\nimport { DEFAULT_STREAM_CONFIG, type StreamMode } from '../config.ts'\nimport { DEFAULT_STREAM_SETTINGS, type StreamMotionPreference } from '../settings.ts'\nimport css from './TypewriterAssistantNodeView.module.css'\n\ntype AssistantProps = ChatNodeViewProps<'assistant-step'>\ntype MarkdownProps = Pick<ComponentProps<typeof MarkdownText>, 'labels' | 'fileMentions' | 'text'>\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(\n () => typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true,\n )\n useEffect(() => {\n if (typeof window === 'undefined' || window.matchMedia === undefined) return\n const query = window.matchMedia('(prefers-reduced-motion: reduce)')\n const onChange = () => setReduced(query.matches)\n query.addEventListener('change', onChange)\n return () => query.removeEventListener('change', onChange)\n }, [])\n return reduced\n}\n\n/**\n * Resolve whether the reveal engine should stay off for this view. The OS\n * preference wins only in `auto` mode: `force-smooth` keeps the engine on\n * machines where a system-wide reduce-motion switch (or a forced browser\n * flag) would otherwise silently bypass smoothing, and `force-reduced`\n * disables it even when the OS asks for motion. Credit: three-state design\n * proposed by @Zn-Dk in #21/#22.\n */\nfunction useMotionReduced(preference: StreamMotionPreference): boolean {\n const system = usePrefersReducedMotion()\n if (preference === 'force-smooth') return false\n if (preference === 'force-reduced') return true\n return system\n}\n\ninterface AnimatedMarkdownTextProps extends MarkdownProps {\n streaming: boolean\n logarithmicFade: boolean\n /** Whether the resolved reduced-motion gate keeps the reveal engine off. */\n motionReduced: boolean\n /** True on the last text block: that block owns conversation follow. */\n ownFollow: boolean\n followSpeedCpsRef?: { current: number } | undefined\n followRevealedCharsRef?: { current: number } | undefined\n followRevealScaleRef?: { current: number } | undefined\n onPredictiveChange?: ((predictive: boolean) => void) | undefined\n preset: StreamSmoothingPreset\n shouldHoldBack: () => boolean\n controlScroll?: boolean\n}\n\n/** Conservative fallback before the streaming Markdown tail has geometry. */\nconst PREDICTIVE_WRAP_FALLBACK_CHARS = 32\nconst STREAM_ANNOUNCEMENT_INTERVAL_MS = 800\nconst STREAM_ANNOUNCEMENT_MAX_CHARS = 320\n\ninterface PendingTextGeometry {\n root: HTMLElement\n visibleText: string\n fontSize: number\n wrapThresholdWidth: number | null\n}\n\nfunction approximateInlineWidth(text: string, emPx: number): number {\n let width = 0\n for (const char of text) {\n if (/\\s/u.test(char)) width += emPx * 0.33\n else if (/^[\\x00-\\x7f]$/u.test(char)) width += emPx * 0.56\n else width += emPx\n }\n return width\n}\n\nfunction measurePendingTextGeometry(root: HTMLElement, visibleText: string): PendingTextGeometry {\n if (\n typeof document.createTreeWalker !== 'function'\n || typeof NodeFilter === 'undefined'\n ) {\n return { root, visibleText, fontSize: 14, wrapThresholdWidth: null }\n }\n const rootRect = root.getBoundingClientRect()\n const rootWidth = Math.max(0, rootRect.width, rootRect.right - rootRect.left, root.clientWidth)\n if (rootWidth <= 0) return { root, visibleText, fontSize: 14, wrapThresholdWidth: null }\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let tail: Text | null = null\n for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {\n if ((node.textContent ?? '').length > 0) tail = node as Text\n }\n const parent = tail?.parentElement ?? root\n const fontSize = Number.parseFloat(getComputedStyle(parent).fontSize) || 14\n if (tail === null || typeof document.createRange !== 'function') {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n\n try {\n const length = tail.textContent?.length ?? 0\n if (length <= 0) return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n const range = document.createRange()\n range.setStart(tail, Math.max(0, length - 1))\n range.setEnd(tail, length)\n const tailRect = range.getBoundingClientRect()\n const contentRight = rootRect.right\n if (!Number.isFinite(tailRect.right) || tailRect.right <= rootRect.left || contentRight <= rootRect.left) {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n const remainingWidth = Math.max(0, contentRight - tailRect.right)\n return {\n root,\n visibleText,\n fontSize,\n wrapThresholdWidth: remainingWidth + fontSize * 0.35,\n }\n } catch {\n return { root, visibleText, fontSize, wrapThresholdWidth: rootWidth }\n }\n}\n\n/** Whether buffered source can reach a new visual line before it drains. */\nfunction pendingTextCanGrow(\n root: HTMLElement | null,\n visibleText: string,\n pending: string,\n geometryRef: { current: PendingTextGeometry | null },\n): boolean {\n if (pending === '') return false\n if (/[\\r\\n]/u.test(pending)) return true\n const pendingChars = [...pending]\n if (root === null) return pendingChars.length >= PREDICTIVE_WRAP_FALLBACK_CHARS\n\n let geometry = geometryRef.current\n if (geometry?.root !== root || geometry.visibleText !== visibleText) {\n geometry = measurePendingTextGeometry(root, visibleText)\n geometryRef.current = geometry\n }\n if (geometry.wrapThresholdWidth === null) {\n return pendingChars.length >= PREDICTIVE_WRAP_FALLBACK_CHARS\n }\n return approximateInlineWidth(pending, geometry.fontSize) >= geometry.wrapThresholdWidth\n}\n\nfunction announcementChunkEnd(source: string, start: number): number {\n const hardEnd = Math.min(source.length, start + STREAM_ANNOUNCEMENT_MAX_CHARS)\n if (hardEnd === source.length) return hardEnd\n const softStart = start + Math.floor(STREAM_ANNOUNCEMENT_MAX_CHARS * 0.6)\n for (let index = hardEnd - 1; index >= softStart; index -= 1) {\n if (/[\\s.,;:!?]/u.test(source[index] ?? '')) return index + 1\n }\n return hardEnd\n}\n\n/** Pace screen-reader updates independently from visual reveal frames. */\ninterface StreamAnnouncementState {\n text: string\n revision: number\n present: boolean\n}\n\n/** A commit-driven live region isolated from the visible Markdown subtree. */\nconst StreamAnnouncement = memo(function StreamAnnouncement({\n text,\n active,\n}: {\n text: string\n active: boolean\n}) {\n const [announcement, setAnnouncement] = useState<StreamAnnouncementState>({\n text: '',\n revision: 0,\n present: active,\n })\n const sourceRef = useRef(text)\n const activeRef = useRef(active)\n const announcedOffsetRef = useRef(active ? 0 : text.length)\n const drainSourceRef = useRef<string | null>(null)\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(() => {\n const clearTimer = (): void => {\n if (timerRef.current === null) return\n clearTimeout(timerRef.current)\n timerRef.current = null\n }\n\n const publishNext = (source: string): boolean => {\n const start = Math.min(announcedOffsetRef.current, source.length)\n const end = announcementChunkEnd(source, start)\n if (end <= start) return false\n announcedOffsetRef.current = end\n setAnnouncement(previous => ({\n text: source.slice(start, end),\n revision: previous.revision + 1,\n present: true,\n }))\n return end < source.length\n }\n\n const hideAfterLinger = (): void => {\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (activeRef.current) return\n drainSourceRef.current = null\n setAnnouncement(previous => ({ ...previous, present: false }))\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const drainNext = (): void => {\n const source = drainSourceRef.current\n if (source === null) return\n if (!publishNext(source)) {\n hideAfterLinger()\n return\n }\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (activeRef.current) return\n drainNext()\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const scheduleLive = (): void => {\n if (timerRef.current !== null || announcedOffsetRef.current >= sourceRef.current.length) return\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n if (!activeRef.current) return\n const source = sourceRef.current\n if (publishNext(source)) scheduleLive()\n }, STREAM_ANNOUNCEMENT_INTERVAL_MS)\n }\n\n const wasActive = activeRef.current\n const previousSource = sourceRef.current\n const continuingDrain = !active && !wasActive && drainSourceRef.current !== null\n if (\n !continuingDrain\n && (!text.startsWith(previousSource) || announcedOffsetRef.current > text.length)\n ) {\n announcedOffsetRef.current = 0\n }\n sourceRef.current = text\n activeRef.current = active\n\n if (active) {\n if (!wasActive) {\n clearTimer()\n drainSourceRef.current = null\n setAnnouncement(previous => ({\n text: '',\n revision: previous.revision + 1,\n present: true,\n }))\n }\n scheduleLive()\n return\n }\n\n if (!wasActive) {\n if (drainSourceRef.current === null) announcedOffsetRef.current = text.length\n return\n }\n\n clearTimer()\n drainSourceRef.current = text\n drainNext()\n }, [active, text])\n\n useEffect(() => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current)\n timerRef.current = null\n }, [])\n\n if (!active && !announcement.present) return null\n const activating = active && !activeRef.current\n return (\n <span\n className={css.visuallyHidden}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n <span key={announcement.revision}>{activating ? '' : announcement.text}</span>\n </span>\n )\n})\n\n/**\n * Smooth streaming text arm. While the reply runs, the accumulated source is\n * revealed through the smoother at a rate that tracks the model's arrival\n * and rendered by the Harness `MarkdownText`\n * streaming arm (incremental parse, frozen non-tail blocks), so there is no\n * raw-text tail and no text-to-markdown swap: the tree stays markdown\n * throughout. The last text block owns conversation-port follow so wraps\n * glide instead of snapping. Once the stream closes and the reveal queue\n * drains, the settled full parse (KaTeX math, fence highlighting, file\n * mentions) swaps in exactly once.\n */\nfunction AnimatedMarkdownText({\n text,\n labels,\n fileMentions,\n streaming,\n logarithmicFade,\n motionReduced,\n ownFollow,\n followSpeedCpsRef,\n followRevealedCharsRef,\n followRevealScaleRef,\n onPredictiveChange,\n preset,\n shouldHoldBack,\n controlScroll = true,\n}: AnimatedMarkdownTextProps) {\n const reduced = motionReduced\n const [typing, setTyping] = useState(streaming)\n const localSpeedCpsRef = useRef(35)\n const followRootRef = useRef<HTMLDivElement>(null)\n const predictionSourceRef = useRef<string | null>(null)\n const predictionStateRef = useRef(false)\n const predictionGeometryRef = useRef<PendingTextGeometry | null>(null)\n const speedCpsRef = followSpeedCpsRef ?? localSpeedCpsRef\n const displayed = useSmoothStreamContent(text, {\n enabled: typing && !reduced,\n inputComplete: !streaming,\n preset,\n shouldHoldBack,\n speedCpsRef,\n revealedCharsRef: followRevealedCharsRef,\n revealScaleRef: followRevealScaleRef,\n onRevealCommit: () => { notifyFollowCommit(followRootRef.current) },\n })\n const shown = reduced ? text : displayed\n const live = typing && !reduced\n useLogarithmicFade(followRootRef, logarithmicFade && !reduced, live, speedCpsRef)\n\n useEffect(() => {\n const root = followRootRef.current\n if (root === null || typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(() => {\n if (predictionGeometryRef.current?.root === root) predictionGeometryRef.current = null\n })\n observer.observe(root)\n return () => { observer.disconnect() }\n }, [])\n\n useLayoutEffect(() => {\n if (onPredictiveChange === undefined) return\n const pending = text.slice(shown.length)\n const sourceChanged = predictionSourceRef.current !== text\n const next = !live || !streaming || pending === ''\n ? false\n : sourceChanged\n ? pendingTextCanGrow(followRootRef.current, shown, pending, predictionGeometryRef)\n : predictionStateRef.current\n predictionSourceRef.current = text\n predictionStateRef.current = next\n onPredictiveChange(next)\n }, [live, onPredictiveChange, shown, streaming, text])\n\n // The stream closed: keep revealing the remaining queue, then swap to the\n // settled parse exactly once. The markdown tree stays mounted until then.\n useEffect(() => {\n if (typing && !streaming && shown.length === text.length) setTyping(false)\n }, [shown, streaming, text, typing])\n\n // A row can mount before the projection flips its assistant step to\n // `running`, which would freeze `typing` at false forever and leave the\n // reveal engine off for the whole reply. Re-arm on the rising edge so late\n // stream starts are still smoothed. (Adopted from #22 by @Zn-Dk.)\n useEffect(() => {\n if (streaming) setTyping(true)\n }, [streaming])\n\n return (\n <FollowHost\n active={live && ownFollow}\n speedCpsRef={speedCpsRef}\n revealedCharsRef={followRevealedCharsRef}\n revealScaleRef={followRevealScaleRef}\n predictive={streaming}\n controlScroll={controlScroll}\n hostRef={followRootRef}\n >\n <MarkdownText\n // `shown` stays authoritative through the completion drain: the\n // settled parse swaps in only when the queue has actually emptied.\n // Rendering `text` early bypasses the drain and teleports the tail.\n text={live ? shown : text}\n streaming={live}\n labels={labels}\n fileMentions={live ? undefined : fileMentions}\n />\n </FollowHost>\n )\n}\n\nfunction imageLabels(t: AssistantProps['t']): MessageImageLabels {\n return {\n image: t('image.label'),\n open: t('image.openOriginal'),\n openNamed: label => t('image.openOriginalLabel', { label }),\n loading: t('image.loading'),\n loadFailed: t('image.loadFailed'),\n lightbox: {\n dialog: t('image.preview'),\n close: t('image.closePreview'),\n },\n }\n}\n\n/**\n * Apply searchable hidden state without unmounting a stable subtree — the\n * Host's completion fold hides the answer-inline reasoning this way, so the\n * takeover renderer must reproduce it to stay inside the contract: the row\n * disappears into the Host's process summary and comes back on find-in-page.\n * (Mirrors the Harness chat kit's `useSearchableHidden`.)\n */\nfunction useSearchableHidden(\n hidden: boolean,\n reveal: () => void,\n): RefObject<HTMLDivElement> {\n const ref = useRef<HTMLDivElement>(null)\n useLayoutEffect(() => {\n const element = ref.current\n if (element === null) return\n if (hidden && element.contains(element.ownerDocument.activeElement)) {\n reveal()\n return\n }\n if (hidden) element.setAttribute('hidden', 'until-found')\n else element.removeAttribute('hidden')\n }, [hidden, reveal])\n useEffect(() => {\n const element = ref.current\n if (element === null) return\n element.addEventListener('beforematch', reveal)\n return () => { element.removeEventListener('beforematch', reveal) }\n }, [reveal])\n return ref\n}\n\n/**\n * One answer-inline reasoning block wrapped in the Host's fold contract. The\n * Host computes the fold decision (turn closed, compact transcript, this node\n * is the answer) and delivers it through the `turnProcess` owner prop; when\n * folded the block hides into the Host's \"thought\" summary row instead of\n * staying mounted above the answer.\n */\nfunction FoldableReasoning({\n hidden,\n reveal,\n children,\n}: {\n hidden: boolean\n reveal: () => void\n children: ReactNode\n}) {\n const ref = useSearchableHidden(hidden, reveal)\n return (\n <div ref={ref} data-turn-process-inline={hidden || undefined}>\n {children}\n </div>\n )\n}\n\nfunction firstLine(text: string): string {\n const newline = text.indexOf('\\n')\n return newline === -1 ? text : text.slice(0, newline)\n}\n\nfunction latestLine(text: string): string {\n const visible = text.trimEnd()\n const newline = visible.lastIndexOf('\\n')\n return newline === -1 ? visible : visible.slice(newline + 1)\n}\n\n/**\n * Built-in Think disclosure with a smoothed `text` feed. Chevron and row\n * click stay on the disclosure chrome, which the plugin's AnimatedDisclosure\n * renders with a height-animated body (the harness primitive would mount and\n * unmount it, which cannot glide). The row opens only while this block is\n * the streaming tail and closes as soon as thinking ends — a later block,\n * or the assistant node settling — not when the rest of the reply is\n * still streaming.\n */\nfunction AnimatedReasoning({\n text,\n running,\n preset,\n thinkAutoExpand,\n motionReduced,\n logarithmicFade,\n shouldHoldBack,\n followSpeedCpsRef,\n followRevealScaleRef,\n t,\n}: {\n text: string\n running: boolean\n preset: StreamSmoothingPreset\n thinkAutoExpand: boolean\n motionReduced: boolean\n logarithmicFade: boolean\n shouldHoldBack: () => boolean\n followSpeedCpsRef?: { current: number } | undefined\n followRevealScaleRef?: { current: number } | undefined\n t: AssistantProps['t']\n}) {\n const reduced = motionReduced\n const [expanded, setExpanded] = useState(running && thinkAutoExpand)\n const [autoClosed, setAutoClosed] = useState(false)\n const summaryRef = useRef<HTMLSpanElement>(null)\n const fadeRootRef = useRef<HTMLDivElement>(null)\n const localFadeSpeedRef = useRef(35)\n const fadeSpeedRef = followSpeedCpsRef ?? localFadeSpeedRef\n const commitAnchorRef = useRef<HTMLDivElement>(null)\n // The running→false flip is the AUTO-close: it collapses instantly and the\n // follower's settle spring absorbs the height step. A later manual toggle\n // keeps the CSS glide.\n const displayed = useSmoothStreamContent(text, {\n enabled: running && !reduced,\n preset,\n shouldHoldBack,\n speedCpsRef: fadeSpeedRef,\n revealScaleRef: followRevealScaleRef,\n onRevealCommit: () => { notifyFollowCommit(commitAnchorRef.current) },\n })\n const shown = running && !reduced ? displayed : text\n const summary = running ? latestLine(shown) : firstLine(text)\n useLogarithmicFade(fadeRootRef, logarithmicFade && !reduced && expanded, running, fadeSpeedRef)\n\n useLayoutEffect(() => {\n // Only the running state owns disclosure while auto-expand is on; with it\n // off, a manual toggle is never wrestled back by the stream.\n if (thinkAutoExpand) {\n setExpanded(running)\n setAutoClosed(!running)\n }\n // A commit that changes this block's height must hand the follower its\n // correction in the SAME task, before the grown-but-uncompensated frame\n // can reach a paint.\n notifyFollowCommit(commitAnchorRef.current)\n }, [running, thinkAutoExpand])\n\n useEffect(() => {\n const element = summaryRef.current\n if (element === null) return\n element.scrollLeft = running ? element.scrollWidth - element.clientWidth : 0\n }, [running, summary])\n\n // Preserve FollowHost's layout wrapper without mounting a second scroll owner.\n return (\n <div className={css.follow} ref={commitAnchorRef}>\n <div className={css.think} data-variant=\"think\" data-state={running ? 'running' : 'ok'}>\n {running && <span className={css.visuallyHidden}>{t('row.running')}</span>}\n <AnimatedDisclosure\n rowClassName={css.thinkRow}\n leadingClassName={css.thinkLeading}\n titleClassName={css.thinkTitle}\n chevronClassName={css.thinkChevron}\n icon={<IconThinkOutline14 size={14} />}\n title=\"Think\"\n open={expanded}\n onToggle={() => {\n setAutoClosed(false)\n setExpanded(value => !value)\n }}\n // The auto-close at stream end snaps (no grid-track animation): the\n // follower's settle spring absorbs the height step through the\n // compositor, so animating the track too would double-animate the\n // collapse. Manual toggles while streaming keep the glide.\n bodyTransition={!autoClosed}\n collapsedContent={(\n <>\n <span className={css.thinkSeparator} aria-hidden />\n <span ref={summaryRef} className={css.thinkSummary} data-follow-end={running || undefined}>{summary}</span>\n </>\n )}\n >\n <div ref={fadeRootRef} className={css.thinkBody}>{shown}</div>\n </AnimatedDisclosure>\n </div>\n </div>\n )\n}\n\n/**\n * Assistant node renderer for the typewriter overlay. Text observed while\n * streaming is revealed by the smoother through the Harness Markdown\n * renderer at a rate that tracks arrival. Reasoning blocks keep the\n * built-in Think disclosure and only receive a smoothed text feed; the\n * outer node owns conversation-port follow while streaming; the final text\n * block keeps ownership while its settled reveal queue drains. The FPS guard\n * holds offscreen reveals when the frame rate is degraded. Settled text\n * renders with the full Markdown pipeline.\n */\nexport const TypewriterAssistantNodeView = memo(function TypewriterAssistantNodeView({\n mode: _mode = DEFAULT_STREAM_CONFIG.mode,\n preset = DEFAULT_STREAM_CONFIG.preset,\n revealCharsPerSec: _revealCharsPerSec = DEFAULT_STREAM_CONFIG.revealCharsPerSec,\n scrollSpeedPxPerSec: _scrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.scrollSpeedPxPerSec,\n maxScrollSpeedPxPerSec: _maxScrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.maxScrollSpeedPxPerSec,\n thinkAutoExpand = DEFAULT_STREAM_SETTINGS.thinkAutoExpand,\n logarithmicFade = DEFAULT_STREAM_SETTINGS.logarithmicFade,\n controlScroll = true,\n motionPreference = DEFAULT_STREAM_SETTINGS.motionPreference,\n node,\n useTurnData,\n openFile,\n loadImage,\n fileMentions,\n turnProcess,\n t,\n}: AssistantProps & {\n mode?: StreamMode\n preset?: StreamSmoothingPreset\n revealCharsPerSec?: number\n scrollSpeedPxPerSec?: number\n maxScrollSpeedPxPerSec?: number\n thinkAutoExpand?: boolean\n logarithmicFade?: boolean\n controlScroll?: boolean\n motionPreference?: StreamMotionPreference\n}) {\n const data = node.data\n const streaming = data.status === 'running'\n const reduced = useMotionReduced(motionPreference)\n // The Host's completion-fold decision for THIS node's inline reasoning:\n // only the answer step folds, only in compact-transcript mode, and only\n // once the turn has closed (foldable implies it). Mirrors the built-in\n // assistant renderer so the takeover keeps the official behavior.\n const reasoningHidden = turnProcess !== undefined\n && turnProcess.foldable\n && turnProcess.spec.answerStep === data.step\n && turnProcess.spec.inlineReasoning\n && !turnProcess.open\n const revealProcess = useCallback(() => { turnProcess?.setOpen(true) }, [turnProcess])\n const { ref: guardRef, shouldHoldBack } = useFpsGuard(streaming)\n const rootSpeedRef = useRef(35)\n const rootRevealedCharsRef = useRef(0)\n const rootRevealScaleRef = useRef(1)\n const reasoningTailIndex = streaming && data.blocks[data.blocks.length - 1]?.kind === 'reasoning'\n ? data.blocks.length - 1\n : -1\n const reasoningOwnsSpeed = reasoningTailIndex !== -1\n const rootPredictiveRef = useRef(false)\n const previousReasoningTailRef = useRef(-1)\n if (reasoningTailIndex !== previousReasoningTailRef.current) {\n // Think growth is already paced by its own text reveal. Opening additional\n // speculative runway here exposes that runway as an empty gap above the\n // fixed turn status, especially when reasoning arrives in fast bursts.\n // The follower still smooths real height growth within the measured gap\n // and catches up any unsafe remainder in the same frame.\n rootPredictiveRef.current = false\n if (!reasoningOwnsSpeed) rootSpeedRef.current = 35\n previousReasoningTailRef.current = reasoningTailIndex\n }\n const updateTextPrediction = useMemo(\n () => (predictive: boolean): void => { rootPredictiveRef.current = predictive },\n [],\n )\n const turn = node.location.kind === 'turn' || node.location.kind === 'step'\n ? node.location.turn\n : undefined\n const tail = useTurnData('turn-tail')\n const owner = useMemo<TurnTailOwnerProps | undefined>(() => {\n if (turn?.status !== 'closed' || data.finalNode === undefined) return undefined\n if (tail?.closing?.finalNode.seq !== data.finalNode.seq) return undefined\n return { turn, seq: data.finalNode.seq, openFile }\n }, [data.finalNode, openFile, tail, turn])\n const mentions = useMemo(\n () => owner === undefined ? undefined : fileMentions(owner),\n [fileMentions, owner],\n )\n const markdownLabels = useMemo(() => ({\n code: { copyLabel: t('copy'), copiedLabel: t('copied') },\n footnotes: t('markdown.footnotes'),\n }), [t])\n const imageLoader: ImageLoader = loadImage ?? (async () => {\n throw new Error(t('image.serviceUnavailable'))\n })\n const hasVisible = streaming\n || data.status === 'interrupted'\n || data.blocks.some(block => block.kind !== 'tool-call')\n if (!hasVisible) return null\n const announcementText = data.blocks\n .filter(block => block.kind === 'text')\n .map(block => block.text)\n .join('\\n')\n\n const rendered: ReactNode[] = []\n const last = data.blocks.length - 1\n let lastFollow = -1\n for (let index = 0; index < data.blocks.length; index += 1) {\n const kind = data.blocks[index]?.kind\n if (kind === 'text' || kind === 'reasoning') lastFollow = index\n }\n for (let index = 0; index < data.blocks.length; index += 1) {\n const block = data.blocks[index]\n if (block === undefined) continue\n switch (block.kind) {\n case 'text':\n rendered.push(\n <AnimatedMarkdownText\n key={index}\n text={block.text}\n labels={markdownLabels}\n fileMentions={mentions}\n streaming={streaming}\n logarithmicFade={logarithmicFade && data.status !== 'interrupted'}\n motionReduced={reduced}\n ownFollow={!streaming && index === lastFollow}\n followSpeedCpsRef={index === lastFollow ? rootSpeedRef : undefined}\n followRevealedCharsRef={index === lastFollow ? rootRevealedCharsRef : undefined}\n followRevealScaleRef={index === lastFollow ? rootRevealScaleRef : undefined}\n onPredictiveChange={index === lastFollow ? updateTextPrediction : undefined}\n preset={preset}\n shouldHoldBack={shouldHoldBack}\n controlScroll={controlScroll}\n />,\n )\n break\n case 'reasoning':\n rendered.push(\n <FoldableReasoning key={index} hidden={reasoningHidden} reveal={revealProcess}>\n <AnimatedReasoning\n text={block.text}\n running={streaming && index === last}\n preset={preset}\n thinkAutoExpand={thinkAutoExpand}\n logarithmicFade={logarithmicFade && data.status !== 'interrupted'}\n motionReduced={reduced}\n shouldHoldBack={shouldHoldBack}\n followSpeedCpsRef={reasoningOwnsSpeed && index === last ? rootSpeedRef : undefined}\n followRevealScaleRef={reasoningOwnsSpeed && index === last ? rootRevealScaleRef : undefined}\n t={t}\n />\n </FoldableReasoning>,\n )\n break\n case 'image': {\n const start = index\n const group = [block]\n while (index + 1 < data.blocks.length) {\n const next = data.blocks[index + 1]\n if (next === undefined || next.kind !== 'image') break\n group.push(next)\n index += 1\n }\n rendered.push(\n <ImageGallery key={start} images={group} load={imageLoader} align=\"start\" labels={imageLabels(t)} />,\n )\n break\n }\n case 'tool-call':\n break\n case 'other':\n rendered.push(\n <JsonBlock\n key={index}\n label={t('message.unknownBlock')}\n payload={block.block}\n truncatedLabel={total => t('json.truncated', { total })}\n />,\n )\n break\n }\n }\n\n return (\n <div ref={guardRef} className={css.root} data-streaming={streaming || undefined}>\n <StreamAnnouncement text={announcementText} active={streaming && !reduced} />\n <FollowHost\n active={streaming && !reduced}\n speedCpsRef={rootSpeedRef}\n revealedCharsRef={rootRevealedCharsRef}\n revealScaleRef={rootRevealScaleRef}\n predictiveRef={rootPredictiveRef}\n controlScroll={controlScroll}\n >\n <div className={css.body}>\n {rendered}\n {data.status === 'interrupted' && <span className={css.stopped}>{t('message.stopped')}</span>}\n </div>\n </FollowHost>\n </div>\n )\n})\n","/**\n * Progressive text reveal for opaque Agent renderers.\n *\n * Slot renderers own arbitrary React trees, so the generic integration cannot\n * clone or classify their business components. This hook leaves that tree and\n * all of its event handlers in place, and only paces visible Text node data\n * while the row belongs to the live Agent turn. No clip, mask, overlay, or\n * duplicate accessibility tree is introduced.\n */\n\nimport { useLayoutEffect, type RefObject } from 'react'\nimport { computeAdaptiveQueueStep } from './useSmoothStreamContent.ts'\nimport { debugRuntime } from './debugRuntime.ts'\n\ninterface TextRevealRecord {\n chars: readonly string[]\n full: string\n shown: number\n}\n\n/** Last presented text per root, retained across follow lifecycle flips. */\nconst ledgerByRoot = new WeakMap<HTMLElement, Map<Text, TextRevealRecord>>()\n\nconst SKIP_TEXT_SELECTOR = [\n '[aria-hidden=\"true\"]',\n '[aria-live]',\n '[contenteditable=\"true\"]',\n 'script',\n 'style',\n 'textarea',\n].join(',')\n\nfunction revealable(node: Text, root: HTMLElement): boolean {\n if (node.data.trim() === '') return false\n const parent = node.parentElement\n return parent !== null\n && root.contains(parent)\n && parent.closest(SKIP_TEXT_SELECTOR) === null\n}\n\nfunction commonPrefix(left: readonly string[], right: readonly string[]): number {\n const limit = Math.min(left.length, right.length)\n let index = 0\n while (index < limit && left[index] === right[index]) index += 1\n return index\n}\n\n/**\n * Pace text inside a renderer whose React component is intentionally opaque.\n * Initial content is revealed only for a genuinely new row; later mutations\n * stay paced until `enabled` becomes false, at which point the full renderer\n * content is restored synchronously before paint.\n */\nexport function useProgressiveDomText(\n rootRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n revealInitial: boolean,\n speedCpsRef: { current: number },\n onSettled?: (() => void) | undefined,\n): void {\n useLayoutEffect(() => {\n const root = rootRef.current\n if (root === null || typeof document === 'undefined') return\n\n let records = ledgerByRoot.get(root)\n if (!enabled && records === undefined) return\n if (records === undefined) {\n records = new Map<Text, TextRevealRecord>()\n ledgerByRoot.set(root, records)\n }\n\n const forEachText = (from: Node, callback: (text: Text) => void): void => {\n if (from.nodeType === Node.TEXT_NODE) {\n callback(from as Text)\n return\n }\n const walker = document.createTreeWalker(from, NodeFilter.SHOW_TEXT)\n let current = walker.nextNode()\n while (current !== null) {\n callback(current as Text)\n current = walker.nextNode()\n }\n }\n\n const settle = (text: Text): void => {\n if (!revealable(text, root)) return\n const chars = [...text.data]\n records.set(text, { chars, full: text.data, shown: chars.length })\n }\n\n const snapshotVisible = (): void => {\n const current = new Set<Text>()\n forEachText(root, (text) => {\n if (!revealable(text, root)) return\n current.add(text)\n settle(text)\n })\n for (const text of records.keys()) {\n if (!current.has(text)) records.delete(text)\n }\n }\n\n if (!enabled) {\n snapshotVisible()\n const observer = typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver(snapshotVisible)\n observer?.observe(root, { childList: true, characterData: true, subtree: true })\n return () => {\n observer?.disconnect()\n }\n }\n\n const pending = new Set<Text>()\n const internalWrites = new WeakMap<Text, string>()\n let rafId = 0\n let lastFrame: number | null = null\n let debt = 0\n let stopped = false\n let announcedSettled = false\n const streamId = `dom-${Math.random().toString(36).slice(2)}`\n\n const announceSettled = (): void => {\n lastFrame = null\n debt = 0\n speedCpsRef.current = 35\n debugRuntime.reportStream(streamId, null)\n if (announcedSettled) return\n announcedSettled = true\n onSettled?.()\n }\n\n const write = (node: Text, value: string): void => {\n if (node.data === value) return\n internalWrites.set(node, value)\n node.data = value\n }\n\n const enqueue = (node: Text, full: string, preserve: TextRevealRecord | undefined): void => {\n if (!revealable(node, root)) return\n const chars = [...full]\n const preserved = preserve === undefined\n ? 0\n : Math.min(preserve.shown, commonPrefix(preserve.chars, chars))\n const record = { chars, full, shown: preserved }\n records.set(node, record)\n if (preserved < chars.length) {\n pending.add(node)\n announcedSettled = false\n } else {\n pending.delete(node)\n }\n write(node, chars.slice(0, preserved).join(''))\n }\n\n const visit = (from: Node, reveal: boolean): void => {\n forEachText(from, (text) => {\n if (!revealable(text, root)) return\n if (reveal) {\n enqueue(text, text.data, records.get(text))\n return\n }\n settle(text)\n })\n }\n\n const forget = (from: Node): void => {\n forEachText(from, (text) => {\n if (root.contains(text)) return\n records.delete(text)\n pending.delete(text)\n })\n }\n\n const scheduleFrame = (): void => {\n if (stopped || pending.size === 0 || rafId !== 0) return\n rafId = requestAnimationFrame(frame)\n }\n\n const frame = (now: number): void => {\n rafId = 0\n if (stopped) return\n if (pending.size === 0) {\n announceSettled()\n return\n }\n announcedSettled = false\n if (lastFrame === null) {\n lastFrame = now\n scheduleFrame()\n return\n }\n const elapsed = Math.max(0, now - lastFrame)\n lastFrame = now\n let backlog = 0\n for (const node of pending) {\n const record = records.get(node)\n if (record !== undefined) backlog += record.chars.length - record.shown\n }\n const step = computeAdaptiveQueueStep(backlog, elapsed, debt, 1, debugRuntime.activeTuning())\n debt = step.debt\n speedCpsRef.current = step.speedCps\n let remaining = step.revealChars\n for (const node of [...pending]) {\n if (remaining <= 0) break\n const record = records.get(node)\n if (record === undefined || !node.isConnected) {\n pending.delete(node)\n records.delete(node)\n continue\n }\n const amount = Math.min(remaining, record.chars.length - record.shown)\n const shown = record.shown + amount\n const next = { ...record, shown }\n records.set(node, next)\n write(node, next.chars.slice(0, shown).join(''))\n remaining -= amount\n if (shown >= next.chars.length) pending.delete(node)\n }\n let targetChars = 0\n let displayedChars = 0\n let nextBacklog = 0\n for (const [node, record] of records) {\n if (!node.isConnected) {\n records.delete(node)\n pending.delete(node)\n continue\n }\n targetChars += record.chars.length\n displayedChars += record.shown\n if (pending.has(node)) nextBacklog += record.chars.length - record.shown\n }\n debugRuntime.reportStream(streamId, {\n backlog: nextBacklog,\n speedCps: step.speedCps,\n targetChars,\n displayedChars,\n active: pending.size > 0,\n })\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n }\n\n visit(root, revealInitial)\n\n const observer = typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'characterData') {\n const node = mutation.target as Text\n const expected = internalWrites.get(node)\n if (expected === node.data) {\n internalWrites.delete(node)\n continue\n }\n enqueue(node, node.data, records.get(node))\n continue\n }\n for (const removed of mutation.removedNodes) forget(removed)\n for (const added of mutation.addedNodes) visit(added, true)\n }\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n })\n observer?.observe(root, { childList: true, characterData: true, subtree: true })\n if (pending.size === 0) announceSettled()\n else scheduleFrame()\n\n return () => {\n stopped = true\n cancelAnimationFrame(rafId)\n observer?.disconnect()\n for (const [node, record] of records) {\n const controlled = record.chars.slice(0, record.shown).join('')\n // React may have committed a terminal replacement in the same mutation\n // phase that disables this hook. Never overwrite that newer renderer\n // value with the previous controlled source during layout cleanup.\n if (node.isConnected && node.data === controlled) {\n write(node, record.full)\n }\n }\n pending.clear()\n speedCpsRef.current = 35\n debugRuntime.reportStream(streamId, null)\n }\n }, [enabled, onSettled, revealInitial, rootRef, speedCpsRef])\n}\n","import { createElement, useCallback, useEffect, useLayoutEffect, useRef, useState, type ComponentType } from 'react'\nimport { FollowHost } from './FollowHost.tsx'\nimport { useProgressiveDomText } from './useProgressiveDomText.ts'\nimport { hasRecentConversationFollow } from './teleprompterGlide.ts'\nimport entranceCss from './AgentRowEntrance.module.css'\n\n/** Props forwarded through a follow wrap; extra kit seats pass through. */\nexport type FollowWrapProps = {\n node?: unknown\n renderSlot?: unknown\n} & Record<string, unknown>\n\nfunction openAgentLocation(node: unknown): boolean {\n if (node === null || typeof node !== 'object' || !('location' in node)) return false\n const location = (node as { location: unknown }).location\n if (location === null || typeof location !== 'object' || !('kind' in location)) return false\n const kind = (location as { kind: unknown }).kind\n if (!('turn' in location)) return false\n const turn = (location as { turn: unknown }).turn\n if (turn === null || typeof turn !== 'object' || !('status' in turn)) return false\n if (kind === 'turn') return (turn as { status: unknown }).status === 'open'\n if (kind !== 'step' || !('step' in location)) return false\n const step = (location as { step: unknown }).step\n return step !== null\n && typeof step === 'object'\n && 'status' in step\n && (step as { status: unknown }).status === 'open'\n}\n\n/**\n * True while a Chat node has an explicitly unfinished lifecycle: an\n * assistant/workflow `status: 'running'` payload, a Tool root that has not\n * settled (`kind` absent), or a model-retry whose current attempt is still\n * `scheduled`. Open-but-otherwise-unknown rows are covered by\n * `isFollowableChatNode` below.\n * @param node - The Chat node's view `node` prop.\n * @returns whether this row should own conversation follow.\n */\nexport function isGrowingChatNode(node: unknown): boolean {\n if (node === null || typeof node !== 'object' || !('data' in node)) return false\n const data = (node as { data: unknown }).data\n if (data === null || typeof data !== 'object') return false\n if ('status' in data && (data as { status: unknown }).status === 'running') return true\n if (\n 'kind' in data\n && (data as { kind: unknown }).kind === 'command'\n && 'outcome' in data\n && (data as { outcome: unknown }).outcome === null\n ) return true\n if ('command' in data) {\n const command = (data as { command: unknown }).command\n if (\n command !== null\n && typeof command === 'object'\n && 'outcome' in command\n && (command as { outcome: unknown }).outcome === null\n ) return true\n }\n if ('root' in data) {\n const root = (data as { root: unknown }).root\n if (root !== null && typeof root === 'object' && !('kind' in root)) return true\n }\n if ('current' in data) {\n const current = (data as { current: unknown }).current\n if (\n current !== null\n && typeof current === 'object'\n && 'retryState' in current\n && (current as { retryState: unknown }).retryState === 'scheduled'\n ) return true\n }\n return false\n}\n\n/**\n * True for any Agent-owned Chat row in the currently open turn/step. This is\n * the extensibility boundary: a newly registered Context, Command, Tool, or\n * workflow renderer is followed without adding another kind-specific branch.\n */\nexport function isFollowableChatNode(node: unknown): boolean {\n return isGrowingChatNode(node) || openAgentLocation(node)\n}\n\n/**\n * True when a newly mounted Agent-owned row belongs to the current open\n * Turn/Step, or is itself an unresolved growing lifecycle.\n * @param node - The Chat node's view `node` prop.\n * @returns whether its initial height should enter through conversation follow.\n */\nexport function shouldAnimateChatNodeEntrance(node: unknown): boolean {\n return isFollowableChatNode(node)\n}\n\n/** Runtime-only fallback for unknown or terminal rows at the active flow tip. */\nfunction liveAgentTailMode(root: HTMLElement): 'turn' | 'handoff' | null {\n const port = root.closest<HTMLElement>('[data-conversation-scroll]')\n if (port === null) return null\n const row = root.closest<HTMLElement>('[data-chat-flow-key]')\n if (row !== null) {\n let sibling = row.nextElementSibling\n while (sibling !== null) {\n if (sibling instanceof HTMLElement && sibling.hasAttribute('data-chat-flow-key')) return null\n sibling = sibling.nextElementSibling\n }\n }\n const flow = root.closest<HTMLElement>('[data-chat-flow]')\n const hasTurnStatus = flow !== null && [...flow.children].some(child =>\n child instanceof HTMLElement\n && child.getAttribute('role') === 'status'\n && !child.hasAttribute('data-chat-flow-key'))\n if (hasTurnStatus) return 'turn'\n return hasRecentConversationFollow(port) ? 'handoff' : null\n}\n\n/**\n * Wrap a prior Agent Chat renderer so its entrance and later growth share\n * conversation follow. Presentation stays with the wrapped component; kit\n * seats (`renderSlot`, locale, inject) pass through unchanged.\n * @param Inner - The already-registered row component.\n * @returns A follow-hosted row.\n */\nexport function wrapFollowNodeView(\n Inner: ComponentType<FollowWrapProps>,\n useControlScroll?: () => boolean,\n) {\n return function TypewriterFollowNodeView(props: FollowWrapProps) {\n const controlScroll = useControlScroll?.() ?? true\n const speedCpsRef = useRef(35)\n const hostRef = useRef<HTMLDivElement>(null)\n const growing = isGrowingChatNode(props.node)\n const structurallyFollowable = isFollowableChatNode(props.node)\n const structuralRef = useRef(structurallyFollowable)\n const [runtimeFollowable, setRuntimeFollowable] = useState(false)\n const runtimePersistentRef = useRef(false)\n const runtimeHandledRef = useRef(false)\n const followable = structurallyFollowable || runtimeFollowable\n const revealInitialRef = useRef(true)\n const [entering, setEntering] = useState(() => shouldAnimateChatNodeEntrance(props.node))\n const [growthPulse, setGrowthPulse] = useState(false)\n const followableRef = useRef(false)\n const growingRef = useRef(growing)\n const entranceActiveRef = useRef(entering || growthPulse)\n const growthExtentRef = useRef<number | null>(null)\n const mountedRef = useRef(true)\n const pulseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n structuralRef.current = structurallyFollowable\n followableRef.current = followable\n growingRef.current = growing\n entranceActiveRef.current = entering || growthPulse\n const finishRuntimeReveal = useCallback(() => {\n if (structuralRef.current || runtimePersistentRef.current) return\n runtimeHandledRef.current = true\n setRuntimeFollowable(false)\n }, [])\n useProgressiveDomText(\n hostRef,\n followable,\n revealInitialRef.current,\n speedCpsRef,\n runtimeFollowable ? finishRuntimeReveal : undefined,\n )\n useLayoutEffect(() => {\n if (structurallyFollowable) return\n const root = hostRef.current\n if (root === null) return\n const mode = liveAgentTailMode(root)\n if (runtimeFollowable) {\n if (runtimePersistentRef.current && mode !== 'turn') {\n runtimePersistentRef.current = false\n runtimeHandledRef.current = true\n setRuntimeFollowable(false)\n }\n return\n }\n if (runtimeHandledRef.current || mode === null) return\n runtimePersistentRef.current = mode === 'turn'\n setRuntimeFollowable(true)\n setEntering(true)\n }, [runtimeFollowable, structurallyFollowable])\n const finishEntrance = useCallback(() => {\n growthExtentRef.current = null\n if (pulseTimerRef.current !== null) {\n clearTimeout(pulseTimerRef.current)\n pulseTimerRef.current = null\n }\n setEntering(false)\n setGrowthPulse(false)\n }, [])\n const onGrowth = useCallback((deltaPx: number) => {\n // A row with an explicit streaming lifecycle keeps its original owner\n // through completion. For every other Agent row, a pure layout increase\n // is enough evidence to glide it; renderer kind and payload shape are\n // intentionally irrelevant.\n if (\n !mountedRef.current\n || !followableRef.current\n || growingRef.current\n || entranceActiveRef.current\n ) return\n growthExtentRef.current = deltaPx\n setGrowthPulse(true)\n if (pulseTimerRef.current !== null) clearTimeout(pulseTimerRef.current)\n pulseTimerRef.current = setTimeout(() => {\n pulseTimerRef.current = null\n setGrowthPulse(false)\n }, 1200)\n }, [])\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n if (pulseTimerRef.current !== null) clearTimeout(pulseTimerRef.current)\n }\n }, [])\n return (\n <FollowHost\n active={growing}\n entrance={entering || growthPulse}\n onEntranceSettled={finishEntrance}\n onGrowth={followable ? onGrowth : undefined}\n entranceExtentRef={growthExtentRef}\n speedCpsRef={speedCpsRef}\n controlScroll={controlScroll}\n // Generic Agent rows reveal and spring their measured growth, but do\n // not continuously reserve space for a future Markdown line wrap.\n // Keeping that assistant-only prediction here creates an idle gap\n // above TurnStatus and a visible return when a short Tool row settles.\n predictive={false}\n hostRef={hostRef}\n className={entranceCss.surface}\n entranceActive={entering || growthPulse}\n >\n {createElement(Inner, props)}\n </FollowHost>\n )\n }\n}\n","/**\n * The smooth-stream plugin configuration card, rendered inside the Web\n * Settings \"plugin configuration\" page. Preferences are staged until the user\n * saves — the same shape as the Host-shipped cards, hand-drawn because the\n * Host cards' chrome is not exported for reuse.\n */\n\nimport { useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { IconChevronDownOutline14, IconRefreshOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { SmoothStreamCardFace } from './smooth-stream-card-controller.ts'\nimport css from './SmoothStreamCard.module.css'\n\n/** Props the renderer binds for the smooth-stream card. */\nexport type SmoothStreamCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'settings.smoothStream'>\n & InjectFace<SmoothStreamCardFace>\n\n/** Render the smooth-stream card independently of the core settings namespace allowlist. */\nexport function SmoothStreamCard(props: SmoothStreamCardProps) {\n const { t } = props\n const [open, setOpen] = useState(false)\n const state = props.useSmoothStreamCard(snapshot => snapshot)\n const blocked = !state.dirty || state.saving || state.status !== 'ready'\n const versionLabel = state.version === undefined\n ? null\n : t(state.installation === 'development' ? 'developmentVersion' : 'version')\n .replace('{version}', state.version)\n\n return (\n <li className={open ? `${css.card} ${css.cardOpen}` : css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {versionLabel === null ? null : <span className={css.version}>{versionLabel}</span>}\n {state.dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron} />\n </button>\n {open\n ? (\n <div className={css.body}>\n {state.status === 'loading' ? <p className={css.readOnly} role=\"status\">{t('loading')}</p> : null}\n {state.status === 'unavailable' ? (\n <div className={css.failure}>\n <p className={css.readOnly} role=\"status\">{t('unavailable')}</p>\n <button type=\"button\" className={css.discard} onClick={props.reload}>{t('retry')}</button>\n </div>\n ) : null}\n {state.status === 'ready' ? (\n <>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n <label className={css.field}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('enabled')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.enabled}\n disabled={!state.writable || state.saving}\n onChange={(event) => { props.edit({ enabled: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('enabledHint')}</span>\n </label>\n <label className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('controlScroll')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.controlScroll}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={(event) => { props.edit({ controlScroll: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('controlScrollHint')}</span>\n </label>\n <label className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('logarithmicFade')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.logarithmicFade}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={(event) => { props.edit({ logarithmicFade: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('logarithmicFadeHint')}</span>\n </label>\n {/* Motion preference is a radio group, so this row is a div:\n nesting the choice labels inside a field <label> would be\n illegal HTML (label within label) and browsers route the\n inner click away, so React never sees onChange. */}\n <div className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('motionPreference')}</span>\n </span>\n <span className={css.hint}>{t('motionPreferenceHint')}</span>\n <span className={css.choiceRow} role=\"radiogroup\" aria-label={t('motionPreference')}>\n {([\n ['auto', 'motionAuto', 'motionAutoHint'],\n ['force-smooth', 'motionForceSmooth', 'motionForceSmoothHint'],\n ['force-reduced', 'motionForceReduced', 'motionForceReducedHint'],\n ] as const).map(([value, label, hint]) => (\n <label key={value} className={css.choice} title={t(hint)}>\n <input\n type=\"radio\"\n className={css.choiceInput}\n name=\"smooth-stream-motion\"\n checked={state.motionPreference === value}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={() => { props.edit({ motionPreference: value }) }}\n />\n {t(label)}\n </label>\n ))}\n </span>\n </div>\n <label className={state.enabled ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('thinkAutoExpand')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.thinkAutoExpand}\n disabled={!state.writable || state.saving || !state.enabled}\n onChange={(event) => { props.edit({ thinkAutoExpand: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{t('thinkAutoExpandHint')}</span>\n </label>\n <label className={state.debugAvailable ? css.field : `${css.field} ${css.fieldDisabled}`}>\n <span className={css.fieldHead}>\n <span className={css.label}>{t('debugEnabled')}</span>\n <input\n type=\"checkbox\"\n className={css.toggle}\n checked={state.debugEnabled}\n disabled={!state.debugAvailable || !state.writable || state.saving}\n onChange={(event) => { props.edit({ debugEnabled: event.target.checked }) }}\n />\n </span>\n <span className={css.hint}>{state.debugAvailable ? t('debugEnabledHint') : t('debugUnavailable')}</span>\n </label>\n <div className={css.updateRow}>\n <span className={css.updateCopy}>\n <span className={css.label}>{t('updates')}</span>\n <span className={css.hint}>\n {state.restartRequired\n ? t('restartRequired')\n : state.installation === 'npm' ? t('updateHint')\n : state.installation === 'development' ? t('developmentBuild') : t('updateUnavailable')}\n </span>\n </span>\n <button\n type=\"button\"\n className={css.update}\n disabled={!state.canUpgrade || state.upgrading || state.restartRequired}\n title={state.canUpgrade ? undefined : t('updateUnavailable')}\n onClick={props.upgrade}\n >\n <span aria-hidden=\"true\"><IconRefreshOutline14 /></span>\n {t(state.upgrading ? 'updating' : 'update')}\n </button>\n </div>\n {state.upgradeFailed ? <p className={css.failed} role=\"status\">{t('updateFailed')}</p> : null}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{t('saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.discard}\n >\n {t('discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </button>\n </div>\n </>\n ) : null}\n </div>\n )\n : null}\n </li>\n )\n}\n","/** Staged form state for the plugin-owned smooth-stream settings RPC. */\n\nimport { createSnapshotStore, type SnapshotStore } from './clientStore.ts'\nimport {\n DEFAULT_STREAM_DEBUG_TUNING,\n DEFAULT_STREAM_SETTINGS,\n type StreamDebugTuning,\n type StreamMotionPreference,\n type StreamSettings,\n} from '../settings.ts'\nimport type {\n StreamDebugSettingsView,\n StreamInstallationKind,\n StreamSettingsView,\n} from '../settings-api.ts'\nimport type { SmoothStreamSettingsApi } from './smooth-stream-settings-api.ts'\n\n/** What the smooth-stream card renders. It remains visible while its Host RPC loads. */\nexport interface SmoothStreamCardState {\n status: 'loading' | 'ready' | 'unavailable'\n writable: boolean\n dirty: boolean\n saving: boolean\n failed: boolean\n enabled: boolean\n controlScroll: boolean\n motionPreference: StreamMotionPreference\n thinkAutoExpand: boolean\n logarithmicFade: boolean\n debugEnabled: boolean\n debugTuning: StreamDebugTuning\n debugAvailable: boolean\n version: string | undefined\n installation: StreamInstallationKind\n canUpgrade: boolean\n upgrading: boolean\n upgradeFailed: boolean\n restartRequired: boolean\n}\n\n/** The registration-side face injected into the settings slot renderer. */\nexport interface SmoothStreamCardFace {\n hooks: {\n smoothStreamCard: SnapshotStore<SmoothStreamCardState>\n }\n edit: (patch: Partial<StreamSettings>) => void\n save: () => void\n discard: () => void\n reload: () => void\n upgrade: () => void\n}\n\n/** Bridges the plugin's protected Host interface onto a staged settings form. */\nexport class SmoothStreamCardController {\n private readonly store = createSnapshotStore<SmoothStreamCardState>(this.projection())\n private loaded: StreamSettingsView | undefined\n private loadedDebug: StreamDebugSettingsView | undefined\n private stagedBase: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand' | 'logarithmicFade'> | undefined\n private stagedDebug: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'> | undefined\n private saving = false\n private failed = false\n private upgrading = false\n private upgradeFailed = false\n private restartRequired = false\n private loadGeneration = 0\n private loadStatus: 'loading' | 'ready' | 'unavailable' = 'loading'\n\n constructor(private readonly api: SmoothStreamSettingsApi) {}\n\n /** Begin the background read after the card has been registered. */\n start(): void {\n void this.load()\n }\n\n /** Ignore a late response after the surrounding optional services unload. */\n stop(): void {\n this.loadGeneration += 1\n }\n\n /** Current card snapshot, also consumed by the streaming preference cell. */\n getSnapshot(): SmoothStreamCardState {\n return this.store.getSnapshot()\n }\n\n /** Subscribe to state changes. */\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** Build the face consumed by the settings slot renderer. */\n inject(): SmoothStreamCardFace {\n return {\n hooks: { smoothStreamCard: this.store },\n edit: (patch) => {\n if (this.saving) return\n if (patch.enabled !== undefined || patch.controlScroll !== undefined || patch.motionPreference !== undefined || patch.thinkAutoExpand !== undefined || patch.logarithmicFade !== undefined) {\n this.stagedBase = {\n ...this.baseValues(),\n ...(patch.enabled === undefined ? {} : { enabled: patch.enabled }),\n ...(patch.controlScroll === undefined ? {} : { controlScroll: patch.controlScroll }),\n ...(patch.motionPreference === undefined ? {} : { motionPreference: patch.motionPreference }),\n ...(patch.thinkAutoExpand === undefined ? {} : { thinkAutoExpand: patch.thinkAutoExpand }),\n ...(patch.logarithmicFade === undefined ? {} : { logarithmicFade: patch.logarithmicFade }),\n }\n }\n if (this.loadedDebug !== undefined && (patch.debugEnabled !== undefined || patch.debugTuning !== undefined)) {\n this.stagedDebug = {\n ...this.debugValues(),\n ...(patch.debugEnabled === undefined ? {} : { debugEnabled: patch.debugEnabled }),\n ...(patch.debugTuning === undefined ? {} : { debugTuning: { ...this.debugValues().debugTuning, ...patch.debugTuning } }),\n }\n }\n this.failed = false\n this.publish()\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.stagedBase === undefined && this.stagedDebug === undefined && !this.failed) return\n this.stagedBase = undefined\n this.stagedDebug = undefined\n this.failed = false\n this.publish()\n },\n reload: () => { void this.load() },\n upgrade: () => { void this.upgrade() },\n }\n }\n\n private projection(): SmoothStreamCardState {\n return {\n status: this.loadStatus,\n writable: this.loaded?.writable ?? false,\n dirty: this.stagedBase !== undefined || this.stagedDebug !== undefined,\n saving: this.saving,\n failed: this.failed,\n ...this.baseValues(),\n ...this.debugValues(),\n debugAvailable: this.loadedDebug !== undefined,\n version: this.loaded?.version,\n installation: this.loaded?.installation ?? 'unmanaged',\n canUpgrade: this.loaded?.canUpgrade ?? false,\n upgrading: this.upgrading,\n upgradeFailed: this.upgradeFailed,\n restartRequired: this.restartRequired,\n }\n }\n\n private baseValues(): Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand' | 'logarithmicFade'> {\n return this.stagedBase ?? {\n enabled: this.loaded?.enabled ?? DEFAULT_STREAM_SETTINGS.enabled,\n controlScroll: this.loaded?.controlScroll ?? DEFAULT_STREAM_SETTINGS.controlScroll,\n motionPreference: this.loaded?.motionPreference ?? DEFAULT_STREAM_SETTINGS.motionPreference,\n thinkAutoExpand: this.loaded?.thinkAutoExpand ?? DEFAULT_STREAM_SETTINGS.thinkAutoExpand,\n logarithmicFade: this.loaded?.logarithmicFade ?? DEFAULT_STREAM_SETTINGS.logarithmicFade,\n }\n }\n\n private debugValues(): Pick<StreamSettings, 'debugEnabled' | 'debugTuning'> {\n return this.stagedDebug ?? {\n debugEnabled: this.loadedDebug?.debugEnabled ?? DEFAULT_STREAM_SETTINGS.debugEnabled,\n debugTuning: this.loadedDebug?.tuning ?? DEFAULT_STREAM_DEBUG_TUNING,\n }\n }\n\n /** Complete settings projection consumed by the live SettingsCell bridge. */\n values(): StreamSettings {\n return { ...this.baseValues(), ...this.debugValues() }\n }\n\n private async load(): Promise<void> {\n const generation = ++this.loadGeneration\n this.loadStatus = 'loading'\n this.loaded = undefined\n this.loadedDebug = undefined\n this.publish()\n try {\n const view = await this.api.read()\n if (generation !== this.loadGeneration) return\n this.loaded = view\n this.loadStatus = 'ready'\n this.publish()\n try {\n const debug = await this.api.readDebug()\n if (generation !== this.loadGeneration) return\n this.loadedDebug = debug\n } catch {\n if (generation !== this.loadGeneration) return\n // Older hosts expose the original settings endpoints only. Keep the\n // card usable and hide debug-only controls until the host is upgraded.\n this.loadedDebug = undefined\n }\n } catch {\n if (generation !== this.loadGeneration) return\n this.loaded = undefined\n this.loadedDebug = undefined\n this.loadStatus = 'unavailable'\n }\n this.publish()\n }\n\n private async save(): Promise<void> {\n if ((this.stagedBase === undefined && this.stagedDebug === undefined)\n || this.saving || this.loaded?.writable !== true) return\n const base = this.stagedBase\n const debug = this.stagedDebug\n this.saving = true\n this.failed = false\n this.publish()\n try {\n if (base !== undefined) {\n const combined = debug !== undefined && this.loadedDebug !== undefined\n this.loaded = await this.api.write(combined ? { ...base, ...debug } : base)\n this.stagedBase = undefined\n if (combined) {\n this.loadedDebug = {\n debugEnabled: debug.debugEnabled,\n tuning: { ...debug.debugTuning },\n }\n this.stagedDebug = undefined\n }\n }\n if (debug !== undefined && this.loadedDebug !== undefined && this.stagedDebug !== undefined) {\n this.loadedDebug = await this.api.writeDebug(debug)\n this.stagedDebug = undefined\n }\n } catch {\n this.failed = true\n }\n this.saving = false\n this.publish()\n }\n\n private async upgrade(): Promise<void> {\n if (this.loaded?.canUpgrade !== true || this.upgrading) return\n this.upgrading = true\n this.upgradeFailed = false\n this.restartRequired = false\n this.publish()\n try {\n const result = await this.api.upgrade()\n this.restartRequired = result.restartRequired\n } catch {\n this.upgradeFailed = true\n }\n this.upgrading = false\n this.publish()\n }\n\n private publish(): void {\n this.store.set(this.projection())\n }\n}\n","/** Shared wire vocabulary for the plugin-owned settings RPC channel. */\n\n/** Dedicated, loopback-only RPC channel registered by the Host half. */\nexport const STREAM_SETTINGS_RPC_CHANNEL = '/smooth-stream'\n\n/** Endpoints accepted by {@link STREAM_SETTINGS_RPC_CHANNEL}. */\nexport const STREAM_SETTINGS_RPC = {\n read: 'settings.read',\n write: 'settings.write',\n debugRead: 'debug.read',\n debugWrite: 'debug.write',\n upgrade: 'plugin.upgrade',\n} as const\n\n/** How the active profile supplied this plugin. */\nexport type StreamInstallationKind = 'npm' | 'development' | 'unmanaged'\n\n/** Redacted, plugin-owned configuration state returned to the browser. */\nexport interface StreamSettingsView {\n /** Version of the package currently running in the Host process. */\n version: string\n /** Source class of this package in the active profile. */\n installation: StreamInstallationKind\n /** Whether the Host settings provider permits a write. */\n writable: boolean\n /** Whether smooth-stream currently owns conversation rendering. */\n enabled: boolean\n /** Whether smooth-stream also owns conversation bottom-follow. */\n controlScroll: boolean\n /** How the reveal honors the OS reduced-motion preference. */\n motionPreference: import('./settings.ts').StreamMotionPreference\n /** Current resolved preference. */\n thinkAutoExpand: boolean\n /** Whether new answer/thinking text fades into its original color. */\n logarithmicFade: boolean\n /** Whether a fixed npm update command is safe to offer. */\n canUpgrade: boolean\n}\n\n/** Debug-only settings returned by the diagnostics RPC. */\nexport interface StreamDebugSettingsView {\n debugEnabled: boolean\n tuning: import('./settings.ts').StreamDebugTuning\n}\n\n/** Successful package update acknowledgement; loading the new code needs a restart. */\nexport interface StreamUpgradeView {\n restartRequired: true\n}\n","/** Browser adapter for the Host-owned smooth-stream settings RPC. */\n\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type { StreamDebugTuning, StreamSettings } from '../settings.ts'\nimport {\n STREAM_SETTINGS_RPC,\n STREAM_SETTINGS_RPC_CHANNEL,\n type StreamDebugSettingsView,\n type StreamSettingsView,\n type StreamUpgradeView,\n} from '../settings-api.ts'\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined\n}\n\nfunction settingsView(value: unknown): StreamSettingsView {\n const data = record(value)\n if (data === undefined\n || typeof data.version !== 'string'\n || !['npm', 'development', 'unmanaged'].includes(data.installation as string)\n || typeof data.writable !== 'boolean'\n || typeof data.enabled !== 'boolean'\n || typeof data.controlScroll !== 'boolean'\n || !['auto', 'force-smooth', 'force-reduced'].includes(data.motionPreference as string)\n || typeof data.thinkAutoExpand !== 'boolean'\n || (data.logarithmicFade !== undefined && typeof data.logarithmicFade !== 'boolean')\n || typeof data.canUpgrade !== 'boolean') {\n throw new Error('dsh-smooth-stream: malformed settings response')\n }\n return { ...data, logarithmicFade: data.logarithmicFade ?? true } as unknown as StreamSettingsView\n}\n\nfunction upgradeView(value: unknown): StreamUpgradeView {\n const data = record(value)\n if (data?.restartRequired !== true) throw new Error('dsh-smooth-stream: malformed update response')\n return { restartRequired: true }\n}\n\nfunction debugSettingsView(value: unknown): StreamDebugSettingsView {\n const data = record(value)\n const tuning = record(data?.tuning)\n if (data === undefined\n || typeof data.debugEnabled !== 'boolean'\n || tuning === undefined\n || typeof tuning.revealScale !== 'number'\n || typeof tuning.queuePressure !== 'number'\n || typeof tuning.maxRevealCps !== 'number'\n || typeof tuning.springStiffness !== 'number'\n || typeof tuning.springDamping !== 'number'\n || typeof tuning.springMass !== 'number'\n || typeof tuning.runwayPx !== 'number'\n || typeof tuning.reserveResponseMs !== 'number'\n || typeof tuning.backpressureMinScale !== 'number') {\n throw new Error('dsh-smooth-stream: malformed debug settings response')\n }\n return {\n debugEnabled: data.debugEnabled,\n tuning: tuning as unknown as StreamDebugTuning,\n }\n}\n\nfunction accepted(result: Awaited<ReturnType<ConnectionHandle['rpc']['call']>>): unknown {\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n}\n\n/** Narrow client contract consumed by the staged settings-card controller. */\nexport interface SmoothStreamSettingsApi {\n read(): Promise<StreamSettingsView>\n write(settings: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand' | 'logarithmicFade'> & Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>): Promise<StreamSettingsView>\n readDebug(): Promise<StreamDebugSettingsView>\n writeDebug(settings: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>): Promise<StreamDebugSettingsView>\n upgrade(): Promise<StreamUpgradeView>\n}\n\n/** Build the typed facade over the generic Connection RPC service. */\nexport function createSmoothStreamSettingsApi(connection: ConnectionHandle): SmoothStreamSettingsApi {\n return {\n async read(): Promise<StreamSettingsView> {\n return settingsView(accepted(await connection.rpc.call(STREAM_SETTINGS_RPC_CHANNEL, STREAM_SETTINGS_RPC.read, {})))\n },\n async write(settings: Pick<StreamSettings, 'enabled' | 'controlScroll' | 'motionPreference' | 'thinkAutoExpand' | 'logarithmicFade'> & Partial<Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>>): Promise<StreamSettingsView> {\n return settingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.write,\n {\n enabled: settings.enabled,\n controlScroll: settings.controlScroll,\n motionPreference: settings.motionPreference,\n thinkAutoExpand: settings.thinkAutoExpand,\n logarithmicFade: settings.logarithmicFade,\n ...(settings.debugEnabled === undefined || settings.debugTuning === undefined\n ? {}\n : { debugEnabled: settings.debugEnabled, debugTuning: settings.debugTuning }),\n },\n )))\n },\n async readDebug(): Promise<StreamDebugSettingsView> {\n return debugSettingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.debugRead,\n {},\n )))\n },\n async writeDebug(settings: Pick<StreamSettings, 'debugEnabled' | 'debugTuning'>): Promise<StreamDebugSettingsView> {\n return debugSettingsView(accepted(await connection.rpc.call(\n STREAM_SETTINGS_RPC_CHANNEL,\n STREAM_SETTINGS_RPC.debugWrite,\n { debugEnabled: settings.debugEnabled, tuning: settings.debugTuning },\n )))\n },\n async upgrade(): Promise<StreamUpgradeView> {\n return upgradeView(accepted(await connection.rpc.call(STREAM_SETTINGS_RPC_CHANNEL, STREAM_SETTINGS_RPC.upgrade, {})))\n },\n }\n}\n","import { useEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport {\n IconCloseOutline16,\n IconCodeOutline16,\n IconCopyOutline16,\n IconQuestionOutline14,\n IconRefreshOutline16,\n Tooltip,\n writeClipboard,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { StreamDebugTuning } from '../settings.ts'\nimport type { DebugPanelFace, DebugRuntimeState } from './debugRuntime.ts'\nimport type { NS } from './locales.ts'\nimport css from './DebugPanel.module.css'\n\nexport type DebugPanelProps =\n PropsRuntime<'conversation.session.header.utilities'>\n & PropsLocale<typeof NS>\n & InjectFace<DebugPanelFace>\n\ntype TuningKey = keyof StreamDebugTuning\n\ninterface TuningControl {\n key: TuningKey\n label: Parameters<DebugPanelProps['t']>[0]\n tip: Parameters<DebugPanelProps['t']>[0]\n min: number\n max: number\n step: number\n unit: string\n}\n\nconst REVEAL_CONTROLS: readonly TuningControl[] = [\n { key: 'revealScale', label: 'debugRevealMultiplier', tip: 'debugTipRevealMultiplier', min: 0.25, max: 2, step: 0.05, unit: 'x' },\n { key: 'queuePressure', label: 'debugQueuePressure', tip: 'debugTipQueuePressure', min: 0, max: 2, step: 0.05, unit: 'x' },\n { key: 'maxRevealCps', label: 'debugMaxReveal', tip: 'debugTipMaxReveal', min: 120, max: 1000, step: 10, unit: 'cps' },\n]\n\nconst FOLLOW_CONTROLS: readonly TuningControl[] = [\n { key: 'springStiffness', label: 'debugSpringStiffness', tip: 'debugTipSpringStiffness', min: 40, max: 320, step: 5, unit: '' },\n { key: 'springDamping', label: 'debugSpringDamping', tip: 'debugTipSpringDamping', min: 8, max: 80, step: 1, unit: '' },\n { key: 'springMass', label: 'debugSpringMass', tip: 'debugTipSpringMass', min: 0.5, max: 3, step: 0.05, unit: '' },\n { key: 'runwayPx', label: 'debugRunway', tip: 'debugTipRunway', min: 0, max: 120, step: 2, unit: 'px' },\n { key: 'reserveResponseMs', label: 'debugReserveResponse', tip: 'debugTipReserveResponse', min: 60, max: 600, step: 10, unit: 'ms' },\n { key: 'backpressureMinScale', label: 'debugBackpressureMin', tip: 'debugTipBackpressureMin', min: 0.25, max: 1, step: 0.05, unit: 'x' },\n]\n\nfunction fixed(value: number | null, digits = 1): string {\n return value === null || !Number.isFinite(value) ? '-' : value.toFixed(digits)\n}\n\nfunction Metric({ label, value, tone }: { label: string; value: string; tone?: 'good' | 'warn' | undefined }) {\n return (\n <div className={css.metric}>\n <dt>{label}</dt>\n <dd data-tone={tone}>{value}</dd>\n </div>\n )\n}\n\nfunction TuningField({\n control,\n state,\n edit,\n label,\n t,\n}: {\n control: TuningControl\n state: DebugRuntimeState\n edit: DebugPanelFace['edit']\n label: string\n t: DebugPanelProps['t']\n}) {\n const value = state.tuning[control.key]\n const labelId = `smooth-stream-debug-${control.key}`\n const update = (next: number) => {\n if (!Number.isFinite(next)) return\n const clamped = Math.min(control.max, Math.max(control.min, next))\n edit({ debugTuning: { ...state.tuning, [control.key]: clamped } })\n }\n return (\n <div className={css.control}>\n <span className={css.controlHead}>\n <span className={css.controlLabel}>\n <span id={labelId}>{label}</span>\n <Tooltip label={t(control.tip)} side=\"right\" maxWidth={300}>\n <button\n className={css.infoButton}\n type=\"button\"\n aria-label={label}\n title={t(control.tip)}\n >\n <IconQuestionOutline14 />\n </button>\n </Tooltip>\n </span>\n <span className={css.numberWrap}>\n <input\n className={css.number}\n type=\"number\"\n aria-labelledby={labelId}\n min={control.min}\n max={control.max}\n step={control.step}\n value={value}\n disabled={!state.writable}\n onChange={event => { update(event.currentTarget.valueAsNumber) }}\n />\n {control.unit === '' ? null : <span className={css.unit}>{control.unit}</span>}\n </span>\n </span>\n <input\n className={css.range}\n type=\"range\"\n aria-labelledby={labelId}\n min={control.min}\n max={control.max}\n step={control.step}\n value={value}\n disabled={!state.writable}\n onChange={event => { update(event.currentTarget.valueAsNumber) }}\n />\n </div>\n )\n}\n\nexport function DebugPanel(props: DebugPanelProps) {\n const { t } = props\n const state = props.useDebugRuntime(snapshot => snapshot)\n const [open, setOpen] = useState(true)\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n if (!copied) return\n const timer = setTimeout(() => { setCopied(false) }, 1400)\n return () => { clearTimeout(timer) }\n }, [copied])\n\n useEffect(() => {\n if (state.enabled) setOpen(true)\n }, [state.enabled])\n\n if (!state.available || !state.enabled || !open) return null\n const metrics = state.metrics\n const live = metrics.streamActive || metrics.followActive\n const progress = metrics.streamTargetChars <= 0\n ? '-'\n : `${String(metrics.streamDisplayedChars)} / ${String(metrics.streamTargetChars)}`\n const copyDiagnostics = async () => {\n const accepted = await writeClipboard(JSON.stringify({\n tuning: state.tuning,\n metrics: state.metrics,\n }, null, 2))\n if (accepted) setCopied(true)\n }\n\n const panel = !state.enabled || !open ? null : (\n <aside className={css.panel} role=\"complementary\" aria-label={t('debugPanelTitle')}>\n <header className={css.panelHeader}>\n <span className={live ? `${css.statusDot} ${css.statusLive}` : css.statusDot} aria-hidden />\n <span className={css.title}>{t('debugPanelTitle')}</span>\n <span className={css.state}>{t(live ? 'debugLive' : 'debugIdle')}</span>\n {state.dirty ? <span className={css.unsaved}>{t('debugUnsaved')}</span> : null}\n <button className={css.iconButton} type=\"button\" title={t('debugCopy')} aria-label={t('debugCopy')} onClick={() => { void copyDiagnostics() }}>\n <IconCopyOutline16 />\n </button>\n <button\n className={css.iconButton}\n type=\"button\"\n title={t('debugPanelClose')}\n aria-label={t('debugPanelClose')}\n disabled={!state.writable}\n onClick={() => {\n setOpen(false)\n props.edit({ debugEnabled: false })\n props.save()\n }}\n >\n <IconCloseOutline16 />\n </button>\n <span className={css.visuallyHidden} aria-live=\"polite\">{copied ? t('debugCopied') : ''}</span>\n </header>\n\n <div className={css.scrollArea}>\n <p className={css.guide}>{t('debugGuide')}</p>\n <section className={css.section} aria-labelledby=\"smooth-stream-live-heading\">\n <h2 id=\"smooth-stream-live-heading\">{t('debugSectionLive')}</h2>\n <dl className={css.metrics}>\n <Metric label={t('debugFps')} value={fixed(metrics.fps, 0)} tone={(metrics.fps ?? 60) < 45 ? 'warn' : 'good'} />\n <Metric label={t('debugFrameTime')} value={`${fixed(metrics.frameMs)} ms`} />\n <Metric label={t('debugBacklog')} value={String(metrics.streamBacklog)} tone={metrics.streamBacklog > 32 ? 'warn' : undefined} />\n <Metric label={t('debugRevealSpeed')} value={`${fixed(metrics.streamSpeedCps, 0)} cps`} />\n <Metric label={t('debugProgress')} value={progress} />\n <Metric label={t('debugFollowState')} value={t(metrics.followFollowing ? 'debugFollowing' : 'debugReleased')} />\n <Metric label={t('debugLag')} value={`${fixed(metrics.followLagPx)} px`} tone={metrics.followConstrained ? 'warn' : undefined} />\n <Metric label={t('debugVelocity')} value={`${fixed(metrics.followVelocityPxPerSec, 0)} px/s`} />\n <Metric label={t('debugReserve')} value={`${fixed(metrics.followReservePx)} px`} />\n <Metric label={t('debugCapacity')} value={`${fixed(metrics.followCapacityPx)} px`} />\n <Metric label={t('debugAppliedScale')} value={`${fixed(metrics.followRevealScale, 2)}x`} />\n </dl>\n </section>\n\n <section className={css.section} aria-labelledby=\"smooth-stream-reveal-heading\">\n <h2 id=\"smooth-stream-reveal-heading\">{t('debugSectionReveal')}</h2>\n {REVEAL_CONTROLS.map(control => (\n <TuningField key={control.key} control={control} state={state} edit={props.edit} label={t(control.label)} t={t} />\n ))}\n </section>\n\n <section className={css.section} aria-labelledby=\"smooth-stream-follow-heading\">\n <h2 id=\"smooth-stream-follow-heading\">{t('debugSectionFollow')}</h2>\n {FOLLOW_CONTROLS.map(control => (\n <TuningField key={control.key} control={control} state={state} edit={props.edit} label={t(control.label)} t={t} />\n ))}\n </section>\n </div>\n\n <footer className={css.footer}>\n <button className={css.secondaryButton} type=\"button\" disabled={!state.writable} onClick={props.reset}>\n <IconRefreshOutline16 />\n {t('debugReset')}\n </button>\n <span className={css.footerSpacer} />\n <button className={css.secondaryButton} type=\"button\" disabled={!state.writable || !state.dirty} onClick={props.discard}>{t('debugDiscard')}</button>\n <button className={css.primaryButton} type=\"button\" disabled={!state.writable || !state.dirty} onClick={props.save}>{t('debugSave')}</button>\n </footer>\n </aside>\n )\n\n return (\n <>\n <button\n type=\"button\"\n className={state.enabled && open ? `${css.trigger} ${css.triggerActive}` : css.trigger}\n aria-expanded={state.enabled && open}\n aria-label={t('debugPanelToggle')}\n title={t('debugPanelToggle')}\n onClick={() => { setOpen(current => !current) }}\n >\n <IconCodeOutline16 />\n </button>\n {typeof document === 'undefined' || panel === null ? null : createPortal(panel, document.body)}\n </>\n )\n}\n","/** Locale bundles for the smooth-stream plugin configuration card. */\n\n/** Dictionary namespace owned by this plugin's settings card. */\nexport const NS = 'settings.smoothStream'\n\n/** Locale keys the card renders. */\nexport type SmoothStreamLocaleKey =\n | 'title' | 'description'\n | 'enabled' | 'enabledHint'\n | 'controlScroll' | 'controlScrollHint'\n | 'motionPreference' | 'motionPreferenceHint'\n | 'motionAuto' | 'motionAutoHint'\n | 'motionForceSmooth' | 'motionForceSmoothHint'\n | 'motionForceReduced' | 'motionForceReducedHint'\n | 'thinkAutoExpand' | 'thinkAutoExpandHint'\n | 'logarithmicFade' | 'logarithmicFadeHint'\n | 'debugEnabled' | 'debugEnabledHint' | 'debugUnavailable'\n | 'debugPanelTitle' | 'debugPanelToggle' | 'debugPanelClose' | 'debugGuide'\n | 'debugLive' | 'debugIdle' | 'debugUnsaved'\n | 'debugSave' | 'debugDiscard' | 'debugReset' | 'debugCopy' | 'debugCopied'\n | 'debugSectionLive' | 'debugSectionReveal' | 'debugSectionFollow'\n | 'debugFps' | 'debugFrameTime' | 'debugBacklog' | 'debugRevealSpeed' | 'debugProgress'\n | 'debugFollowState' | 'debugFollowing' | 'debugReleased'\n | 'debugLag' | 'debugVelocity' | 'debugReserve' | 'debugCapacity' | 'debugAppliedScale'\n | 'debugRevealMultiplier' | 'debugQueuePressure' | 'debugMaxReveal'\n | 'debugSpringStiffness' | 'debugSpringDamping' | 'debugSpringMass'\n | 'debugRunway' | 'debugReserveResponse' | 'debugBackpressureMin'\n | 'debugTipRevealMultiplier' | 'debugTipQueuePressure' | 'debugTipMaxReveal'\n | 'debugTipSpringStiffness' | 'debugTipSpringDamping' | 'debugTipSpringMass'\n | 'debugTipRunway' | 'debugTipReserveResponse' | 'debugTipBackpressureMin'\n | 'readOnly' | 'loading' | 'unavailable' | 'retry'\n | 'version' | 'developmentVersion'\n | 'updates' | 'updateHint' | 'developmentBuild' | 'updateUnavailable'\n | 'update' | 'updating' | 'restartRequired' | 'updateFailed'\n | 'save' | 'saving' | 'discard' | 'unsaved' | 'saveFailed'\n\n/** English copy. */\nexport const en: Record<SmoothStreamLocaleKey, string> = {\n title: 'Smooth stream',\n description: 'How replies are revealed while they stream.',\n enabled: 'Enable smooth streaming',\n enabledHint: 'Let this plugin render and follow streaming replies. Turn off to use the built-in Harness renderer.',\n controlScroll: 'Take over scrolling',\n controlScrollHint: 'On by default; smooth-stream writes the conversation scroll position. Turn off to leave bottom-follow to Harness.',\n motionPreference: 'Motion',\n motionPreferenceHint: 'How streaming responds to the system reduce-motion setting.',\n motionAuto: 'Follow system',\n motionAutoHint: 'Reduced-motion systems get raw text (accessibility first).',\n motionForceSmooth: 'Always smooth',\n motionForceSmoothHint: 'Keep the smoothing engine even when the system asks for reduced motion.',\n motionForceReduced: 'Always raw',\n motionForceReducedHint: 'Render raw text even when the system allows motion.',\n thinkAutoExpand: 'Auto-expand thinking',\n logarithmicFade: 'Logarithmic fade',\n logarithmicFadeHint: 'Fade new answer and expanded thinking text into view. Follows the motion preference.',\n thinkAutoExpandHint: 'Open the thinking block while it streams. Turn off to keep it collapsed.',\n debugEnabled: 'Show render diagnostics',\n debugEnabledHint: 'Show live streaming and scroll metrics on the right side of the chat. Tune values there, then save them here.',\n debugUnavailable: 'Live diagnostics require a newer plugin Host.',\n debugPanelTitle: 'Render diagnostics',\n debugPanelToggle: 'Toggle render diagnostics',\n debugPanelClose: 'Hide diagnostics panel',\n debugGuide: 'Tune one value at a time while a reply streams. Keep FPS stable and backlog near zero. If text lags, raise the reveal multiplier, queue pressure, or maximum reveal; if a blank gap appears, reduce Predictive runway. Increase damping when the scroll feels springy. Save only after the behavior is stable; Reset restores the production defaults.',\n debugLive: 'Streaming',\n debugIdle: 'Idle',\n debugUnsaved: 'Unsaved tuning',\n debugSave: 'Save tuning',\n debugDiscard: 'Discard changes',\n debugReset: 'Reset tuning',\n debugCopy: 'Copy diagnostics',\n debugCopied: 'Copied',\n debugSectionLive: 'Live renderer',\n debugSectionReveal: 'Reveal tuning',\n debugSectionFollow: 'Scroll tuning',\n debugFps: 'FPS',\n debugFrameTime: 'Frame',\n debugBacklog: 'Backlog',\n debugRevealSpeed: 'Reveal',\n debugProgress: 'Progress',\n debugFollowState: 'Follow',\n debugFollowing: 'Pinned',\n debugReleased: 'Released',\n debugLag: 'Visual lag',\n debugVelocity: 'Velocity',\n debugReserve: 'Reserve',\n debugCapacity: 'Capacity',\n debugAppliedScale: 'Applied scale',\n debugRevealMultiplier: 'Reveal multiplier',\n debugQueuePressure: 'Queue pressure',\n debugMaxReveal: 'Maximum reveal',\n debugSpringStiffness: 'Spring stiffness',\n debugSpringDamping: 'Spring damping',\n debugSpringMass: 'Spring mass',\n debugRunway: 'Predictive runway',\n debugReserveResponse: 'Runway response',\n debugBackpressureMin: 'Minimum backpressure',\n debugTipRevealMultiplier: 'Overall reveal speed multiplier. Higher reveals text faster and clears backlog sooner, but can feel jumpy. Lower is smoother but takes longer to finish.',\n debugTipQueuePressure: 'Backlog acceleration strength. Higher catches up to a growing queue more aggressively; lower keeps speed steadier but may leave backlog.',\n debugTipMaxReveal: 'Hard cap for reveal speed in characters per second. Higher allows faster catch-up; lower limits bursts and keeps motion calmer.',\n debugTipSpringStiffness: 'Scroll spring strength. Higher closes visual lag faster but can feel sharp; lower feels softer but follows more slowly.',\n debugTipSpringDamping: 'Scroll energy damping. Higher suppresses overshoot and jitter but feels heavier; lower feels livelier but may oscillate.',\n debugTipSpringMass: 'Scroll inertia. Higher makes movement slower and heavier; lower makes it react faster but can feel abrupt.',\n debugTipRunway: 'Predictive blank space reserved while content grows. Higher absorbs growth and protects the bottom follow, but can create a larger visible gap; lower reduces blank space but leaves less room to absorb lag.',\n debugTipReserveResponse: 'How quickly the reserved runway opens or closes. Higher changes more gradually; lower reacts faster but can look abrupt.',\n debugTipBackpressureMin: 'Slowest reveal multiplier under scroll pressure. Higher keeps text moving but may increase visual lag; lower slows text more to protect smooth following.',\n readOnly: 'This deployment stores settings read-only.',\n loading: 'Loading plugin settings…',\n unavailable: 'Plugin settings are unavailable in this connection.',\n retry: 'Retry',\n version: 'Version {version}',\n developmentVersion: 'Development version {version}',\n updates: 'Updates',\n updateHint: 'Install the newest npm version, then restart Harness.',\n developmentBuild: 'Linked source; updates are managed in the checkout.',\n updateUnavailable: 'Updates are available only for an npm profile installation.',\n update: 'Update',\n updating: 'Updating…',\n restartRequired: 'Updated. Restart Harness to load the new version.',\n updateFailed: 'The package update failed; your current version is unchanged.',\n save: 'Save',\n saving: 'Saving…',\n discard: 'Discard',\n unsaved: 'Unsaved',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n}\n\n/** Simplified Chinese copy. */\nexport const zh: Record<SmoothStreamLocaleKey, string> = {\n title: '丝滑流式',\n description: '回复在流式输出时如何逐字展现。',\n enabled: '启用丝滑流式渲染',\n enabledHint: '由本插件渲染并跟随流式回复;关闭后使用 Harness 内置渲染。',\n controlScroll: '接管滚动',\n controlScrollHint: '默认开启,由丝滑流式写入会话滚动位置;关闭后贴底滚动交给 Harness。',\n motionPreference: '动效偏好',\n motionPreferenceHint: '流式渲染如何响应系统的「减少动态效果」设置。',\n motionAuto: '跟随系统',\n motionAutoHint: '系统开启减少动态效果时直接呈现原始文本(优先无障碍)。',\n motionForceSmooth: '始终平滑',\n motionForceSmoothHint: '即使系统要求减少动态效果,仍保持平滑流式渲染。',\n motionForceReduced: '始终原始',\n motionForceReducedHint: '即使系统允许动效,也直接呈现原始文本。',\n thinkAutoExpand: '自动展开思考',\n logarithmicFade: '对数淡入',\n logarithmicFadeHint: '让回答正文和展开的思考文字由淡变实,遵循动效偏好。',\n thinkAutoExpandHint: '思考块在流式时自动展开;关闭后保持折叠,可手动展开。',\n debugEnabled: '显示渲染调试面板',\n debugEnabledHint: '在聊天右侧显示流式渲染和滚动的实时参数,可在面板中调节并在这里保存。',\n debugUnavailable: '当前 Host 版本不支持实时调试,请先更新插件 Host。',\n debugPanelTitle: '渲染诊断',\n debugPanelToggle: '显示或隐藏渲染诊断',\n debugPanelClose: '收起诊断面板',\n debugGuide: '流式输出时一次只调一个参数,观察帧率、积压和视觉滞后。优先保持帧率稳定、积压接近 0;如果文字滞后,提高揭示倍率、队列压力或最大揭示速度;如果底部出现空白,降低“预测预留空间”。滚动有回弹或抖动时提高阻尼。确认表现稳定后再保存;“恢复默认参数”会回到生产默认值。',\n debugLive: '正在流式输出',\n debugIdle: '空闲',\n debugUnsaved: '参数尚未保存',\n debugSave: '保存参数',\n debugDiscard: '放弃修改',\n debugReset: '恢复默认参数',\n debugCopy: '复制诊断数据',\n debugCopied: '已复制',\n debugSectionLive: '实时渲染',\n debugSectionReveal: '流式参数',\n debugSectionFollow: '滚动参数',\n debugFps: '帧率',\n debugFrameTime: '帧耗时',\n debugBacklog: '积压字符',\n debugRevealSpeed: '揭示速度',\n debugProgress: '渲染进度',\n debugFollowState: '跟随状态',\n debugFollowing: '跟随底部',\n debugReleased: '用户已释放',\n debugLag: '视觉滞后',\n debugVelocity: '滚动速度',\n debugReserve: '预留空间',\n debugCapacity: '安全容量',\n debugAppliedScale: '实际倍率',\n debugRevealMultiplier: '揭示倍率',\n debugQueuePressure: '队列压力',\n debugMaxReveal: '最大揭示速度',\n debugSpringStiffness: '弹簧刚度',\n debugSpringDamping: '弹簧阻尼',\n debugSpringMass: '弹簧质量',\n debugRunway: '预测预留空间',\n debugReserveResponse: '预留响应时间',\n debugBackpressureMin: '最小背压倍率',\n debugTipRevealMultiplier: '整体文字揭示速度倍率。调大能更快清空积压,但可能显得跳;调小更平滑,但完成回复需要更久。',\n debugTipQueuePressure: '积压对加速的影响强度。调大能更积极追赶增长中的队列;调小速度更稳定,但积压可能持续。',\n debugTipMaxReveal: '每秒揭示字符数上限。调大允许更快追赶;调小限制突发速度,让动作更平稳。',\n debugTipSpringStiffness: '滚动弹簧刚度。调大更快收拢视觉滞后,但感觉更硬;调小更柔和,但跟随更慢。',\n debugTipSpringDamping: '滚动能量阻尼。调大能抑制过冲和抖动,但感觉更沉;调小更灵活,但可能回弹。',\n debugTipSpringMass: '滚动惯性。调大移动更慢更沉;调小反应更快,但可能显得突兀。',\n debugTipRunway: '内容增长时预留的预测空白。调大更能吸收增长、保护底部跟随,但可能产生更大的可见空区;调小能减少空白,但可吸收滞后的空间也更少。',\n debugTipReserveResponse: '预留空间打开或关闭的响应时间。调大变化更渐进;调小反应更快,但可能显得突变。',\n debugTipBackpressureMin: '滚动压力下允许的最低揭示倍率。调大文字仍会较快前进,但视觉滞后可能增加;调小会更积极减速,以保护跟随平滑。',\n readOnly: '本部署的设置为只读。',\n loading: '正在加载插件设置…',\n unavailable: '当前连接无法访问插件设置。',\n retry: '重试',\n version: '版本 {version}',\n developmentVersion: '开发版本 {version}',\n updates: '更新',\n updateHint: '安装最新 npm 版本后重启 Harness。',\n developmentBuild: '当前为本地链接版本,请在源码目录管理更新。',\n updateUnavailable: '只有 profile 使用 npm 包时才能更新。',\n update: '更新',\n updating: '更新中…',\n restartRequired: '已更新;重启 Harness 后加载新版本。',\n updateFailed: '包更新失败,当前版本未改变。',\n save: '保存',\n saving: '保存中…',\n discard: '放弃修改',\n unsaved: '未保存',\n saveFailed: '本部署没有接受这些值,已保留供你修改。',\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.smoothStream': SmoothStreamLocaleKey\n }\n}\n","import { createElement, useSyncExternalStore, type ComponentType } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: the connection Context merge and the plugins section's SlotMap\n// entry ('settings.plugin.item').\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { TypewriterAssistantNodeView } from './TypewriterAssistantNodeView.tsx'\nimport { wrapFollowNodeView, type FollowWrapProps } from './TypewriterToolNodeView.tsx'\nimport { SmoothStreamCard } from './SmoothStreamCard.tsx'\nimport { SmoothStreamCardController } from './smooth-stream-card-controller.ts'\nimport { createSmoothStreamSettingsApi } from './smooth-stream-settings-api.ts'\nimport { DebugPanel } from './DebugPanel.tsx'\nimport { debugRuntime } from './debugRuntime.ts'\nimport { NS as SETTINGS_NS, en, zh } from './locales.ts'\nimport { DEFAULT_STREAM_CONFIG, STREAM_BOOT_GLOBAL, type StreamConfig } from '../config.ts'\nimport { DEFAULT_STREAM_SETTINGS, STREAM_SETTINGS_NS, type StreamSettings } from '../settings.ts'\n\n/**\n * Cordis services required by the browser half. Only `slots` is load-bearing\n * for the stream itself; locale and Connection power the configuration card\n * and are wired through `ctx.inject` below so a deployment without them still\n * streams with defaults.\n */\nexport const inject = ['slots']\n\ntype AssistantProps = ChatNodeViewProps<'assistant-step'>\n\nconst STREAM_MODES: readonly string[] = ['typewriter', 'teleprompter']\nconst STREAM_PRESETS: readonly string[] = ['realtime', 'balanced', 'silky']\n\n/**\n * The assistant renderer owns its own character queue and conversation\n * follower, so wrapping it again would create two scroll owners. Human input\n * stays immediate; every Agent-owned output renderer goes through the same\n * generic follow boundary. This is deliberately keyed by the owner that\n * provides the renderer, not by individual tool names, so new Context,\n * Command, and Tool rows are covered automatically.\n */\nconst SKIP_WRAP = new Set(['assistant-step', 'user', 'steering', 'command-input'])\n\n/** React function/class or an exotic component such as memo/forwardRef/lazy. */\nfunction isWrappableComponent(value: unknown): value is ComponentType<FollowWrapProps> {\n return typeof value === 'function'\n || (value !== null && typeof value === 'object' && '$$typeof' in value)\n}\n\n/**\n * Read the Host-bridged boot config. The inline script is produced by this\n * plugin's Host half from a schema-validated value, so only the structural\n * guarantees that could break between the two halves are re-checked: the\n * global is absent when the client runs without its Host entry (defaults\n * apply), and any present-but-malformed value fails loudly instead of\n * rendering a half-configured view.\n * @returns The resolved configuration for the assistant node view.\n */\nfunction readBootConfig(): StreamConfig {\n const raw = (globalThis as Record<string, unknown>)[STREAM_BOOT_GLOBAL]\n if (raw === undefined) {\n console.info('[dsh-smooth-stream] no host config bridge; using defaults')\n return DEFAULT_STREAM_CONFIG\n }\n if (\n typeof raw !== 'object' || raw === null\n || !STREAM_MODES.includes((raw as StreamConfig).mode)\n || !STREAM_PRESETS.includes((raw as StreamConfig).preset)\n || typeof (raw as StreamConfig).revealCharsPerSec !== 'number'\n || typeof (raw as StreamConfig).scrollSpeedPxPerSec !== 'number'\n || typeof (raw as StreamConfig).maxScrollSpeedPxPerSec !== 'number'\n ) {\n throw new Error(`[dsh-smooth-stream] malformed ${STREAM_BOOT_GLOBAL} boot global: ${JSON.stringify(raw)}`)\n }\n return raw as StreamConfig\n}\n\n/**\n * Wrap every Agent-owned keyed Chat row except the assistant renderer in\n * place. A second\n * register with the same `children` table throws because the child slot is\n * already declared, and only the winning entry receives `renderSlot`;\n * swapping `entry.component` keeps the original children, locale, and inject\n * seats. `assistant-step` is replaced below so text and Think use the\n * typewriter reveal. The wrapper owns only the shared layout-growth/follow\n * lifecycle; the Harness keeps each renderer's controls, disclosures, and\n * cards intact.\n * @param ctx - Browser context carrying the slot registry.\n * @returns Restorer that puts the original components back.\n */\nfunction wrapAgentChatRows(\n ctx: ClientContext,\n useControlScroll: () => boolean,\n): () => void {\n const restores: Array<() => void> = []\n const wrapped = new WeakSet<object>()\n\n const wrapAll = (): void => {\n for (const entry of ctx.slots.entries('conversation.chat.node')) {\n const key = entry.options.key\n if (key === undefined || SKIP_WRAP.has(key)) continue\n const current = entry.component\n if (!isWrappableComponent(current) || wrapped.has(current)) continue\n const inner = current as ComponentType<FollowWrapProps>\n const next = wrapFollowNodeView(inner, useControlScroll)\n wrapped.add(next)\n entry.component = next\n restores.push(() => {\n if (entry.component === next) entry.component = inner\n })\n }\n }\n\n wrapAll()\n const off = ctx.on('slots/changed', (key: string) => {\n if (key === 'conversation.chat.node') wrapAll()\n })\n return () => {\n off()\n for (const restore of restores) restore()\n }\n}\n\n/**\n * A live settings cell shared by the renderer lifecycle and React views. It\n * starts on the shared defaults and follows the plugin-owned controller once\n * the optional settings services arrive.\n */\nclass SettingsCell {\n private readonly listeners = new Set<() => void>()\n private card: SmoothStreamCardController | undefined\n private value: StreamSettings = DEFAULT_STREAM_SETTINGS\n private pending = false\n\n /** Re-point the cell at the plugin-owned settings controller. */\n attach(card: SmoothStreamCardController): () => void {\n this.card = card\n this.refresh()\n const unsubscribe = card.subscribe(() => { this.refresh() })\n return () => {\n unsubscribe()\n if (this.card !== card) return\n this.card = undefined\n this.refresh()\n }\n }\n\n private read(): StreamSettings {\n const snapshot = this.card?.getSnapshot()\n if (snapshot === undefined || snapshot.status !== 'ready') return this.value\n return this.card?.values() ?? this.value\n }\n\n private refresh(): void {\n const next = this.read()\n const pending = this.card?.getSnapshot().status === 'loading'\n if (\n pending === this.pending\n && next.enabled === this.value.enabled\n && next.controlScroll === this.value.controlScroll\n && next.motionPreference === this.value.motionPreference\n && next.thinkAutoExpand === this.value.thinkAutoExpand\n && next.logarithmicFade === this.value.logarithmicFade\n && next.debugEnabled === this.value.debugEnabled\n && next.debugTuning === this.value.debugTuning\n ) return\n this.pending = pending\n this.value = next\n for (const listener of this.listeners) listener()\n }\n\n /** False while an available settings service is resolving its authority. */\n takeoverEnabled(): boolean {\n return !this.pending && this.value.enabled\n }\n\n readonly getSnapshot = (): StreamSettings => this.value\n\n readonly subscribe = (listener: () => void): () => void => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n}\n\n/**\n * Register the typewriter renderer after the conversation package declares the\n * keyed Chat node seat. A lower priority shadows the built-in assistant row;\n * every other keyed renderer is wrapped in place so Context, commands, Tool\n * cards, retries, and workflow runs share one extensible follow boundary. The\n * Host-bridged configuration\n * selects the render direction, smoothing preset, and glide speed; the\n * plugin-owned settings RPC supplies the live auto-expand preference when the\n * settings surface is composed.\n * @param ctx - Browser context carrying the shared slot registry.\n */\nexport function apply(ctx: ClientContext): void {\n const config = readBootConfig()\n const settings = new SettingsCell()\n const useControlScroll = (): boolean => useSyncExternalStore(\n settings.subscribe,\n () => settings.getSnapshot().controlScroll,\n () => settings.getSnapshot().controlScroll,\n )\n\n // The card talks to the plugin-owned loopback RPC, so the core settings\n // namespace allowlist cannot make it disappear. The stream still applies\n // with defaults when the optional Settings UI or Connection is absent.\n ctx.inject(['slots', 'locale', 'connection'], (settingsCtx) => {\n const card = new SmoothStreamCardController(\n // The shared Context augmentation also carries the Host-side Connection\n // shape. This browser entry runs after the client provider installs its\n // handle, so narrow through unknown to its client contract here.\n createSmoothStreamSettingsApi(settingsCtx.get('connection') as unknown as ConnectionHandle),\n )\n const detachSettings = settings.attach(card)\n const syncDebug = (): void => {\n const snapshot = card.getSnapshot()\n debugRuntime.syncSettings({\n available: snapshot.debugAvailable,\n enabled: snapshot.debugEnabled,\n writable: snapshot.writable && !snapshot.saving,\n dirty: snapshot.dirty,\n status: snapshot.status,\n tuning: snapshot.debugTuning,\n })\n }\n const detachBinding = debugRuntime.bindSettings({\n edit: patch => { card.inject().edit(patch) },\n save: () => { card.inject().save() },\n discard: () => { card.inject().discard() },\n })\n const detachDebug = card.subscribe(syncDebug)\n syncDebug()\n card.start()\n settingsCtx.effect(() => settingsCtx.locale.register(SETTINGS_NS, { zh, en }), 'dsh-smooth-stream: settings dictionaries')\n settingsCtx.slots.inject('settings.plugin.item', () => settingsCtx.slots.register({\n name: 'settings.plugin.item',\n id: 'smooth-stream',\n key: STREAM_SETTINGS_NS,\n order: 30,\n locale: SETTINGS_NS,\n inject: () => card.inject(),\n // Older Harness declares this slot as a list (`id`); newer Harness uses a\n // keyed slot filtered by the Host settings namespace (`key`).\n } as never, SmoothStreamCard))\n settingsCtx.slots.inject('conversation.session.header.utilities', () => settingsCtx.slots.register({\n name: 'conversation.session.header.utilities',\n id: 'smooth-stream-debug',\n order: 40,\n locale: SETTINGS_NS,\n inject: () => debugRuntime.panelFace(),\n }, DebugPanel))\n return () => {\n card.stop()\n detachDebug()\n detachSettings()\n detachBinding()\n }\n })\n\n const configured = function StreamConfiguredView(props: AssistantProps) {\n const preferences = useSyncExternalStore(\n settings.subscribe,\n settings.getSnapshot,\n settings.getSnapshot,\n )\n return createElement(TypewriterAssistantNodeView, {\n ...props,\n mode: config.mode,\n preset: config.preset,\n revealCharsPerSec: config.revealCharsPerSec,\n scrollSpeedPxPerSec: config.scrollSpeedPxPerSec,\n maxScrollSpeedPxPerSec: config.maxScrollSpeedPxPerSec,\n thinkAutoExpand: preferences.thinkAutoExpand,\n logarithmicFade: preferences.logarithmicFade,\n controlScroll: preferences.controlScroll,\n motionPreference: preferences.motionPreference,\n })\n }\n ctx.slots.inject('conversation.chat.node', () => {\n let releaseTakeover: (() => void) | undefined\n\n const syncTakeover = (): void => {\n if (!settings.takeoverEnabled()) {\n releaseTakeover?.()\n releaseTakeover = undefined\n return\n }\n if (releaseTakeover !== undefined) return\n const unwrap = wrapAgentChatRows(ctx, useControlScroll)\n const unshadow = ctx.slots.register({\n name: 'conversation.chat.node',\n key: 'assistant-step',\n priority: -100,\n locale: 'conversation',\n registrant: 'dsh-smooth-stream',\n }, configured)\n releaseTakeover = () => {\n // Stop observing slot changes before the shadow entry is removed.\n unwrap()\n unshadow()\n }\n }\n\n const unsubscribe = settings.subscribe(syncTakeover)\n syncTakeover()\n return () => {\n unsubscribe()\n releaseTakeover?.()\n }\n })\n}\n"],"mappings":"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"}