Skip to content

feat: add per-row extension points inside sidebar chat list x-for loop#1379

Merged
frdel merged 1 commit intoagent0ai:developmentfrom
Krashnicov:feat/sidebar-chat-item-extension-points
Apr 1, 2026
Merged

feat: add per-row extension points inside sidebar chat list x-for loop#1379
frdel merged 1 commit intoagent0ai:developmentfrom
Krashnicov:feat/sidebar-chat-item-extension-points

Conversation

@Krashnicov
Copy link
Copy Markdown
Contributor

Summary

Adds two new x-extension points inside the x-for loop in chats-list.html:

  • sidebar-chat-item-start — injected immediately after the opening chat-container div, before the chat label
  • sidebar-chat-item-end — injected after the close button, before the closing chat-container div

Motivation

Previously only sidebar-chats-list-start and sidebar-chats-list-end existed, both placed outside the x-for loop. Plugins that need to inject UI into individual chat rows had no framework-sanctioned way to do so.

This forced third-party plugins to work around the gap by:

  • Monkey-patching internal store methods (chatsStore.applyContexts, chatsStore.selectChat)
  • Using MutationObserver + index-based DOM scanning (contexts[index]) to locate rows
  • Calling imperative createElement / insertBefore instead of declarative Alpine bindings

All three patterns are fragile — they break silently when internal store method names or DOM structure changes.

Solution

With sidebar-chat-item-start / sidebar-chat-item-end inside the x-for loop, extension HTML has access to the reactive Alpine context object (including context.id, context.name, context.running, context.project, etc.) through the normal Alpine scope chain.

This enables purely declarative per-row plugin UI:

<!-- No DOM scanning, no monkey-patching needed -->
<span x-show="context.running" class="my-running-dot"></span>

Change

Minimal — 2 lines added to webui/components/sidebar/chats/chats-list.html. No logic changes, no style changes, no new dependencies.

Backwards Compatibility

Fully backwards compatible. Existing sidebar-chats-list-start and sidebar-chats-list-end extension points are unchanged. The new points are no-ops when no plugin registers extensions for them.

Adds sidebar-chat-item-start and sidebar-chat-item-end x-extension
points inside the x-for loop in chats-list.html.

Previously only sidebar-chats-list-start/end existed, both outside
the x-for loop. This forced plugins that need per-chat-row UI (e.g.
status indicators, labels, badges) to resort to MutationObserver +
index-based DOM scanning and monkey-patching internal store methods.

With these new extension points, plugins can inject content into
each chat row with access to the reactive Alpine context object
(context.id, context.name, context.running, context.project, etc.)
entirely through declarative Alpine bindings — no DOM scanning,
no method patching, no index arithmetic.
@frdel frdel merged commit d357c24 into agent0ai:development Apr 1, 2026
@Krashnicov Krashnicov deleted the feat/sidebar-chat-item-extension-points branch April 1, 2026 15:41
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.

2 participants