-
Notifications
You must be signed in to change notification settings - Fork 245
fix: re-enable batch state debouncing to resolve Auto Run performance regression #465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
4c9f951
48b8de3
efe7dfc
9268995
e29b425
615ff25
7eff634
d6842b1
4403705
2a05348
cd0734c
cf06151
1b65706
c47fca2
d9698cb
26d100b
3c388c7
b9252ef
d4829ed
3cf3ccd
ed2e54b
f494fad
ad846a8
f779e9a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # ENCORE-INBOX-02: Add `unifiedInbox` flag to EncoreFeatureFlags | ||
|
|
||
| ## Objective | ||
| Register the Unified Inbox as an Encore Feature with a type flag and default value. | ||
|
|
||
| ## Context | ||
| - `EncoreFeatureFlags` interface is at `src/renderer/types/index.ts:906` — currently only has `directorNotes: boolean` | ||
| - `DEFAULT_ENCORE_FEATURES` is at `src/renderer/stores/settingsStore.ts:110` — currently `{ directorNotes: false }` | ||
| - The settings store hydration merges saved values with defaults at `settingsStore.ts:1669-1673` using spread: `{ ...DEFAULT_ENCORE_FEATURES, ...(saved) }` — so new fields with defaults are safe | ||
| - Both type AND default MUST be updated in the same task to avoid runtime `undefined` | ||
|
|
||
| ## Tasks | ||
|
|
||
| - [x] In `src/renderer/types/index.ts`, find the `EncoreFeatureFlags` interface at line 906. Add `unifiedInbox: boolean` below `directorNotes`. Also in `src/renderer/stores/settingsStore.ts`, find `DEFAULT_ENCORE_FEATURES` at line 110. Add `unifiedInbox: false` to the object. Both changes must happen together: | ||
| ```typescript | ||
| // types/index.ts:906 | ||
| export interface EncoreFeatureFlags { | ||
| directorNotes: boolean; | ||
| unifiedInbox: boolean; | ||
| } | ||
|
|
||
| // stores/settingsStore.ts:110 | ||
| export const DEFAULT_ENCORE_FEATURES: EncoreFeatureFlags = { | ||
| directorNotes: false, | ||
| unifiedInbox: false, | ||
| }; | ||
| ``` | ||
|
|
||
| - [x] Run `npm run lint` to verify the new field doesn't cause type errors. Existing code spreading `encoreFeatures` will pick up the new field automatically via the default merge at line 1669-1673. | ||
|
|
||
| ## Gate | ||
| - `npm run lint` passes | ||
| - `EncoreFeatureFlags` has both `directorNotes` and `unifiedInbox` fields | ||
| - `DEFAULT_ENCORE_FEATURES` has `unifiedInbox: false` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ import { | |
| Clapperboard, | ||
| HelpCircle, | ||
| AppWindow, | ||
| Inbox, | ||
| } from 'lucide-react'; | ||
| import { useSettings } from '../hooks'; | ||
| import type { | ||
|
|
@@ -3638,6 +3639,89 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro | |
| ); | ||
| })()} | ||
| </div> | ||
|
|
||
| {/* Unified Inbox Feature Section */} | ||
| <div | ||
| className="rounded-lg border" | ||
| style={{ | ||
| borderColor: encoreFeatures.unifiedInbox | ||
| ? theme.colors.accent | ||
| : theme.colors.border, | ||
| backgroundColor: encoreFeatures.unifiedInbox | ||
| ? `${theme.colors.accent}08` | ||
| : 'transparent', | ||
| }} | ||
| > | ||
| {/* Feature Toggle Header */} | ||
| <button | ||
| className="w-full flex items-center justify-between p-4 text-left" | ||
| onClick={() => | ||
| setEncoreFeatures({ | ||
| ...encoreFeatures, | ||
| unifiedInbox: !encoreFeatures.unifiedInbox, | ||
| }) | ||
| } | ||
| > | ||
| <div className="flex items-center gap-3"> | ||
| <Inbox | ||
| className="w-5 h-5" | ||
| style={{ | ||
| color: encoreFeatures.unifiedInbox | ||
| ? theme.colors.accent | ||
| : theme.colors.textDim, | ||
| }} | ||
| /> | ||
| <div> | ||
| <div | ||
| className="text-sm font-bold flex items-center gap-2" | ||
| style={{ color: theme.colors.textMain }} | ||
| > | ||
| Unified Inbox | ||
| <span | ||
| className="px-1.5 py-0.5 rounded text-[9px] font-bold uppercase" | ||
| style={{ | ||
| backgroundColor: theme.colors.warning + '30', | ||
| color: theme.colors.warning, | ||
| }} | ||
| > | ||
| Beta | ||
| </span> | ||
| </div> | ||
| <div className="text-xs mt-0.5" style={{ color: theme.colors.textDim }}> | ||
| Cross-session notification center with keyboard-first navigation | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div | ||
| className={`relative w-10 h-5 rounded-full transition-colors ${encoreFeatures.unifiedInbox ? '' : 'opacity-50'}`} | ||
| style={{ | ||
| backgroundColor: encoreFeatures.unifiedInbox | ||
| ? theme.colors.accent | ||
| : theme.colors.border, | ||
| }} | ||
| > | ||
| <div | ||
| className="absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform" | ||
| style={{ | ||
| transform: encoreFeatures.unifiedInbox | ||
| ? 'translateX(22px)' | ||
| : 'translateX(2px)', | ||
| }} | ||
| /> | ||
| </div> | ||
| </button> | ||
|
|
||
| {/* Unified Inbox Info (shown when enabled) */} | ||
| {encoreFeatures.unifiedInbox && ( | ||
| <div className="px-4 pb-4"> | ||
| <p className="text-xs" style={{ color: theme.colors.textDim }}> | ||
| Access via Option+I (Mac) or Alt+I (Windows). Aggregates status updates, | ||
| errors, and action items from all running agents into a single | ||
| keyboard-navigable view. | ||
|
Comment on lines
+3719
to
+3721
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Search for the shortcut mentions in TypeScript/TSX files
echo "=== Searching for Option+I / Alt+I mentions ==="
rg -n --type=ts --type=tsx "Option\+I|Alt\+I|Unified Inbox" | head -20
echo ""
echo "=== Searching for keyboard event handlers related to shortcuts ==="
rg -n --type=ts --type=tsx "KeyI|shortcut.*[iI]|hotkey.*[iI]" | head -30
echo ""
echo "=== Searching for inbox open/toggle handlers ==="
rg -n --type=ts --type=tsx "(altKey|metaKey).*(keyCode|key).*73|key.*73.*(altKey|metaKey)" | head -20
echo ""
echo "=== Searching for keyboard event handling in components ==="
rg -n --type=ts --type=tsx "onKeyDown|onKeyUp|addEventListener.*key" | grep -i "component\|modal" | head -20Repository: RunMaestro/Maestro Length of output: 154 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Searching for Option+I / Alt+I mentions ==="
rg -n "Option\+I|Alt\+I|Unified Inbox" --include="*.ts" --include="*.tsx" | head -30
echo ""
echo "=== Searching for keyboard handler patterns ==="
rg -n "KeyI|keyCode.*73|key.*I.*alt|key.*I.*meta" --include="*.ts" --include="*.tsx" | head -30
echo ""
echo "=== Searching for shortcut/hotkey bindings ==="
rg -n "shortcut|hotkey|keybind" --include="*.ts" --include="*.tsx" -i | head -40
echo ""
echo "=== Check SettingsModal specifically for context ==="
rg -n "Option|Alt|shortcut" src/renderer/components/SettingsModal.tsx | head -20Repository: RunMaestro/Maestro Length of output: 568 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Searching for Option+I / Alt+I mentions ==="
fd -e ts -e tsx | xargs rg -n "Option\+I|Alt\+I|Unified Inbox" | head -30
echo ""
echo "=== Searching for keyboard handlers with key code 73 (I key) ==="
fd -e ts -e tsx | xargs rg -n "keyCode.*73|key.*[\"']i[\"']" | head -30
echo ""
echo "=== Check SettingsModal file for context around line 3718 ==="
cat -n src/renderer/components/SettingsModal.tsx | sed -n '3710,3730p'
echo ""
echo "=== Search for keyboard event listeners in codebase ==="
fd -e ts -e tsx | xargs rg -n "onKeyDown|onKeyPress|addEventListener.*key" | head -20
echo ""
echo "=== Search for shortcuts/keybindings mention ==="
fd -e ts -e tsx | xargs rg -n "shortcut|keybind|hotkey" -i | head -20Repository: RunMaestro/Maestro Length of output: 576 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== View context around line 3718 ==="
cat -n src/renderer/components/SettingsModal.tsx | sed -n '3710,3730p'
echo ""
echo "=== Search for Unified Inbox open/toggle handlers ==="
fd -e ts -e tsx | xargs rg -n "Unified.*Inbox|unifiedInbox|unified_inbox" -i | head -20
echo ""
echo "=== Search for any Alt key handlers ==="
fd -e ts -e tsx | xargs rg -n "altKey|metaKey" | head -20
echo ""
echo "=== Search for keyboard shortcuts/command palette ==="
fd -e ts -e tsx | xargs rg -n "registerShortcut|registerKeybinding|keymap|shortcut.*map" -i | head -20
echo ""
echo "=== Search for event listeners that might handle Alt+I ==="
fd -e ts -e tsx | xargs rg -n "addEventListener|on.*key|handleKey" -i | head -30Repository: RunMaestro/Maestro Length of output: 10811 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Search for where Unified Inbox is actually opened/triggered ==="
fd -e ts -e tsx | xargs rg -n "openUnifiedInbox|showUnifiedInbox|unifiedInbox.*open|inbox.*trigger" -i | head -20
echo ""
echo "=== Search for shortcut definitions/registrations ==="
fd -e ts -e tsx | xargs rg -n "Alt.*I|Option.*I" | head -20
echo ""
echo "=== Check if shortcuts are defined in constants ==="
fd -e ts -e tsx | xargs rg -n "const.*SHORTCUTS|const.*SHORTCUT" -A5 | head -40
echo ""
echo "=== Search in ShortcutEditor or shortcuts config ==="
cat -n src/renderer/components/ShortcutEditor.tsx 2>/dev/null | head -50
echo ""
echo "=== Look for where shortcuts are consumed in handlers ==="
fd -e ts -e tsx | xargs rg -n "handleKeyDown|handleKeyPress" | grep -v test | head -20Repository: RunMaestro/Maestro Length of output: 131 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== List files that might contain shortcuts ==="
fd -e ts -e tsx | xargs grep -l "shortcut" | head -20
echo ""
echo "=== Search more broadly for Inbox opening ==="
fd -e ts -e tsx -e js | xargs grep -l "inbox" -i | head -20
echo ""
echo "=== Check main app files ==="
ls -la src/renderer/ | head -20
echo ""
echo "=== Look at App.tsx or main entry ==="
fd -name "App.tsx" -o -name "main.tsx" -o -name "index.tsx"Repository: RunMaestro/Maestro Length of output: 993 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Check App.tsx for keyboard handlers ==="
wc -l src/renderer/App.tsx
echo ""
head -100 src/renderer/App.tsx
echo ""
echo "=== Search for keyboard event listener in App.tsx ==="
grep -n "onKeyDown\|onKeyPress\|addEventListener\|shortcut" src/renderer/App.tsx | head -20
echo ""
echo "=== Check settingsStore for shortcut definitions ==="
grep -n "unifiedInbox\|Alt.*I\|Option.*I" src/renderer/stores/settingsStore.ts | head -20
echo ""
echo "=== Search for keyboard handler in AppModals or AppOverlays ==="
grep -n "onKeyDown\|handleKey\|keyboard" src/renderer/components/AppModals.tsx | head -10
grep -n "onKeyDown\|handleKey\|keyboard" src/renderer/components/AppOverlays.tsx | head -10Repository: RunMaestro/Maestro Length of output: 5089 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Find useMainKeyboardHandler ==="
fd -e ts -e tsx | xargs grep -l "useMainKeyboardHandler" | head -10
echo ""
echo "=== Search for Alt+I in useMainKeyboardHandler ==="
fd -e ts -e tsx | xargs grep -l "useMainKeyboardHandler" | xargs grep -l "Alt.*I\|Option.*I"
echo ""
echo "=== Find the hook definition ==="
fd -name "*useMainKeyboardHandler*"
echo ""
echo "=== Search for where shortcut handlers are defined ==="
fd -e ts -e tsx | xargs grep -l "shortcuts\[" | head -10
echo ""
echo "=== Look for keyboard shortcuts configuration ==="
fd -name "*shortcut*" -type f | head -20Repository: RunMaestro/Maestro Length of output: 425 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Read useMainKeyboardHandler.ts ==="
wc -l src/renderer/hooks/keyboard/useMainKeyboardHandler.ts
echo ""
cat -n src/renderer/hooks/keyboard/useMainKeyboardHandler.ts | head -150
echo ""
echo "=== Search for shortcut matching/handling logic ==="
grep -n "shortcut\|Alt\|Option\|metaKey\|altKey" src/renderer/hooks/keyboard/useMainKeyboardHandler.ts | head -40Repository: RunMaestro/Maestro Length of output: 11816 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Continue reading useMainKeyboardHandler.ts (rest of file) ==="
cat -n src/renderer/hooks/keyboard/useMainKeyboardHandler.ts | tail -n +150 | head -100
echo ""
echo "=== Search entire codebase for Alt+I handler ==="
fd -e ts -e tsx | xargs grep -n "altKey.*keyLower.*===.*'i'\|key.*===.*'i'.*altKey\|keyCode.*73" | head -20
echo ""
echo "=== Search for where unifiedInbox shortcut would be handled ==="
fd -e ts -e tsx | xargs grep -n "unifiedInbox" | head -20
echo ""
echo "=== Check if Alt+I appears anywhere as a shortcut ==="
fd -e ts -e tsx | xargs grep -n "'i'" | grep -i "alt\|shift.*i" | head -20Repository: RunMaestro/Maestro Length of output: 4535 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Search for unifiedInbox in keyboard handler ==="
grep -n "unifiedInbox" src/renderer/hooks/keyboard/useMainKeyboardHandler.ts
echo ""
echo "=== Check entire codebase for Alt+I ==="
fd -e ts -e tsx | xargs grep -i "alt.*i\|option.*i" | grep -v "option.*interactive\|option.*int\|optional\|altitude\|alternativ\|allergen" | head -30
echo ""
echo "=== Search for where inbox is opened ==="
fd -e ts -e tsx | xargs grep -n "inbox.*open\|open.*inbox\|show.*inbox" -i | head -20
echo ""
echo "=== Search for all keyboard shortcuts mapped ==="
grep -n "ctx.isShortcut(e," src/renderer/hooks/keyboard/useMainKeyboardHandler.ts | head -40Repository: RunMaestro/Maestro Length of output: 113 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Check entire codebase for Alt+I or Option+I ==="
fd -e ts -e tsx | xargs grep "Alt.*I\|Option.*I" 2>/dev/null | head -20
echo ""
echo "=== List all shortcuts defined via isShortcut ==="
grep -n "ctx.isShortcut(e," src/renderer/hooks/keyboard/useMainKeyboardHandler.ts
echo ""
echo "=== Check SettingsModal line 3718 in context again ==="
sed -n '3710,3730p' src/renderer/components/SettingsModal.tsx
echo ""
echo "=== Search for shortcuts object definition ==="
fd -e ts | xargs grep -l "shortcuts.*=" | head -10
echo ""
echo "=== Check if there's a default shortcuts object ==="
fd -e ts | xargs grep -n "const.*shortcuts.*=.*{" | head -20Repository: RunMaestro/Maestro Length of output: 2115 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Search for shortcuts configuration file ==="
fd -e ts | xargs grep -l "toggleSidebar\|toggleRightPanel" | head -10
echo ""
echo "=== Check settingsStore for all default shortcuts ==="
grep -n -A 50 "const.*shortcuts\|export.*shortcuts" src/renderer/stores/settingsStore.ts | head -80
echo ""
echo "=== Look for keyboard shortcut definitions ==="
fd -e ts -e json | xargs grep -l "shortcut.*Key\|keyboard.*map" | grep -v test | head -10Repository: RunMaestro/Maestro Length of output: 2390 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Read shortcuts.ts ==="
wc -l src/renderer/constants/shortcuts.ts
echo ""
cat -n src/renderer/constants/shortcuts.ts
echo ""
echo "=== Search for unifiedInbox in shortcuts ==="
grep -n "unifiedInbox\|Alt.*I\|Option.*I" src/renderer/constants/shortcuts.tsRepository: RunMaestro/Maestro Length of output: 8813 Remove misleading keyboard shortcut documentation; the documented shortcut is not actually implemented. Line 3718 advertises "Option+I (Mac) or Alt+I (Windows)" to access Unified Inbox, but this shortcut does not exist in the codebase. It is not defined in 🤖 Prompt for AI Agents |
||
| </p> | ||
| </div> | ||
| )} | ||
| </div> | ||
| </div> | ||
| )} | ||
| </div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import type { SessionState } from './index'; | ||
|
|
||
| export interface InboxItem { | ||
| sessionId: string; | ||
| tabId: string; | ||
| groupId?: string; | ||
| groupName?: string; | ||
| sessionName: string; | ||
| tabName?: string; | ||
| toolType: string; | ||
| gitBranch?: string; | ||
| contextUsage?: number; // 0-100, undefined = unknown | ||
| lastMessage: string; // truncated to 90 chars | ||
| timestamp: number; // Unix ms, must be validated > 0 | ||
| state: SessionState; | ||
| hasUnread: boolean; | ||
| starred?: boolean; | ||
| } | ||
|
|
||
| /** UI labels: "Newest", "Oldest", "Grouped", "By Agent" */ | ||
| export type InboxSortMode = 'newest' | 'oldest' | 'grouped' | 'byAgent'; | ||
|
|
||
| /** UI labels: "All", "Unread", "Read", "Starred" */ | ||
| export type InboxFilterMode = 'all' | 'unread' | 'read' | 'starred'; | ||
|
|
||
| /** Human-readable status badges */ | ||
| export const STATUS_LABELS: Record<SessionState, string> = { | ||
| idle: 'Ready', | ||
| waiting_input: 'Needs Input', | ||
| busy: 'Processing', | ||
| connecting: 'Connecting', | ||
| error: 'Error', | ||
| }; | ||
|
|
||
| /** Status badge color keys (map to theme.colors.*) */ | ||
| export const STATUS_COLORS: Record<SessionState, string> = { | ||
| idle: 'success', | ||
| waiting_input: 'warning', | ||
| busy: 'info', | ||
| connecting: 'textMuted', | ||
| error: 'error', | ||
| }; | ||
|
|
||
| /** View mode inside the AgentInbox modal */ | ||
| export type InboxViewMode = 'list' | 'focus'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expose toggle state to assistive technologies.
The Unified Inbox toggle is visually stateful, but Line 3656’s button does not expose pressed/checked state. Add toggle semantics so screen readers can announce enabled/disabled state.
♿ Suggested accessibility fix
<button className="w-full flex items-center justify-between p-4 text-left" onClick={() => setEncoreFeatures({ ...encoreFeatures, unifiedInbox: !encoreFeatures.unifiedInbox, }) } + aria-pressed={encoreFeatures.unifiedInbox} + aria-label={`Unified Inbox ${encoreFeatures.unifiedInbox ? 'enabled' : 'disabled'}`} >🤖 Prompt for AI Agents