[FEATURE] Mods: one band row per plugin above the prompt, instead of one shared AbovePrompt chain
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Every function-hooks plugin that draws above the prompt hooks the same ui.render site, { component: 'AbovePrompt' }. There is one band and one chain: each hook receives what the plugins beneath it drew (await next(e)) and has to fit that into its own tree. A plugin can't pick its place in the chain; within the user tier the order follows load order.
The result is that every band plugin also does layout for every other band plugin. I run three: a cluster-status row (kube context, alerts, Argo CD drift), a backlog toggle button, and a GitLab merge request row (pipeline, conflicts, open threads, an auto-fix toggle). The MR row ended up squeezed into the right end of the cluster row, because the cluster plugin sits above it and lays out below inline. Fixing that took a change to the cluster plugin (flexWrap="wrap"), not to the MR plugin.
The coupling also fails hard: a layout prop such as width on a Box that wraps below makes the engine refuse the tree ("engine node under a Box with prop width") and draw its own empty band, so one plugin's mistake removes every plugin's row.
The desktop app itself doesn't work this way: its diff bar and its GitHub PR bar are separate bars stacked above the composer. Plugins get one shared row.
Proposed Solution
Give each plugin its own band row: for example a ui.render site keyed per plugin ({ component: 'AbovePrompt', requestId: <plugin> }), or a Band component opened like a Pane ($.ui.band({ id })). The engine stacks the rows in a stable order and draws each one independently, with no below to compose. A plugin that draws nothing takes no row. $.ui.status already works this way: one entry per plugin, laid out by the engine.
The shared AbovePrompt chain can stay for plugins that really do want to rewrite what's beneath them.
Alternative Solutions
- Compose by convention: every band mod uses
flexWrap="wrap"and full-width rows, and never sizes a Box aroundbelow. It works, but every mod author has to know the convention, and one mod that breaks it breaks the rest. $.ui.status: per plugin, but plain text with a plugin-name prefix and no colours, links or buttons, so it can't hold a PR/MR-style bar with a toggle.PromptHint: also a single shared line, and drawing a tree there replaces the engine's own hints.- A
Pane: per plugin, but a whole side panel is too heavy for a one-line status.
Priority
Medium - Would be very helpful
Feature Category
Developer tools/SDK
Use Case Example
- Install a mod that draws a cluster status in the band:
⎈ dev · 🔔 0 alerts · 🐙 synced. - Install a mod that draws the session's merge request:
!123 Fix login redirect · ✓ pipeline passed · ⚠ conflicts · 2 open threads. - Expected: two rows, like the desktop's diff and PR bars. Actual: the MR text is laid out inside the cluster row, because the cluster mod sits above it in the chain.
Additional Context
- Claude Code 2.1.293, desktop app 2.31226.0 (macOS).
- Related band issues: #99217 (AbovePrompt/Pane not drawn in Remote Control views), #99975 (hover delay in Desktop).