Uh oh!
There was an error while loading. Please reload this page.
Add Approval Navigation Banner and Related Functionality - #474
Conversation
🦋 Changeset detectedLatest commit: e50e635 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…al-flow-for-multiple-approvals-composer-it
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
kumarsks619
commented
Aug 27, 2026
should add some padding to the highlighting box @govindavashishtha |
…ability during flashing
…al-flow-for-multiple-approvals-composer-it
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e50e635. Configure here.
| flashingApprovalId, | ||
| }), | ||
| [registerTarget, registerExpand, focus, flashingApprovalId], | ||
| ); |
There was a problem hiding this comment.
Focus context churns on stream
Medium Severity
ApprovalFocusProvider reads thread.messages into the focus callback, so the context value is recreated on every message update. Every ToolCallCard subscribes via useOptionalApprovalFocus, so streaming tokens re-render all tool cards — including expanded Monaco/markdown bodies — even when no approval is pending.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e50e635. Configure here.
| } | ||
| } | ||
| }, MOUNT_RETRY_MS); | ||
| }, |
There was a problem hiding this comment.
Stale ancestors block nested focus
Medium Severity
focus snapshots subagent ancestors once from messages at call time, and useApprovalNav then records focusedIdRef so the same id is never focused again. If useTrueFoundryApprovals updates before the thread tree contains the nested tool, retries expand nothing, and a later message update does not re-focus.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e50e635. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
| aria-label={`${label}. Click to go to approval ${String(current)} of ${String(count)}.`} | ||
| onClick={onFocusCurrent} | ||
| className={cn( | ||
| // Figma light 6747:4232 / dark 6748:1977 — top border only; sides & bottom open into the composer. |
There was a problem hiding this comment.
can remove comment, not useful
| onFocusCurrent, | ||
| className, | ||
| }: ApprovalNavBannerProps) { | ||
| // Figma Agents node 6747:4232 — "N tools need your input" |
| import { cn } from './lib/cn.js'; | ||
| export type ApprovalNavBannerProps = { | ||
| count: number; |
There was a problem hiding this comment.
| count: number; | |
| total: number; |
| // Pending-approval cards keep top/right padding always so flash doesn't jump the layout. | ||
| // Left stays unpadded so the step rail stays aligned with siblings. |
| toolName?: string; | ||
| argsText?: string; | ||
| /** Kept for call-site compat; flash/scroll target is `ToolCallCard`. */ | ||
| approvalId?: string; |
There was a problem hiding this comment.
couldn't get it why we need this prop if not being used
| export function useRegisterApprovalTarget(approvalId: string | undefined, getElement: () => HTMLElement | null): void { | ||
| const api = useOptionalApprovalFocus(); | ||
| const getElementRef = useRef(getElement); | ||
| getElementRef.current = getElement; |
There was a problem hiding this comment.
shouldn't be part of render cycle, should do it a useeffect
| export function useRegisterApprovalExpand(toolCallId: string, expand: () => void): void { | ||
| const api = useOptionalApprovalFocus(); | ||
| const expandRef = useRef(expand); | ||
| expandRef.current = expand; |
| } | ||
| /** Registers a sub-agent expand callback. No-ops outside the provider (tests). */ | ||
| export function useRegisterApprovalExpand(toolCallId: string, expand: () => void): void { |
| } | ||
| /** Registers a DOM target for scroll/flash. No-ops outside the provider (tests). */ | ||
| export function useRegisterApprovalTarget(approvalId: string | undefined, getElement: () => HTMLElement | null): void { |
There was a problem hiding this comment.
want to understand how it is working, whats the flow here


Summary
Adds a composer approval navigation banner for threads with one or more pending tool approvals, so users can find, cycle through, and re-focus approvals — including nested subagent tools — without losing context after scrolling.
ApprovalNavBannerslot +ApprovalNavContainer, wired above the composer when approvals are pendingN tools need your input),(current/total), and prev/next chevrons (no wrap)ApprovalFocusProviderregisters approval DOM targets / subagent expand callbacks and handles focus + flash@truefoundry/trueforge-uiminorScreen.Recording.2026-08-27.at.7.11.08.PM.mov
Test plan
ApprovalNavBannerpnpm --filter @truefoundry/trueforge-ui testpassesNote
Medium Risk
Changes composer pause ordering and thread-wide focus/scroll behavior for human-in-the-loop tool approvals, including nested sub-agent DOM timing with retry logic.
Overview
Adds an approval navigation banner above the composer when one or more tool approvals are pending, with an overridable
ApprovalNavBannerslot andApprovalNavContainer.While approvals are open,
useComposerPauseViewreturns{ kind: 'approval' }(below MCP/custom/ask-user): the banner shows “N tools need your input”, a (current/total) counter, and prev/next chevrons that do not wrap; the message input stays disabled and visually flush with the banner.useApprovalNavdrives selection fromuseTrueFoundryApprovals, auto-focuses the first item, and keeps the same list index as items are resolved.ApprovalFocusProvider(on the thread) registers scroll targets onToolCallCardviaapprovalId, expands nestedcreate_sub_agentancestors (findSubAgentAncestorsForApproval), smooth-scrolls, and applies a short flash highlight. Tool call rendering passesapprovalIdthrough sandbox/MCP/generic paths and registers sub-agent expand callbacks.Theme adds approval-banner tokens and
aui-approval-flashanimation; public exports includeApprovalNavBanner,useApprovalNav, anduseTrueFoundryApprovals.Reviewed by Cursor Bugbot for commit e50e635. Bugbot is set up for automated code reviews on this repo. Configure here.