Skip to content

Director's Notes#333

Merged
pedramamini merged 46 commits intomainfrom
directors-notes
Feb 15, 2026
Merged

Director's Notes#333
pedramamini merged 46 commits intomainfrom
directors-notes

Conversation

@pedramamini
Copy link
Collaborator

  • MAESTRO: Add Director's Notes settings types, useSettings integration, and SettingsModal tab
  • MAESTRO: Extract shared History components from HistoryPanel
  • MAESTRO: Wire up ActivityGraph import from History/ and remove local definition from HistoryPanel
  • MAESTRO: Wire up HistoryEntryItem import from History/ and remove local definition from HistoryPanel
  • MAESTRO: Wire up HistoryFilterToggle import from History/ and remove inline filter rendering from HistoryPanel
  • MAESTRO: Wire up DoubleCheck import from History/ and remove local definition from HistoryDetailModal
  • MAESTRO: Add Director's Notes IPC handlers for unified history and synopsis generation
  • MAESTRO: Add DirectorNotesModal shell with tab switching between Unified History and AI Overview
  • MAESTRO: Implement UnifiedHistoryTab with virtualized list, agent name display, and sessionless modal support
  • MAESTRO: Fix HistoryDetailModal tests and add sessionless context test coverage for Director's Notes
  • MAESTRO: Implement AIOverviewTab with synopsis generation, progress bar, and save-to-disk
  • MAESTRO: Integrate Director's Notes into Command Palette, Hamburger Menu, and keyboard shortcuts
  • MAESTRO: Add comprehensive tests for extracted History components (ActivityGraph, HistoryEntryItem, HistoryFilterToggle)
  • MAESTRO: Add comprehensive tests for DirectorNotesModal component
  • MAESTRO: Add comprehensive tests for Director's Notes IPC handlers
  • MAESTRO: Add comprehensive tests for UnifiedHistoryTab component
  • MAESTRO: Add Director's Notes settings tab tests and fix tab wrap assertions
  • MAESTRO: Add Director's Notes Command Palette integration tests
  • MAESTRO: Add Director's Notes Hamburger Menu integration tests
  • MAESTRO: Add Director's Notes entries to CLAUDE.md key files table
  • MAESTRO: Clean up TODO comments in Director's Notes implementation
  • Fix infinite re-render loop and keyboard focus in DirectorNotesModal
  • Fix keyboard focus in UnifiedHistoryTab list after data loads
  • Implement AI synopsis generation via groomContext in Director's Notes
  • Add custom agent configuration and session name resolution to Director's Notes
  • Enhance Director's Notes UI with Help tab, search, and keyboard navigation
  • Improve history entry display hierarchy for Director's Notes unified view
  • Add Director's Notes agent configuration panel to Settings
  • Refine Director's Notes modal layout, focus management, and keyboard shortcut migration
  • Replace inline JSON data with file-path manifest for Director's Notes synopsis generation
  • Add paginated loading, lookback filtering, and validation toggle to Director's Notes
  • Standardize agent vs session terminology across docs and fix Director's Notes shortcut display
  • Replace hardcoded keyboard shortcuts with platform-aware formatShortcutKeys across 25 components

kianhub and others added 30 commits February 11, 2026 00:00
…, and SettingsModal tab

- Added DirectorNotesSettings interface to renderer types (provider + defaultLookbackDays)
- Integrated into useSettings with default values, getter/setter, load/save logic
- Added Director's Notes tab to SettingsModal with Clapperboard icon
- Implemented settings panel with provider dropdown and lookback period slider (1-90 days)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create src/renderer/components/History/ folder with reusable components:
- historyConstants.tsx: LookbackPeriod type, LOOKBACK_OPTIONS, DoubleCheck SVG,
  MAX_HISTORY_IN_MEMORY, ESTIMATED_ROW_HEIGHT constants
- ActivityGraph.tsx: Activity bar graph with configurable lookback window
- HistoryEntryItem.tsx: Memoized history entry item with helper functions
- HistoryFilterToggle.tsx: AUTO/USER filter toggle buttons
- index.ts: Barrel export for all components and constants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…definition from HistoryPanel

