diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 4f31351c3..bd790b367 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -344,6 +344,9 @@ function MaestroConsoleInner() { // Director's Notes Modal directorNotesOpen, setDirectorNotesOpen, + // Agent Inbox Modal (Unified Inbox) + agentInboxOpen, + setAgentInboxOpen, } = useModalActions(); // --- MOBILE LANDSCAPE MODE (reading-only view) --- @@ -3009,6 +3012,7 @@ function MaestroConsoleInner() { setMarketplaceModalOpen, setSymphonyModalOpen, setDirectorNotesOpen, + setAgentInboxOpen, encoreFeatures, setShowNewGroupChatModal, deleteGroupChatWithConfirmation, @@ -3708,6 +3712,7 @@ function MaestroConsoleInner() { onOpenDirectorNotes={ encoreFeatures.directorNotes ? () => setDirectorNotesOpen(true) : undefined } + onOpenAgentInbox={encoreFeatures.unifiedInbox ? () => setAgentInboxOpen(true) : undefined} autoScrollAiMode={autoScrollAiMode} setAutoScrollAiMode={setAutoScrollAiMode} tabSwitcherOpen={tabSwitcherOpen} @@ -4103,6 +4108,17 @@ function MaestroConsoleInner() { )} + {/* --- AGENT INBOX MODAL (Encore Feature — component TBD) --- */} + {/* Gate: renders only when unifiedInbox encore feature is enabled */} + {/* {encoreFeatures.unifiedInbox && agentInboxOpen && ( + + setAgentInboxOpen(false)} + /> + + )} */} + {/* --- GIST PUBLISH MODAL --- */} {/* Supports both file preview tabs and tab context gist publishing */} {gistPublishModalOpen && (activeFileTab || tabGistContent) && ( diff --git a/src/renderer/components/AppModals.tsx b/src/renderer/components/AppModals.tsx index fb8de50c2..39f8ca335 100644 --- a/src/renderer/components/AppModals.tsx +++ b/src/renderer/components/AppModals.tsx @@ -859,6 +859,9 @@ export interface AppUtilityModalsProps { // Director's Notes onOpenDirectorNotes?: () => void; + // Agent Inbox (Unified Inbox) + onOpenAgentInbox?: () => void; + // Auto-scroll autoScrollAiMode?: boolean; setAutoScrollAiMode?: (value: boolean) => void; @@ -1060,6 +1063,8 @@ export const AppUtilityModals = memo(function AppUtilityModals({ onOpenSymphony, // Director's Notes onOpenDirectorNotes, + // Agent Inbox (Unified Inbox) + onOpenAgentInbox, // Auto-scroll autoScrollAiMode, setAutoScrollAiMode, @@ -1218,6 +1223,7 @@ export const AppUtilityModals = memo(function AppUtilityModals({ onOpenLastDocumentGraph={onOpenLastDocumentGraph} onOpenSymphony={onOpenSymphony} onOpenDirectorNotes={onOpenDirectorNotes} + onOpenAgentInbox={onOpenAgentInbox} autoScrollAiMode={autoScrollAiMode} setAutoScrollAiMode={setAutoScrollAiMode} /> @@ -2013,6 +2019,8 @@ export interface AppModalsProps { onOpenSymphony?: () => void; // Director's Notes onOpenDirectorNotes?: () => void; + // Agent Inbox (Unified Inbox) + onOpenAgentInbox?: () => void; // Auto-scroll autoScrollAiMode?: boolean; setAutoScrollAiMode?: (value: boolean) => void; @@ -2337,6 +2345,8 @@ export const AppModals = memo(function AppModals(props: AppModalsProps) { onOpenSymphony, // Director's Notes onOpenDirectorNotes, + // Agent Inbox (Unified Inbox) + onOpenAgentInbox, // Auto-scroll autoScrollAiMode, setAutoScrollAiMode, @@ -2651,6 +2661,7 @@ export const AppModals = memo(function AppModals(props: AppModalsProps) { onOpenMarketplace={onOpenMarketplace} onOpenSymphony={onOpenSymphony} onOpenDirectorNotes={onOpenDirectorNotes} + onOpenAgentInbox={onOpenAgentInbox} autoScrollAiMode={autoScrollAiMode} setAutoScrollAiMode={setAutoScrollAiMode} tabSwitcherOpen={tabSwitcherOpen} diff --git a/src/renderer/components/QuickActionsModal.tsx b/src/renderer/components/QuickActionsModal.tsx index 144c8e229..4d2137128 100644 --- a/src/renderer/components/QuickActionsModal.tsx +++ b/src/renderer/components/QuickActionsModal.tsx @@ -117,6 +117,8 @@ interface QuickActionsModalProps { onOpenSymphony?: () => void; // Director's Notes onOpenDirectorNotes?: () => void; + // Agent Inbox (Unified Inbox) + onOpenAgentInbox?: () => void; // Auto-scroll autoScrollAiMode?: boolean; setAutoScrollAiMode?: (value: boolean) => void; @@ -204,6 +206,7 @@ export const QuickActionsModal = memo(function QuickActionsModal(props: QuickAct onOpenLastDocumentGraph, onOpenSymphony, onOpenDirectorNotes, + onOpenAgentInbox, autoScrollAiMode, setAutoScrollAiMode, } = props; @@ -1034,6 +1037,21 @@ export const QuickActionsModal = memo(function QuickActionsModal(props: QuickAct }, ] : []), + // Agent Inbox (Unified Inbox) - cross-agent message hub + ...(onOpenAgentInbox + ? [ + { + id: 'agentInbox', + label: 'Unified Inbox', + shortcut: shortcuts.agentInbox, + subtext: 'Open the unified inbox for cross-agent messages', + action: () => { + onOpenAgentInbox(); + setQuickActionOpen(false); + }, + }, + ] + : []), // Auto-scroll toggle ...(setAutoScrollAiMode ? [ diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx index e67f7b9ea..359b6e8c0 100644 --- a/src/renderer/components/SettingsModal.tsx +++ b/src/renderer/components/SettingsModal.tsx @@ -37,6 +37,8 @@ import { Clapperboard, HelpCircle, AppWindow, + Inbox, + FileText, } from 'lucide-react'; import { useSettings } from '../hooks'; import type { @@ -1234,7 +1236,7 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro tabIndex={-1} title="Encore Features" > - + {activeTab === 'encore' && Encore Features}
@@ -3638,6 +3640,136 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro ); })()}
+ + {/* Unified Inbox Feature Card */} +
+ +
+ + {/* Tab Descriptions Feature Card */} +
+ +
)} diff --git a/src/renderer/constants/shortcuts.ts b/src/renderer/constants/shortcuts.ts index 37f530386..cdee93147 100644 --- a/src/renderer/constants/shortcuts.ts +++ b/src/renderer/constants/shortcuts.ts @@ -78,6 +78,7 @@ export const DEFAULT_SHORTCUTS: Record = { label: "Director's Notes", keys: ['Meta', 'Shift', 'o'], }, + agentInbox: { id: 'agentInbox', label: 'Unified Inbox', keys: ['Alt', 'i'] }, }; // Non-editable shortcuts (displayed in help but not configurable) diff --git a/src/renderer/hooks/keyboard/useMainKeyboardHandler.ts b/src/renderer/hooks/keyboard/useMainKeyboardHandler.ts index 93675698d..4873d7d35 100644 --- a/src/renderer/hooks/keyboard/useMainKeyboardHandler.ts +++ b/src/renderer/hooks/keyboard/useMainKeyboardHandler.ts @@ -420,6 +420,10 @@ export function useMainKeyboardHandler(): UseMainKeyboardHandlerReturn { e.preventDefault(); ctx.setDirectorNotesOpen?.(true); trackShortcut('directorNotes'); + } else if (ctx.isShortcut(e, 'agentInbox') && ctx.encoreFeatures?.unifiedInbox) { + e.preventDefault(); + ctx.setAgentInboxOpen?.(true); + trackShortcut('agentInbox'); } else if (ctx.isShortcut(e, 'jumpToBottom')) { e.preventDefault(); // Jump to the bottom of the current main panel output (AI logs or terminal output) diff --git a/src/renderer/stores/modalStore.ts b/src/renderer/stores/modalStore.ts index b385ea745..55301501c 100644 --- a/src/renderer/stores/modalStore.ts +++ b/src/renderer/stores/modalStore.ts @@ -218,7 +218,9 @@ export type ModalId = // Platform Warnings | 'windowsWarning' // Director's Notes - | 'directorNotes'; + | 'directorNotes' + // Agent Inbox (Unified Inbox) + | 'agentInbox'; /** * Type mapping from ModalId to its data type. @@ -757,6 +759,10 @@ export function getModalActions() { setDirectorNotesOpen: (open: boolean) => open ? openModal('directorNotes') : closeModal('directorNotes'), + // Agent Inbox Modal (Unified Inbox) + setAgentInboxOpen: (open: boolean) => + open ? openModal('agentInbox') : closeModal('agentInbox'), + // Lightbox refs replacement - use updateModalData instead setLightboxIsGroupChat: (isGroupChat: boolean) => updateModalData('lightbox', { isGroupChat }), setLightboxAllowDelete: (allowDelete: boolean) => updateModalData('lightbox', { allowDelete }), @@ -846,6 +852,7 @@ export function useModalActions() { const symphonyModalOpen = useModalStore(selectModalOpen('symphony')); const windowsWarningModalOpen = useModalStore(selectModalOpen('windowsWarning')); const directorNotesOpen = useModalStore(selectModalOpen('directorNotes')); + const agentInboxOpen = useModalStore(selectModalOpen('agentInbox')); // Get stable actions const actions = getModalActions(); @@ -1014,6 +1021,9 @@ export function useModalActions() { // Director's Notes Modal directorNotesOpen, + // Agent Inbox Modal (Unified Inbox) + agentInboxOpen, + // Lightbox ref replacements (now stored as data) lightboxIsGroupChat: lightboxData?.isGroupChat ?? false, lightboxAllowDelete: lightboxData?.allowDelete ?? false, diff --git a/src/renderer/stores/settingsStore.ts b/src/renderer/stores/settingsStore.ts index c10e6071e..945052a66 100644 --- a/src/renderer/stores/settingsStore.ts +++ b/src/renderer/stores/settingsStore.ts @@ -109,6 +109,8 @@ export const DEFAULT_ONBOARDING_STATS: OnboardingStats = { export const DEFAULT_ENCORE_FEATURES: EncoreFeatureFlags = { directorNotes: false, + unifiedInbox: false, + tabDescription: false, }; export const DEFAULT_DIRECTOR_NOTES_SETTINGS: DirectorNotesSettings = { diff --git a/src/renderer/types/index.ts b/src/renderer/types/index.ts index 74fdb2b14..0039a74d2 100644 --- a/src/renderer/types/index.ts +++ b/src/renderer/types/index.ts @@ -905,6 +905,8 @@ export interface LeaderboardSubmitResponse { // Each key is a feature ID, value indicates whether it's enabled export interface EncoreFeatureFlags { directorNotes: boolean; + unifiedInbox: boolean; + tabDescription: boolean; } // Director's Notes settings for synopsis generation