- agent.py: add finally block to _process_chain that calls mark_dirty_all()
so non-active tabs see running:false without manual refresh
- message-queue-store.js: deduplicate allItems by id to prevent Alpine
'Duplicate key' errors during server-poll vs pending-item race
- chats-list.html: add data-chat-id attribute for DOM-based targeting
- index.js: move chatsStore/tasksStore updates before context-equality
check so background state changes always reach the sidebar