fischer-agentkit/docs/solutions/conventions/emoji-removal-pattern.md

4.5 KiB

title date category module problem_type component severity applies_when tags
Emoji Removal Pattern — Ant Design Icons, Text Labels, and Pre-commit Guard 2026-07-03 conventions cross-cutting convention tooling low
Adding new UI components, CLI output, or shell scripts that need status markers
Reviewing PRs for emoji regressions
Setting up pre-commit hooks for code style enforcement
emoji
ant-design
pre-commit
cli
frontend
unicode

Emoji Removal Pattern — Ant Design Icons, Text Labels, and Pre-commit Guard

Context

The agentkit project had emoji/glyph characters scattered across frontend components (ReviewResultCard.vue, useMessageRenderer.ts), CLI output (cli/chat.py), shell scripts (deploy.sh, dev-start.sh), CI workflows, and even docstrings. These caused inconsistent rendering across terminals, OSes, and fonts — on Linux servers without Noto Color Emoji they display as tofu blocks, and they clash with the project's Ant Design Vue Outlined icon family.

Guidance

Three replacement strategies based on context (see detailed guide: no-emoji-style-guide.md):

KTD1: Ant Design Vue Outlined icons (frontend)

Replace string glyph avatars with Component types. Use <component :is> for dynamic rendering:

<!-- Before -->
<span class="icon">{{ statusIcon }}</span>
const statusIcon = computed(() => {
  if (props.review.passed) return '\u2713'
  return '\u2717'
})

<!-- After -->
<span class="icon"><component :is="statusIcon" /></span>
import { CheckOutlined, CloseOutlined, ReloadOutlined } from '@ant-design/icons-vue'
import { type Component } from 'vue'
const statusIcon = computed<Component>(() => {
  if (props.review.passed) return CheckOutlined
  if (props.review.final_status === 'failed') return CloseOutlined
  return ReloadOutlined
})

For useMessageRenderer.ts shell avatars, import the Component and assign directly: avatar: ApartmentOutlined instead of avatar: '◆'.

KTD2: Text labels with ANSI colors (CLI/shell)

# Before
"completed": ("OK", "green"),
"in_progress": ("\u25b6", "blue"),  # ▶
icon_map.get(status, ("\u25cb", "dim"))  # ○

# After
"completed": ("OK", "green"),
"in_progress": ("RUN", "blue"),
icon_map.get(status, ("--", "dim"))

Shell scripts: echo "[FAIL] ..." instead of echo "\u274c ...".

KTD3: ASCII art (docstrings)

Replace Unicode box-drawing arrows with ASCII equivalents in docstrings: -> for ─►, | for , v for .

Why This Matters

  1. Cross-platform consistency — ASCII text and Ant Design components render identically across macOS, Linux, and Windows terminals/browsers.
  2. Type safety — Using Component types instead of string for icon props enables TypeScript compile-time checks.
  3. Automated enforcement — A pre-commit hook (scripts/check-no-emoji.sh) prevents regression without manual review burden.

When to Apply

  • New UI components needing status icons — use Ant Design Outlined icons
  • New CLI output or shell script status markers — use OK/FAIL/WARN/RUN/--
  • New docstring diagrams — use ASCII art (->, |, v)
  • Any code review involving visual markers — run bash scripts/check-no-emoji.sh

Examples

Unicode range exclusions (key learning)

The check-no-emoji.sh script excludes two Unicode ranges that are pervasive in comments/docstrings but are NOT emoji:

Range Block Reason
2190-21FF Arrows -> (U+2192) is a pervasive docstring flow indicator
2500-257F Box Drawings -- (U+2500) is a pervasive comment section separator

Without these exclusions, the script flags 200+ files for false positives.

Escaped unicode detection

The script also detects escaped unicode sequences (\u2713, \u2717, etc.) in string literals. The escape pattern is narrowed to emoji-like ranges only — a broad 2[0-5]xxx pattern causes false positives in minified JS bundles (\u2000 en-space, \u2014 em-dash).

Pre-commit hook configuration

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: agentkit-no-emoji
        name: agentkit-no-emoji
        entry: bash scripts/check-no-emoji.sh
        language: system
        pass_filenames: false
        always_run: true
  • No-Emoji Style Guide — detailed KTD1-3 replacement strategies
  • Plan: docs/plans/2026-07-02-001-refactor-remove-all-emoji-plan.md
  • PR #20: refactor/remove-all-emoji branch