Skip to content

Inline pending approvals into composer header and actions - #184

Merged
juliusmarminge merged 2 commits into
mainfrom
t3code/composer-inline-approvals-header
Mar 6, 2026
Merged

juliusmarminge merged 2 commits into
mainfrom
t3code/composer-inline-approvals-header

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Mar 6, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Move pending approval UI from a separate alert panel into the composer header for a more focused approval flow.
  • Prioritize approval state in composer rendering by showing only the active approval, disabling prompt input, and hiding command/image affordances while approval is unresolved.
  • Add dedicated composer approval components for header context and action buttons, including queue position (1/N) when multiple approvals are pending.
  • Keep existing plan/user-input composer flows intact while making approval handling the top-priority composer state.

Testing

  • Not run (PR content generated from provided diff/commits only).

Note

Medium Risk
Changes the chat composer’s state/priority logic and approval-response UI, which could regress send/compose behavior or block interactions if the approval state is misdetected. No backend/API or security-sensitive logic changes.

Overview
Pending approvals are now handled inline in the composer instead of a separate banner/panel. The UI shows only the active approval (with 1/N position when multiple are queued) in a new composer header and moves approval decision buttons into the composer’s bottom toolbar.

While an approval is pending, the composer input is disabled/cleared and its placeholder shows the approval detail, and the command menu + image attachments UI are suppressed to keep the flow focused on resolving the approval.

Written by Cursor Bugbot for commit 005dd9a. This will update automatically on new commits. Configure here.

Note

Inline pending approvals into the chat composer by disabling ChatView input, showing a header, and replacing the toolbar with approval action buttons

Introduce approval-aware state in ChatView to render an inline header and compact actions during an active approval, hide command menu and images, disable and clear the prompt input with an approval placeholder, and remove the top-of-thread approvals panel. Add ComposerPendingApprovalPanel and ComposerPendingApprovalActions. Remove PendingApprovalsPanel. Changes center on ChatView.tsx.

📍Where to Start

Start with the approval gating and composer branching in ChatView within ChatView.tsx, focusing on how activePendingApproval and isComposerApprovalState control rendering and actions.

Macroscope summarized 005dd9a.

juliusmarminge and others added 2 commits March 6, 2026 08:59
Co-authored-by: codex <codex@users.noreply.github.com>
- Treat pending approvals as a dedicated composer state
- Disable prompt input and hide command menu/image chips while approval is active
- Move approval decision buttons into footer actions and simplify the header panel
@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ea578244-adbd-46e4-b711-d8d6e71908fe

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch t3code/composer-inline-approvals-header

Comment @coderabbitai help to get the list of available commands and usage tips.

@juliusmarminge
juliusmarminge merged commit d58ff5d into main Mar 6, 2026
4 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/composer-inline-approvals-header branch March 6, 2026 17:03

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

{/* Error banner */}
<ProviderHealthBanner status={activeProviderStatus} />
<ThreadErrorBanner error={activeThread.error} />
<PendingApprovalsPanel

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing approval-state guard in send and key handlers

Medium Severity

