Commit Graph

2643 Commits

Author SHA1 Message Date
Pedram Amini
21f1bbdec3 Fix file preview tab close button visibility when tab is focused
- Add shrink-0 to AI Tab and FileTab containers to prevent flex
  compression, ensuring tabs maintain natural width for all content
  including extension badge and close button
- Use double requestAnimationFrame for scroll-into-view to ensure
  DOM has fully rendered (including conditional close button) before
  measuring tab width for scrolling
- Replace scrollIntoView with manual scrollLeft calculation to ensure
  the ENTIRE tab (including right edge with close button) is visible,
  not just enough to show some portion of the tab
- Update scroll behavior tests to match new implementation
2026-02-04 18:35:51 -06:00
Pedram Amini
1a888973d2 Remove unused error variable in logger catch block
The catch block intentionally ignores all errors to prevent infinite
loops, so the error value is never used. Use bare catch syntax.
2026-02-04 14:33:49 -06:00
Pedram Amini
c3309e05ed Add missing Info and Wand2 icon mocks to wizard integration tests
The AgentSelectionScreen now uses Info and Wand2 icons from lucide-react
(added for the inline wizard tip box). Update the test mock to include
these icons so tests don't fail with missing export errors.
2026-02-04 13:51:19 -06:00
Pedram Amini
9ce51a88f9 Trim leading/trailing whitespace on paste across all input areas
When pasting content, automatically trim leading and trailing whitespace
to reduce manual cleanup. The trimming only intercepts paste when there
is actual whitespace to remove, otherwise native paste behavior is used.

Input areas updated:
- Main AI/terminal input (App.tsx)
- Group chat input (GroupChatInput.tsx)
- Prompt composer modal (PromptComposerModal.tsx)
- Auto Run document editor (useAutoRunImageHandling.ts)
- Wizard document editor (DocumentEditor.tsx)
- Inline wizard document generation (DocumentGenerationView.tsx)
2026-02-04 13:50:54 -06:00
Pedram Amini
32bb3cf354 Add tip box with inline wizard alternatives to agent selection screen
- Move "Select the provider" text directly above agent tiles for better flow
- Add info box explaining keyboard capture and alternatives (/wizard command, wand button)
- Display inline Wand2 icon for visual clarity
- Center note box vertically with equal spacing above/below
- Update test mocks to include Info, Wand2, and AlertTriangle icons
2026-02-04 13:17:30 -06:00
Pedram Amini
a0f104f58f Add tip box with inline wizard alternatives to agent selection screen
- Move "Select the provider" text directly above agent tiles for better flow
- Add info box explaining keyboard capture and alternatives (/wizard command, wand button)
- Display inline Wand2 icon for visual clarity
- Update test mocks to include Info, Wand2, and AlertTriangle icons
2026-02-04 13:15:40 -06:00
Pedram Amini
798541cb4b Rename provider-nuances to provider-notes and add custom configuration docs
Add new Custom Configuration section documenting custom CLI arguments and
environment variables with screenshot. Rename navigation group to "Providers
& CLI" and reorder to list provider-notes first.
2026-02-04 13:14:17 -06:00
Pedram Amini
f599072cdc Fix SSH remote sessions displaying raw JSON instead of parsed responses
Enable stream-json mode for SSH stdin script execution. When SSH wraps
agent commands, the args being checked (SSH args like -o BatchMode=yes)
don't contain 'stream-json', causing JSON output to bypass the parser.

Added sshStdinScript to isStreamJsonMode detection so remote agent
output is properly parsed through the JSON output parser.
2026-02-04 12:21:20 -06:00
Pedram Amini
da5551fea5 Add Sentry breadcrumbs and memory monitoring for crash diagnostics
- Add addBreadcrumb() utility to track user actions before crashes
- Add startMemoryMonitoring() with configurable threshold and interval
- Record breadcrumbs at agent spawn/kill operations
- Auto-start memory monitoring when Sentry initializes (500MB threshold, 1min interval)

This provides context in crash reports to help identify patterns
leading to renderer crashes (MAESTRO-5A/4Y).

Relates to MAESTRO-5A, MAESTRO-4Y
2026-02-04 11:41:15 -06:00
Pedram Amini
a761b84e77 Ensure dialog:selectFolder IPC handler always sends reply
Add try-catch wrapper and isDestroyed() check to prevent "reply was
never sent" errors when the window closes during dialog operations.

Fixes MAESTRO-58
2026-02-04 11:41:06 -06:00
Pedram Amini
3109189305 Fix EPIPE error when console stdout is disconnected
Wrap console output in try-catch to gracefully handle EPIPE errors
that occur when a parent process consuming output dies unexpectedly.

Fixes MAESTRO-5C
2026-02-04 11:40:58 -06:00
Pedram Amini
af4a6c4c93 ## CHANGES
- Symphony modal now receives sessions list for richer contribution context 🧩
- Active contributions show clickable session name with new Terminal icon 🖥️
- Added “navigate to session” flow directly from contribution cards 🧭
- Selecting a session updates active session and auto-closes modal 
- Session lookup wires contributions to matching session IDs seamlessly 🔗
2026-02-04 07:51:29 -06:00
Pedram Amini
16cf35390c let users know about how maestro works 2026-02-04 00:59:45 -06:00
Pedram Amini
f38f6b66e6 ## CHANGES
- Renamed empty-state action from “Select Folder” to “Change Folder” for clarity 🧭
- Refreshed empty-state helper text to match the new folder-change flow 📝
- Cleaned up `EditGroupChatModal` icon imports by dropping the unused `X` 🎛️
2026-02-04 00:15:13 -06:00
Pedram Amini
17fed4f232 ## CHANGES
- Added Code Style section to CLAUDE.md specifying tabs-for-indentation requirement 📏
- Added Root Cause Verification section under Debugging with historical bug patterns 🔍
- Added UI Bug Debugging Checklist to CLAUDE-PATTERNS.md (section 11) 🎨
- Documents CSS-first debugging, portal escapes, and fixed positioning pitfalls 🐛
2026-02-03 23:29:48 -06:00
Pedram Amini
a7e504e205 ## CHANGES
- Symphony IPC now validates active contributions against stored sessions 🧩
- Orphaned contributions auto-filtered when sessions disappear, keeping UI clean 🧹
- `symphony:getState` returns only session-backed active items for accuracy 🎯
- `symphony:getActive` now excludes contributions tied to missing sessions 🚫
- Added reusable `filterOrphanedContributions` helper with detailed logging 🪵
- Wired `sessionsStore` dependency through main + handler registration flow 🔌
- Integration tests now mock sessions store for realistic state scenarios 🧪
- Expanded handler tests to cover missing-session filtering behavior 🛡️
2026-02-03 23:21:06 -06:00
Pedram Amini
bcf6c4e60d ## CHANGES
- Added brand-new cross-platform guide covering Windows, Linux, macOS, SSH gotchas 🌍
- Documented SSH remote constraints: no chokidar watch, stdin prompts, path norms 🛰️
- Standardized path best-practices: `path.join`, `path.posix`, delimiters, tilde expansion 🧭
- Clarified shell execution differences: default shells, which/where lookup, permissions 🐚
- Codified agent portability quirks: session IDs, storage locations, resume flags 📦
- Introduced keyboard/input pitfalls: macOS Alt keycodes, Windows command-length limits ⌨️
- Added Git cross-platform warnings: stat differences and case-sensitivity traps 🧩
- Upgraded collaboration rules: assumptions, confusion stops, pushback, scope discipline 🤝
- Added Sentry/error-handling guidance: bubble unexpected errors, report with context 🔎
- Refreshed docs structure references to match current `src/` layout and modules 🗺️
2026-02-03 19:31:52 -06:00
Pedram Amini
d5ad08ec9f ## CHANGES
- Default OpenCode vision model now uses `ollama/qwen3-vl:latest` tagging 🏷️
- SSH integration detects remote auth failures across Claude, Codex, OpenCode 🔐
- Added remote config-error detection for missing models/providers in output 🧩
- Added remote path/environment error detection to avoid false SSH failures 🗺️
- SSH tests now skip assertions when remote paths don’t exist (expected) ⏭️
- New SSH integration test validates end-to-end image OCR via agents 🖼️
- Image SSH test auto-copies fixture to remote `/tmp` for file-based agents 📤
- IPC SSH execution switched to stdin-fed `/bin/bash` for cleaner runs 🐚
- SSH command builder now exports env + cwd via stdin script reliably 📜
- AutoRun shows Save/Revert whenever dirty (even in preview mode) 💾
- Context consumption warnings now default to disabled in settings ⚙️
2026-02-03 16:43:13 -06:00
Raza Rauf
e6ced8a77b Merge pull request #289 from pedramamini/code-refactor
feat: add conservative context growth estimation during multi-tool turns
2026-02-03 16:40:56 -06:00
Raza Rauf
4fe009e30f Merge branch 'main' into code-refactor 2026-02-04 03:35:43 +05:00
Raza Rauf
d4d94471f0 resolved merge conflicts 2026-02-04 03:27:32 +05:00
Raza Rauf
234d13ac08 Merge branch 'code-refactor' of https://github.com/pedramamini/Maestro into code-refactor 2026-02-04 03:24:31 +05:00
Pedram Amini
44e11ecf16 Merge branch 'fix-opencode'
Merges OpenCode fixes and SSH stdin improvements:
- Use stdin passthrough for all SSH prompts (simplifies escaping)
- Add question:deny to OpenCode permission block for robust tool disabling
- Simplify stdin prompt delivery by appending after exec (no heredoc needed)
2026-02-03 15:21:21 -06:00
Pedram Amini
963531e4ff ## CHANGES
- Swapped moderator selection tiles for a clean agent dropdown picker 🔽
- Added expandable “Customize” panel directly inside both group chat modals ⚙️
- Lazily loads agent config/models only when customization panel expands 🚀
- Resets custom path/args/env overrides automatically when changing agents 🧹
- Displays clear “Detecting agents…” inline spinner during agent discovery 
- Labels Codex, OpenCode, and Factory Droid options as “(Beta)” 🧪
- Expands empty-state messaging to recommend installing Factory Droid too 🧩
- Simplified modal flow by removing separate config-view navigation entirely 🧭
- Improved accessibility with proper combobox/button roles in modal controls 
- Strengthened test coverage for dropdown options and moderator-change warning 🧯
2026-02-03 15:17:25 -06:00
Pedram Amini
63d15d1a16 fix(opencode): add question:deny to permission block for robust tool disabling
Per OpenCode GitHub issue workaround, add "question": "deny" to the
permission block in addition to the existing "tools":{"question":false}.

This ensures the question tool is disabled via both configuration methods,
preventing stdin hangs in batch mode.

Config now: {"permission":{"*":"allow","external_directory":"allow","question":"deny"},"tools":{"question":false}}
2026-02-03 15:17:01 -06:00
Pedram Amini
ccabe75248 refactor(ssh): simplify stdin prompt delivery with passthrough approach
Replace heredoc-based prompt delivery with simpler stdin passthrough.

How it works:
1. Bash script is sent via stdin to /bin/bash on the remote
2. Script sets up PATH, cd, env vars, then calls `exec <agent>`
3. The `exec` replaces bash with the agent process
4. The agent inherits stdin and reads the remaining content (the prompt)

Benefits:
- No heredoc syntax needed
- No delimiter collision detection
- No prompt escaping required - prompt is never parsed by any shell
- Works with any prompt content (quotes, newlines, $, backticks, etc.)
- Simpler, more maintainable code

Changes:
- Remove heredoc logic from buildSshCommandWithStdin()
- Update process.ts to use stdin passthrough for ALL agents over SSH
  (not just OpenCode - all agents benefit from this approach)
- Update tests to verify stdin passthrough behavior

Verified locally that both OpenCode and Claude Code read prompts from stdin.
2026-02-03 15:13:55 -06:00
Raza Rauf
e409123d9e feat: add conservative context growth estimation during multi-tool turns
When Claude Code performs multi-tool turns (many internal API calls),
accumulated token values cause estimateContextUsage to return null,
freezing the context gauge. This adds estimateAccumulatedGrowth which
provides conservative 1-3% per-turn growth estimates so the gauge
keeps moving during tool-heavy sessions.

