## CHANGES

- Added a gorgeous main-screen screenshot to README for faster onboarding 🖼️
- Polished batch-stop UI label from “Stopping...” to “Stopping” everywhere 
- Updated MainPanel tests to match the refined stopping button text 🧪
- Refreshed achievement badge styling with sleek purple accent gradients 🎨
- Replaced trophy mini-badge with a signature Maestro wand + sparkle icon 🪄
- Switched default achievement icon rendering to a crisp trophy emoji 🏆
This commit is contained in:
Pedram Amini
2025-12-28 04:42:12 -06:00
parent 6e871565f9
commit 8d145f6546
3 changed files with 65 additions and 50 deletions

View File

@@ -94,6 +94,12 @@ npm run dev
## Screenshots
<p align="center">
<img src="docs/screenshots/main-screen.png" alt="Maestro Main Screen" width="800">
</p>
*Main screen with multiple agents and conversation*
<p align="center">
<img src="docs/screenshots/cmd-k-1.png" alt="Command Palette" width="800">
</p>

View File

@@ -991,7 +991,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={currentSessionBatchState} />);
expect(screen.getByText('Stopping...')).toBeInTheDocument();
expect(screen.getByText('Stopping')).toBeInTheDocument();
});
it('should call onStopBatchRun directly when Auto button is clicked', () => {
@@ -1048,7 +1048,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={currentSessionBatchState} onStopBatchRun={onStopBatchRun} />);
fireEvent.click(screen.getByText('Stopping...'));
fireEvent.click(screen.getByText('Stopping'));
expect(onStopBatchRun).not.toHaveBeenCalled();
});
@@ -1057,7 +1057,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={null} />);
expect(screen.queryByText('Auto')).not.toBeInTheDocument();
expect(screen.queryByText('Stopping...')).not.toBeInTheDocument();
expect(screen.queryByText('Stopping')).not.toBeInTheDocument();
});
it('should not display Auto mode button when currentSessionBatchState is undefined', () => {
@@ -1201,7 +1201,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={currentSessionBatchState} />);
const button = screen.getByText('Stopping...').closest('button');
const button = screen.getByText('Stopping').closest('button');
expect(button).toBeDisabled();
});
@@ -1282,7 +1282,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={currentSessionBatchState} />);
const button = screen.getByText('Stopping...').closest('button');
const button = screen.getByText('Stopping').closest('button');
expect(button).toHaveAttribute('title', 'Stopping after current task...');
});
@@ -1390,7 +1390,7 @@ describe('MainPanel', () => {
render(<MainPanel {...defaultProps} currentSessionBatchState={currentSessionBatchState} />);
const button = screen.getByText('Stopping...').closest('button');
const button = screen.getByText('Stopping').closest('button');
expect(button).toHaveClass('cursor-not-allowed');
});

View File

