Commit Graph

2440 Commits

Author SHA1 Message Date
Pedram Amini
9dbb2419b6 feat(left-bar): add drop zone for ungrouping when all sessions are in groups
- Shows "Drop here to ungroup" zone when dragging a session and no ungrouped sessions exist
- Allows users to drag sessions out of groups even when Ungrouped Agents folder is hidden
- Added tests for drop zone visibility and drop handler
2026-02-01 22:46:01 -06:00
Pedram Amini
434f89268e fix(notifications): show Stop button only while command is running
Previously, the Test button would show "Stop" after the notification
command started and remain visible even after the process exited,
requiring an 8-second timeout fallback to reset.

Now the component listens for the onCommandCompleted event and
immediately resets to "Test" (via Success state) when the process
exits naturally. The Stop button is only shown while the process
is actively running.
2026-02-01 22:44:15 -06:00
Pedram Amini
ed14745e63 test updates 2026-02-01 22:36:35 -06:00
Pedram Amini
c769668b6c refactor(notifications): complete ttsId to notificationId migration
Remove backward compatibility shim and fully migrate from legacy ttsId
property to notificationId across all notification-related code:

- Update NotificationsPanel.tsx to use result.notificationId
- Remove deprecated ttsId from NotificationCommandResponse interface
- Remove legacy TTS alias exports from handler
- Update all test files and mocks to use notificationId
2026-02-01 22:30:29 -06:00
Pedram Amini
141d0e015e fix(history): use actual task duration for USER entry elapsed time
Changed elapsed time calculation for USER history entries to use the
actual task duration (from thinkingStartTime to completion) instead of
time since the last synopsis. This accurately reflects how long the
agent was actively working on the task being synopsized.
2026-02-01 22:25:47 -06:00
Pedram Amini
d9d4a44894 feat(history): add elapsed time tracking for USER history entries
Add elapsed time calculation when creating USER history entries via
the saveToHistory/synopsis feature. Time is calculated from lastSynopsisTime
(if a previous synopsis exists) or tabCreatedAt (for first synopsis).
This complements the existing elapsed time tracking for AUTO entries.
2026-02-01 22:24:04 -06:00
Pedram Amini
2968a36e11 docs: update notification docs for Custom Notifications rename (#168)
- Rename "Speakable Notifications" to "Custom Notifications" in features
- Update Notifications tab description to remove TTS-specific language
- Revise Custom Notification section with broader command examples
- Remove default TTS bias from configuration guidance
2026-02-01 22:21:13 -06:00
Pedram Amini
9605e44366 docs(skills): add documentation for /skills command with screenshot
Documents the /skills slash command in the slash commands guide,
including the screenshot and explanation that it's Claude Code only.
2026-02-01 22:18:10 -06:00
Pedram Amini
e306be17ac chore: fix 39 ESLint unused variable warnings
- Remove unused FocusArea import from App.tsx
- Prefix unused destructured variables with _ (inline wizard state, refs)
- Remove unused imports (useCallback, MainPanelHandle, hasExistingAutoRunDocs, etc.)
- Remove unused SymphonyCategory type import
- Fix prefer-const warning in fileExplorer.ts (regexStr)
2026-02-01 22:13:46 -06:00
Pedram Amini
1c75629805 fix(drag-drop): use capture phase for document-level listeners to enable repeated drops
The previous fix added document-level dragover/drop handlers to call
preventDefault(), but handleImageDragOver was calling stopPropagation()
which prevented the document-level handlers from firing during the bubble
phase. Switching to capture phase ensures preventDefault() is called at
the document level before element handlers can stop propagation.
2026-02-01 21:58:50 -06:00
Pedram Amini
33de2c15ab test(notifications): explicitly verify NO whitelist for custom commands
Update notification tests to clearly document and verify that:
- Custom notification commands have NO whitelist and NO validation
- ANY executable path, binary name, or arguments are allowed
- Shell pipelines with redirects and pipes are fully supported

Also rename TTS terminology to generic notification terminology:
- resetTtsState → resetNotificationState
- getTtsQueueLength → getNotificationQueueLength
- getActiveTtsCount → getActiveNotificationCount
- clearTtsQueue → clearNotificationQueue
- getTtsMaxQueueSize → getNotificationMaxQueueSize
- Add onCommandCompleted alongside deprecated onTtsCompleted

This ensures the feature remains open-ended for user flexibility.
2026-02-01 21:52:31 -06:00
Pedram Amini
6b33e72a21 perf: lazy-load heavy modals and consolidate session ID parsing
- Add sessionIdParser utility with pre-compiled regex patterns for parsing
  session IDs (AI tab, synopsis, batch, group chat formats). Replaces 20+
  inline regex compilations with shared module-level constants.

- Lazy-load rarely-used heavy components to reduce initial bundle:
  - SymphonyModal (2,193 lines)
  - MarketplaceModal (playbook exchange)
  - UsageDashboardModal (8 chart components)
  - ProcessMonitor
  - LogViewer (system logs)
  - GitLogViewer
  - GitDiffViewer
  - DocumentGraphView (mind map visualization)

- Add comprehensive test coverage for sessionIdParser utility

These changes reduce initial JavaScript execution time by deferring
loading of ~10k+ lines of rarely-accessed modal code until first use.
2026-02-01 21:48:12 -06:00
Pedram Amini
90bb955df5 fix(drag-drop): add document-level preventDefault to enable repeated image drops
Without preventing default on both dragover and drop at the document level,
Electron/Chromium can reject subsequent drag-and-drop operations after the
first drop. This adds document-level handlers that call preventDefault() on
both events, ensuring the drop zone remains valid across multiple operations.
2026-02-01 20:10:34 -06:00
Pedram Amini
2dc99e646a feat(notifications): allow any custom notification command
- Remove TTS command whitelist validation - users can now configure any
  command for custom notifications (e.g., fabric piped to 11s)
- Enable shell mode for spawn to support pipes and command chains
- Add visual feedback to Test button (running/success/error states)
- Remove speech bubble from AI response messages in TerminalOutput
- Rename internal TTS terminology to more generic "notification command"
- Update tests to reflect new behavior
2026-02-01 20:06:34 -06:00
Pedram Amini
9e83588ffd fix(save-markdown-modal): use createPortal to render at document body
Fixes overlay not covering sidebar and file panel by rendering the
modal via React portal to document.body, ensuring proper z-index
stacking across all UI layers.
2026-02-01 19:49:27 -06:00
Pedram Amini
f9db845712 fix(tests): add missing webContents.on mock for render-process-gone handler
The window-manager tests were failing because the mock webContents
object was missing the 'on' method needed by the crash detection handler.
2026-02-01 18:16:47 -06:00
Pedram Amini
c2239fee70 feat(stats-db): add Sentry error reporting for database failures
Stats DB initialization failures were only logged locally, providing no
visibility into production issues. This change adds Sentry reporting for:

- Database corruption detection (integrity check failures)
- Native module loading failures (architecture mismatches)
- Database creation failures
- General initialization failures

Created reusable Sentry utilities in src/main/utils/sentry.ts that
lazily load @sentry/electron to avoid module initialization issues.
2026-02-01 18:13:24 -06:00
Pedram Amini
5ccebfd73e feat(crash-detection): add renderer crash handlers and Sentry reporting
Add comprehensive crash detection for renderer process failures that
Sentry in the renderer cannot capture (because the process is dead,
broken, or failed before Sentry initialized):

- render-process-gone: captures crash, kill, OOM, launch-failed
- unresponsive/responsive: tracks frozen window states
- crashed: handles page-level crashes
- did-fail-load: captures page load failures (network, invalid URLs)
- preload-error: captures preload script failures before app loads
- console-message: forwards critical renderer errors (TypeError, etc.)

Reports to Sentry from main process with detailed context.
Auto-reloads renderer after non-intentional crashes.
2026-02-01 18:07:19 -06:00
Pedram Amini
4405540003 fix(settings): restore maxOutputLines correctly when set to Infinity
When users select "All" for Max Output Lines, Infinity is stored but
JSON.stringify(Infinity) produces null. On app restart, this null value
was being loaded directly, causing:
- null * 1.5 = 0 for maxHeight calculation
- All AI responses appearing fully collapsed (only "Show all X lines")

Now we detect null values for maxOutputLines and restore them as
Infinity, matching the user's original "All" selection.

Root cause: JSON cannot represent Infinity, so it becomes null during
serialization to electron-store.

Fixes the regression where maxOutputLines setting was lost on restart.
2026-02-01 17:46:33 -06:00
Pedram Amini
93faa712b0 feat(terminal-output): add save button to AI response tool panel
Add a save icon to the action buttons at the bottom of AI responses
that opens a modal allowing users to save the markdown content to a
file. The modal includes:
- Folder path input with a browse button for filesystem navigation
- Filename input with automatic .md extension handling
- Error handling and validation
2026-02-01 16:23:43 -05:00
Pedram Amini
528dbf27a6 fix(tour): remove labels from pencil/image icons, fix thinking description
- Remove "Pencil" and "Image" labels to show icon-only for those controls
- Update Thinking description to "toggles display of agent thinking"
- Make label prop optional in TourIcon component
2026-02-01 16:08:21 -05:00
Pedram Amini
274698efea feat(file-preview): dismiss TOC overlay on click outside
Add an invisible fixed backdrop behind the TOC overlay that captures
clicks outside the menu, providing standard dismiss-on-click-outside
behavior.
2026-02-01 15:57:47 -05:00
Pedram Amini
db5ae7cac1 feat(tour): render actual Lucide icons inline in input area step
- Convert tourSteps.ts to tourSteps.tsx to support JSX content
- Add descriptionContent/descriptionContentGeneric fields to TourStepConfig
  for rendering JSX after the text description
- Create TourIcon component that renders actual Lucide icons inline
- Update input area step to show PenLine, ImageIcon, History, Eye, Brain,
  and Keyboard icons matching the actual UI controls
- Widen tooltip to 480px when step has extra JSX content
- Restore original description text, move icon explanations to JSX content
2026-02-01 15:56:09 -05:00
Pedram Amini
88d960e73b fix(main-panel): remote file loading state now fills entire main panel
When loading remote content (e.g., README.md from SSH), the loading
indicator now takes over the entire main panel instead of showing
alongside the terminal output. This prevents the awkward half-filled
appearance.
2026-02-01 15:47:15 -05:00
Pedram Amini
8f63b6d87d fix(symphony): fallback to expired cache when GitHub fetch fails
Apply the same fix from the marketplace handlers to Symphony:
- getRegistry: Falls back to expired cache when GitHub fetch fails
- getIssues: Falls back to expired cache when GitHub fetch fails

This prevents showing empty data when the network is unavailable
but valid (though expired) cache data exists.
2026-02-01 15:22:16 -05:00
Pedram Amini
7c4c40b7c2 fix(marketplace): fallback to expired cache when GitHub fetch fails
When the Playbook Exchange modal opens and the manifest cache is expired,
we attempt to fetch fresh data from GitHub. Previously, if this fetch
failed (network error, timeout, etc.), we would return an empty manifest
showing "No playbooks available" - a confusing UX.

Now we fall back to the expired cache data if available, which is better
than showing nothing. This ensures users can still browse playbooks even
when GitHub is temporarily unreachable.

Changes:
- getManifest: Fall back to expired cache when fresh fetch fails
- refreshManifest: Fall back to existing cache when refresh fails
- Added tests for new fallback behavior
2026-02-01 15:18:26 -05:00
Pedram Amini
c6097b18e3 feat(prompts): add code reuse and refactoring guidance to system prompts
Add hints across implementation-focused prompts to encourage searching
for existing code patterns before creating new implementations. This
addresses the issue of duplicate code being generated by guiding agents
to reuse and extend existing utilities, helpers, and patterns.

Updated prompts:
- autorun-default.md: Task implementation now searches for existing code first
- maestro-system-prompt.md: New "Code Reuse and Refactoring" section
- wizard-document-generation.md: Tasks should be reuse-aware, phases include guidance
- speckit.tasks.md: New "Code Reuse Principle" section before task generation
- speckit.implement.md: Task guidelines include reuse-awareness
- openspec.implement.md: Task guidelines include reuse-awareness
2026-02-01 15:01:03 -05:00
Pedram Amini
9028120a2e feat(tour): use icon descriptions matching actual UI elements
Update input area tour step to describe each icon with visual hints that
match the actual Lucide icons used in the input area. Also update
TourStep component to properly render newlines as line breaks so the
bulleted list of icons displays correctly.

Icons now described:
- Pencil (✎) for expanded prompt editor
- Image (🖼) for file attachments
- History (⏱) for session history toggle
- Eye (👁) for read-only mode
- Brain (🧠) for extended thinking
- Keyboard (⌨) for submit hotkey toggle
2026-02-01 14:12:48 -05:00
Pedram Amini
02f86bcff4 feat(tour): enhance input area step with detailed feature descriptions
Add comprehensive description of input area features during introductory
tour including expanded prompt editor (pencil icon), image attachments,
and toggle buttons for History, Read-Only, and Thinking modes. Also
mention the submission hotkey option and link to Settings for defaults.
2026-02-01 13:34:43 -05:00
Pedram Amini
6d0cc1e326 fix(file-preview): ensure TOC overlay sashes are fully visible
Use flexbox layout with flex-shrink-0 on header and sash elements to
prevent them from being clipped. The scrollable entries section now
uses flex-1 min-h-0 to take remaining space while allowing proper
overflow scrolling.
2026-02-01 13:25:30 -05:00
Pedram Amini
23f4212933 fix(settings): reload settings on system resume to prevent reset after sleep
When the computer goes to sleep and wakes up, some settings like
MAX OUTPUT LINES PER RESPONSE were resetting to default values.

This adds Electron's powerMonitor to detect system resume events and
notify the renderer to reload settings from persistent storage:

- Add powerMonitor.on('resume') listener in main process
- Add onSystemResume IPC handler in preload API
- Refactor loadSettings to useCallback for reuse
- Register system resume listener in useSettings hook

Closes #269
2026-02-01 10:31:45 -05:00
Pedram Amini
c1da1711e6 fix(file-preview): fix TOC Top/Bottom scroll using correct container
The scroll function was targeting markdownContainerRef (inner content div)
instead of contentRef (the actual scrollable parent container).
2026-02-01 10:13:23 -05:00
Pedram Amini
d914470918 fix(tests): make tool execution event tests provider-aware
Claude Code reliably emits tool execution events in stream-json format,
but Codex and OpenCode may not emit parseable tool events or may answer
from context without using tools.

Updated the 'should emit tool execution events' and 'should track tool
execution state transitions' tests to only assert tool event requirements
for Claude Code, while keeping informational logging for other providers.

The tests still verify the core functionality (correct response) for all
providers, but tool event parsing is now provider-specific.

Fixes integration test failure for Codex tool execution events.
2026-02-01 10:12:17 -05:00
Pedram Amini
f045c08fbc docs: move SYMPHONY_*.md to project root
These are internal/maintainer docs (not user-facing), so they belong
at the top level alongside CLAUDE.md, CONTRIBUTING.md, etc.
2026-02-01 09:51:16 -05:00
Pedram Amini
c2e9efc444 fix(git): handle malformed HTTPS+SSH hybrid remote URLs
Some git clients produce malformed URLs that mix HTTPS and SSH formats
(e.g., `https://git@github.com:user/repo`). These URLs would cause
window.open() to fail with an invalid URL error.

Added handling to convert these hybrid URLs to proper HTTPS format.

Fixes MAESTRO-43
2026-02-01 09:38:48 -05:00
Pedram Amini
e2fffe2987 chore: simplify Playbook Exchange description text
Remove "development" from "common development workflows" since
playbooks cover broader use cases beyond development.
2026-02-01 09:35:49 -05:00
Pedram Amini
2d2d80733e refactor(file-preview): move TOC widget to bottom-right corner
Move the floating Table of Contents button and overlay from bottom-left
to bottom-right for better visual balance with the content area.
2026-02-01 09:34:26 -05:00
Pedram Amini
1560594360 docs: consolidate React DevTools profiling guide in CONTRIBUTING.md
Move React DevTools profiling instructions from CLAUDE-PERFORMANCE.md
to CONTRIBUTING.md under the Profiling section:
- Full installation and launch commands
- Components and Profiler tab descriptions
- Step-by-step profiler workflow
- Chrome DevTools Performance tab guidance

CLAUDE-PERFORMANCE.md now references CONTRIBUTING.md for profiling
workflow (keeping it focused on code patterns for AI).

Claude ID: 286ae250-379b-4b74-a24e-b23e907dba0b
Maestro ID: b9bc0d08-5be2-4fdf-93cd-5618a8d53b35
2026-02-01 09:32:32 -05:00
Pedram Amini
a164f16c07 Merge pull request #270 from chr1syy/0.15.0-rc-win-fixes
feat: Fix inline wizard for Windows cmd.exe and add OpenCode support
2026-02-01 09:32:11 -05:00
Pedram Amini
ed1389ab50 docs: add React DevTools profiling guide to CLAUDE-PERFORMANCE.md
Document the standalone React DevTools app for render profiling:
- Installation and launch commands
- Auto-connection via script in src/renderer/index.html
- Components and Profiler tab descriptions
- Basic profiler workflow for identifying render issues

Claude ID: 286ae250-379b-4b74-a24e-b23e907dba0b
Maestro ID: b9bc0d08-5be2-4fdf-93cd-5618a8d53b35
2026-02-01 09:08:29 -05:00
Pedram Amini
43b4f66895 docs: add React DevTools profiling instructions to CONTRIBUTING.md
Document how to use the standalone React DevTools app for component
inspection and render profiling. The connection script already exists
in src/renderer/index.html but wasn't documented.

Claude ID: 286ae250-379b-4b74-a24e-b23e907dba0b
Maestro ID: b9bc0d08-5be2-4fdf-93cd-5618a8d53b35
2026-02-01 09:06:36 -05:00
Pedram Amini
2f9c0b1c17 test(SessionList): verify New Group button placement (inline vs standalone)
- Test button is inline within Ungrouped Agents header when ungrouped sessions exist
- Test button is standalone (full-width) when no ungrouped sessions exist
- Prevents regression of button placement behavior
2026-02-01 09:03:06 -05:00
chr1syy
d8b4e3f271 fix failing inline Wizard test 2026-02-01 14:48:15 +01:00
chr1syy
227b0b73b4 feat: Fix inline wizard for Windows cmd.exe and add OpenCode support
## Windows Command Line Length Fix

Resolved 'Die Befehlszeile ist zu lang' (command line too long) error on Windows by:
- Modified inline document generation to use sendPromptViaStdin on Windows
  - Passes prompt via stdin instead of as command line argument
  - Bypasses Windows cmd.exe ~8KB command line length limit
  - Matches approach already used for SSH remote execution
- Added --input-format stream-json when using stdin with stream-json compatible agents
- Added logging for prompt length and stdin usage for debugging

## OpenCode Agent Support

Extended inline wizard to support OpenCode agent alongside Claude Code and Codex:
- Added 'opencode' to supported wizard agents list in useInlineWizard hook
- OpenCode batch mode args handling already present in buildArgsForAgent functions
- Added SSH-aware availability checking in both conversation and document generation phases

## SSH Remote Configuration

Improved SSH remote session handling:
- Added sessionSshRemoteConfig to DocumentGenerationConfig interface
- Added sendPromptViaStdin and sendPromptViaStdinRaw to renderer ProcessConfig
- Pass sessionSshRemoteConfig through entire wizard lifecycle (conversation → document generation)
- Skip local agent availability checks when executing on remote hosts
- Use agent type as command fallback for remote-only agents
- Added logging to distinguish remote execution from local

## Remote Agent Availability Fix

Fixed critical bug preventing remote SSH agents from being used:
- Split agent availability checks to allow null agents for remote sessions
- For remote sessions: skip both null-check AND availability-check
- For local sessions: enforce both checks as before
- Allows remote-only agents (like SSH-configured OpenCode) to work for both conversation and document generation

## Test Updates

- Fixed useInlineWizard.test.ts by adding window.maestro.agents.get mock
- Mock returns agent info needed for availability checks
- Added comprehensive test coverage for remote agent scenarios
2026-02-01 14:32:29 +01:00
Pedram Amini
d59142366d fix(file-preview): make TOC Top/Bottom buttons sticky sash elements
- Move Top and Bottom navigation buttons outside the scrollable section
- Add distinct background styling with accent color tint
- Add border separators for visual hierarchy (border-b for Top, border-t for Bottom)
- Reduce scrollable section height to account for fixed sash buttons
- Add data-testid attributes for testing
- Add test coverage for sash button visibility and functionality
2026-02-01 01:23:33 -05:00
Pedram Amini
ecdcd5b883 fix(left-bar): show New Group button inline with Ungrouped Agents header
- When ungrouped agents exist: inline button in header (like Group Chats)
- When no ungrouped agents: standalone full-width button (folder hidden)
- When no groups exist (flat list): standalone full-width button below sessions
2026-02-01 01:19:41 -05:00
Pedram Amini
ef7ac9c6a2 ## CHANGES
- Added “View Git Log” action right inside GitStatusWidget tooltip 🧭
- Wired MainPanel to open Git Log directly from the widget 🪟
- Expanded GitStatusWidget API with optional `onViewLog` callback 🧩
- Improved test coverage for Git log tooltip interactions and rendering 🧪
- Cleaned repo by removing auto-generated CLAUDE.md memory context files 🧹
- Enhanced release notes frontmatter with a new newspaper icon 🗞️
2026-02-01 00:14:51 -05:00
Pedram Amini
a809be18e0 test: update tests for expanded Usage Dashboard metrics and new icons
- Update SummaryCards tests for 9 metric cards (was 6)
  - New metrics: Queries/Session, Peak Hour, Local %
  - Add aria-label queries to disambiguate duplicate percentage values

- Add missing lucide-react icons to test mocks
  - SummaryCards: Sunrise, Globe, Zap
  - WeekdayComparisonChart: Briefcase, Coffee

- Update UsageDashboardModal tests
  - Time range options: 6 (added 'quarter')
  - Activity view sections: activity-heatmap → weekday-comparison → duration-trends

- DocumentGraphView: focus content area after history navigation

Claude ID: 9d439c12-65ed-4ca4-b721-f9393614b8c2
Maestro ID: b9bc0d08-5be2-4fdf-93cd-5618a8d53b35
2026-01-31 23:35:06 -05:00
Pedram Amini
c849757c46 ## CHANGES
- Preview panel now supports back/forward history with arrow-key navigation 🧭
- Added slick chevron buttons for preview back/forward with disabled states 🔙
- Wiki-link resolution now scans *all* markdown files, not just graphed ones 🗂️
- Graph data builder now pre-scans markdown paths for faster preview linking 🔎
- Stats dashboards gained a new “This Quarter” time range everywhere 📆
- Activity heatmap adds quarter support with richer 4-hour block granularity 🧱
- Brand-new Agent Efficiency chart compares average response time per agent ⏱️
- New Weekday vs Weekend comparison chart highlights productivity patterns 🗓️
- New “Tasks by Time of Day” chart surfaces Auto Run hourly hotspots 🌙
- Modal PR link is now keyboard-accessible and opens externally safely 
2026-01-31 23:03:11 -05:00
Pedram Amini
ec3a5b528f fix(ssh): skip adding prompt to args when using stdin for SSH
When sendPromptViaStdin or sendPromptViaStdinRaw is set, the prompt
will be sent via stdin as stream-json data. The ChildProcessSpawner
was incorrectly ALSO adding the prompt to the command line args,
causing shell escaping issues with zsh on remote hosts.

This fix skips adding the prompt to args when it will be sent via
stdin, preventing:
- "zsh:35: parse error near 'do'" from multi-line prompts
- "zsh:3: no matches found: **Summary:**" from glob-like patterns

The prompt still gets sent correctly via stdin in the isStreamJsonMode
block at line 389+.
2026-01-31 21:47:16 -05:00