diff --git a/docs/solutions/conventions/emoji-removal-pattern.md b/docs/solutions/conventions/emoji-removal-pattern.md new file mode 100644 index 0000000..0a66c60 --- /dev/null +++ b/docs/solutions/conventions/emoji-removal-pattern.md @@ -0,0 +1,133 @@ +--- +title: "Emoji Removal Pattern — Ant Design Icons, Text Labels, and Pre-commit Guard" +date: 2026-07-03 +category: conventions +module: cross-cutting +problem_type: convention +component: tooling +severity: low +applies_when: + - "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" +tags: [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](../style/no-emoji-style-guide.md)): + +### KTD1: Ant Design Vue Outlined icons (frontend) + +Replace string glyph avatars with Component types. Use `` for dynamic rendering: + +```vue + +{{ statusIcon }} +const statusIcon = computed(() => { + if (props.review.passed) return '\u2713' + return '\u2717' +}) + + + +import { CheckOutlined, CloseOutlined, ReloadOutlined } from '@ant-design/icons-vue' +import { type Component } from 'vue' +const statusIcon = computed(() => { + 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) + +```python +# 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 + +```yaml +# .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](../style/no-emoji-style-guide.md) — 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