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:
@@ -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
|
||||
|
||||
@@ -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[] => {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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.",
|
||||
|
||||
Reference in New Issue
Block a user