agentleFS
withevergrowwithevergrow/withicons/AGENTS.md

withicons

AGENTS.md3 starsChanged 28 days agoMITView on GitHub

This file is for coding agents (Claude Code, Cursor, Codex, Copilot) that change this repo. If you only need to use the icons in another project, read skills/with-icons/SKILL.md instead. 1,000 icons x 34 styles = 34,000 icons (current numbers; generators read them from data), all generated from 1,000 hand-authored skeletons (plus hand-drawn per-style overrides in forge/hand/), plus one optional animation spec and 20-30 colour palettes per icon, and a separate set of up to 50 live icons (content you set:…

  • Commits and pushes

We split this AGENTS.md into the rules it gives an agent

4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Originality: never copy path data from Lucide, Feather, Heroicons, Tabler, Phosphor, Material, Font Awesome or any other set.

    line 92
  2. Very specific:

    Counts are data: never hard-code "500 icons" / "12 styles" in generators.

    line 103
  3. Very specific:

    Never run npm publish, scripts/deploy.mjs without --dry-run, AWS mutations, or git push unless the user asks.

    line 121
  4. Distinctive:

    When several agents work at once, each owns specific files.

    line 125

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md: working on the with icons repository

This file is for coding agents (Claude Code, Cursor, Codex, Copilot) that change this repo. If you only need to use the icons in another project, read skills/with-icons/SKILL.md instead.

What this repo is

1,000 icons x 34 styles = 34,000 icons (current numbers; generators read them from data), all generated from 1,000 hand-authored skeletons (plus hand-drawn per-style overrides in forge/hand/), plus one optional animation spec and 20-30 colour palettes per icon, and a separate set of up to 50 live icons (content you set: dates, times, counts, labels) whose generators every style renders.

forge/icons/<name>.json     the ONLY hand-drawn input: one skeleton per icon (paths + plates, fills, cutouts, aliases, synonyms, tags)
forge/manifest.json         icon list + categories
forge/motion/<name>.json     hand-authored animation spec per icon (loop, hover, alt presets, swaps); contract: forge/MOTION.md
forge/palettes/<name>.json   20-30 colour palettes picked per icon (ten roles: ink c1-c4 tint accent shadow shine edge);
                             contract: forge/PALETTES.md; ships as @withicons/core/palettes/* (+ palette-map.js)
forge/styles/<style>.mjs    one deterministic renderer per style, in this order everywhere (STYLE_ORDER in forge/lib/emit-core.mjs):
                            line solid duo gloss engrave blueprint sketch | palette styles: glass kawaii sticker pixel retro
                            | studio styles: luxe bauhaus skeuo (site group "Studio"; role-named vars --with-<style>-<role>)
                            | storybook styles: anime gothic pastel coquette plush (site group "Storybook"; role-named vars)
                            | rich styles (run 12, gradients allowed, role-named vars): clay bento suite dock liquid chrome soft3d brutal
                            | holiday styles (run 13, rich): utsav rangoli halloween christmas lunar valentine (site group "Holidays");
                            glass is rich too (soft frosted glass with gradients); duo has an accent detail + opt-in gradient.
                            Site groups (site/js/site.js GROUPS): Essentials, Product & brand, 3D & glass, Playful, Artistic, Holidays
                            (palette colours are var(--with-<style>-<role>, #hex), ink stays currentColor)
forge/hand/<style>/<icon>.mjs hand-drawn override of one icon in one style (replaces the generated drawing);
                            contract: forge/HAND.md; validate with node forge/tools/hand.mjs check <style> <icon>
forge/dynamic/<name>.mjs    live icon generators: params -> skeleton, rendered by every style (forge/DYNAMIC.md);
                            ships as @withicons/dynamic (emit-dynamic) and site/vendor/dynamic/dynamic.js (live.html)
forge/loaders/<name>.mjs    animated loaders (50: common / creative / festival): parts = skeletons + CSS keyframe motion, drawn by
                            every style; _morphs.mjs = icon morph presets; contract: forge/LOADERS.md; compiler forge/lib/loader-compile.mjs;
                            ships as @withicons/loaders (emit-loaders) + site/loaders.html (Loader Studio) + MCP get_loader
forge/kernel/**             geometry + boolean ops shared by renderers
forge/lib/load.mjs          loads/prepares skeletons
forge/lib/emit-*.mjs        one emitter per package -> packages/*/dist (generated, gitignored); emit-motion -> packages/motion
                            emit-core also exports the shared helpers: STYLE_ORDER, flattenVars, countText, paletteDoc, motionDoc
forge/tools/site-data.mjs   site data (site/data/meta.js, style-<name>.js); build.mjs calls its build(ctx)
forge/tools/site-seo.mjs    generated pages: site/icons/*.html, categories/, styles/, sitemap, robots, llms*.txt, icons.json, og/
forge/build.mjs             renders everything once, runs every emitter, then site-data + site-seo
packages/*                  npm packages @withicons/{core,core-plus,soft3d,holiday,react,vue,svelte,angular,solid,web,web-plus,classes,classes-plus,static,static-plus,search,mcp,motion,dynamic,loaders} + CLI `withicons`
                            companions (jsDelivr: 150 MB per package): the newest styles' core files (svg, nodes) and class files
                            live in core-plus / classes-plus / web-plus / static-plus, the styles in STYLE_PACKAGE in their own packages (@withicons/soft3d,
                            @withicons/holiday: dist/ + dist/classes/); core and classes keep the older styles, except the class files of CLASSES_PLUS_STYLES (glass, skeuo, gothic: classes-plus). Every package stays under 145 MB (scripts/package-budget.mjs). Build every CDN URL with cdnPkg/cdnDir/cdnSvgUrl
                            (forge/lib/emit-core.mjs), never with a hard-coded core@ or classes@ path per style
site/                       zero-build static website (vanilla HTML/CSS/JS), deployed to withicons.com
skills/with-icons/          the agent skill for USERS of the library (reference/icons.md is generated)
infra/                      AWS CloudFormation (S3 + CloudFront + Lambda API + OIDC role + budget)
scripts/                    deploy.mjs, publish.mjs, skill-sync.mjs
docs/                       LAUNCH.md (launch plan), COSTS.md (AWS cost model)

Commands

npm ci                                   # Node 22+
node forge/build.mjs                     # full build (packages + site), ~1-2 min
node forge/build.mjs react vue           # only some emitters (site data/SEO still regenerate)
node forge/tools/check.mjs               # lint all skeletons + render every style (exit 1 on hard errors)
node forge/tools/check.mjs home lock     # just these icons
node forge/tools/check-motion.mjs [names] # validate forge/motion/*.json against forge/MOTION.md
node forge/tools/check-palettes.mjs [names] [--quiet] # validate forge/palettes/*.json against forge/PALETTES.md
node forge/tools/preview.mjs --styles line,solid --icons home,lock --size 56 --small --out .preview/<agent>-x.png   # add --dark for palette styles
node forge/tools/serve.mjs               # http://localhost:4321 (site/)
npm test --workspaces --if-present       # package tests (incl. packages/search)
node forge/tools/check-loaders.mjs [names] [--styles a,b]   # validate loader specs, compile every style, size, determinism
node forge/tools/preview-loaders.mjs --loaders spinner,orbit --styles line,glass --frames 8   # frame strips (motion on a PNG)
node forge/lib/emit-loaders.mjs [--styles line,glass]        # @withicons/loaders + site loader files only (~2 min); --styles redraws just those (+ line) and leaves package.json, README and MCP data alone
node scripts/skill-sync.mjs [--check]    # regenerate the skill's icons.md, palette + motion tables, counts, site/skill/SKILL.md
node scripts/deploy.mjs --dry-run        # deploy plan; never run without --dry-run unless asked
node scripts/publish.mjs --dry-run       # npm pack check (warns if v<version> is already tagged elsewhere); never publish unless asked

Look at your output. For any drawing or renderer change, render a preview PNG and inspect it at 56px and at real 16/24px (--small), on light and --dark.

Rules

  • Read forge/CONTRACT.md before touching icons or styles. Grid, keylines, plates, fills/cutouts, renderer contract. Reuse the shared parts in forge/PARTS.md exactly.
  • Adding a style touches more than its renderer: STYLE_ORDER/PALETTE_STYLES/RICH_STYLES (+ STYLE_PACKAGE when it ships in a package of its own) in forge/lib/emit-core.mjs, the site lists (ORDER, GROUPS, INFO, ROOTS, NAV_STYLE, NEW_STYLES in site/js/site.js; WORDS in style-picker.js; HEX/STYLE_SAY in live.js; ORDER/GROUPS/HEX/SAY in library.js; ORDER/HEX/CLABEL in editor.js), its colour trio + -on in site/css/tokens.css (light and dark) and library.css, forge/tools/site-seo.mjs, forge/tools/site-pages/lib.mjs (ORDER, STYLE_COLOR), its site group in GROUPS (site/js/site.js, read by forge/tools/style-groups.mjs), the picker rows in site/css/icon-page.css, site/css/live.css + SB_GROUPS in forge/tools/site-dynamic.mjs (STYLE_SAY), the home packs (FOLLOW/WASHLINE/SHOWCASE in forge/tools/site-data.mjs), STYLES_3D in packages/motion/src/meta.js when its motion should play in 3D, an allowance in forge/tools/livegate-thresholds.json (node forge/tools/check-dynamic.mjs --calibrate --style <name>), a "Free … icons" lander (forge/tools/site-alternatives/free-more.mjs, gated by hasStyle) and the search words (packages/search/src/engine.mjs STYLE_WORDS + STYLE_PHRASES + test). Counts and copy are data-driven; never hard-code "15".
  • Originality: never copy path data from Lucide, Feather, Heroicons, Tabler, Phosphor, Material, Font Awesome or any other set.
  • Deterministic: same input, byte-identical output. Use the kernel rng(seed), never Math.random() or dates.
  • Colour: renderers paint currentColor. Only the palette styles may add colours, and only as var(--with-<style>-<role>, #hex) (no defs, ids, gradients, filters, masks, text or images; rich styles may add gradients, see below). Standalone .svg outputs flatten the variables (flattenVars); inline outputs keep them.
  • Rich styles (glass and the AI / Product / Trend groups) may also use gradients, and only as one <defs> node of linear/radial gradients whose ids are wg-<style>-<icon>-<n> and whose stop colours are role variables (var(--with-<style>-<role>, #hex)), so palettes recolour the gradients too. Still no filters, masks, text or images. Inline outputs (packages, the site via uniqIds in forge/tools/site-pages/lib.mjs) make the ids unique per instance; standalone .svg flattens the variables. Heavy styles load on demand on icon pages and style hubs.
  • Counts are data: never hard-code "500 icons" / "12 styles" in generators; use countText(ctx) / ctx.styles.length.
  • Palettes: per-icon palettes live only in forge/palettes/<name>.json and set colour roles, never style variables; each style maps roles to its own --with-* variables (palette-map), so one palette recolours every multi-colour style.
  • Motion: animations live only in forge/motion/<name>.json (closed preset vocabulary, forge/MOTION.md) and ship in @withicons/motion; icons never depend on it.
  • Generated files are not edited by hand: packages/*/dist, site/data/*, site/icons/*.html, site/categories/, site/styles/, site/og/, sitemap.xml, llms*.txt, icons.json, skills/with-icons/reference/icons.md, site/skill/SKILL.md, packages/motion/dist, site/vendor/motion/*, site/data/motion.js, packages/cli/src/skill-data.mjs, packages/mcp/src/data-inline.mjs, packages/loaders/dist, packages/loaders/{package.json,README.md}, packages/mcp/src/loaders-data.mjs, site/data/loaders.js, site/vendor/loaders/*, site/loaders/svg/*, skills/with-icons/reference/loaders.md (the table). Change the generator and rebuild.
  • Names: kebab-case canonical names. aliases (3-15) are what people guess. An alias may not equal another icon's name. synonyms are extra search words. Renaming an icon is a breaking change: keep the old name as an alias.
  • Brand: the product is with icons (lowercase wordmark), domain withicons.com, "Powered by Evergrow". The old names egopenicons / Evergrow Open Icons / eg- prefixes are retired, so never reintroduce them. Public identifiers: npm @withicons/*, element <with-icon>, classes with with-<name>, CSS vars --with-*.
  • Site: zero build, relative links (works from file:// and S3), .html URLs, every page works without JS for reading. Design contract: site/DESIGN.md.
  • Previews go to .preview/<agent-name>-*.png (gitignored). Temporary files go to .tmp/.
  • Never run npm publish, scripts/deploy.mjs without --dry-run, AWS mutations, or git push unless the user asks.

Ownership (parallel agents)

When several agents work at once, each owns specific files. Do not edit files you do not own. Ask the coordinator instead.

areaownerfiles
icon skeletonsicon authors (per batch, see forge/.claims/)forge/icons/<name>.json
animation specsmotion authors (per icon)forge/motion/<name>.json
colour palettespalette authors (per icon)forge/palettes/<name>.json
motion packagemotion ownerforge/lib/emit-motion.mjs, packages/motion/**
style renderersone agent per styleforge/styles/<style>.mjs, forge/styles/_<style>-*.mjs
packagespackages ownerforge/build.mjs, forge/lib/emit-*.mjs (not emit-motion), packages/** (not motion), forge/tools/site-data.mjs, forge/tools/site-integrations.mjs
site brand + home (D1)D1site/fonts/**, css/tokens.css, css/chrome.css, js/site.js, index.html, home css/js, 404.html, site/brand/**
library + generated pages (D2)D2icons.html, library css/js, forge/tools/site-seo.mjs and all it generates
content pages (D3)D3guides/**, developers.html, ai.html, about.html, license.html, faq.html, pages css/js
launch, infra, CI, skilllaunch ownerinfra/**, scripts/**, .github/**, docs/LAUNCH.md, docs/COSTS.md, skills/**, site/skill/SKILL.md, AGENTS.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, LICENSE, CHANGELOG.md, .cursor/rules/**
frozennobodyforge/kernel/**, forge/lib/load.mjs, forge/tools/check.mjs, forge/tools/check-motion.mjs, forge/manifest.json, forge/CONTRACT.md, forge/MOTION.md (lead only)

Deploy and release (maintainers)

  • Site: push to main and .github/workflows/deploy-site.yml runs scripts/deploy.mjs with an OIDC role. It uploads changed files with per-class Cache-Control, updates the API Lambda (packages/mcp/dist/lambda.mjs, which must be a self-contained bundle wrapped by infra/lambda/index.mjs), and invalidates changed paths.
  • npm: bump the root version (withiconsVersion; v0.1.0 is already tagged, so the next release is 0.2.0), build, then tag vX.Y.Z. .github/workflows/release.yml publishes all packages in lockstep, @withicons/motion included (Trusted Publishing + provenance; scripts/publish.mjs fails if one is missing). See docs/LAUNCH.md.
  • The API Lambda must never answer with HTTP 403: CloudFront maps origin 403s to the site's /404.html.

Download now (ZIP)

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository2 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.