Skip to content
~/terminal-noir

Engine & pipeline

How it works

One palette, compiled into each app's native theme format, with tests that catch any drift.

  1. 01 / Source

    One palette.json

    Every color, for noir and paper, lives by role in palette/palette.json.

  2. 02 / Generation

    Generated ports

    make build runs one small bash and jq script per app, writing its native theme files.

  3. 03 / Validation

    Tested against drift

    bats suites check the palette, each port's color mapping, and that committed ports match a fresh build.

make build testbash · jq · bats
$ make build
✓ ports/noctalia✓ ports/niri✓ ports/gtk✓ ports/ghostty✓ ports/p10k✓ ports/vscode✓ ports/obsidian✓ ports/bat✓ ports/btop✓ ports/fzf✓ ports/chrome✓ ports/shiki$ make test✓ 53 tests: palette, port mappings, build freshness

Quickstart

Installation

Ports ship ready-made files, so nothing needs building. Every port page has the full steps.

From ports/ghostty, in the repo root:
mkdir -p ~/.config/ghostty/themes
cp terminal-noir-dark terminal-noir-light ~/.config/ghostty/themes/

Open source

Contributing

Ground rules

  • Colors live only in palette/palette.json. A port never hardcodes a hex value; it reads palette roles.
  • Syntax colors live in palette/syntax.json as palette paths (accent.primary, ansi.bright.cyan).
  • Generated files under ports/ are committed, so people can install a port without running anything. make test fails when they drift from the palette.

Changing a color

  1. Edit palette/palette.json.
  2. Run make build and make test.
  3. Commit the palette change together with the regenerated ports.

Adding a port

  1. Create scripts/ports/<app>.sh defining build_<app>, which writes its files under "$OUT/ports/<app>/". Read colors from "$PALETTE" (and "$SYNTAX" for highlighting) with jq; see scripts/ports/btop.sh for a small example.
  2. Add <app> to the PORTS list in scripts/build.
  3. Add the generated files to GENERATED in tests/build.bats, and a mapping test in tests/ports.bats that checks the app's key slots against pal <variant> <role>.
  4. Write ports/<app>/README.md with install steps: a # Terminal Noir for <App> title, a one-paragraph description (the site shows it on the port card), then the steps. Add README.pt-br.md too, titled # Terminal Noir para <App>, with the same code blocks.
  5. Register the port in ports.json (name, category, variants, homepage) and list it in the main README.
  6. Run make build test lint.

Prefer the app's native theme format, and ship a light variant when the app supports switching.