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 |
|
|
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
- Cross-platform consistency — ASCII text and Ant Design components render identically across macOS, Linux, and Windows terminals/browsers.
- Type safety — Using
Componenttypes instead ofstringfor icon props enables TypeScript compile-time checks. - 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
Related
- 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-emojibranch