Removed the local ActivityGraph component (lines 55-447), LookbackPeriod type,
and LOOKBACK_OPTIONS array from HistoryPanel.tsx. These are now imported from
the shared History/ folder along with DoubleCheck, MAX_HISTORY_IN_MEMORY,
ESTIMATED_ROW_HEIGHT, and ESTIMATED_ROW_HEIGHT_SIMPLE constants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…al definition from HistoryPanel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…inline filter rendering from HistoryPanel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…finition from HistoryDetailModal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nopsis generation

Create the main process IPC infrastructure for Director's Notes:
- director-notes:getUnifiedHistory - aggregates history across all sessions with time range and type filtering
- director-notes:estimateTokens - estimates token count for synopsis generation strategy
- director-notes:generateSynopsis - placeholder for AI synopsis (Phase 07)
- Preload module exposing window.maestro.directorNotes API
- TypeScript types in global.d.ts for renderer consumption
- Fix pre-existing TS error in SettingsModal tab navigation array

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ied History and AI Overview

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e display, and sessionless modal support

- Replace UnifiedHistoryTab placeholder with full implementation using @tanstack/react-virtual,
  ActivityGraph, HistoryFilterToggle, and HistoryDetailModal
- Add showAgentName prop to HistoryEntryItem for displaying source agent in unified history view
- Make HistoryDetailModal's delete button conditional on onDelete handler presence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t coverage for Director's Notes

Fix 4 pre-existing test failures where tests expected Delete button without
providing onDelete callback. Add new "Sessionless Context (Director Notes)"
test section verifying the modal gracefully handles entries without session
callbacks (onResumeSession, onDelete, onUpdate, onJumpToAgentSession).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ar, and save-to-disk

Replaces the Phase 07 placeholder AIOverviewTab with full implementation including:
- Time range slider (1-90 days lookback) with settings-aware defaults
- Multi-phase progress bar during synopsis generation
- MarkdownRenderer for rich synopsis display with theme-aware prose styles
- Save-to-disk via SaveMarkdownModal integration
- Refresh button for manual regeneration
- Error display for failed generations
- Token estimation for large dataset detection
- Added director-notes.md system prompt for synopsis generation
- Added error field to SynopsisResult type across IPC boundary
- Updated DirectorNotesModal to render AIOverviewTab hidden for background
  generation, enabling the tab when synopsis is ready
- 14 passing tests covering generation flow, error handling, UI controls

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…enu, and keyboard shortcuts

- Add DirectorNotesModal lazy import and conditional rendering in App.tsx
- Add directorNotesOpen/setDirectorNotesOpen state to ModalContext
- Add Director's Notes command to QuickActionsModal (Command+K palette)
- Add Director's Notes menu item to HamburgerMenu in SessionList
- Add Alt+Meta+D keyboard shortcut (avoids conflict with Meta+Shift+D git diff)
- Wire props through AppModals, useSessionListProps, and useMainKeyboardHandler

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tivityGraph, HistoryEntryItem, HistoryFilterToggle)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
19 tests covering rendering, tab switching, close behavior, layer stack
integration, props forwarding, and synopsis ready state management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests cover all three IPC handlers:
- getUnifiedHistory: aggregation, lookback filtering, type filtering, sorting, agentName derivation
- estimateTokens: token estimation heuristic, edge cases, ceiling behavior
- generateSynopsis: placeholder synopsis structure and content validation

20 tests total, following established history.test.ts patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verifies Director's Notes modal unified history: data fetching/aggregation,
filter toggles (AUTO/USER), activity graph integration, keyboard navigation,
detail modal open/close/navigation, agent name display, and error handling.
20 new tests across 7 test categories, all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ertions

Add 8 comprehensive tests for the Director's Notes settings tab in
SettingsModal covering: tab rendering, tab switching, provider dropdown
(claude-code/codex/opencode), lookback slider (1-90 range), description
text, setter callbacks for provider and lookback changes, and scale markers.

Fix 2 pre-existing tab wrap tests that expected SSH as the last tab but
Director's Notes was added after SSH as the new last tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The onClose prop was passed directly to registerLayer's onEscape callback
and included in the useEffect dependency array. Since onClose was an inline
arrow function from App.tsx, it created a new reference every render,
causing registerLayer to re-fire infinitely.

Fix: Use onCloseRef pattern (matching SettingsModal) to stabilize the
callback reference. Also add auto-focus on the modal container so keyboard
navigation works immediately without requiring a click first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The arrow key handler is attached to the list div inside
UnifiedHistoryTab, not the modal container. Auto-focus the list div
when loading completes so keyboard navigation works immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace placeholder generateSynopsis handler with real implementation
that spawns a batch-mode agent process using groomContext. The handler
gathers cross-session history entries, builds a prompt from the
director-notes.md system prompt, and returns the agent's response.
Update tests to cover agent availability, empty history, groomContext
success/failure, and empty response cases.
…r's Notes

- Extend SynopsisOptions/DirectorNotesSettings to support customPath, customArgs, customEnvVars
- Add generatedAt timestamp to SynopsisResult for tracking generation time
- Build session name map from Maestro sessions store for accurate agent name display
- Change provider type from union to string for flexible agent detection
- Update shortcut from Alt+Meta+D to Meta+Shift+O and add searchDirectorNotes shortcut
- Add shortcut migration for existing users
- Update IPC handler tests for session name resolution and custom config passthrough
…ation

- Add OverviewTab as first tab with contextual help explaining the feature
- Reorder tabs: Help → Unified History → AI Overview
- Add Cmd+F search bar that filters UnifiedHistoryTab entries
- Add Cmd+Shift+[/] keyboard navigation between tabs
- Add title row with heading and icon matching Symphony pattern
- Add module-level cache to AIOverviewTab for tab switch persistence
- Pass custom agent config through to synopsis generation
- Show generation timestamp and empty state with timestamp
- Move search state from UnifiedHistoryTab to parent (controlled via prop)
- Fix AIOverviewTab test cache isolation with _resetCacheForTesting helper
- Add comprehensive tests for search, tab navigation, and Help tab
…view

- Display agentName as prominent h2/h3 header when present
- Reorder HistoryEntryItem header: Agent Name → Session Pill → Type Pill → Timestamp
- Show sessionName as subheading when both agentName and sessionName exist
- Add agentName pill in metadata row for entries without sessionName
- Fix HistoryDetailModal test for multiple elements with same title attribute
- Add Sessionless Context tests for Director's Notes usage
- Replace static provider dropdown with dynamic agent detection
- Add Customize button to expand AgentConfigPanel for custom paths/args/env vars
- Support model selection for agents with supportsModelSelection capability
- Add agent refresh functionality and customization indicator dot
- Persist custom config to settings on blur
- Add Codex to mock detected agents and update provider change test
…shortcut migration

Restructured modal to use pill-style tab navigation, role="dialog" semantics, and
proper focus forwarding to tab content via forwardRef/useImperativeHandle. Updated
keyboard shortcut migration to also handle the brief Meta+Shift+D binding. Tests
updated to match new DOM structure and styling patterns.
… synopsis generation

The AI agent now receives history file paths instead of serialized entry data,
allowing it to read files directly and drill into fullResponse details selectively.
This reduces prompt bloat and gives the agent access to full entry detail.

- Rewrite director-notes.md prompt for file-based analysis strategy
- Replace entry-gathering loop with file-path manifest in generateSynopsis handler
- Remove estimateTokens IPC handler, preload method, and type declaration
- Simplify AIOverviewTab to a single generateSynopsis IPC call
- Update handler and renderer tests for the new approach
…irector's Notes

UnifiedHistoryTab now uses progressive page-based loading (100 entries per page)
with infinite scroll instead of fetching all entries at once. The activity graph
uses a stable snapshot that only updates on fresh loads, not scroll-appends.
Lookback period changes in the graph now filter the entry list in both
HistoryPanel and UnifiedHistoryTab. Added validation toggle support via
onUpdate prop wired through the per-session history API. Extracted
LookbackSelector as a shared History component. Updated all affected tests.
…'s Notes shortcut display

Docs: Establish "agent" for user-facing entities (Left Bar items) and "session/provider session" for conversation contexts (tabs). Updated 11 documentation files to enforce this distinction consistently.

Code: Fix OverviewTab hardcoded wrong shortcut (Cmd+Shift+D → dynamic from settings), make all displayed shortcuts platform-aware using formatShortcutKeys (⌘ on Mac, Ctrl on Windows).
…utKeys across 25 components

Add formatMetaKey, formatEnterToSend, and formatEnterToSendTooltip helpers
to shortcutFormatter.ts. Replace all hardcoded ⌘/Cmd/Ctrl shortcut strings
in tooltips, kbd hints, and button labels with formatShortcutKeys() calls.
Remove duplicate isMacPlatform() helpers from BatchRunnerModal and
DocumentsPanel in favor of shared formatMetaKey().
…tings

The header context bar used hardcoded 60/80% thresholds while the bottom
warning sash used configurable thresholds from settings, causing color
mismatches (e.g., green bar at top but yellow warning at bottom).
…ctor's Notes AI Overview

- Add generation stats (history entry count, agent count, duration) to
  SynopsisResult across the full IPC stack (handler, preload, global.d.ts)
- Display stats bar with History/Bot/Timer icons above synopsis content
- Fix memory leak: guard setState calls with mountedRef while still caching
  results for next modal open
- Update AI prompt to include human-readable date range and suppress
  preamble text, raw timestamps, and redundant stats in generated output
Bumped opacity from 50% to 70% on "Loading history..." and "No history
entries found." messages so they're legible against dark backgrounds.
Clicking a session ID badge in the list view or the RESUME button in the
detail view now closes Director's Notes and navigates to the correct
agent's session tab. Supports cross-agent navigation via a pending-resume
ref + effect pattern that defers session loading until the agent switch
completes. Also migrates search from modal-level to within UnifiedHistoryTab.
The prompt no longer includes a 'Current time:' field, so the test
assertion was failing. Removed the outdated check.
Search icon sits left of the AUTO/USER filter pills. Clicking it (or
pressing ⌘F) reveals a search bar above the filter row without hiding
the existing controls. Escape closes the search first; a second Escape
closes the modal. Search state now lives inside UnifiedHistoryTab
instead of the parent modal.
Compute agent count, unique session count, and AUTO/USER/total entry
counts in the getUnifiedHistory IPC handler (from the full unfiltered
dataset) and surface them via a new HistoryStatsBar component that
scrolls with the entry list below the pinned filter/graph row.
Add full documentation page for Director's Notes covering unified history,
AI overview, and keyboard shortcuts. Restructure docs.json navigation by
renaming "Usage" to "General Usage" and extracting Auto Run-related pages
into a dedicated "Auto Run" section.
@claude
Copy link

claude bot commented Feb 11, 2026

Code Review: Director's Notes Feature

This is an impressive implementation of a comprehensive cross-agent history aggregation and AI synopsis generation feature. The code quality is excellent overall, with strong adherence to the project's architectural patterns and coding standards. Here's my detailed feedback:


✅ Strengths

Architecture & Design

  • Clean separation of concerns: IPC handlers, UI components, and business logic are well-organized
  • Proper use of existing patterns: Follows established Maestro patterns (layer stack, modal priorities, theme system, settings persistence)
  • Progressive loading: UnifiedHistoryTab uses pagination (100 entries/page) with infinite scroll instead of loading everything at once - excellent for performance
  • Module-level caching: AIOverviewTab caches synopsis results across tab switches to avoid regeneration - smart UX optimization
  • File-based history approach: Passing file paths to the AI agent instead of inline JSON is elegant and reduces prompt bloat

Code Quality

  • Comprehensive test coverage: 649 lines of IPC handler tests, 528 lines for DirectorNotesModal, 654 for UnifiedHistoryTab, 337 for AIOverviewTab, plus shared History component tests
  • Strong TypeScript usage: Well-defined interfaces, proper type safety across IPC boundaries
  • Memory leak prevention: Proper use of mountedRef guards in AIOverviewTab to prevent setState on unmounted components
  • Accessibility: Good use of ARIA attributes (role="dialog", aria-modal, aria-labelledby)
  • Focus management: useImperativeHandle pattern for focus control, proper tab focus forwarding
  • Keyboard navigation: Comprehensive keyboard support (Cmd+Shift+[/], Cmd+F search, arrow navigation)

