Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/sim/app/workspace/[workspaceId]/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ export function Home({ chatId }: HomeProps = {}) {
[sendMessage]
)

useEffect(() => {
const handler = (e: Event) => {
const message = (e as CustomEvent<{ message: string }>).detail?.message
if (message) sendMessage(message)
}
window.addEventListener('mothership-send-message', handler)
return () => window.removeEventListener('mothership-send-message', handler)
}, [sendMessage])

const handleContextAdd = useCallback(
(context: ChatContext) => {
let resourceType: MothershipResourceType | null = null
Expand Down
16 changes: 16 additions & 0 deletions apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,22 @@ export function useChat(
) {
clientExecutionStarted.add(id)
const args = data?.arguments ?? data?.input ?? {}
const targetWorkflowId =
typeof (args as Record<string, unknown>).workflowId === 'string'
? ((args as Record<string, unknown>).workflowId as string)
: useWorkflowRegistry.getState().activeWorkflowId
if (targetWorkflowId) {
const meta = useWorkflowRegistry.getState().workflows[targetWorkflowId]
const wasAdded = addResource({
type: 'workflow',
id: targetWorkflowId,
title: meta?.name ?? 'Workflow',
})
if (!wasAdded && activeResourceIdRef.current !== targetWorkflowId) {
setActiveResourceId(targetWorkflowId)
}
onResourceEventRef.current?.()
}
executeRunToolOnClient(id, name, args as Record<string, unknown>)
}
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type Notification,
type NotificationAction,
openCopilotWithMessage,
sendMothershipMessage,
useNotificationStore,
} from '@/stores/notifications'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
Expand Down Expand Up @@ -81,7 +82,11 @@ function CountdownRing({ onPause }: { onPause: () => void }) {
* Workflow error notifications auto-dismiss after {@link AUTO_DISMISS_MS}ms with a countdown
* ring. Clicking the ring pauses all timers until the notification stack clears.
*/
export const Notifications = memo(function Notifications() {
interface NotificationsProps {
embedded?: boolean
}

export const Notifications = memo(function Notifications({ embedded }: NotificationsProps) {
const activeWorkflowId = useWorkflowRegistry((state) => state.activeWorkflowId)

const allNotifications = useNotificationStore((state) => state.notifications)
Expand Down Expand Up @@ -112,7 +117,11 @@ export const Notifications = memo(function Notifications() {

switch (action.type) {
case 'copilot':
openCopilotWithMessage(action.message)
if (embedded) {
sendMothershipMessage(action.message)
} else {
openCopilotWithMessage(action.message)
}
break
case 'refresh':
window.location.reload()
Expand All @@ -133,7 +142,7 @@ export const Notifications = memo(function Notifications() {
})
}
},
[removeNotification]
[embedded, removeNotification]
)

useRegisterGlobalCommands(() =>
Expand Down Expand Up @@ -281,7 +290,9 @@ export const Notifications = memo(function Notifications() {
onClick={() => executeAction(notification.id, notification.action!)}
className='w-full rounded-[5px] px-[8px] py-[4px] font-medium text-[12px]'
>
{ACTION_LABELS[notification.action!.type] ?? 'Take action'}
{embedded && notification.action!.type === 'copilot'
? 'Fix in Mothership'
: (ACTION_LABELS[notification.action!.type] ?? 'Take action')}
</Button>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3922,7 +3922,7 @@ const WorkflowContent = React.memo(
</>
)}

{!embedded && <Notifications />}
<Notifications embedded={embedded} />

{!embedded && isWorkflowReady && isWorkflowEmpty && effectivePermissions.canEdit && (
<CommandList />
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/stores/notifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export type {
Notification,
NotificationAction,
} from './types'
export { openCopilotWithMessage } from './utils'
export { openCopilotWithMessage, sendMothershipMessage } from './utils'
14 changes: 14 additions & 0 deletions apps/sim/stores/notifications/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@ import { useCopilotStore, usePanelStore } from '@/stores/panel'

const logger = createLogger('NotificationUtils')

/**
* Dispatches a message to the mothership chat via a custom window event.
* The mothership `Home` component listens for this event and calls `sendMessage`.
*/
export function sendMothershipMessage(message: string): void {
const trimmed = message.trim()
if (!trimmed) {
logger.warn('sendMothershipMessage called with empty message')
return
}
window.dispatchEvent(new CustomEvent('mothership-send-message', { detail: { message: trimmed } }))
logger.info('Dispatched mothership message event', { messageLength: trimmed.length })
}

/**
* Opens the copilot panel and directly sends the message.
*
Expand Down
Loading