Safety: App.tsx caps all estimates at yellowThreshold - 5, guaranteeing
that estimates can never trigger compact warnings — only real
measurements from non-accumulated turns can.
2026-02-04 01:43:00 +05:00
Pedram Amini
ed374bc69d fix(dashboard): use accurate agent count excluding terminal sessions
Update SummaryCards to accept sessions prop and filter out terminal-only
sessions when calculating agent count for consistent metrics display.
This ensures queries-per-session and total sessions accurately reflect
AI agent sessions rather than including terminal sessions.
2026-02-03 14:27:30 -06:00
Pedram Amini
4bdfa86b83 fix(wizard): use navigator.platform for Windows detection in renderer
Replace process.platform with navigator.platform for Windows detection
in the inline wizard conversation service, as process.platform is not
available in the browser/renderer context.
2026-02-03 14:27:24 -06:00
Pedram Amini
078a837ef4 feat(agents): add Factory Droid to Beta badge list
Adds 'factory-droid' agent to the Beta badge display in:
- NewInstanceModal agent selection
- AgentSelectionScreen wizard tiles
2026-02-03 14:27:19 -06:00
Pedram Amini
69b6299677 fix(windows): handle full paths in known exe command detection
Fixes an issue in PR #288's Windows shell fix where full paths like
'C:\Program Files\Git\bin\git' weren't recognized as known commands.

Changes:
- Extract command basename using regex for both Unix and Windows separators
- Change from array to Set for O(1) lookup performance
- Add additional common commands: npx, pnpm, pip, pip3
- Export needsWindowsShell for testability
- Add comprehensive test suite for needsWindowsShell function
2026-02-03 14:27:03 -06:00
Pedram Amini
fb64d4a769 feat(ssh): use heredoc for stdin prompts to avoid CLI length limits
IMPORTANT: Prompts must be passed via stdin to avoid CLI argument length
limits. Prompts can be huge and contain arbitrary characters that would
break if passed as command-line arguments.

Changes:
- Add stdinInput parameter to buildSshCommandWithStdin for heredoc-based
  prompt delivery
- Use MAESTRO_PROMPT_EOF delimiter with collision detection (appends _N
  suffix if prompt contains the delimiter)
- OpenCode prompts now always sent via stdin heredoc, not CLI args
- Add comprehensive tests for heredoc behavior and delimiter collision
- Add comment in process.ts documenting this requirement to prevent
  regressions

The heredoc approach: exec opencode 'run' <<'MAESTRO_PROMPT_EOF'
ensures prompts of any size with any characters work correctly.
2026-02-03 14:26:25 -06:00
Pedram Amini
3d593719fb fix(ssh): use stdin-based execution to bypass shell escaping issues
This is a complete rewrite of SSH remote command execution that eliminates
all shell escaping issues by sending the entire script via stdin.

Previously, the SSH command was built as:
  ssh host '/bin/bash -c '\''cd /path && VAR='\''value'\'' cmd arg'\'''

This required complex nested escaping that broke with:
- Heredocs (cat << 'EOF')
- Long prompts (command line length limits)
- Special characters in prompts

Now the SSH command is simply:
  ssh host /bin/bash

And the entire script is piped via stdin:
  export PATH="$HOME/.local/bin:..."
  cd '/project/path'
  export OPENCODE_CONFIG_CONTENT='{"permission":...}'
  exec opencode run --format json 'prompt here'

Benefits:
- No shell escaping layers (stdin is binary-safe)
- No command line length limits
- Works with any remote shell (bash, zsh, fish)
- Handles any prompt content (quotes, newlines, $, etc.)
- Much simpler to debug and maintain

Changes:
- Add buildSshCommandWithStdin() in ssh-command-builder.ts
- Update process.ts to use stdin-based SSH for all agents
- Add sshStdinScript to ProcessConfig type
- Update ChildProcessSpawner to send stdin script
- Add comprehensive tests for new function
2026-02-03 14:26:25 -06:00
Pedram Amini
09aa978932 fix(ssh): remove heredoc approach for OpenCode prompts
The heredoc syntax (cat << 'EOF' ... EOF) was breaking when passed
through buildSshCommand's single-quote escaping. The '\'' escape
pattern was being applied to the heredoc delimiters, producing
invalid shell syntax like cat << '\''EOF'\''.

Solution: Embed OpenCode prompts directly as positional arguments.
The prompt will be properly escaped by buildRemoteCommand using
shellEscape(), which handles the single-quote escaping correctly
for bash -c command execution.

This was the root cause of SSH remote execution failures with
OpenCode - the OPENCODE_CONFIG_CONTENT env var escaping was
correct, but the heredoc escaping was not.
2026-02-03 14:26:24 -06:00
Pedram Amini
7be82ce338 fix(tab-bar): ensure full tab visibility when scrolling into view
Changed from centering the tab to using scrollIntoView with 'nearest' option.
This ensures the entire tab including the close button is visible, rather than
potentially cutting off the right edge when near container boundaries.
2026-02-03 14:26:24 -06:00
Pedram Amini
99f4257c17 feat(symphony): add manual contribution credit handler
Add symphony:manualCredit IPC handler to allow crediting contributions
made outside the Symphony workflow (e.g., manual PRs, external
contributors). This enables proper tracking of all contributions
regardless of how they were created.

- Add symphony:manualCredit handler with full validation
- Add preload API for manual credit
- Support all contribution fields (tokens, time, merged status, etc.)
- Prevent duplicate PR credits
- Update contributor stats (streak, repos, totals)
- Add comprehensive tests for validation and success cases
2026-02-03 14:26:24 -06:00
Pedram Amini
81c64d9858 Merge pull request #288 from chr1syy/main
fix(windows): Shell interpration of % in git log format string
2026-02-03 14:25:35 -06:00
Raza Rauf
7d76a5a06d feat: add conservative context growth estimation during multi-tool turns
When Claude Code performs multi-tool turns (many internal API calls),
accumulated token values cause estimateContextUsage to return null,
freezing the context gauge. This adds estimateAccumulatedGrowth which
provides conservative 1-3% per-turn growth estimates so the gauge
keeps moving during tool-heavy sessions.

Safety: App.tsx caps all estimates at yellowThreshold - 5, guaranteeing
that estimates can never trigger compact warnings — only real
measurements from non-accumulated turns can.
2026-02-04 01:20:51 +05:00
Chris
a9e725b9e7 Merge branch 'pedramamini:main' into main 2026-02-03 19:41:00 +01:00
chr1syy
2f5c74480f fix: Windows shell interpretation of % in git log format string
On Windows, when execFile detects 'git' without extension, it enables shell
mode for PATHEXT resolution. However, shell mode interprets '%' characters in
arguments as environment variable expansions, causing 'git log --pretty=format:%an'
to fail with 'Der Befehl "%an" ist entweder falsch geschrieben...'

The fix adds 'git' (and other known .exe commands) to a list of exceptions
that don't require shell mode, allowing the format string to pass through
to git unchanged. This works because these commands have .exe variants on
Windows and don't need PATHEXT resolution.
2026-02-03 19:37:07 +01:00
Pedram Amini
fc7880cc32 feat(ssh): use heredoc for stdin prompts to avoid CLI length limits
IMPORTANT: Prompts must be passed via stdin to avoid CLI argument length
limits. Prompts can be huge and contain arbitrary characters that would
break if passed as command-line arguments.

Changes:
- Add stdinInput parameter to buildSshCommandWithStdin for heredoc-based
  prompt delivery
- Use MAESTRO_PROMPT_EOF delimiter with collision detection (appends _N
  suffix if prompt contains the delimiter)
- OpenCode prompts now always sent via stdin heredoc, not CLI args
- Add comprehensive tests for heredoc behavior and delimiter collision
- Add comment in process.ts documenting this requirement to prevent
  regressions

The heredoc approach: exec opencode 'run' <<'MAESTRO_PROMPT_EOF'
ensures prompts of any size with any characters work correctly.
2026-02-03 12:15:49 -06:00
Pedram Amini
07df61fbcf fix(ssh): use stdin-based execution to bypass shell escaping issues
This is a complete rewrite of SSH remote command execution that eliminates
all shell escaping issues by sending the entire script via stdin.

Previously, the SSH command was built as:
  ssh host '/bin/bash -c '\''cd /path && VAR='\''value'\'' cmd arg'\'''

This required complex nested escaping that broke with:
- Heredocs (cat << 'EOF')
- Long prompts (command line length limits)
- Special characters in prompts

Now the SSH command is simply:
  ssh host /bin/bash

And the entire script is piped via stdin:
  export PATH="$HOME/.local/bin:..."
  cd '/project/path'
  export OPENCODE_CONFIG_CONTENT='{"permission":...}'
  exec opencode run --format json 'prompt here'

Benefits:
- No shell escaping layers (stdin is binary-safe)
- No command line length limits
- Works with any remote shell (bash, zsh, fish)
- Handles any prompt content (quotes, newlines, $, etc.)
- Much simpler to debug and maintain

Changes:
- Add buildSshCommandWithStdin() in ssh-command-builder.ts
- Update process.ts to use stdin-based SSH for all agents
- Add sshStdinScript to ProcessConfig type
- Update ChildProcessSpawner to send stdin script
- Add comprehensive tests for new function
2026-02-03 12:15:49 -06:00
Pedram Amini
3a8dd62a13 fix(ssh): remove heredoc approach for OpenCode prompts
The heredoc syntax (cat << 'EOF' ... EOF) was breaking when passed
through buildSshCommand's single-quote escaping. The '\'' escape
pattern was being applied to the heredoc delimiters, producing
invalid shell syntax like cat << '\''EOF'\''.

Solution: Embed OpenCode prompts directly as positional arguments.
The prompt will be properly escaped by buildRemoteCommand using
shellEscape(), which handles the single-quote escaping correctly
for bash -c command execution.

This was the root cause of SSH remote execution failures with
OpenCode - the OPENCODE_CONFIG_CONTENT env var escaping was
correct, but the heredoc escaping was not.
2026-02-03 12:15:49 -06:00
Pedram Amini
4ae5d86a05 fix(tab-bar): ensure full tab visibility when scrolling into view
Changed from centering the tab to using scrollIntoView with 'nearest' option.
This ensures the entire tab including the close button is visible, rather than
potentially cutting off the right edge when near container boundaries.
2026-02-03 12:15:49 -06:00
Pedram Amini
b4c5f155ed feat(symphony): add manual contribution credit handler
Add symphony:manualCredit IPC handler to allow crediting contributions
made outside the Symphony workflow (e.g., manual PRs, external
contributors). This enables proper tracking of all contributions
regardless of how they were created.

- Add symphony:manualCredit handler with full validation
- Add preload API for manual credit
- Support all contribution fields (tokens, time, merged status, etc.)
- Prevent duplicate PR credits
- Update contributor stats (streak, repos, totals)
- Add comprehensive tests for validation and success cases
2026-02-03 12:15:49 -06:00
Raza Rauf
802ecd52a1 Merge pull request #287 from pedramamini/code-refactor
fix(file-preview): resolve image flickering under heavy parallel agen…
2026-02-03 10:58:43 -06:00
Raza Rauf
6e36f6b63f fix(file-preview): stabilize fileTree prop to complete memoization chain
The fileTree prop was passed as `activeSession?.fileTree || []` which
creates a new array reference on every render, defeating React.memo()
on FilePreview during agent activity. Memoize it with useMemo so the
reference only changes when the actual fileTree changes.
2026-02-03 21:46:07 +05:00
Raza Rauf
2f8a77a65d fix(file-preview): resolve image flickering under heavy parallel agent load
Wrap FilePreview and MarkdownImage with React.memo to prevent unnecessary
re-renders caused by upstream state updates from running agents.
2026-02-03 21:31:34 +05:00
Pedram Amini
2cd882ed7b Merge pull request #286 from chr1syy/main
Add @chr1syy as Windows Contributor and tester
2026-02-03 09:24:34 -06:00
Chris
00016e2342 Add @chr1syy as Windows Contributor and tester 2026-02-03 15:34:37 +01:00