Performance

  • Virtualization: Uses @tanstack/react-virtual for efficient list rendering
  • Memoization: Proper use of useMemo and useCallback to prevent unnecessary re-renders
  • Lazy loading: Components are lazy-loaded with Suspense boundaries
  • Debounced search: Search filtering happens client-side without thrashing

🔍 Potential Issues & Improvements

1. Security: AI Prompt Injection Risk (Medium Priority)

Location: src/main/ipc/handlers/director-notes.ts:264-276

The prompt construction concatenates user-controlled data (session names, file paths) directly into the AI prompt without sanitization. If a session name contains markdown or prompt injection sequences, it could manipulate the AI's behavior.

Recommendation: Sanitize displayName and paths before inserting into the prompt.

2. Error Handling: Missing IPC Registration Check (Low Priority)

Location: src/main/index.ts

Verify that the dependency injection pattern (getProcessManager, getAgentDetector) properly handles null cases and that the handlers are registered after all dependencies are initialized.

3. Performance: Unbounded Graph Data (Low Priority)

Location: src/renderer/components/DirectorNotes/UnifiedHistoryTab.tsx:98-99

Consider sampling or limiting the graph data to a reasonable size (e.g., max 1000 entries) to ensure the graph remains responsive even for power users.

4. UX: Unclear Empty State (Low Priority)

Location: src/renderer/components/DirectorNotes/UnifiedHistoryTab.tsx:383-387

The empty state message doesn't distinguish between no history, filtered out history, or history outside lookback window. Make the message contextual.

5. Type Safety: Generic Provider Type (Low Priority)

Location: src/main/ipc/handlers/director-notes.ts:83

The provider field is typed as string instead of the union type of valid agent IDs. Use ToolType for better type safety.

6. Documentation: Missing SSH Remote Awareness (Low Priority)

Add a note in the documentation about SSH remote support (or explicitly test it if not covered).


📝 Minor Nits

  1. Magic number: The "500px from bottom" threshold for infinite scroll should be a named constant
  2. Hardcoded opacity: opacity-70 could use the theme's textDim color instead

🎯 Summary

Overall Assessment: This is production-ready code with excellent architecture, comprehensive testing, and strong adherence to Maestro's conventions. The feature is well-designed and solves a real UX problem (cross-agent visibility) elegantly.

Blocking Issues: None

Recommended Before Merge:

  1. Address the prompt injection security concern (sanitize user input in AI prompts)
  2. Verify IPC handler registration error handling

Nice-to-Have:
3. Improve empty state messaging
4. Add SSH remote documentation
5. Consider graph data sampling for large datasets

Great work! The 33 commits show a thoughtful, iterative development process with excellent commit messages. The test coverage is outstanding, and the feature is very well documented.


Files Reviewed: 91 changed files, focusing on IPC handlers, Modal components, Settings integration, Test coverage, and Documentation

…re refactors)

- App.tsx: Remove Group/GroupChatMessage imports (moved to groupChatStore),
  keep both Director's Notes navigation and new useAgentListeners hook
- AutoRun.tsx: Take main's batchStore indentation, preserve formatShortcutKeys
- HistoryPanel.tsx: Keep extracted History/ imports, add useUIStore from main,
  remove re-inlined components that already exist in History/ module
- Add sanitizeDisplayName() to strip markdown from session names in AI prompts
- Tighten SynopsisOptions.provider from string to ToolType union
- Replace hardcoded opacity-70 with theme.colors.textDim
- Extract scroll threshold magic number to SCROLL_LOAD_THRESHOLD constant
- Make empty state messaging contextual (search, filters, lookback, no data)
@pedramamini pedramamini merged commit 49935ae into main Feb 15, 2026
1 check failed
@pedramamini pedramamini deleted the directors-notes branch February 15, 2026 03:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants