Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Create Glyph

ASecurity

Create R-based pictogram glyphs for skill, agent, or team icons in the visualization layer. Covers concept sketching, ggplot2 layer composition using the primitives library, color strategy, registration in the appropriate glyph mapping file and manifest, rendering via the build pipeline, and visual verification of the neon-glow output. Use when a new entity has been added and needs a visual icon for the force-graph visualization, an existing glyph needs replacement, or when batch-creating gly...

31 stars
0 votes
0 copies
4 views
Added 9/3/2026
ai-agentsgobashflaskawsgitdevopssecurity

Works with

terminalclimcp

Security Analysis

A100/100

Scanned 9/3/2026

$npx -y skills add pjt222/agent-almanac --skill create-glyph --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Create Glyph?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Create Glyph
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pjt222-create-glyph-agent-almanac/badge)](https://www.skillsdirectory.com/skills/pjt222-create-glyph-agent-almanac)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: create-glyph
locale: caveman-lite
source_locale: en
source_commit: 82c77053
fence_basis_commit: 82c77053
translator: "Julius Brussee homage — caveman"
translation_date: "2026-04-19"
description: >
  Create R-based pictogram glyphs for skill, agent, or team icons in the
  visualization layer. Covers concept sketching, ggplot2 layer composition using
  the primitives library, color strategy, registration in the appropriate glyph
  mapping file and manifest, rendering via the build pipeline, and visual
  verification of the neon-glow output. Use when a new entity has been added and
  needs a visual icon for the force-graph visualization, an existing glyph needs
  replacement, or when batch-creating glyphs for a new domain.
license: MIT
allowed-tools: Read Write Edit Bash Grep Glob
metadata:
  author: Philipp Thoss
  version: "2.0"
  domain: design
  complexity: intermediate
  language: R
  tags: design, glyph, pictogram, icon, ggplot2, visualization, neon
---

# 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`, or `team`
- **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-sigma` value (default: 4)

## Procedure

### Step 1: Concept — Design the Visual Metaphor

Identify the entity being iconified and choose a visual metaphor.

1. Read the entity's source file to understand its core concept:
   - Skills: `skills/<id>/SKILL.md`
   - Agents: `agents/<id>.md`
   - Teams: `teams/<id>.md`
2. 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)
3. Reference existing glyphs for complexity calibration:

```text
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        |
+----------+--------+-------------------------------------------+
```

4. 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.

1. Function signature (immutable contract):
   ```r
   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
   }
   ```

2. Apply scale factor `* s` to ALL dimensions for consistent scaling:
   ```r
   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
   ```

3. 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 |

4. Apply the color strategy:

   ```text
   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                |
   +----------------------+------------+--------------------------+
   ```

5. Return a flat `list()` of layers (the renderer iterates and wraps each with glow)

6. 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, defensive
     - `primitives_2.R` — devops, general, git, mcp-integration
     - `primitives_3.R` — mlops, observability, PM, r-packages, reporting, review, web-dev, esoteric, design
     - Additional `primitives_4.R` through `primitives_19.R` for newer domains
   - **Agents**: `viz/R/agent_primitives.R`
   - **Teams**: `viz/R/team_primitives.R`

**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:
```r
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:**
1. Open `viz/R/glyphs.R`
2. Find the comment section for the target domain (e.g., `# -- design (3)`)
3. Add the entry in alphabetical order within the domain block:
   ```r
   "skill-id" = "glyph_function_name",
   ```
4. Update the domain count in the comment if applicable

**For agents:**
1. Open `viz/R/agent_glyphs.R`
2. Find the alphabetical position in `AGENT_GLYPHS`
3. Add the entry:
   ```r
   "agent-id" = "glyph_function_name",
   ```

**For teams:**
1. Open `viz/R/team_glyphs.R`
2. Find the alphabetical position in `TEAM_GLYPHS`
3. Add the entry:
   ```r
   "team-id" = "glyph_function_name",
   ```

5. 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`
```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`
```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`
```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](../render-icon-pipeline/SKILL.md) for the full flag reference and pipeline architecture.

```bash
# 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 in `get_palette_colors()` in `palettes.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.

1. Verify file exists and has reasonable size:
   ```bash
   ls -la viz/public/icons/cyberpunk/<type-path>/<entity-id>.webp
   # Expected: 15-80 KB typical range
   ```

2. 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

3. 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.

1. Common adjustments:
   - **Bolder strokes**: increase `.lw(s, base)` — try `base = 3.0` or `3.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

2. To re-render after changes:
   ```bash
   # 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
   ```

3. 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 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:
```r
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`:
1. `PALETTE_DOMAIN_ORDER` (alphabetical)
2. `get_cyberpunk_colors()` domains list
3. Run `bash viz/build.sh` to 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.R` through `viz/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 `* s` scaling factor
- [ ] Color strategy uses `col` for fills, `bright` for 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.R` file
- [ ] 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 by `s`.
- **Canvas origin confusion**: (0,0) is bottom-left, not top-left. Higher `y` values 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()` in `palettes.R`, rendering will error. Add the color first, then regenerate.
- **Wrong primitives file**: Skills go in domain-grouped `primitives*.R`, agents in `agent_primitives.R`, teams in `team_primitives.R`.

## Related Skills

- [enhance-glyph](../enhance-glyph/SKILL.md) — improve an existing glyph's visual quality, fix rendering issues, or add detail layers
- [audit-icon-pipeline](../audit-icon-pipeline/SKILL.md) — detect missing glyphs and icons to know what needs creating
- [render-icon-pipeline](../render-icon-pipeline/SKILL.md) — run the full rendering pipeline end-to-end
- [ornament-style-mono](../ornament-style-mono/SKILL.md) — complementary AI-based image generation (Z-Image vs R-coded glyphs)
- [ornament-style-color](../ornament-style-color/SKILL.md) — color theory applicable to glyph accent fill decisions
- [create-skill](../create-skill/SKILL.md) — the parent workflow that triggers glyph creation when adding new skills

Attribution

pjt222pjt222
View sourceSee grades on GitHubMore from pjt222 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698621 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →