create-glyph
关于
This skill creates R-based pictogram glyphs for visualization icons using ggplot2 and a primitives library. It handles the full pipeline from concept and color strategy to registration, build rendering, and verification of the neon-glow output. Use it when adding new entities needing icons, replacing existing glyphs, or batch-creating for a new domain.
快速安装
Claude Code
推荐npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/create-glyph在 Claude Code 中复制并粘贴此命令以安装该技能
技能文档
Create Glyph
Create R-based pictogram glyphs for skill, agent, or team icons in the viz/ visualization layer. Each glyph is a pure-ggplot2 function that draws a recognizable shape on a 100x100 canvas, rendered with a neon glow effect to transparent-background WebP.
When to Use
- A new skill, agent, or team has been added and needs a visual icon
- An existing glyph needs replacement or redesign
- Batch-creating glyphs for a new domain of skills
- Prototyping visual metaphors for entity concepts
Inputs
- Required: Entity type —
skill,agent, orteam - Required: Entity ID (e.g.,
create-glyph,mystic,r-package-review) and domain (for skills) - Required: Visual concept — what the glyph should depict
- Optional: Reference glyph to study for complexity level
- Optional: Custom
--glow-sigmavalue (default: 4)
Procedure
Step 1: Concept — Design the Visual Metaphor
Identify the entity being iconified and choose a visual metaphor.
- Read the entity's source file to understand its core concept:
- Skills:
skills/<id>/SKILL.md - Agents:
agents/<id>.md - Teams:
teams/<id>.md
- Skills:
- Choose a metaphor type:
- Literal object: a flask for experiments, a shield for security
- Abstract symbol: arrows for merging, spirals for iteration
- Composite: combine 2-3 simple shapes (e.g., document + pen)
- Reference existing glyphs for complexity calibration:
Complexity Tiers:
+----------+--------+-------------------------------------------+
| Tier | Layers | Examples |
+----------+--------+-------------------------------------------+
| Simple | 2 | glyph_flame, glyph_heartbeat |
| Moderate | 3-5 | glyph_document, glyph_experiment_flask |
| Complex | 6+ | glyph_ship_wheel, glyph_bridge_cpp |
+----------+--------+-------------------------------------------+
- Decide on a function name:
glyph_<descriptive_name>(snake_case, unique)
Got: A clear mental sketch of the shape with 2-6 planned layers.
If fail: If the concept is too abstract, fall back to a related concrete object. Review existing glyphs in the same domain for inspiration.
Step 2: Compose — Write the Glyph Function
Write the R function that produces ggplot2 layers.
-
Function signature (immutable contract):
glyph_<name> <- function(cx, cy, s, col, bright) { # cx, cy = center coordinates (50, 50 on 100x100 canvas) # s = scale factor (1.0 = fill ~70% of canvas) # col = domain color hex (e.g., "#ff88dd" for design) # bright = brightened variant of col (auto-computed by renderer) # Returns: list() of ggplot2 layers } -
Apply scale factor
* sto ALL dimensions for consistent scaling:r <- 20 * s # radius hw <- 15 * s # half-width lw <- .lw(s) # line width (default base 2.5) lw_thin <- .lw(s, 1.2) # thinner line width -
Build geometry using available primitives:
Geometry Usage ggplot2::geom_polygon(data, .aes(x, y), ...)Filled shapes ggplot2::geom_path(data, .aes(x, y), ...)Open lines/curves ggplot2::geom_segment(data, .aes(x, xend, y, yend), ...)Line segments, arrows ggplot2::geom_rect(data, .aes(xmin, xmax, ymin, ymax), ...)Rectangles ggforce::geom_circle(data, .aes(x0, y0, r), ...)Circles -
Apply the color strategy:
Alpha Guide: +----------------------+------------+--------------------------+ | Purpose | Alpha | Example | +----------------------+------------+--------------------------+ | Large fill (body) | 0.08-0.15 | hex_with_alpha(col, 0.1) | | Medium fill (accent) | 0.15-0.25 | hex_with_alpha(col, 0.2) | | Small fill (detail) | 0.25-0.35 | hex_with_alpha(bright, 0.3) | | Outline stroke | 1.0 | color = bright | | Secondary stroke | 1.0 | color = col | | No fill | --- | fill = NA | +----------------------+------------+--------------------------+ -
Return a flat
list()of layers (the renderer iterates and wraps each with glow) -
Place the function in the appropriate primitives file based on entity type:
- Skills: domain-grouped across 19 primitives files:
primitives.R— bushcraft, compliance, containerization, data-serialization, defensiveprimitives_2.R— devops, general, git, mcp-integrationprimitives_3.R— mlops, observability, PM, r-packages, reporting, review, web-dev, esoteric, design- Additional
primitives_4.Rthroughprimitives_19.Rfor newer domains
- Agents:
viz/R/agent_primitives.R - Teams:
viz/R/team_primitives.R
- Skills: domain-grouped across 19 primitives files:
Got: A working R function that returns a list of 2-6 ggplot2 layers.
If fail: If ggforce::geom_circle causes errors, ensure ggforce is installed. If coordinates are off, remember the canvas is 100x100 with (0,0) at bottom-left. Test the function interactively:
source("viz/R/utils.R"); source("viz/R/primitives.R") # etc.
layers <- glyph_<name>(50, 50, 1.0, "#ff88dd", "#ffa8f0")
p <- ggplot2::ggplot() + ggplot2::coord_fixed(xlim=c(0,100), ylim=c(0,100)) +
ggplot2::theme_void()
for (l in layers) p <- p + l
print(p)
Step 3: Register — Map Entity to Glyph
Add the entity-to-glyph mapping in the appropriate glyph mapping file.
For skills:
- Open
viz/R/glyphs.R - Find the comment section for the target domain (e.g.,
# -- design (3)) - Add the entry in alphabetical order within the domain block:
"skill-id" = "glyph_function_name", - Update the domain count in the comment if applicable
For agents:
- Open
viz/R/agent_glyphs.R - Find the alphabetical position in
AGENT_GLYPHS - Add the entry:
"agent-id" = "glyph_function_name",
For teams:
-
Open
viz/R/team_glyphs.R -
Find the alphabetical position in
TEAM_GLYPHS -
Add the entry:
"team-id" = "glyph_function_name", -
Verify no duplicate ID exists in the target list
Got: The appropriate *_GLYPHS list contains the new mapping.
If fail: If the build later reports "No glyph mapped", double-check that the entity ID exactly matches the one in the manifest and registry.
Step 4: Manifest — Add Icon Entry
Register the icon in the appropriate manifest file.
For skills: viz/data/icon-manifest.json
{
"skillId": "skill-id",
"domain": "domain-name",
"prompt": "<domain basePrompt>, <descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/<domain>/<skill-id>.webp",
"status": "pending"
}
For agents: viz/data/agent-icon-manifest.json
{
"agentId": "agent-id",
"prompt": "<agent-specific descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/agents/<agent-id>.webp",
"status": "pending"
}
For teams: viz/data/team-icon-manifest.json
{
"teamId": "team-id",
"prompt": "<team-specific descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/teams/<team-id>.webp",
"status": "pending"
}
Got: Valid JSON with the new entry placed among its type siblings.
If fail: Validate JSON syntax. Common mistakes: trailing comma after last array element, missing quotes.
Step 5: Render — Generate the Icon
Run the icon pipeline to render the new glyph. Always use build.sh as the entry point — it handles platform detection and R binary selection. See render-icon-pipeline for the full flag reference and pipeline architecture.
# From project root — renders all palettes, standard + HD, skips existing icons
bash viz/build.sh --only <domain> --skip-existing # skills
bash viz/build.sh --type agent --only <id> --skip-existing # agents
bash viz/build.sh --type team --only <id> --skip-existing # teams
# Dry run first:
bash viz/build.sh --only <domain> --dry-run
build.sh runs the full pipeline (palette → data → manifest → render → terminal glyphs). The non-render steps add ~10 seconds but ensure all data is current.
Output locations:
- Skills:
viz/public/icons/<palette>/<domain>/<skill-id>.webp - Agents:
viz/public/icons/<palette>/agents/<agent-id>.webp - Teams:
viz/public/icons/<palette>/teams/<team-id>.webp
Got: The log shows OK: <entity> (seed=XXXXX, XX.XKB) and the WebP file exists.
If fail:
"No glyph mapped"— Step 3 mapping is missing or has a typo"Unknown domain"— Domain not inget_palette_colors()inpalettes.R- R package errors — Run
install.packages(c("ggplot2", "ggforce", "ggfx", "ragg", "magick"))first - If rendering crashes, test the glyph function interactively (see Step 2 fallback)
Step 6: Verify — Visual Inspection
Check the rendered output meets quality standards.
-
Verify file exists and has reasonable size:
ls -la viz/public/icons/cyberpunk/<type-path>/<entity-id>.webp # Expected: 15-80 KB typical range -
Open the WebP in an image viewer to check:
- Shape reads clearly at full size (1024x1024)
- Neon glow is present but not overpowering
- Background is transparent (no black/white rectangle)
- No clipping at canvas edges
-
Check at small sizes (the icon renders at ~40-160px in the force graph):
- Shape remains recognizable
- Detail doesn't turn to noise
- Glow doesn't overwhelm the shape
Got: A clear, recognizable pictogram with even neon glow on transparent background.
If fail:
- Glow too strong: re-render with
--glow-sigma 2(default is 4) - Glow too weak: re-render with
--glow-sigma 8 - Shape unreadable at small sizes: simplify the glyph (fewer layers, bolder strokes, increase
.lw(s, base)base value) - Clipping at edges: reduce shape dimensions or shift center
Step 7: Iterate — Refine if Needed
Make adjustments and re-render.
-
Common adjustments:
- Bolder strokes: increase
.lw(s, base)— trybase = 3.0or3.5 - More visible fill: increase alpha from 0.10 to 0.15-0.20
- Shape proportions: adjust multipliers on
s(e.g.,20 * s->24 * s) - Add/remove detail layers: keep total layers between 2-6 for best results
- Bolder strokes: increase
-
To re-render after changes:
# Delete the existing icon first, then re-render rm viz/public/icons/cyberpunk/<type-path>/<entity-id>.webp # Use the appropriate build command from Step 5 -
When satisfied, verify the manifest status shows
"done"(the build script updates it automatically on success)
Got: The final icon passes all verification checks from Step 6.
If fail: If after 3+ iterations the glyph still doesn't read well, consider using a completely different visual metaphor (return to Step 1).
Reference
Domain and Entity Color Palettes
All 58 domain colors (for skills) are defined in viz/R/palettes.R (the single source of truth). Agent and team colors are also managed in palettes.R. The cyberpunk palette (hand-tuned neon colors) is in get_cyberpunk_colors(). Viridis-family palettes are auto-generated via viridisLite.
To look up a color:
source("viz/R/palettes.R")
get_palette_colors("cyberpunk")$domains[["design"]] # skill domain
get_palette_colors("cyberpunk")$agents[["mystic"]] # agent
get_palette_colors("cyberpunk")$teams[["tending"]] # team
When adding a new domain, add it to three places in palettes.R:
PALETTE_DOMAIN_ORDER(alphabetical)get_cyberpunk_colors()domains list- Run
bash viz/build.shto regenerate palettes, data, and manifests
Glyph Function Catalog
See the full catalog of available glyph functions in the primitives source files:
- Skills:
viz/R/primitives.Rthroughviz/R/primitives_19.R(domain-grouped) - Agents:
viz/R/agent_primitives.R - Teams:
viz/R/team_primitives.R
Helper Functions
| Function | Signature | Purpose |
|---|---|---|
.lw(s, base) | (scale, base=2.5) | Scale-aware line width |
.aes(...) | alias for ggplot2::aes | Shorthand aesthetic mapping |
hex_with_alpha(hex, alpha) | (string, 0-1) | Add alpha to hex color |
brighten_hex(hex, factor) | (string, factor=1.3) | Brighten a hex color |
dim_hex(hex, factor) | (string, factor=0.4) | Dim a hex color |
Validation Checklist
- Glyph function follows
glyph_<name>(cx, cy, s, col, bright) -> list()signature - All dimensions use
* sscaling factor - Color strategy uses
colfor fills,brightfor outlines,hex_with_alpha()for transparency - Function placed in correct primitives file for entity type and domain
- Glyph mapping entry added in the appropriate
*_glyphs.Rfile - Manifest entry added with correct entity ID, path, and
"status": "pending" - Build command runs without error (dry-run first)
- Rendered WebP exists at the expected path
- File size in expected range (15-80 KB)
- Icon reads clearly at both 1024px and ~40px display sizes
- Transparent background (no solid rectangle behind the glyph)
- Manifest status updated to
"done"after successful render
Pitfalls
- Forgetting
* s: Hard-coded pixel values break when scale changes. Always multiply bys. - Canvas origin confusion: (0,0) is bottom-left, not top-left. Higher
yvalues move UP. - Double glow: The renderer already applies
ggfx::with_outer_glow()to every layer. Do NOT add glow inside the glyph function. - Too many layers: Each layer gets individual glow wrapping. More than 8 layers makes rendering slow and visually noisy.
- Mismatched IDs: The entity ID in the glyph mapping, manifest, and registry must all match exactly.
- JSON trailing commas: The manifest is strict JSON. No trailing comma after the last array element.
- Missing domain color: If the domain isn't in
get_cyberpunk_colors()inpalettes.R, rendering will error. Add the color first, then regenerate. - Wrong primitives file: Skills go in domain-grouped
primitives*.R, agents inagent_primitives.R, teams inteam_primitives.R.
Related Skills
- enhance-glyph — improve an existing glyph's visual quality, fix rendering issues, or add detail layers
- audit-icon-pipeline — detect missing glyphs and icons to know what needs creating
- render-icon-pipeline — run the full rendering pipeline end-to-end
- ornament-style-mono — complementary AI-based image generation (Z-Image vs R-coded glyphs)
- ornament-style-color — color theory applicable to glyph accent fill decisions
- create-skill — the parent workflow that triggers glyph creation when adding new skills
GitHub 仓库
相关推荐技能
content-collections
元Content Collections 是一个 TypeScript 优先的构建工具,可将本地 Markdown/MDX 文件转换为类型安全的数据集合。它专为构建博客、文档站和内容密集型 Vite+React 应用而设计,提供基于 Zod 的自动模式验证。该工具涵盖从 Vite 插件配置、MDX 编译到生产环境部署的完整工作流。
polymarket
元这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。
creating-opencode-plugins
元该Skill帮助开发者创建OpenCode插件,用于接入命令、文件、LSP等25+种事件。它提供了插件结构、事件API规范和JavaScript/TypeScript实现模式,适合需要拦截操作、扩展功能或自定义事件处理的场景。开发者可通过它快速构建响应式模块来增强OpenCode AI助手的能力。
sglang
元SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。
