fix(app): make composer track clearance deterministic

Layout measurement excluded pill margin on some renderers, collapsing the intended gap above visible tracks. Keep the two-pill rail on one line and derive its complete tail clearance from shared geometry so chat switching and layout callbacks cannot change the result.
This commit is contained in:
Mohamed Boudra
2026-08-17 23:23:51 +02:00
parent a6a533bc6a
commit 1cc6712e51
8 changed files with 62 additions and 69 deletions
+5 -14
View File
@@ -256,10 +256,8 @@ export interface AgentStreamViewProps {
turnPresentation: TurnPresentation;
routeBottomAnchorRequest?: BottomAnchorRouteRequest | null;
isAuthoritativeHistoryReady?: boolean;
/** Measured transparent overlay at the bottom edge, rendered by the owning panel. */
bottomOverlayHeight?: number;
/** Visible space kept between the final content and that overlay. */
bottomOverlayClearance?: number;
/** Tail space required by a transparent overlay rendered at the bottom edge. */
bottomOverlayTailClearance?: number;
toast?: ToastApi | null;
onOpenWorkspaceFile?: (request: WorkspaceFileOpenRequest) => void;
readOnly?: boolean;
@@ -308,8 +306,7 @@ const AgentStreamViewComponent = forwardRef<AgentStreamViewHandle, AgentStreamVi
turnPresentation,
routeBottomAnchorRequest = null,
isAuthoritativeHistoryReady = true,
bottomOverlayHeight = 0,
bottomOverlayClearance = 0,
bottomOverlayTailClearance = 0,
toast,
onOpenWorkspaceFile,
readOnly = false,
@@ -966,8 +963,7 @@ const AgentStreamViewComponent = forwardRef<AgentStreamViewHandle, AgentStreamVi
const existingTailSpacing =
auxiliary.turnFooter && !auxiliary.pendingPermissions ? TURN_FOOTER_BOTTOM_SPACING : 0;
const bottomOverlayInset = resolveBottomOverlayTailInset({
overlayHeight: bottomOverlayHeight,
clearance: bottomOverlayClearance,
requiredTailClearance: bottomOverlayTailClearance,
existingTailSpacing,
});
return renderLiveAuxiliaryNode({
@@ -975,12 +971,7 @@ const AgentStreamViewComponent = forwardRef<AgentStreamViewHandle, AgentStreamVi
turnFooter: auxiliary.turnFooter,
bottomOverlayInset,
});
}, [
auxiliary.pendingPermissions,
auxiliary.turnFooter,
bottomOverlayClearance,
bottomOverlayHeight,
]);
}, [auxiliary.pendingPermissions, auxiliary.turnFooter, bottomOverlayTailClearance]);
const renderers = useMemo<StreamSegmentRenderers>(
() => ({