skills-experimental/grapheme-width-calculation/SKILL.md
# Grapheme Width Calculation Skill Grapheme Width Calculation - graphemeWidth function + hasMultipleCodepoints check + isEmoji detection + isEastAsianWide detection + codePoint extraction + width 1 or 2 return + segmentGraphemes generator + Intl.Segmenter usage。 ## 功能概述 从Claude Code的ink/termio/parser.ts提取的Grapheme宽度计算模式,用于OpenClaw的终端字符宽度计算。 ## 核心机制 ### graphemeWidth Function ```typescript function graphemeWidth(grapheme: string): 1 | 2 { if (hasMultipleCodepoints(grapheme)) return 2 //
npx skillsauth add bianhaifeng789-hue/openclaw-config skills-experimental/grapheme-width-calculationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Grapheme Width Calculation - graphemeWidth function + hasMultipleCodepoints check + isEmoji detection + isEastAsianWide detection + codePoint extraction + width 1 or 2 return + segmentGraphemes generator + Intl.Segmenter usage。
从Claude Code的ink/termio/parser.ts提取的Grapheme宽度计算模式,用于OpenClaw的终端字符宽度计算。
function graphemeWidth(grapheme: string): 1 | 2 {
if (hasMultipleCodepoints(grapheme)) return 2 // Emoji cluster
const codePoint = grapheme.codePointAt(0)
if (codePoint === undefined) return 1
if (isEmoji(codePoint) || isEastAsianWide(codePoint)) return 2
return 1
}
// Returns 1 or 2
# Multiple codepoints: width 2
# Emoji or EastAsianWide: width 2
# Otherwise: width 1
function hasMultipleCodepoints(str: string): boolean {
let count = 0
for (const _ of str) {
count++
if (count > 1) return true // More than one codepoint
}
return false
}
// Check if grapheme has multiple codepoints
# Emoji cluster: multiple codepoints
# Returns true if count > 1
function isEmoji(codePoint: number): boolean {
return (
(codePoint >= 0x2600 && codePoint <= 0x26ff) || // Misc symbols
(codePoint >= 0x2700 && codePoint <= 0x27bf) || // Dingbats
(codePoint >= 0x1f300 && codePoint <= 0x1f9ff) || // Emoji
(codePoint >= 0x1fa00 && codePoint <= 0x1faff) || // Extended emoji
(codePoint >= 0x1f1e0 && codePoint <= 0x1f1ff) // Flags
)
}
// Emoji codepoint ranges
# Misc symbols, Dingbats, Emoji ranges
function isEastAsianWide(codePoint: number): boolean {
return (
(codePoint >= 0x1100 && codePoint <= 0x115f) || // Hangul Jamo
(codePoint >= 0x2e80 && codePoint <= 0x9fff) || // CJK
(codePoint >= 0xac00 && codePoint <= 0xd7a3) || // Hangul
(codePoint >= 0xf900 && codePoint <= 0xfaff) || // CJK compat
(codePoint >= 0xfe10 && codePoint <= 0xfe1f) || // Vertical forms
(codePoint >= 0xfe30 && codePoint <= 0xfe6f) || // CJK compat forms
(codePoint >= 0xff00 && codePoint <= 0xff60) || // Half/fullwidth
(codePoint >= 0xffe0 && codePoint <= 0xffe6) || // Fullwidth symbols
(codePoint >= 0x20000 && codePoint <= 0x2fffd) || // CJK Ext B
(codePoint >= 0x30000 && codePoint <= 0x3fffd) // CJK Ext G
)
}
// East Asian Wide codepoint ranges
# CJK, Hangul, Fullwidth chars
const codePoint = grapheme.codePointAt(0)
if (codePoint === undefined) return 1 // Fallback for empty
// Extract first codepoint
# codePointAt(0) for first char
return 1 | 2
// Width 1: narrow/single-width chars
// Width 2: wide/double-width chars (emoji, CJK)
// Terminal display width
function* segmentGraphemes(str: string): Generator<Grapheme> {
for (const { segment } of getGraphemeSegmenter().segment(str)) {
yield { value: segment, width: graphemeWidth(segment) }
}
}
// Yield grapheme clusters with width
# Intl.Segmenter for proper segmentation
import { getGraphemeSegmenter } from '../../utils/intl.js'
for (const { segment } of getGraphemeSegmenter().segment(str)) {
// Process grapheme cluster
}
// Intl.Segmenter for grapheme segmentation
# Handles emoji + modifiers correctly
{
"grapheme": "👨👩👧👦",
"codepoints": 7,
"width": 2
}
hasMultipleCodepoints(grapheme) → true → width 2 → emoji cluster handling
# 多codepoints grapheme
# emoji cluster(emoji + modifiers)
# width 2
0x2600-0x26ff (Misc symbols) + 0x1f300-0x1f9ff (Emoji) → emoji detection
# Emoji codepoint ranges
# Misc symbols + Emoji blocks
CJK (0x2e80-0x9fff) + Hangul (0xac00-0xd7a3) + Fullwidth (0xff00-0xff60) → wide
# East Asian Wide ranges
# CJK, Hangul, Fullwidth
Intl.Segmenter → grapheme clusters → emoji + modifiers as one unit → correct width
# Intl.Segmenter分割grapheme
# emoji + modifiers作为一个cluster
# 正确计算width
graphemeWidth → 1 | 2 → binary return → no complex width values
# 只返回1或2
# terminal width binary
# 无中间值
ink/termio/parser.ts (394 lines)business
IAA 日报飞书输出能力。 支持把固定 CSV 模板一键转换成: - 中文运营结论 - 飞书卡片 JSON - 飞书发送载荷 Use when: - 需要把 IAA 日报直接发到飞书 - 需要从 CSV 一键生成运营日报
data-ai
IAA日报分析模型 功能: - 渠道日报自动分析 - 小时级+日级ROI联动判断 - 按地区输出加量/降量/停投建议 - 按产品类型输出阈值 - 自动识别利润区/观察区/止损区 Use when: - 分析每天投放数据 - 生成运营日报结论 - 判断是否加量/降量/停投 - 对比美加澳/日韩表现 Keywords: - 日报模型, 投放日报, 加量, 降量, 停投, ROI日报, 分地区分析
data-ai
IAA固定日报分析模板 功能: - 固定字段模板(可直接贴每天数据) - 自动输出总盘结论 - 自动输出美加澳/日韩结论 - 自动给出加量/降量/停投建议 - 适配文件修复/清理两类产品 Use when: - 需要固定日报格式 - 每天复盘渠道表现 - 给运营团队出统一结论 Keywords: - 固定模板, 日报模板, ROI模板, IAA日报, 运营模板
development
# HyperlinkPool Pattern Skill HyperlinkPool Pattern - HyperlinkPool class + strings array + stringMap + Index 0 no hyperlink + intern(hyperlink) + get(id) + undefined handling + 5-minute reset + OSC8 hyperlink interning。 ## 功能概述 从Claude Code的ink/screen.ts提取的HyperlinkPool模式,用于OpenClaw的OSC8超链接池管理。 ## 核心机制 ### HyperlinkPool Class ```typescript export class HyperlinkPool { private strings: string[] = [''] // Index 0 = no hyperlink private stringMap = new Map<string, number>() // strings