The onComposerCommandKey handler calls onSend() when Enter is pressed (line 3222) without checking isComposerApprovalState. The onSend handler itself also has no early-return for approval state. If the Lexical editor dispatches key commands while disabled (Lexical's setEditable(false) still processes registered commands), pressing Enter during approval state could trigger onSend, which would proceed with the stale prompt value — potentially submitting a plan follow-up or sending a message while the user intended only to resolve an approval.

Additional Locations (1)

Fix in Cursor Fix in Web

aorwall added a commit to aorwall/t3code that referenced this pull request Sep 21, 2026
Merges `pingdotgg/t3code` into the fork: `7445aa733..5781b52`, 41
commits.

191 files landed (`git diff --stat HEAD^1 HEAD`) against 192 in the
upstream
range; the gap of one is `apps/server/src/cli/pair.ts`, a deliberate
fork
deletion that pingdotgg#12657 modified — kept deleted. Fork delta 786 files.

Four conflicts, each resolved with the verdict `preflight.mjs` printed.
The one
worth reading is `ProjectScriptsControl.tsx` / `chat/ChatHeader.tsx`:
upstream
extracted a shared `scriptItems` const and moved the header's controls
into a
`headerActions` fragment, so the fork's task-scoped-script deltas had no
anchor
left and were re-applied onto upstream's structure rather than kept as
the
fork's copy of it. Details in `docs/fork/upstream-merge-log.md`.

`verify.mjs`: all 10 checks pass. Two failures were found and fixed here
— the
`dataUpdatedAt` field pingdotgg#12545 added to `EnvironmentQueryView`, which the
fork's
two sandbox hooks build by hand; and a latent bug in `features.test.ts`
where
`import.meta.glob` keys a sibling as `./name.ts`, so every inventory
delta guard
on a file in `apps/web/src/fork/` had been silently unchecked since the
guards
landed.

The first commit on this branch, `docs(fork): stack an upstream merge on
an open
merge PR`, is the instruction change asked for separately: a run that
finds a
merge PR still open now branches from its head and opens its PR against
that
branch instead of stopping.

## Usable as-is

- Undo for settle, snooze and archive, with a `mod+z` shortcut (pingdotgg#12848),
and
  undo after unpin (`6b0a04ade`).
- Composer fixes: control visibility, Escape handling, paste, inline
chips
  (`6cc7f7006`, `a4bc7deb9`, `dca84efb5`, `c789cd174`).
- Branch-picker fixes (`67285e4b8`, `7ade2d2c6`) and the narrow
chat-header
  layout (`c14f6015b`).
- Pull request link hover preview (`933492470`) and sidebar PR status
reuse
(pingdotgg#12545), diff whitespace settings (`4a560b4e4`), mobile diff word wrap
  (`f6cc6bc7e`).
- Sidebar shelf motion (`f391b88c3`), notification icons (`30e3649c3`),
the
  `MiddleTruncate` component (`f7efb5354`), Codex citation backslashes
  (`2efb8178d`).
- The client half of the raised attachment limits (pingdotgg#12620) — the
contract now
  allows 100 attachments per message.

## Unsupported in Moatless / needs implementation

- **The device hub**, seven commits of it (pingdotgg#12819, pingdotgg#12818, pingdotgg#12817,
pingdotgg#12816,
  pingdotgg#12807, pingdotgg#12809, pingdotgg#12639) across `apps/server/src/device/*`,
`apps/web/src/components/device/*` and
`packages/contracts/src/device.ts`.
  Already held by `FEATURES.deviceHub: false` and the existing
  `UnsupportedMethodError` entries for the `device.*` methods; the new
`DeviceHostUpdates.tsx` needed no gate of its own, since all three of
its call
  sites are already behind that flag.
- **Worktree-mode-only UI** (`a6cb1dd20`, `584450a1f`) — behind
  `FEATURES.worktreeSelection`.
- **Connections copy** (`ead1dee22`) — behind `FEATURES.connections`.
- **Pull request detail surface** (`a9ab9049b`, `411da2a73`,
`6a699f0f2`) —
  behind `FEATURES.pullRequestSurface`; Moatless serves only
  `pullRequests.summary`.
- **Electron-only preview recording** (`55c24273a`, desktop half) — the
fork
  ships no desktop build.

## Backend behavior to consider reproducing in Moatless

New entries in `docs/fork/gaps.md`, 2026-09-21 group:

- **Attachment and image payload budget** (pingdotgg#12620). The per-message cap
goes
from 8 attachments to 100, with a new 80 MiB aggregate image budget
beside the
existing 10 MiB per-image one, derived in
`getProviderAttachmentLimitError`
and applied twice by the server — before decoding, and again per decoded
data
URL, so a client that under-reports `sizeBytes` is still caught.
Moatless
  normalizes turns itself and has the raised count already; without the
aggregate check, 100 images at the per-image limit is a gigabyte of
base64
  bound for a sandbox.
- **Idempotent host teardown and tool reclaim** (pingdotgg#12807, pingdotgg#12819).
Shutting down
an already-stopped simulator is treated as success, and obsolete managed
tool
versions are pruned while current, previous, active and half-installed
ones
are kept. Moot while `FEATURES.deviceHub` is off, recorded because
Moatless
  tears down sandboxes and installs managed tooling on its own schedule.
- **Per-signal OTLP export settings** (pingdotgg#12657), folded into the existing
pingdotgg#12493
bullet: traces, metrics and logs each carry their own endpoint and
headers, so
one signal can go elsewhere or be turned off without the other two
following.

Contracts: `unsupported-methods.mjs` reports ADD 0 and DROP 0, so no
union entry
in `packages/contracts/src/rpc.ts` changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
Moatless task:
https://moatless.soaplabstest.com/tasks/4ed6d32e-0278-4fff-9a6e-923ded2b30fe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant