Skip to main content

Adaptive contrast/readability toolkit for translucent terminals, starting with iTerm2.

Project description

Term Chameleon

Term Chameleon is an adaptive contrast/readability toolkit for translucent terminals, starting with iTerm2 on macOS.

Glassy terminal themes look good until white text disappears over a bright window, black/dim text vanishes over dark blur, or iTerm2 Light/Dark profile variants silently override the intended palette. Term Chameleon provides static profile diagnostics/fixes plus live background-aware sampling, staging, and adaptation for iTerm2.

Current status

This repository is prepared as v0.1.0 / Python package version 0.1.0: a dogfooded beta for static profile diagnostics, safe profile mutation, deterministic visual artifacts, live iTerm2 adaptation, controlled macOS GUI/screenshot QA, and real iTerm2 AutoLaunch watcher operation. Implemented:

  • iTerm2 Dynamic Profile JSON parsing.
  • Color conversion between hex and iTerm2 color dictionaries.
  • WCAG contrast calculations.
  • Static diagnostics for common glass-terminal readability failures.
  • Conservative static fixer with dry-run, backups, deterministic JSON, and explainable changes.
  • iTerm2 Dynamic Profile preset install flow, including optional AutoLaunch default-profile script.
  • Manual readability mode switching for profile JSON files.
  • OSC color sequence generation, including tmux passthrough wrapping.
  • Dynamic watcher foundation via watch-sim risk classifier and hysteresis mode selector.
  • iTerm2 live-adapter script generation/probe foundation for session-local Python API validation.
  • Screen/image sampling one-shot adaptation via sample and adapt-once.
  • Live adaptive watcher via watch-live, with dry-run, stable-sample, cooldown, duration, and real iTerm2 session-local apply modes.
  • Deterministic E2E staging bundle that combines controlled backgrounds, ANSI pattern artifacts, visual simulation, screenshot capture, and screenshot pixel analysis.
  • Screenshot contrast estimation for captured PNG/PPM artifacts.
  • Text-row/glyph-aware screenshot contrast estimation for rendered terminal pattern captures.
  • Live GUI staging that arranges controlled Safari background + iTerm2 ANSI pattern windows and can optionally capture/analyze the result with text-row contrast and pixel-cluster fallback.
  • macOS screencapture probe and screenshot-test artifact foundation for screenshot-based visual tests.
  • Long-running daemon packaging for continuous adaptation.
  • Permission-free deterministic self-check command for post-install validation.
  • Local readiness status command with human and JSON output.
  • Guided setup command that runs deterministic checks and optionally installs the default profile.
  • TOML config example, validation, and --config support for setup/watch-live/watch daemon flows.
  • Watch daemon status and uninstall commands for AutoLaunch lifecycle management.
  • Top-level release-readiness gate that composes deterministic checks, config validation, readiness, daemon, and live-stage checks.
  • Fixture tests for good and bad iTerm2 profiles.

Optional future refinements:

  • Replace heuristic text-row detection with OCR/terminal-cell-aware glyph segmentation.
  • Add broader terminal emulator support beyond iTerm2.

Beta release verification

Build and install the beta wheel locally:

uv build
python3 -m venv /tmp/term-chameleon-beta-venv
/tmp/term-chameleon-beta-venv/bin/pip install 'dist/term_chameleon-0.1.0-py3-none-any.whl[iterm]'
/tmp/term-chameleon-beta-venv/bin/term-chameleon setup --yes
/tmp/term-chameleon-beta-venv/bin/term-chameleon release-check --output-dir /tmp/term-chameleon-beta-release-check
/tmp/term-chameleon-beta-venv/bin/term-chameleon release-check --output-dir /tmp/term-chameleon-beta-live-check --live --live-stage --threshold 1.0

The real iTerm2 AutoLaunch watcher was dogfooded for this beta by installing the daemon, restarting iTerm2, verifying a single running watcher process, checking daemon status, and confirming screenshot sample artifacts were written.

See CHANGELOG.md for release notes.

Use it

python3 -m venv ~/.local/share/term-chameleon/venv
~/.local/share/term-chameleon/venv/bin/pip install 'term-chameleon[iterm]'
~/.local/share/term-chameleon/venv/bin/term-chameleon setup --yes
~/.local/share/term-chameleon/venv/bin/term-chameleon release-check --live --live-stage --threshold 1.0
~/.local/share/term-chameleon/venv/bin/term-chameleon install-watch-daemon
~/.local/share/term-chameleon/venv/bin/term-chameleon watch-daemon-status

Restart iTerm2 after installing the daemon. The AutoLaunch script starts one long-running watch-live process and records its pid/log paths; use watch-daemon-status to inspect it and uninstall-watch-daemon to remove the AutoLaunch script. The daemon samples the whole screen by default for startup robustness; pass install-watch-daemon --iterm-window if you prefer front-iTerm-window sampling after confirming Accessibility/iTerm2 API startup behavior on your machine.

CLI examples

Run a permission-free deterministic self-check after installation or inspect local readiness:

term-chameleon check --output-dir artifacts/check
term-chameleon release-check --output-dir artifacts/release-check
term-chameleon setup
term-chameleon setup --yes
term-chameleon setup --live
term-chameleon config-example --output ~/.config/term-chameleon/config.toml
term-chameleon config-check --config ~/.config/term-chameleon/config.toml
term-chameleon watch-live --config ~/.config/term-chameleon/config.toml --dry-run
term-chameleon status
term-chameleon status --live
term-chameleon status --json

setup is a guided flow: it runs deterministic checks and reports status. On first run, bare setup exits nonzero until a healthy profile exists; use setup --yes to install the generated profile, and setup --live to include live iTerm2 API/window readiness.

release-check is the top-level local gate. By default it is permission-free and writes JSON/Markdown reports; add --config, --live, --daemon, or --live-stage to include config validation, live iTerm2 probes, AutoLaunch health, or controlled Safari+iTerm2 screenshot QA.

config-example prints a commented TOML file. config-check validates value types, preset names, region shape, and unknown sections/keys. watch-live, install-watch-daemon, and setup accept --config; explicit CLI flags override config values.

Install a balanced preset into a target directory:

term-chameleon install --target-dir /tmp/iterm-dynamic-profiles --name "Adaptive Glass"

Install an iTerm2 AutoLaunch script that starts the live watcher whenever iTerm2 launches:

term-chameleon install-watch-daemon --dry-run
term-chameleon watch-daemon-status
term-chameleon install-watch-daemon
term-chameleon watch-daemon-status --json
term-chameleon uninstall-watch-daemon --dry-run
term-chameleon uninstall-watch-daemon

uninstall-watch-daemon removes the iTerm2 AutoLaunch script only; it does not stop an already-running watcher process or remove logs/pid files. It creates a backup by default unless --no-backup is passed.

Apply a manual readability mode to a profile JSON file:

term-chameleon mode bright-safe ~/Library/Application\ Support/iTerm2/DynamicProfiles/adaptive-glass.json --dry-run

Check iTerm2 Python API readiness and generate a conservative session-local adapter script:

term-chameleon iterm-api-check
term-chameleon iterm-connect-probe
term-chameleon iterm-window-bounds
term-chameleon iterm-live-script --preset balanced --output /tmp/term-chameleon-live.py

Probe macOS screenshot availability and generate controlled screenshot-test artifacts:

term-chameleon screenshot-probe
term-chameleon screenshot-probe --capture --output artifacts/screenshot-probe/screen.png
term-chameleon screenshot-contrast artifacts/screenshot-probe/screen.png --output-dir artifacts/screenshot-contrast
term-chameleon screenshot-text-contrast artifacts/screenshot-probe/screen.png --output-dir artifacts/screenshot-text-contrast
term-chameleon screenshot-test --output-dir artifacts/screenshot-test
term-chameleon screenshot-test --capture --output-dir artifacts/screenshot-test
term-chameleon background-html --output-dir artifacts/background-html
term-chameleon pattern-script --output-dir artifacts/pattern-script
term-chameleon e2e-stage tests/fixtures/iterm/good-dark-glass.json --output-dir artifacts/e2e-stage
term-chameleon live-stage --dry-run --output-dir artifacts/live-stage
term-chameleon live-stage --yes --capture --output-dir artifacts/live-stage

live-stage --yes is intentionally explicit because it activates Safari, opens the controlled background page, creates/resizes an iTerm2 window, writes the ANSI pattern command into that session, and may require macOS Automation/Accessibility/Screen Recording permissions. It leaves the staged windows open for inspection.

term-chameleon sample --screen --output artifacts/adapt/screen.png
term-chameleon sample --screen --iterm-window --output artifacts/adapt/iterm-window.png
term-chameleon sample --screen --region 0,0,800,600 --output artifacts/adapt/region.png
term-chameleon adapt-once tests/fixtures/iterm/good-dark-glass.json --screen --dry-run
term-chameleon watch-live --dry-run --duration 10 --interval 1 --stable 2
term-chameleon watch-live --dry-run --iterm-window --duration 10 --interval 1 --stable 2
term-chameleon watch-live --yes --iterm-window --duration 30 --interval 2 --stable 3 --cooldown 10

