Changeset 0.30.1 (#200)

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit is contained in:
2026-03-18 13:22:15 +00:00
committed by xcaliber
parent 7d14e6a439
commit 8fee53e440
23 changed files with 1294 additions and 846 deletions

View File

@@ -298,7 +298,7 @@ async function selectChat(chatId) {
updateChatTokenCount();
// Notify surfaces and extensions about channel switch (v0.21.6)
Events.emit('chat.switched', { chatId, projectId: chat.projectId || null }, { localOnly: true });
sw.emit('chat.switched', { chatId, projectId: chat.projectId || null }, { localOnly: true });
// Update browser URL to reflect selected chat
window.history.replaceState(null, '', `${window.__BASE__ || ''}/chat/${chatId}`);
@@ -437,7 +437,7 @@ async function newChat() {
}
if (typeof KnowledgeUI !== 'undefined') KnowledgeUI.onChatChanged();
// Notify surfaces — no channel selected (v0.21.6)
Events.emit('chat.switched', { chatId: null, projectId: null }, { localOnly: true });
sw.emit('chat.switched', { chatId: null, projectId: null }, { localOnly: true });
window.history.replaceState(null, '', `${window.__BASE__ || ''}/`);
}
@@ -537,7 +537,7 @@ async function newGroupChat() {
App.chats.unshift(chat);
App.setActive(chat.id, 'group');
UI.renderChatList();
Events.emit('chat.created', { chatId: chat.id, projectId: null }, { localOnly: true });
sw.emit('chat.created', { chatId: chat.id, projectId: null }, { localOnly: true });
window.history.replaceState(null, '', `${window.__BASE__ || ''}/chat/${chat.id}`);
// Load the channel model roster (populated by participant auto-add)
@@ -708,7 +708,7 @@ async function sendMessage() {
App.setActive(chat.id, 'direct');
UI.renderChatList();
// Notify surfaces about new chat creation (v0.21.6)
Events.emit('chat.created', { chatId: chat.id, projectId: chat.projectId || null }, { localOnly: true });
sw.emit('chat.created', { chatId: chat.id, projectId: chat.projectId || null }, { localOnly: true });
window.history.replaceState(null, '', `${window.__BASE__ || ''}/chat/${chat.id}`);
} catch (e) { UI.toast('Failed to create chat: ' + e.message, 'error'); return; }
}
@@ -1120,7 +1120,7 @@ function _initChatListeners() {
// AI-to-AI chain: handle messages arriving via WebSocket (v0.23.0)
// When a persona @mentions another persona, the follow-up completion
// runs server-side and delivers the result via WS, not SSE.
Events.on('message.created', (payload) => {
sw.on('message.created', (payload) => {
if (!payload || !payload.channel_id) return;
// v0.23.2: If this channel isn't in our sidebar yet, fetch and add it
@@ -1170,7 +1170,7 @@ function _initChatListeners() {
});
// Typing indicators from persona chain activity
Events.on('typing.start', (payload) => {
sw.on('typing.start', (payload) => {
if (!payload || payload.channel_id !== App.activeId) return;
if (payload.participant_type !== 'persona') return;
@@ -1192,16 +1192,16 @@ function _initChatListeners() {
container.scrollTop = container.scrollHeight;
});
Events.on('typing.stop', (payload) => {
sw.on('typing.stop', (payload) => {
if (!payload || payload.channel_id !== App.activeId) return;
document.getElementById('typingIndicator')?.remove();
document.getElementById('userTypingIndicator')?.remove();
});
// v0.23.2: Human typing indicator from other participants
Events.on('typing.user', (payload) => {
sw.on('typing.user', (payload) => {
if (!payload || payload.channel_id !== App.activeId) return;
if (payload.user_id === API.user?.id) return; // ignore self
if (payload.user_id === sw.user?.id) return; // ignore self
// Show or refresh typing indicator
let typing = document.getElementById('userTypingIndicator');
@@ -1231,7 +1231,7 @@ function _initChatListeners() {
});
// v0.23.2: User @mention notification
Events.on('user.mentioned', (payload) => {
sw.on('user.mentioned', (payload) => {
if (!payload) return;
const channelId = payload.channel_id;
// Increment unread badge on the channel sidebar item
@@ -1246,14 +1246,14 @@ function _initChatListeners() {
});
// v0.23.2: Live presence updates for sidebar online dots
Events.on('user.presence', (payload) => {
sw.on('user.presence', (payload) => {
if (!payload || !payload.user_id) return;
App.presence[payload.user_id] = payload.status || 'offline';
if (typeof UI !== 'undefined') UI.renderChannelsSection();
});
// v0.27.0: Workflow stage advanced — refresh stage bar + auto-switch persona
Events.on('workflow.advanced', (payload) => {
sw.on('workflow.advanced', (payload) => {
if (!payload) return;
const ac = App.activeConversation;
if (ac && ac.id === payload.channel_id) {
@@ -1264,7 +1264,7 @@ function _initChatListeners() {
});
// v0.27.0: Workflow completed — refresh stage bar
Events.on('workflow.completed', (payload) => {
sw.on('workflow.completed', (payload) => {
if (!payload) return;
const ac = App.activeConversation;
if (ac && ac.id === payload.channel_id) {
@@ -1274,9 +1274,9 @@ function _initChatListeners() {
});
// v0.27.0: Workflow assigned — refresh queue + toast
Events.on('workflow.assigned', (payload) => {
sw.on('workflow.assigned', (payload) => {
if (!payload) return;
if (payload.assigned_to === (API.user && API.user.id)) {
if (payload.assigned_to === sw.user?.id) {
UI.toast('Workflow stage "' + (payload.stage_name || '?') + '" assigned to you', 'info');
}
if (typeof WorkflowQueue !== 'undefined') WorkflowQueue.refresh();