refactor(FN-2056): replace agent preset emojis with symbol glyphs

- Replace emoji role icons in AgentListModal, AgentsView, and NewAgentDialog with consistent geometric symbols
- Update agent preset catalog icons, including reviewer and template agent presets, to professional symbol-based glyphs
- Change the default unknown-role icon fallback from a robot emoji to a neutral symbol
- Update NewAgentDialog and agent-presets tests to assert symbol icons and broaden icon validation beyond emoji ranges
This commit is contained in:
Fusion
2026-04-18 12:14:43 -07:00
committed by gsxdsm
parent 3977b38895
commit eccaed9e69
6 changed files with 52 additions and 48 deletions

View File

@@ -14,13 +14,13 @@ interface AgentListModalProps {
}
const AGENT_ROLES: { value: AgentCapability; label: string; icon: string }[] = [
{ value: "triage", label: "Triage", icon: "🔍" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "👁" },
{ value: "merger", label: "Merger", icon: "🔀" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "🛠" },
{ value: "custom", label: "Custom", icon: "🔧" },
{ value: "triage", label: "Triage", icon: "" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "" },
{ value: "merger", label: "Merger", icon: "" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "" },
{ value: "custom", label: "Custom", icon: "" },
];
const STATE_COLORS: Record<AgentState, { bg: string; text: string; border: string }> = {
@@ -165,7 +165,7 @@ export function AgentListModal({ isOpen, onClose, addToast, projectId }: AgentLi
};
const getRoleLabel = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.label ?? role;
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "🤖";
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "";
// Use centralized health status utility for consistent labels across all views
// This fixes the previous hardcoded 60s timeout that was inconsistent with other views

View File

@@ -22,13 +22,13 @@ export interface AgentsViewProps {
}
const AGENT_ROLES: { value: AgentCapability; label: string; icon: string }[] = [
{ value: "triage", label: "Triage", icon: "🔍" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "👁" },
{ value: "merger", label: "Merger", icon: "🔀" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "🛠" },
{ value: "custom", label: "Custom", icon: "🔧" },
{ value: "triage", label: "Triage", icon: "" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "" },
{ value: "merger", label: "Merger", icon: "" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "" },
{ value: "custom", label: "Custom", icon: "" },
];
const STATE_COLORS: Record<AgentState, { bg: string; text: string; border: string }> = {
@@ -436,7 +436,7 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
};
const getRoleLabel = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.label ?? role;
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "🤖";
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "";
/** Get skill badges from agent metadata */
const getSkillBadges = (agent: Agent): string[] => {

View File

@@ -15,13 +15,13 @@ export interface NewAgentDialogProps {
}
const AGENT_ROLES: { value: AgentCapability; label: string; icon: string }[] = [
{ value: "triage", label: "Triage", icon: "🔍" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "👁" },
{ value: "merger", label: "Merger", icon: "🔀" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "🛠" },
{ value: "custom", label: "Custom", icon: "🔧" },
{ value: "triage", label: "Triage", icon: "" },
{ value: "executor", label: "Executor", icon: "" },
{ value: "reviewer", label: "Reviewer", icon: "" },
{ value: "merger", label: "Merger", icon: "" },
{ value: "scheduler", label: "Scheduler", icon: "" },
{ value: "engineer", label: "Engineer", icon: "" },
{ value: "custom", label: "Custom", icon: "" },
];
type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high";

View File

@@ -780,7 +780,7 @@ describe("NewAgentDialog", () => {
// Verify name
expect(screen.getByText("Reviewer")).toBeTruthy();
// Verify icon
expect(screen.getByText("👁️")).toBeTruthy();
expect(screen.getByText("")).toBeTruthy();
// Create
await user.click(screen.getByText("Create"));
@@ -791,7 +791,7 @@ describe("NewAgentDialog", () => {
const createCall = mockCreateAgent.mock.calls[0][0];
expect(createCall.name).toBe("Reviewer");
expect(createCall.icon).toBe("👁️");
expect(createCall.icon).toBe("");
// Title should be the preset's description
expect(createCall.title).toBe("Reviews code changes for correctness, security, performance, and adherence to project coding standards.");
expect(createCall.role).toBe("reviewer");

View File

@@ -67,12 +67,16 @@ describe("agent-presets", () => {
});
});
it("every preset has a non-empty icon (emoji)", () => {
it("every preset has a non-empty icon symbol", () => {
AGENT_PRESETS.forEach((preset) => {
expect(preset.icon).toBeTruthy();
expect(preset.icon.length).toBeGreaterThan(0);
// Should contain at least one emoji character
expect(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u.test(preset.icon)).toBe(true);
// Icons may be emoji or geometric/mathematical symbols.
// Validate that the first code point is in a non-ASCII symbol range.
const firstCodePoint = preset.icon.codePointAt(0);
expect(firstCodePoint).toBeDefined();
expect(firstCodePoint).toBeGreaterThan(0x2000);
});
});

View File

@@ -58,7 +58,7 @@ export const AGENT_PRESETS: AgentPreset[] = [
{
id: "ceo",
name: "CEO",
icon: "👔",
icon: "",
title: "Chief Executive Officer",
role: "custom",
description: "Oversees project strategy, sets priorities, and coordinates between departments to ensure alignment with business goals.",
@@ -72,7 +72,7 @@ Keep long-term vision in focus while making short-term tradeoffs.`,
{
id: "cto",
name: "CTO",
icon: "🧠",
icon: "",
title: "Chief Technology Officer",
role: "custom",
description: "Defines technical architecture, evaluates technology choices, and guides engineering standards across the project.",
@@ -86,7 +86,7 @@ Document architectural decisions with rationale for future reference.`,
{
id: "cmo",
name: "CMO",
icon: "📢",
icon: "",
title: "Chief Marketing Officer",
role: "custom",
description: "Drives product positioning, audience engagement strategy, and content planning to grow user adoption.",
@@ -100,7 +100,7 @@ Track engagement metrics to validate content and campaign effectiveness.`,
{
id: "cfo",
name: "CFO",
icon: "💰",
icon: "",
title: "Chief Financial Officer",
role: "custom",
description: "Manages budget allocation, cost optimization, and financial planning to maximize resource efficiency.",
@@ -114,7 +114,7 @@ Ensure resource allocation aligns with project priorities.`,
{
id: "engineer",
name: "Engineer",
icon: "👨‍💻",
icon: "",
title: "Software Engineer",
role: "engineer",
description: "Implements features, fixes bugs, and writes well-tested code across the full application stack.",
@@ -128,7 +128,7 @@ Document complex logic with inline comments explaining the why, not the what.`,
{
id: "backend-engineer",
name: "Backend Engineer",
icon: "⚙️",
icon: "",
title: "Backend Engineer",
role: "engineer",
description: "Builds and maintains server-side logic, APIs, database schemas, and background processing pipelines.",
@@ -143,7 +143,7 @@ Design APIs with consistent error responses and status codes.`,
{
id: "frontend-engineer",
name: "Frontend Engineer",
icon: "🎨",
icon: "",
title: "Frontend Engineer",
role: "engineer",
description: "Develops user interfaces, manages component libraries, and ensures responsive, accessible UI experiences.",
@@ -158,7 +158,7 @@ Follow the project's existing component patterns and naming conventions.`,
{
id: "fullstack-engineer",
name: "Fullstack Engineer",
icon: "🚀",
icon: "",
title: "Full Stack Engineer",
role: "engineer",
description: "Works across frontend and backend to deliver end-to-end features from database to user interface.",
@@ -172,7 +172,7 @@ Optimize at the right layer — don't compensate for backend issues in frontend
{
id: "qa-engineer",
name: "QA Engineer",
icon: "🧪",
icon: "",
title: "Quality Assurance Engineer",
role: "engineer",
description: "Designs test plans, writes automated tests, and validates that features meet acceptance criteria before release.",
@@ -186,7 +186,7 @@ Report issues with clear reproduction steps and expected vs actual behavior.`,
{
id: "devops-engineer",
name: "DevOps Engineer",
icon: "🔧",
icon: "",
title: "DevOps Engineer",
role: "engineer",
description: "Manages infrastructure, deployment pipelines, and monitoring to ensure reliable and scalable service delivery.",
@@ -200,7 +200,7 @@ Document runbooks for common operational incidents.`,
{
id: "ci-engineer",
name: "CI Engineer",
icon: "",
icon: "",
title: "CI/CD Engineer",
role: "engineer",
description: "Builds and optimizes continuous integration and delivery pipelines for fast, reliable release cycles.",
@@ -214,7 +214,7 @@ Measure and report pipeline duration trends over time.`,
{
id: "security-engineer",
name: "Security Engineer",
icon: "🛡️",
icon: "",
title: "Security Engineer",
role: "engineer",
description: "Identifies vulnerabilities, enforces security best practices, and conducts audits to protect application integrity.",
@@ -228,7 +228,7 @@ Apply the principle of least privilege to all access control decisions.`,
{
id: "data-engineer",
name: "Data Engineer",
icon: "📊",
icon: "",
title: "Data Engineer",
role: "engineer",
description: "Designs data pipelines, manages storage infrastructure, and ensures reliable data flow for analytics and features.",
@@ -242,7 +242,7 @@ Ensure pipeline failures trigger alerts with actionable error context.`,
{
id: "ml-engineer",
name: "ML Engineer",
icon: "🤖",
icon: "",
title: "Machine Learning Engineer",
role: "engineer",
description: "Builds, trains, and deploys machine learning models, and integrates AI capabilities into the product.",
@@ -256,7 +256,7 @@ Write unit tests for data preprocessing and feature engineering pipelines.`,
{
id: "product-manager",
name: "Product Manager",
icon: "📋",
icon: "",
title: "Product Manager",
role: "custom",
description: "Defines product requirements, prioritizes the backlog, and coordinates cross-functional delivery from concept to launch.",
@@ -270,7 +270,7 @@ Ensure every feature has a measurable success metric.`,
{
id: "designer",
name: "Designer",
icon: "✏️",
icon: "",
title: "Product Designer",
role: "custom",
description: "Creates wireframes, prototypes, and design systems that balance usability, aesthetics, and brand consistency.",
@@ -284,7 +284,7 @@ Keep component variants minimal — add new variants only when existing ones don
{
id: "marketing-manager",
name: "Marketing Manager",
icon: "📣",
icon: "",
title: "Marketing Manager",
role: "custom",
description: "Plans campaigns, manages content channels, and analyzes market data to drive brand awareness and growth.",
@@ -298,7 +298,7 @@ Track and report campaign performance with actionable insights.`,
{
id: "technical-writer",
name: "Technical Writer",
icon: "📝",
icon: "",
title: "Technical Writer",
role: "custom",
description: "Writes and maintains documentation, API references, and guides that help users and developers succeed.",
@@ -312,7 +312,7 @@ Structure content with clear headings for easy scanning and navigation.`,
{
id: "triage",
name: "Triage Agent",
icon: "🔍",
icon: "",
title: "Task Triage Agent",
role: "triage",
description: "Analyzes incoming tasks, generates detailed specifications, and prepares PROMPT.md files for execution.",
@@ -326,7 +326,7 @@ Include relevant context files for the executor to read first.`,
{
id: "reviewer",
name: "Reviewer",
icon: "👁️",
icon: "",
title: "Code Reviewer",
role: "reviewer",
description: "Reviews code changes for correctness, security, performance, and adherence to project coding standards.",