Manual live smoke test, once iTerm2 is running and the Python API is enabled:

scripts/live-iterm-smoke.sh

Run deterministic visual simulation:

term-chameleon visual-test tests/fixtures/iterm/good-dark-glass.json

Doctor a profile:

term-chameleon doctor tests/fixtures/iterm/bad-light-variant.json
term-chameleon doctor tests/fixtures/iterm/bad-light-variant.json --json

doctor --json emits machine-readable diagnostics after a profile loads successfully; profile load/parse errors still use the standard nonzero exit code with an error on stderr.

Preview fixes:

term-chameleon fix tests/fixtures/iterm/bad-light-variant.json --dry-run

Apply fixes to a copy:

cp tests/fixtures/iterm/bad-light-variant.json /tmp/profile.json
term-chameleon fix /tmp/profile.json --yes
term-chameleon doctor /tmp/profile.json

Troubleshooting

iTerm2 Python API not connected:

Ensure iTerm2 is running and Python API support is enabled: iTerm2 → Settings → General → Magic → check "Enable Python API". Run term-chameleon iterm-api-check to verify.

Screen Recording permission denied:

macOS requires Screen Recording permission for screencapture. Grant it in System Settings → Privacy & Security → Screen Recording for the terminal running Term Chameleon.

AutoLaunch daemon not starting:

Verify the script exists and is executable:

term-chameleon watch-daemon-status

If the PID file is stale (process not running), remove it and restart iTerm2:

rm ~/Library/Application\ Support/term-chameleon/watch-live.pid

Stale watcher process after uninstall:

uninstall-watch-daemon removes the AutoLaunch script but does not kill a running watcher. Stop it manually:

kill "$(cat ~/Library/Application\ Support/term-chameleon/watch-live.pid)"

Daemon CPU or disk usage:

The daemon defaults to a 10-second sampling interval and prunes artifacts to the 200 most recent. To reduce overhead further, increase the interval via config or --interval.

iTerm2 window bounds unavailable on startup:

The daemon defaults to whole-screen sampling for startup robustness. If using --iterm-window, the watcher waits up to 60 seconds for iTerm2 to create a window before failing.

Development

uv sync --extra dev
uv run pytest
uv run ruff check .

If you do not use uv:

python3 -m pytest
python3 -m term_chameleon.cli doctor tests/fixtures/iterm/bad-light-variant.json

Safety principles

  • Static analysis before mutation.
  • --dry-run support for fixes.
  • Timestamped backups before writing.
  • Deterministic JSON output.
  • Explainable diagnostics and fixes.
  • No direct mutation of ~/Library/Preferences/com.googlecode.iterm2.plist as the primary mechanism.

Positioning

Term Chameleon is not just another terminal theme and does not claim to invent automatic contrast. Prior art includes iTerm2 Minimum Contrast, Apple Terminal contrast tweaking, Ghostty minimum contrast, terminal opacity/blur settings, CSS blend-mode/backdrop approaches, and WCAG/APCA contrast engines.

The intended differentiated direction is a live contrast controller for translucent terminal windows: sample or infer the actual visual environment behind the terminal, then adapt palette, opacity, blur, and contrast to keep text readable without giving up the glass effect.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

term_chameleon-0.1.0.tar.gz (103.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

term_chameleon-0.1.0-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

File details

Details for the file term_chameleon-0.1.0.tar.gz.

File metadata

  • Download URL: term_chameleon-0.1.0.tar.gz
  • Upload date:
  • Size: 103.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for term_chameleon-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bd4e8f9a9790f14d17060dab99a278433edb899d88f55bf577fb4ed88ab5cc06
MD5 050900a5af22792d9839c1382c7145b6
BLAKE2b-256 aecfcb899e1c9010c40fab40c5ad405645a7db3cc1a795e63464001ff2fa16e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for term_chameleon-0.1.0.tar.gz:

Publisher: publish.yml on connectwithprakash/term-chameleon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file term_chameleon-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: term_chameleon-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 72.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for term_chameleon-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ed947d3aa61f45aa9c58d5a2fdc136b6337564d914185b87c969e339343b449f
MD5 3b3577e16860e949a47d8a26de8aa99b
BLAKE2b-256 476b91dc52cace0a0513593ce95d0c6862ff899c5cc11973c11243566c6f5cc1

See more details on using hashes here.

Provenance

The following attestation bundles were made for term_chameleon-0.1.0-py3-none-any.whl:

Publisher: publish.yml on connectwithprakash/term-chameleon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page