@@ -501,68 +501,77 @@ export function AchievementCard({ theme, autoRunStats, globalStats, usageStats,
ctx.lineWidth = 3;
ctx.stroke();
// Add a larger trophy badge in the bottom-right corner - MAXIMUM BRIGHTNESS
// Add Maestro wand badge in the bottom-right corner
const badgeRadius = 18;
const badgeX = iconX + iconRadius - 6;
const badgeY = iconY + iconRadius - 6;
// Draw badge background - bright gold circle
// Draw badge background - purple/accent gradient
ctx.beginPath();
ctx.arc(badgeX, badgeY, badgeRadius, 0, Math.PI * 2);
const trophyBadgeGradient = ctx.createRadialGradient(badgeX - 4, badgeY - 4, 0, badgeX, badgeY, badgeRadius);
trophyBadgeGradient.addColorStop(0, '#FFFF99');
trophyBadgeGradient.addColorStop(0.4, '#FFE135');
trophyBadgeGradient.addColorStop(1, '#FFD700');
ctx.fillStyle = trophyBadgeGradient;
const wandBadgeGradient = ctx.createRadialGradient(badgeX - 4, badgeY - 4, 0, badgeX, badgeY, badgeRadius);
wandBadgeGradient.addColorStop(0, '#C4B5FD'); // Light purple center
wandBadgeGradient.addColorStop(0.5, '#A78BFA'); // Medium purple
wandBadgeGradient.addColorStop(1, '#8B5CF6'); // Accent purple edge
ctx.fillStyle = wandBadgeGradient;
ctx.fill();
ctx.strokeStyle = '#FFFF66';
ctx.strokeStyle = '#DDD6FE';
ctx.lineWidth = 2;
ctx.stroke();
// Draw trophy shape manually with BRIGHT GOLD (not emoji)
const ts = badgeRadius * 0.55; // trophy scale
ctx.fillStyle = '#1a1a2e'; // Dark color for contrast on gold background
// Draw Maestro wand shape
const ws = badgeRadius * 0.5; // wand scale
ctx.strokeStyle = '#FFFFFF';
ctx.lineWidth = 2.5;
ctx.lineCap = 'round';
// Wand stick (diagonal line)
ctx.beginPath();
// Cup body
ctx.moveTo(badgeX - ts * 0.6, badgeY - ts * 0.5);
ctx.quadraticCurveTo(badgeX - ts * 0.7, badgeY + ts * 0.1, badgeX - ts * 0.3, badgeY + ts * 0.4);
ctx.lineTo(badgeX + ts * 0.3, badgeY + ts * 0.4);
ctx.quadraticCurveTo(badgeX + ts * 0.7, badgeY + ts * 0.1, badgeX + ts * 0.6, badgeY - ts * 0.5);
ctx.closePath();
ctx.fill();
// Stem
ctx.fillRect(badgeX - ts * 0.12, badgeY + ts * 0.4, ts * 0.24, ts * 0.3);
// Base
ctx.fillRect(badgeX - ts * 0.35, badgeY + ts * 0.65, ts * 0.7, ts * 0.15);
ctx.moveTo(badgeX + ws * 0.5, badgeY + ws * 0.5);
ctx.lineTo(badgeX - ws * 0.4, badgeY - ws * 0.4);
ctx.stroke();
// Sparkle at tip (star shape)
const starX = badgeX - ws * 0.5;
const starY = badgeY - ws * 0.5;
const starSize = ws * 0.4;
ctx.lineWidth = 1.5;
// Vertical line
ctx.beginPath();
ctx.moveTo(starX, starY - starSize);
ctx.lineTo(starX, starY + starSize);
ctx.stroke();
// Horizontal line
ctx.beginPath();
ctx.moveTo(starX - starSize, starY);
ctx.lineTo(starX + starSize, starY);
ctx.stroke();
// Diagonal lines (smaller)
ctx.beginPath();
ctx.moveTo(starX - starSize * 0.7, starY - starSize * 0.7);
ctx.lineTo(starX + starSize * 0.7, starY + starSize * 0.7);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(starX + starSize * 0.7, starY - starSize * 0.7);
ctx.lineTo(starX - starSize * 0.7, starY + starSize * 0.7);
ctx.stroke();
} else {
// Default trophy icon - MAXIMUM BRIGHTNESS gold circle
// Default trophy icon with purple gradient background
ctx.beginPath();
ctx.arc(iconX, iconY, iconRadius, 0, Math.PI * 2);
const defaultTrophyGradient = ctx.createRadialGradient(iconX - 10, iconY - 10, 0, iconX, iconY, iconRadius);
defaultTrophyGradient.addColorStop(0, '#FFFF99');
defaultTrophyGradient.addColorStop(0.4, '#FFE135');
defaultTrophyGradient.addColorStop(1, '#FFD700');
ctx.fillStyle = defaultTrophyGradient;
const defaultGradient = ctx.createRadialGradient(iconX - 10, iconY - 10, 0, iconX, iconY, iconRadius);
defaultGradient.addColorStop(0, '#C4B5FD'); // Light purple center
defaultGradient.addColorStop(0.5, '#A78BFA'); // Medium purple
defaultGradient.addColorStop(1, '#8B5CF6'); // Accent purple edge
ctx.fillStyle = defaultGradient;
ctx.fill();
ctx.strokeStyle = '#FFFF66';
ctx.strokeStyle = '#DDD6FE';
ctx.lineWidth = 3;
ctx.stroke();
// Draw trophy shape manually with dark color for contrast (not emoji)
const ts = iconRadius * 0.55;
ctx.fillStyle = '#1a1a2e';
ctx.beginPath();
// Cup body
ctx.moveTo(iconX - ts * 0.6, iconY - ts * 0.5);
ctx.quadraticCurveTo(iconX - ts * 0.7, iconY + ts * 0.1, iconX - ts * 0.3, iconY + ts * 0.4);
ctx.lineTo(iconX + ts * 0.3, iconY + ts * 0.4);
ctx.quadraticCurveTo(iconX + ts * 0.7, iconY + ts * 0.1, iconX + ts * 0.6, iconY - ts * 0.5);
ctx.closePath();
ctx.fill();
// Stem
ctx.fillRect(iconX - ts * 0.12, iconY + ts * 0.4, ts * 0.24, ts * 0.3);
// Base
ctx.fillRect(iconX - ts * 0.35, iconY + ts * 0.65, ts * 0.7, ts * 0.15);
// Trophy emoji
ctx.font = '38px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('🏆', iconX, iconY + 2);
}
// Title - show display name if personalized, otherwise generic title