Skip to content

feat(gateway): approval queue tray in web UI sidebar - #2269

Closed
serrrfirat wants to merge 1 commit into
stagingfrom
feat/approval-queue
Closed

serrrfirat wants to merge 1 commit into
stagingfrom
feat/approval-queue

Conversation

@serrrfirat

Copy link
Copy Markdown
Collaborator

Summary

Adds a cross-thread approval queue tray to the web gateway sidebar that provides visibility into all pending tool approval gates — not just those in the active thread. Companion to #2267 (thread-scoped approvals), which fixes correctness but creates a visibility gap for background threads.

Problem

When a background routine, heartbeat, or non-active thread triggers a tool approval gate, the user has no way to see it without manually switching to that thread. Gates from inactive threads are silently blocked.

Solution

Three-layer non-intrusive design that adds zero UI surface when no gates are pending:

  • Sidebar tray — "Awaiting" section appears between the assistant-item and thread list only when gates exist. Each item shows tool name, source thread, description, and inline approve/always/deny buttons. Collapsible with a chevron.
  • Tab badge — Small amber pill on the Chat tab shows pending count; pulses 3x on new arrivals.
  • Thread gate dots — Pulsing amber dot on thread items that have pending approvals, visible even when the tray is collapsed.

Features

  • Batch approve-all / deny-all (visible on header hover)
  • Click tray item body to jump to its owning thread
  • Spring animations for item entry/exit
  • Full dark + light theme support
  • Touch-friendly targets on coarse pointer devices
  • Tray auto-hides when all gates are resolved

Screenshot

approval-queue-dark

Dark theme showing 3 pending gates across main, routine, and heartbeat threads

Changes

  • index.html — approval tray skeleton + tab badge span
  • style.css — ~270 lines of tray styles, animations, light theme overrides
  • app.js — pendingGates Map, tray CRUD functions, wired into existing approval_needed event + sendApprovalAction

Test plan

  • Open web gateway, trigger a tool approval → verify inline card AND tray item appear
  • Trigger approval in a background thread → verify tray shows it, active chat does not
  • Approve from tray → verify both tray item and inline card resolve
  • Approve from inline card → verify tray item also resolves
  • Resolve all gates → verify tray disappears, badge disappears
  • Toggle tray collapse/expand
  • Test batch approve-all / deny-all
  • Verify dark and light themes
  • Verify sidebar collapsed state hides tray

🤖 Generated with Claude Code

@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Screenshot (dark theme)

The approval queue tray sits in the sidebar between the assistant item and thread list. It shows pending gates from all threads with inline approve/deny controls.

Screenshot attached below:

@github-actions github-actions Bot added scope: agent Agent core (agent loop, router, scheduler) scope: channel Channel infrastructure scope: channel/cli TUI / CLI channel scope: channel/web Web gateway channel scope: channel/wasm WASM channel runtime scope: tool Tool infrastructure scope: tool/builtin Built-in tools scope: tool/wasm WASM tool sandbox scope: tool/builder Dynamic tool builder scope: db Database trait / abstraction scope: db/postgres PostgreSQL backend scope: db/libsql libSQL / Turso backend scope: llm LLM integration scope: orchestrator Container orchestrator scope: worker Container worker scope: config Configuration scope: setup Onboarding / setup scope: sandbox Docker sandbox scope: ci CI/CD workflows scope: docs Documentation size: XL 500+ changed lines risk: high Safety, secrets, auth, or critical infrastructure labels Apr 10, 2026
@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Screenshot

approval-queue-prototype

Note: For a live interactive preview, open the prototype file locally. The screenshot below shows the sidebar tray with 3 pending gates across main, routine, and heartbeat threads.

@github-actions github-actions Bot added the contributor: core 20+ merged PRs label Apr 10, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces several significant enhancements and fixes across the codebase. Key changes include: the addition of a 'DB MIGRATION' label and corresponding automation in the labeler and setup scripts; improvements to the Telegram channel's message splitting logic to correctly handle UTF-16 character limits; the implementation of a 'sendVoice' feature for Telegram; and the addition of cross-channel approval authorization logic, which includes a new database column 'source_channel' for conversations. Additionally, the pull request expands the GitHub tool's capabilities to include repository creation, code search, branch management, file operations, and release management, along with corresponding schema updates and regression tests. Configuration resolution logic has been updated to prioritize database settings over environment variables, and the sandbox worker now supports per-job MCP server filtering. I have no feedback to provide as all changes appear well-implemented and covered by tests.

Adds a cross-thread approval queue tray to the chat sidebar that shows
all pending tool approval gates across all threads, not just the active
one. This solves the visibility gap where background routines, heartbeat
threads, or other non-active threads could be silently blocked waiting
for approval.

Design:
- Sidebar tray appears between assistant-item and thread list only when
  gates are pending (zero UI cost when empty)
- Each item shows tool name, source thread, description, and inline
  approve/always/deny buttons
- Amber badge on the Chat tab pulses when new gates arrive
- Thread items show pulsing amber dot when they have pending approvals
- Batch approve-all / deny-all on header hover
- Collapsible tray with smooth spring animations
- Full light/dark theme support
- Touch-friendly targets on coarse pointer devices

Wired into both legacy approval_needed and v2 gate_required/gate_resolved
SSE events. sendApprovalAction now resolves using the gate's owning thread
rather than the currently-viewed thread.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@serrrfirat
serrrfirat force-pushed the feat/approval-queue branch from df2d4a4 to cedce8e Compare April 10, 2026 16:09
@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Closing: branch was rebased onto staging. Replaced by new PR.

@serrrfirat serrrfirat closed this Apr 10, 2026
@github-actions github-actions Bot added risk: low Changes to docs, tests, or low-risk modules and removed risk: high Safety, secrets, auth, or critical infrastructure labels Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules scope: agent Agent core (agent loop, router, scheduler) scope: channel/cli TUI / CLI channel scope: channel/wasm WASM channel runtime scope: channel/web Web gateway channel scope: channel Channel infrastructure scope: ci CI/CD workflows scope: config Configuration scope: db/libsql libSQL / Turso backend scope: db/postgres PostgreSQL backend scope: db Database trait / abstraction scope: docs Documentation scope: llm LLM integration scope: orchestrator Container orchestrator scope: sandbox Docker sandbox scope: setup Onboarding / setup scope: tool/builder Dynamic tool builder scope: tool/builtin Built-in tools scope: tool/wasm WASM tool sandbox scope: tool Tool infrastructure scope: worker Container worker size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant