Skip to content

feat: universal theme installer — scraper, CLI commands, and browser preview - #16

Merged
basiclines merged 21 commits into
mainfrom
feat/theme-installer
Mar 20, 2026
Merged

feat: universal theme installer — scraper, CLI commands, and browser preview#16
basiclines merged 21 commits into
mainfrom
feat/theme-installer

Conversation

@basiclines

@basiclines basiclines commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Overview

This PR adds a full theme ecosystem to the rampa CLI: a VSCode Marketplace scraper that normalises themes into a shared YAML format, enrichment pipeline scripts, and new rampa theme CLI commands including an interactive browser preview.


Getting started locally

# 1. Install deps + build the CLI
cd cli && bun install && bun run build

# 2. Try the new commands (themes/ dir is included in the repo)
./dist/rampa theme list --local
./dist/rampa theme list --local --sort installs
./dist/rampa theme list --local --sort installs --all

# Curated list: popular, good contrast, deduplicated
./dist/rampa theme list --local --sort installs --paired \
  --min-installs 1000 --min-contrast 50 --min-distinct 20 --all

./dist/rampa theme "Dracula" --show --local
./dist/rampa theme "Tokyo Night" --preview --local   # opens browser

./dist/rampa theme "Dracula" --install ghostty --dry-run --local

New CLI commands

rampa theme list

List and filter available themes.

Flag Description
--local Load themes from the local themes/ directory
--sort name|installs|rating|ratings|mode Sort results (chainable)
--paired Show only dark/light pairs (one row per pair)
--min-installs <n> Only show themes with at least n installs
--min-contrast <n> Only show themes where avg APCA contrast of fg + tonal colors >= n (0-108)
--min-distinct <n> Deduplicate similar themes within the same publisher using full OKLCH signature
--all Show all results (default: first 100 with a count footer)

rampa theme "<name>" --show

Print full metadata for a theme (colors, contrast values, mode, accent, pair).

rampa theme "<name>" --preview

Spin up a local Bun.serve server and open a rich browser preview with:

  • Dark/light toggle (hidden when theme has no paired variant)
  • 16-color swatches in list mode with APCA contrast values
  • Terminal, syntax, and banner previews
  • Accent, Author, Source metadata chips
  • Install command panel (OS-filtered app selector + copy button)

rampa theme "<name>" --install <app>[,app2,...]

Write the theme config to the correct path for the target app.

Supported apps: ghostty, iterm2, iterm, alacritty, kitty, windows-terminal, wt, warp, hyper, vscode, xcode, android-studio

Note: iterm is an alias for iterm2, wt for windows-terminal. Windows Terminal requires pasting the generated JSON snippet into the schemes array in settings.json — it cannot be auto-installed.

Flag Description
--dry-run Print what would be written without touching the filesystem

Theme pairing

Dark/light pairs are resolved in 4 passes:

  1. Same-publisher exact token match — e.g. dracula vs dracula-light from the same author
  2. Cross-publisher token match — well-known themes where variants are published separately
  3. Implicit counterpart — one side has no variant token; the other does
  4. Full OKLCH color signature + name similarity — catches flavor-named families (Catppuccin Latte vs Mocha, etc.)

After pairing, dark/light assignment is validated by comparing actual background lightness and swapped if needed (catches themes where meta.mode does not match the real background brightness).


Pipeline scripts (for maintainers)

These scripts maintain the themes/ dataset. Run them in order after a re-scrape:

# 1. Scrape VSCode Marketplace (with retry/backoff)
bun run scripts/scrape-themes.ts

# 2. Remove exact color duplicates (keeps highest installs)
bun run scripts/dedup-themes.ts

# 3. Link dark/light pairs (4-pass algorithm)
bun run scripts/pair-themes.ts

# 4. Re-embed the preview HTML template (only needed after editing the template)
bun scripts/embed-preview-template.js

Current dataset: ~7,800 themes, 34 dupes removed, 373+ dark/light pairs linked.


Theme YAML format

name: "Dracula"
source:
  marketplace_id: "dracula-theme.theme-dracula"
  installs: 7000000
  author: "Dracula Theme"
  repo: "https://github.com/dracula/visual-studio-code"
  url: "https://marketplace.visualstudio.com/items?itemName=dracula-theme.theme-dracula"
colors:
  bg: "#282A36"
  fg: "#F8F8F2"
  # ... 16 ANSI colors
meta:
  mode: "dark"
  accent: "purple"
  hue: 265
  pair: "Dracula Light"   # null if no paired variant
  contrast:
    fg: 85.2
    red: 52.1
    # ... APCA Lc values for all 16 colors

Review comments addressed

  • SUPPORTED_APPS aliases — now derived from Object.keys(generators) so iterm/wt aliases are included in help and error messages automatically
  • Windows Terminal install path — standalone JSON files in LocalState are not loaded by WT; generator now returns null from installPath (like VSCode) and shows a hint to paste the scheme into settings.json
  • YAML schema consistency — all theme files include rating, ratings, and pair (null when unpaired); these fields are always emitted by the scraper/normalizer

basiclines and others added 8 commits March 18, 2026 09:55
Add rampa theme subcommand that installs color themes for 10 apps:
Ghostty, iTerm2, Alacritty, Kitty, Windows Terminal, Warp, Hyper,
VSCode, Xcode, and Android Studio.

- Theme YAML schema with ANSI colors + metadata (contrast, accent, mode, hue)
- Scraper fetches ~20k themes from VSCode Marketplace API
- 10 generators output native format per target app
- CLI: rampa theme list, --show, --install <app>, --dry-run

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Initial scrape — each YAML includes ANSI palette, APCA contrast, author, GitHub repo URL.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- scripts/dedup-themes.ts: removes exact color duplicates, keeps highest installs
- scripts/pair-themes.ts: links dark/light variants via meta.pair field
- scrape-themes.ts: removed inline dedup (now a separate step)

Pipeline: scrape → dedup → pair

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- theme list: --sort supports name, installs, rating, ratings, mode
- chain multiple: --sort rating --sort installs (primary then tiebreaker)
- ThemeSource: added rating and ratings fields
- scrape-themes: stores averagerating and ratingcount from marketplace
- removed inline dedup from scraper (use dedup-themes.ts instead)
- fixed themes dir resolution for compiled binaries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- rampa theme "Tokyo Night" --preview --local
- Spins up localhost:7432 serving the full Sarela-style preview page
- Injects CSS vars + JS themes override for the selected theme
- Loads paired theme (dark/light) if meta.pair is set
- Footer shows theme author with link to marketplace
- Template embedded as TS const — works in compiled binaries
- scripts/embed-preview-template.js regenerates the embed after HTML edits

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Hide dark/light toggle when theme has no pair
- Default color view to list mode
- APCA contrast shown in color list desc column
- Banner: theme name, hide romanji/tagline, proper poster-meta
- origin-badge repurposed for accent · author · repo chips
- Export section replaced with Install command (OS-filtered app select + copy)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Removed 34 exact color duplicates (kept highest installs)
- Linked 373 dark/light pairs via meta.pair field
- Updated index.json to reflect removed duplicates

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 18, 2026 22:51
@github-actions

github-actions Bot commented Mar 18, 2026

Copy link
Copy Markdown

🚀 Netlify Deploy Preview

https://feat-theme-installer--rampadesign.netlify.app

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a universal theme ecosystem for the rampa CLI, including a large local theme dataset, an HTML preview embedding script, and multiple app-specific theme generators.

Changes:

  • Added a large collection of normalized theme YAML files under themes/.
  • Added a script to embed the browser preview HTML into a TypeScript constant for compiled/bundled distribution.
  • Added new theme generators (e.g., Windows Terminal, Warp, VSCode, Kitty) and wired up the rampa theme subcommand entrypoint.

Reviewed changes

Copilot reviewed 279 out of 7479 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
themes/andromeda-custom.yaml Adds a new theme YAML entry to the local dataset
themes/anastasia.yaml Adds a new theme YAML entry to the local dataset
themes/anasdev.yaml Adds a new theme YAML entry to the local dataset
themes/anakmun.yaml Adds a new theme YAML entry to the local dataset
themes/amp-light.yaml Adds a new theme YAML entry to the local dataset
themes/amp-dark.yaml Adds a new theme YAML entry to the local dataset
themes/amozonia.yaml Adds a new theme YAML entry to the local dataset
themes/amora.yaml Adds a new theme YAML entry to the local dataset
themes/amoledtest-fork-fork.yaml Adds a new theme YAML entry to the local dataset
themes/amoled-dark-theme.yaml Adds a new theme YAML entry to the local dataset
themes/amminial.yaml Adds a new theme YAML entry to the local dataset
themes/amethyst-stone.yaml Adds a new theme YAML entry to the local dataset
themes/amethyst-dreams.yaml Adds a new theme YAML entry to the local dataset
themes/ambient.yaml Adds a new theme YAML entry to the local dataset
themes/amber-red.yaml Adds a new theme YAML entry to the local dataset
themes/amber-delight.yaml Adds a new theme YAML entry to the local dataset
themes/ambar-for-vscode.yaml Adds a new theme YAML entry to the local dataset
themes/amazonfrog.yaml Adds a new theme YAML entry to the local dataset
themes/alx-theme-toxic.yaml Adds a new theme YAML entry to the local dataset
themes/altin-s-love-symphony.yaml Adds a new theme YAML entry to the local dataset
themes/alternight.yaml Adds a new theme YAML entry to the local dataset
themes/altearn.yaml Adds a new theme YAML entry to the local dataset
themes/alpine.yaml Adds a new theme YAML entry to the local dataset
themes/alpine-warm.yaml Adds a new theme YAML entry to the local dataset
themes/alpha.yaml Adds a new theme YAML entry to the local dataset
themes/aloe.yaml Adds a new theme YAML entry to the local dataset
themes/almond-cream.yaml Adds a new theme YAML entry to the local dataset
themes/allure.yaml Adds a new theme YAML entry to the local dataset
themes/allure-light.yaml Adds a new theme YAML entry to the local dataset
themes/allure-contrast.yaml Adds a new theme YAML entry to the local dataset
themes/allomancer.yaml Adds a new theme YAML entry to the local dataset
themes/alligator-solarized-dark.yaml Adds a new theme YAML entry to the local dataset
themes/alligator-light.yaml Adds a new theme YAML entry to the local dataset
themes/all-nighter-theme.yaml Adds a new theme YAML entry to the local dataset
themes/all-blue.yaml Adds a new theme YAML entry to the local dataset
themes/all-black.yaml Adds a new theme YAML entry to the local dataset
themes/alignment.yaml Adds a new theme YAML entry to the local dataset
themes/alignment-darker.yaml Adds a new theme YAML entry to the local dataset
themes/alien-blood.yaml Adds a new theme YAML entry to the local dataset
themes/aliceblue-theme.yaml Adds a new theme YAML entry to the local dataset
themes/alice-s-theme.yaml Adds a new theme YAML entry to the local dataset
themes/alec-teal-theme.yaml Adds a new theme YAML entry to the local dataset
themes/alchemy-theme.yaml Adds a new theme YAML entry to the local dataset
themes/al-theme-official.yaml Adds a new theme YAML entry to the local dataset
themes/akurdor.yaml Adds a new theme YAML entry to the local dataset
themes/akumanomi-theme.yaml Adds a new theme YAML entry to the local dataset
themes/aksin.yaml Adds a new theme YAML entry to the local dataset
themes/ako-theme.yaml Adds a new theme YAML entry to the local dataset
themes/akihabara.yaml Adds a new theme YAML entry to the local dataset
themes/akari-dawn.yaml Adds a new theme YAML entry to the local dataset
themes/akagami-dark.yaml Adds a new theme YAML entry to the local dataset
themes/aka-kuro-light.yaml Adds a new theme YAML entry to the local dataset
themes/ahoy-theme.yaml Adds a new theme YAML entry to the local dataset
themes/agen-theme.yaml Adds a new theme YAML entry to the local dataset
themes/agathist-dark.yaml Adds a new theme YAML entry to the local dataset
themes/afterpurple.yaml Adds a new theme YAML entry to the local dataset
themes/afternoon-delight-subtle.yaml Adds a new theme YAML entry to the local dataset
themes/afterglow-fade.yaml Adds a new theme YAML entry to the local dataset
themes/afro.yaml Adds a new theme YAML entry to the local dataset
themes/aetherglow.yaml Adds a new theme YAML entry to the local dataset
themes/aether.yaml Adds a new theme YAML entry to the local dataset
themes/aether-zen.yaml Adds a new theme YAML entry to the local dataset
themes/aether-void.yaml Adds a new theme YAML entry to the local dataset
themes/aether-trench-contrast.yaml Adds a new theme YAML entry to the local dataset
themes/aether-neon.yaml Adds a new theme YAML entry to the local dataset
themes/aether-midnight.yaml Adds a new theme YAML entry to the local dataset
themes/aether-light.yaml Adds a new theme YAML entry to the local dataset
themes/aether-coffee.yaml Adds a new theme YAML entry to the local dataset
themes/aether-coffee-dark.yaml Adds a new theme YAML entry to the local dataset
themes/aesthetic.yaml Adds a new theme YAML entry to the local dataset
themes/aesthetic-dark.yaml Adds a new theme YAML entry to the local dataset
themes/aeridia.yaml Adds a new theme YAML entry to the local dataset
themes/adventuresinparadise.yaml Adds a new theme YAML entry to the local dataset
themes/advancedbat.yaml Adds a new theme YAML entry to the local dataset
themes/adrift.yaml Adds a new theme YAML entry to the local dataset
themes/adonis.yaml Adds a new theme YAML entry to the local dataset
themes/adey-coder.yaml Adds a new theme YAML entry to the local dataset
themes/adeol.yaml Adds a new theme YAML entry to the local dataset
themes/adech-theme-superior.yaml Adds a new theme YAML entry to the local dataset
themes/adech-theme-legacy.yaml Adds a new theme YAML entry to the local dataset
themes/adark.yaml Adds a new theme YAML entry to the local dataset
themes/adapt-dark.yaml Adds a new theme YAML entry to the local dataset
themes/aconitum.yaml Adds a new theme YAML entry to the local dataset
themes/acme.yaml Adds a new theme YAML entry to the local dataset
themes/aclear-dark.yaml Adds a new theme YAML entry to the local dataset
themes/acid-trip.yaml Adds a new theme YAML entry to the local dataset
themes/acequartz.yaml Adds a new theme YAML entry to the local dataset
themes/access-color-theme.yaml Adds a new theme YAML entry to the local dataset
themes/acario.yaml Adds a new theme YAML entry to the local dataset
themes/abyssal-blue.yaml Adds a new theme YAML entry to the local dataset
themes/abyss.yaml Adds a new theme YAML entry to the local dataset
themes/abyskai.yaml Adds a new theme YAML entry to the local dataset
themes/abys-zora-dark.yaml Adds a new theme YAML entry to the local dataset
themes/abstract-mh.yaml Adds a new theme YAML entry to the local dataset
themes/absent.yaml Adds a new theme YAML entry to the local dataset
themes/absent-light.yaml Adds a new theme YAML entry to the local dataset
themes/absent-contrast.yaml Adds a new theme YAML entry to the local dataset
themes/abraham.yaml Adds a new theme YAML entry to the local dataset
themes/aboc.yaml Adds a new theme YAML entry to the local dataset
themes/abe-land.yaml Adds a new theme YAML entry to the local dataset
themes/abcdef.yaml Adds a new theme YAML entry to the local dataset
themes/ab-dark.yaml Adds a new theme YAML entry to the local dataset
themes/aauu.yaml Adds a new theme YAML entry to the local dataset
themes/a-j-light.yaml Adds a new theme YAML entry to the local dataset
themes/a-green-cat.yaml Adds a new theme YAML entry to the local dataset
themes/90s-digital-dawning.yaml Adds a new theme YAML entry to the local dataset
themes/9-way-ticket.yaml Adds a new theme YAML entry to the local dataset
themes/8x8-fork.yaml Adds a new theme YAML entry to the local dataset
themes/8x8-darker.yaml Adds a new theme YAML entry to the local dataset
themes/8v.yaml Adds a new theme YAML entry to the local dataset
themes/8-bit-theme.yaml Adds a new theme YAML entry to the local dataset
themes/8-bit-light.yaml Adds a new theme YAML entry to the local dataset
themes/8-bit-light-high-contrast.yaml Adds a new theme YAML entry to the local dataset
themes/8-bit-dark.yaml Adds a new theme YAML entry to the local dataset
themes/7lou-theme.yaml Adds a new theme YAML entry to the local dataset
themes/73nko-light.yaml Adds a new theme YAML entry to the local dataset
themes/73nko-dark.yaml Adds a new theme YAML entry to the local dataset
themes/6szn.yaml Adds a new theme YAML entry to the local dataset
themes/4am-session-yellow.yaml Adds a new theme YAML entry to the local dataset
themes/42nd.yaml Adds a new theme YAML entry to the local dataset
themes/404-muted.yaml Adds a new theme YAML entry to the local dataset
themes/404-flat.yaml Adds a new theme YAML entry to the local dataset
themes/4-colours.yaml Adds a new theme YAML entry to the local dataset
themes/3xay.yaml Adds a new theme YAML entry to the local dataset
themes/2am.yaml Adds a new theme YAML entry to the local dataset
themes/25-blue.yaml Adds a new theme YAML entry to the local dataset
themes/24.yaml Adds a new theme YAML entry to the local dataset
themes/2077.yaml Adds a new theme YAML entry to the local dataset
themes/2-colors.yaml Adds a new theme YAML entry to the local dataset
themes/19th-century.yaml Adds a new theme YAML entry to the local dataset
themes/1989.yaml Adds a new theme YAML entry to the local dataset
themes/1977.yaml Adds a new theme YAML entry to the local dataset
themes/10x-dark-theme.yaml Adds a new theme YAML entry to the local dataset
themes/1.yaml Adds a new theme YAML entry to the local dataset
themes/0x96f-theme.yaml Adds a new theme YAML entry to the local dataset
themes/07-light.yaml Adds a new theme YAML entry to the local dataset
themes/07-dark.yaml Adds a new theme YAML entry to the local dataset
scripts/embed-preview-template.js Adds a build helper to embed HTML preview template into TS
cli/src/theme-generators/windows-terminal.ts Adds Windows Terminal theme generator
cli/src/theme-generators/warp.ts Adds Warp theme generator
cli/src/theme-generators/vscode.ts Adds VSCode theme generator
cli/src/theme-generators/kitty.ts Adds Kitty theme generator
cli/src/theme-generators/index.ts Registers generators and lists supported apps
cli/src/theme-generators/ghostty.ts Adds Ghostty theme generator
cli/src/theme-generators/base.ts Adds shared generator interface and color helpers
cli/src/index.ts Wires the new rampa theme subcommand into the CLI entrypoint

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread cli/src/theme-generators/index.ts Outdated
Comment thread cli/src/theme-generators/windows-terminal.ts Outdated
Comment thread cli/src/theme-generators/ghostty.ts Outdated
Comment thread themes/aether.yaml
Comment thread themes/abraham.yaml
Comment thread scripts/embed-preview-template.js
basiclines and others added 13 commits March 19, 2026 20:45
- Add theme-color-engine.ts: derives full editor palette from ANSI-16
  colors using PlaneColorSpace with LAB interpolation to prevent hue
  drift during plane traversal
- Rewrite all editor generators (vscode, xcode, android-studio, ghostty,
  alacritty, kitty, iterm2, warp, hyper, windows-terminal) to use
  deriveEditorPalette() for consistent, perceptually-accurate colors
- Update theme.ts --install to prefer native format files when available
  (source.formats[app]), falling back to generator with (native)/(generated)
  label
- Add 130-test baseline suite covering 9 diverse themes (dark + light),
  with regression tolerances (±5% OKLCH ΔL) and quality anchors verified
  against the real Aura Theme xcode/alacritty files (±3% ΔL)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
pair-themes.ts:
- Strip surrounding punctuation from words before token matching so
  '(Dark)' / '(Light)' parenthesized patterns are now detected
  (313 themes affected, doubled pairs from 269 → 543)
- Handle hyphen-separated names like 'empire-monokai-dark'
- Add dusk/twilight/eve/evening to DARK tokens
- Add sunrise/noon to LIGHT tokens
- Re-ran script: 548 files updated, 543 total pairs

theme list:
- Add fuzzy search: rampa theme list "Aura" (substring match, sorted by relevance)
- Add --paired flag: show one entry per dark/light pair with ↔ counterpart
- Fix search threshold (> 100) to include mid-string matches, not just prefix
- Fix total count captured after all filters (was showing pre-pair count)
- Update --help with new usage and examples

root help:
- Expand COLOR THEMES section with list/search/paired/install examples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a third pass to pair-themes.ts that detects implicit counterparts:
- "Theme (Dark)" ↔ "Theme" (no mode suffix, meta.mode=light)
- "Theme" (meta.mode=dark) ↔ "Theme Dawn/Morning/Light"

Algorithm: for each unpaired theme with an explicit mode token, look up
the normalised base name in a map of unpaired no-token themes. If found
and meta.mode confirms opposite polarity, create the pair.

Results: 543 → 662 pairs (+119 new pairs), 238 files updated.

Examples newly paired:
- xotopio-dark ↔ xotopio
- Nibelung Dark ↔ Nibelung
- DzSolarized Dark ↔ DzSolarized
- Slack Theme Dark ↔ slack-theme
- Genshin Impact - Furina (Dark) ↔ Genshin Impact - Furina (×17 variants)
- Bombyx ↔ Bombyx Light
- Ocean Mist ↔ Ocean Mist Light

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prevents cross-publisher false positives where unrelated themes from
different authors happen to share the same normalised base name
(e.g. my-theme/yanchenliu ↔ My Light Theme/Akilan).

Result: 662 → 657 pairs (5 false positives removed, 0 legitimate
pairs lost). All remaining Pass 3 pairs are same-publisher.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a fourth pass that pairs themes from the same extension package
using two signals instead of name tokens:

1. Hue fingerprint: average OKLCH hue distance across the 6 accent
   colors (red/green/yellow/blue/magenta/cyan) must be ≤ 30°. Real
   dark/light pairs share near-identical hue palettes (p50=5.9°,
   p90=26°). Unrelated themes diverge sharply (worst: 175°).

2. Name similarity: longest-common-prefix ratio ≥ 0.65 prevents
   cross-variant false positives within large packs (Rainglow 300+).

Greedy matching: each dark pairs with its best-name-match light;
a light can pair with multiple darks (Catppuccin Latte model).

Results: 657 → 1,049 pairs (+392). Examples newly paired:
- Catppuccin Mocha/Macchiato/Frappé ↔ Catppuccin Latte (1.1M installs)
- All 212 Rainglow variants (spearmint ↔ spearmint-light, sim=1.0)
- Zenbones, Vaporizer, MagicUser families

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  rampa theme list --min-installs 1000
  rampa theme list --paired --sort installs --min-installs 5000 --all

Filters out themes below the given install count. Meta is loaded
automatically when the flag is set. Works with all other flags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Filters themes by average APCA contrast of fg + 12 tonal colors:
  fg, red, green, yellow, blue, magenta, cyan,
  brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan

Skips black/white/brightBlack/brightWhite (structurally 0 contrast).
Uses average rather than minimum so themes with one weak color
(typically blue) aren't unfairly penalized.

  rampa theme list --local --paired --sort installs \
    --min-installs 1000 --min-contrast 60 --all

APCA scale: 30=decorative, 45=large text, 60=body text, 75=small text

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Deduplicates visually similar themes, keeping the most-installed
representative from each cluster.

Algorithm:
- Computes OKLCH hue fingerprint across 6 accent colors per theme
- Threshold = minDistinct% of 180° max hue range (e.g. 20 = 36°)
- Greedy pass (installs-desc): keep a theme only if it differs by
  ≥ threshold from all already-kept themes
- Works correctly with --paired (compares the shown dark member's fp)
- The temp installs-desc sort for greedy selection is independent
  of the display sort order

Combinable with all other flags:
  rampa theme list --local --sort installs --paired \
    --min-installs 1000 --min-contrast 50 --min-distinct 20 --all

Results at --min-installs 1000 --min-contrast 50:
  no distinct: 522  distinct-10: 117  distinct-20: 43  distinct-30: 16

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previous approach (hue-only, global dedup) caused GitHub Theme to
block Solarized and Monokai because they share similar warm hues.

Changes:
1. Full OKLCH color signature: L + C/0.4 + H/180 per accent color,
   all normalized to [0-1]. Distance is 0-1 where 0=identical.
   Captures lightness/saturation/hue composition — not just hue.

2. Same-publisher scoping: deduplication runs within each publisher
   group independently. GitHub variants deduplicate each other;
   Solarized/Monokai from different publishers are never compared
   against GitHub. Keeps well-known themes from being blocked.

Result at --min-installs 1000 --min-contrast 30 --min-distinct 10:
  Before: Solarized=false, Monokai=false (blocked by GitHub Theme)
  After:  Solarized=true,  Monokai=true  ✅

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cli/README.md:
- Add full "Color Themes" section with list flags table
  (--paired, --sort, --min-installs, --min-contrast, --min-distinct,
   --all, --local), install/inspect flags, and usage examples
- Document all 10 supported apps

cli/src/index.ts:
- Expand COLOR THEMES section in root help to show curated
  filter example with all new flags

AGENTS.md:
- Add theme-generators/ to CLI file map
- Add Theme Subcommand section covering key files, pairing
  passes (1-4), and list filter flags

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Terminal install

- Derive SUPPORTED_APPS from Object.keys(generators) so iterm/wt
  aliases are included in help text and error messages automatically
- Add optional hint field to ThemeGenerator interface for generators
  that require manual setup
- Windows Terminal: return null from installPath (standalone JSON files
  in LocalState are not loaded by WT; schemes must be in settings.json)
  and add a hint to guide users to paste the snippet manually
- Install flow: show hint when there is no auto-install path, removing
  the misleading 'not supported on X' error for generate-only generators

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@basiclines basiclines self-assigned this Mar 20, 2026
@basiclines
basiclines merged commit 264ad77 into main Mar 20, 2026
1 check passed
@basiclines
basiclines deleted the feat/theme-installer branch March 20, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants