RepoPilotOpen in app →

sharkdp/pastel

A command-line tool to generate, analyze, convert and manipulate colors

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1w ago
  • 26+ active contributors
  • Distributed ownership (top contributor 38% of recent commits)
Show all 6 evidence items →
  • Apache-2.0 licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/sharkdp/pastel)](https://repopilot.app/r/sharkdp/pastel)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/sharkdp/pastel on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: sharkdp/pastel

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/sharkdp/pastel shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 1w ago
  • 26+ active contributors
  • Distributed ownership (top contributor 38% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live sharkdp/pastel repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/sharkdp/pastel.

What it runs against: a local clone of sharkdp/pastel — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in sharkdp/pastel | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 37 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>sharkdp/pastel</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of sharkdp/pastel. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/sharkdp/pastel.git
#   cd pastel
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of sharkdp/pastel and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "sharkdp/pastel(\\.git)?\\b" \\
  && ok "origin remote is sharkdp/pastel" \\
  || miss "origin remote is not sharkdp/pastel (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "src/lib.rs" \\
  && ok "src/lib.rs" \\
  || miss "missing critical file: src/lib.rs"
test -f "src/types.rs" \\
  && ok "src/types.rs" \\
  || miss "missing critical file: src/types.rs"
test -f "src/parser.rs" \\
  && ok "src/parser.rs" \\
  || miss "missing critical file: src/parser.rs"
test -f "src/cli/cli.rs" \\
  && ok "src/cli/cli.rs" \\
  || miss "missing critical file: src/cli/cli.rs"
test -f "src/cli/commands/mod.rs" \\
  && ok "src/cli/commands/mod.rs" \\
  || miss "missing critical file: src/cli/commands/mod.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 37 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~7d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/sharkdp/pastel"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

pastel is a Rust CLI tool for generating, analyzing, converting, and manipulating colors across multiple color spaces (RGB, HSL, CIELAB, CIELCh) and formats (hex, CSS names, ANSI 8/24-bit). It enables composable color operations via Unix pipes, letting users chain commands like pastel random | pastel mix red | pastel lighten 0.2 | pastel format hex to transform colors. Modular binary-centric design: src/cli/main.rs is the entry point, with src/cli/cli.rs defining the clap argument parser. Commands live in src/cli/commands/* (gradient.rs, sort.rs, distinct.rs, etc.). Core color logic lives in src/ as libraries: colorspace.rs handles RGB/HSL/Lab conversions, parser.rs parses color strings (via nom), named.rs maps X11 color names, and delta_e.rs computes perceptual distance. The types.rs and helper.rs provide shared utilities.

👥Who it's for

Terminal-based developers, shell script authors, and data visualization engineers who need programmatic color manipulation without leaving the command line. Specifically: system administrators automating colored terminal output, designers building color palettes via CLI, and developers who need color format conversion and perceptual color operations (like ΔE color distance).

🌱Maturity & risk

Production-ready. The project is at v0.12.0 with a stable Rust 1.83.0 MSRV, comprehensive CI/CD via GitHub Actions (CICD.yml), dual MIT/Apache-2.0 licensing, and evidence of active maintenance (benches/, build.rs for completions). The codebase is well-structured with clear command separation and meaningful abstractions around color spaces.

Low risk. Dependencies are minimal and stable (nom 7.1.3 for parsing, clap 4 for CLI, rand 0.9 for generation)—all widely-used crates. Single maintainer (sharkdp) is a known Rust community contributor, but no open issue/PR data provided to assess backlog. No breaking changes visible in recent structure. The LTO + strip release profile suggests production maturity.

Active areas of work

No specific PR/milestone data visible, but the repo structure shows mature feature completeness: color picking (colorpicker.rs using hdcanvas.rs for terminal canvas rendering), gradient generation, color distinctness algorithms (distinct.rs), colorcheck command (colorcheck.rs), and paint/format utilities. The benches/parse_color.rs benchmark suggests ongoing optimization of the nom-based parser.

🚀Get running

git clone https://github.com/sharkdp/pastel.git
cd pastel
cargo build --release
./target/release/pastel --help

Or install from crates.io: cargo install pastel.

Daily commands:

cargo build
cargo run -- --help
cargo run -- random | cargo run -- lighten 0.2 | cargo run -- format hex
cargo test
cargo bench --bench parse_color

🗺️Map of the codebase

  • src/lib.rs — Core library export point; defines public API for color types, parsing, and manipulation—essential for understanding what functionality is exposed
  • src/types.rs — Defines the Color struct and core color space representations (RGB, HSL, CIELAB, CIELCh); foundational to all color operations
  • src/parser.rs — Nom-based parser for multiple color formats; critical for input handling and format conversion
  • src/cli/cli.rs — CLI argument parsing and main entry point using Clap; routes all user commands to subcommand handlers
  • src/cli/commands/mod.rs — Command module coordinator; re-exports all available commands (saturate, mix, paint, gradient, etc.)
  • src/colorspace.rs — Color space conversion algorithms (RGB↔HSL, RGB↔CIELAB, etc.); mathematical core of color transformations
  • src/delta_e.rs — Delta E color difference calculations; used for color analysis and distinction algorithms

🛠️How to make changes

Add a new color manipulation command

  1. Create a new command module in src/cli/commands/ (e.g., src/cli/commands/my_command.rs) (src/cli/commands/my_command.rs)
  2. Implement pub fn run(color: Color, args: MyCommandArgs) -> Result<Color> with your transformation logic (src/cli/commands/my_command.rs)
  3. Add the module to src/cli/commands/mod.rs with pub mod my_command; (src/cli/commands/mod.rs)
  4. Add a new subcommand struct and case in src/cli/cli.rs to wire Clap arguments (src/cli/cli.rs)
  5. Dispatch the command in src/cli/main.rs within the Commands enum match block (src/cli/main.rs)

Add support for a new color format

  1. Add a new variant to the ColorSpace enum in src/types.rs (e.g., ColorSpace::MyFormat) (src/types.rs)
  2. Extend the Color impl in src/types.rs with conversion methods (to_my_format, from_my_format) (src/types.rs)
  3. Add parsing rule(s) to src/parser.rs using Nom combinators (src/parser.rs)
  4. Add formatting case to src/cli/commands/format.rs Display impl (src/cli/commands/format.rs)
  5. Update src/colorspace.rs with conversion logic to/from standard RGB and other spaces (src/colorspace.rs)

Add a new color analysis/metrics command

  1. Implement analysis logic in a new module (e.g., src/analysis.rs or extend src/delta_e.rs) (src/delta_e.rs)
  2. Create command handler in src/cli/commands/ (e.g., src/cli/commands/analyze.rs) (src/cli/commands/analyze.rs)
  3. Wire command into src/cli/cli.rs with Clap argument definitions (src/cli/cli.rs)
  4. Dispatch in src/cli/main.rs and format output via src/cli/output.rs (src/cli/main.rs)

🔧Why these technologies

  • Nom parser combinator library — Efficient, composable parsing of multiple color format grammars (hex, rgb(), hsl(), lab(), named colors) in a single unified parser
  • Clap CLI framework — Declarative argument parsing with automatic help generation, suggestions, and subcommand routing; reduces boilerplate for complex CLI structure
  • CIELAB/CIELCh/Delta E — Perceptually uniform color space enables accurate color difference metrics for distinct color generation and accessibility analysis
  • Rand crate for random color generation — Provides cryptographically sound randomness for color generation without external dependencies

⚖️Trade-offs already made

  • Pure Rust, no C bindings for color math

    • Why: Simplifies build, portability, and memory safety
    • Consequence: Color space conversions are pure functions but slightly slower than SIMD-optimized C libraries; adequate for interactive use
  • Single-threaded command execution

    • Why: Simplifies state management and piping; CLI tools typically run short-lived, single operations
    • Consequence: Batch operations (e.g., gradient with 1000 colors) are not parallelized; acceptable for typical use but limits throughput
  • Pipe-based composition over config files

    • Why: Aligns with Unix philosophy; commands compose naturally via stdout/stdin
    • Consequence: Complex multi-step workflows require shell piping; no persistent state or saved presets

🚫Non-goals (don't propose these)

  • Interactive GUI—pastel is CLI-only (except pick command which uses terminal UI)
  • Real-time color picking from screen (pick command is interactive terminal input, not screen capture)
  • Network/online color palette services
  • Plugin/extension system
  • Batch image processing or image file manipulation

🪤Traps & gotchas

Color space conversions assume sRGB (no profile handling for wide gamut). Parser is strict: whitespace in rgb() matters (nom is position-sensitive). ANSI detection via output_vt100 requires TTY detection—piped output may disable color. Terminal color picking (pick command) uses raw mode and may leave terminal in a bad state if interrupted ungracefully. No caching of parsed colors—each parse is fresh (nom does not memoize). Bench baseline missing: benches/parse_color.rs exists but Criterion baseline data is not in the repo, so relative performance changes won't show without running locally.

🏗️Architecture

💡Concepts to learn

  • Color Space Conversion (RGB ↔ HSL ↔ Lab) — pastel's core feature; understanding sRGB → XYZ → Lab conversions is essential to modify colorspace.rs and understand why certain operations (lighten, saturate) work differently in different spaces
  • CIE ΔE (Delta E) Color Distance — Used in distinct.rs and sort.rs to measure perceptual color similarity; critical for the distinct command's algorithm and color comparison logic
  • ANSI 256-Color & Truecolor (24-bit) — pastel must map RGB colors to terminal capabilities via src/ansi.rs; understanding ANSI escape codes is necessary to debug output or add new formatting modes
  • Parser Combinators (nom) — src/parser.rs uses nom's combinator API to handle diverse color input formats; modifying or extending color parsing requires understanding nom's declarative parsing model
  • sRGB Gamma Correction — RGB values must be gamma-corrected before Lab conversion; omitting this causes incorrect perceptual results in colorspace.rs
  • Unix Pipe Composition (Streaming Design) — pastel's entire value proposition relies on composability—each command reads stdin and writes stdout; understanding how colors flow through piped commands is essential to design new operations
  • Clap Declarative CLI Parsing — src/cli/cli.rs defines all arguments, subcommands, and help text via clap macros; adding new flags or commands requires understanding clap's builder API
  • BurntSushi/ripgrep — Similar Rust CLI philosophy: single-purpose, composable, focus on performance and UX; sharkdp also authored fd which ripgrep inspired
  • sharkdp/fd — Same author, same ecosystem; parallel tool for file finding vs. color manipulation, shows pastel author's pattern of Rust CLI excellence
  • sharkdp/bat — Same author; cat clone with syntax highlighting that pairs well with pastel for colorized output pipelines
  • olimorris/colorbuddy.nvim — Neovim color picker and palette tool; complementary for developers who want terminal + editor color workflows
  • termstandard/colors — ANSI color standard reference; relevant for understanding the 8-bit/24-bit ANSI output targets in src/ansi.rs

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for all color command subcommands in src/cli/commands/

The repo has tests/integration_tests.rs but analyzing the file structure shows 11+ command modules (format.rs, gradient.rs, gray.rs, distinct.rs, paint.rs, random.rs, sort.rs, colorcheck.rs, pick.rs, etc.) with no visible corresponding test coverage. Adding comprehensive integration tests for each command's various flag combinations and color input formats would improve reliability and prevent regressions.

  • [ ] Review existing integration_tests.rs to understand current test patterns
  • [ ] Add integration tests for src/cli/commands/gradient.rs covering gradient generation with different color stops
  • [ ] Add tests for src/cli/commands/sort.rs with various sort criteria (hue, saturation, lightness)
  • [ ] Add tests for src/cli/commands/distinct.rs validating color distinctness calculations
  • [ ] Add tests for src/cli/commands/paint.rs with different ANSI color modes
  • [ ] Run cargo test --test integration_tests to verify all tests pass

Add benchmark suite for color parsing and manipulation operations in benches/

The repo has a parse_color.rs benchmark but only tests parsing. Given the performance-sensitive nature of color operations (mixing, conversion, delta-e calculations), adding benchmarks for src/delta_e.rs, src/colorspace.rs conversion functions, and src/distinct.rs distinctness calculations would help maintainers catch performance regressions and optimize hot paths.

  • [ ] Create benches/colorspace_conversion.rs to benchmark RGB↔HSL↔CIELAB conversions from src/colorspace.rs
  • [ ] Create benches/delta_e_calculations.rs to benchmark ΔE calculations from src/delta_e.rs
  • [ ] Create benches/color_mixing.rs to benchmark color mixing operations
  • [ ] Run cargo bench and document baseline performance numbers in CHANGELOG.md
  • [ ] Add benchmark comparisons to CI/CD workflow to prevent performance regressions

Document color format specifications and conversion algorithms in doc/

The repo supports multiple color spaces (RGB, HSL, CIELAB, CIELCh, ANSI) as stated in README, but doc/ only contains colorcheck.md and demo scripts. Adding technical documentation for supported formats would help contributors understand the color space implementations in src/colorspace.rs, src/parser.rs, and src/delta_e.rs.

  • [ ] Create doc/color-formats.md documenting all supported formats (hex, rgb, hsl, lab, lch, ansi, named colors) with examples
  • [ ] Create doc/color-spaces.md explaining CIELAB vs CIELCh vs HSL conversion algorithms with references to src/colorspace.rs implementations
  • [ ] Create doc/delta-e.md documenting Delta E color difference calculations referenced in src/delta_e.rs
  • [ ] Add examples of edge cases (e.g., grayscale handling in HSL, achromatic colors in CIELAB)
  • [ ] Update README.md with links to the new documentation files

🌿Good first issues

  • Add integration tests in tests/ directory for the round-trip conversions (e.g., parse hex → convert to HSL → convert back to RGB → format hex, verify byte-for-byte match). Currently, colorspace.rs has unit tests but no end-to-end format stability tests.
  • Extend src/named.rs CSS color name list: verify all X11 + CSS3 named colors are present, add missing ones with tests. Current scope is unclear from file; cross-check against web standards and file a PR with additions.
  • Add --profile flag to pastel pick command to preview colors under different simulated color blindness modes (protanopia, deuteranopia, tritanopia) using existing ΔE + Lab conversions. Code structure in delta_e.rs and colorspace.rs is already there.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 01d4252 — Bump actions/upload-artifact from 6 to 7 (dependabot[bot])
  • 426ec9e — Bump regex from 1.12.2 to 1.12.3 (dependabot[bot])
  • 18b9cf9 — Bump clap_complete from 4.5.65 to 4.5.66 (dependabot[bot])
  • 314ba4c — Bump clap from 4.5.56 to 4.5.60 (dependabot[bot])
  • 5e9f9c0 — Bump to v0.12.0 (sharkdp)
  • 3121f6c — Add ANSI 8-bit parsing (sharkdp)
  • 74a0fc8 — Fix #289 (sharkdp)
  • 7b9335f — Update cargo_bin call, closes #288 (sharkdp)
  • 616bdd5 — Bump actions/checkout from 5 to 6 (dependabot[bot])
  • 15cee26 — Replace atty dependency with std::io::IsTerminal (breaking) (musicinmybrain)

🔒Security observations

The pastel codebase demonstrates good security practices overall. As a command-line color utility written in Rust, it has minimal attack surface. No hardcoded secrets, injection vulnerabilities, or critical issues were identified. The main areas for improvement are: (1) adding automated dependency vulnerability scanning to CI/CD, (2) reviewing the usage of the 'rand' crate to ensure it's appropriate for the use case, and (3) maintaining regular updates to dependencies and Rust version. The project uses standard security practices including Cargo.lock, multiple licensing options, and LTO/stripping in release builds.

  • Low · Outdated Rust MSRV — Cargo.toml. The project specifies rust-version = '1.83.0', which is relatively recent but should be regularly reviewed. While not a direct vulnerability, using very old MSRV can expose the project to known compiler bugs. Fix: Maintain the MSRV as a reasonable balance between compatibility and access to compiler improvements. Consider updating documentation on why this specific version is required.
  • Low · Dependency on 'rand' crate — Cargo.toml, src/random.rs. The project uses 'rand' crate version 0.9 for random color generation. While rand is a well-maintained crate, ensure it's being used appropriately (i.e., not for cryptographic purposes where rand::rngs::OsRng should be used). Fix: Review usage in src/random.rs to ensure rand is appropriate for the use case. If used for non-cryptographic color generation, current usage is acceptable. Add comments clarifying this is not for security-sensitive operations.
  • Low · Incomplete dependency audit trail — .github/workflows/CICD.yml. While Cargo.lock is present (good practice), the project does not appear to have security audit tooling configured in CI/CD (no cargo-audit or cargo-deny in visible workflow files). Fix: Add 'cargo audit' or 'cargo-deny' checks to the CI/CD pipeline to automatically detect known vulnerabilities in dependencies.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · sharkdp/pastel — RepoPilot