{
  "authors": [
    "Heziode"
  ],
  "depends-on": [
    {
      "case(os)": {
        "windows": {
          "win32ada": "^26.0.0"
        }
      },
      "sparklib": "^15.1.0"
    }
  ],
  "description": "Cross-platform terminal capability detection (color, TTY, ...)",
  "environment": {
    "case(os)": {
      "...": {
        "GPR_PROJECT_PATH": {
          "prepend": "${CRATE_ROOT}/gpr"
        }
      },
      "windows": {}
    }
  },
  "licenses": "Apache-2.0 WITH LLVM-exception",
  "long-description": "Terminal capability detection for Ada/SPARK. Cross-platform, dependency-light, no rendering layer attached.\n\nTermicap exists to answer the handful of questions almost every CLI or TUI program has to ask before printing a single byte: is the stream a TTY, how many colors can the terminal handle, how wide is the window, can the locale render Unicode, *which* terminal is this (iTerm, kitty, WezTerm, Windows Terminal, ConPTY, tmux, screen, ...), does it speak OSC 8 hyperlinks or Sixel graphics or the Kitty keyboard protocol, and the question that overrides all the others, did the user already pass `NO_COLOR` or `FORCE_COLOR` or `--color=never`. The answers come back as plain Ada records and enums. Termicap does not emit escape sequences, render styled text, or pretend to be a TUI framework. It is meant to sit underneath whatever rendering layer you already have.\n\n## What it detects\n\nThe base API gives you per-stream TTY booleans (stdin, stdout, stderr), the four canonical color levels (`None`, `Basic_16`, `Extended_256`, `True_Color`) via an 11-step cascade modelled on `supports-color`, `termenv`, and `rich`, terminal dimensions (`ioctl(TIOCGWINSZ)` on POSIX, `GetConsoleScreenBufferInfo` on Windows) with `SIGWINCH` resize notification via a self-pipe and protected object on POSIX, a Unicode support level (`None / Basic / Extended`) from locale, CI and terminal heuristics, terminal identity (multiplexers included) with a program name, the DA1 primary device attributes (VT level, capability flags), DECRPM mode reports through a batched single-sentinel probe, OSC 10/11 background and foreground color with a `COLORFGBG` fallback and a SPARK Gold dark/light classifier, and a passive OSC 8 hyperlink classification. Color responses are normalised to RGB; theme detection runs on luminance.\n\nThe full API adds the active probes: XTVERSION terminal name and version, Kitty / XTerm-CSI / Legacy / Win32 keyboard protocol, `SGR_Pixels / SGR / URXVT / X10` mouse encoding (DECRPM-driven), Sixel and Kitty graphics flags (seeded by DA1 `Ps=4` and XTVERSION name tokens), and OSC 52 clipboard support (`Read / Write / Read_Write / None`). Hyperlinks classification is refined when XTVERSION confirms the terminal.\n\nA couple of standalone helpers come in the box: `wcwidth` / cell width with Unicode 3 / 13 / 16 tables and binary search (SPARK Gold, no FFI in the table layer); a Terminfo parser for header plus boolean / numeric / string entries (bounded, pure); and a process-wide `Override_Mode` (`Auto / Force_None / Force_Basic / Force_256 / Force_True_Color`) with a `Scoped_Override` controlled type for wiring `--color=auto | never | always | 256 | truecolor` straight into the detection engine.\n\n## Color downsampling\n\nDetection only tells you what the terminal can show. Picking a color the terminal can actually display is a separate problem, and that's what the companion `Termicap.Downsampling` package handles: it maps any color you want to emit down to the level the terminal supports (TrueColor -> 256-color -> ANSI 16, or strip to none). One overloaded `Downsample` dispatches on `RGB` or `Color_Index_256`; the primitive conversions (`Downsample_True_To_256`, `Downsample_True_To_16`, `Downsample_256_To_16`) are also exposed for the cases where the dispatch wrapper is overkill. The whole package is pure SPARK Gold with idempotency and monotonicity postconditions, no FFI, no allocation.\n\n## Architecture notes\n\nThe detection logic is *written* against SPARK Silver (Gold for downsampling and cell width); FFI and tasking boundaries are isolated behind clearly marked `SPARK_Mode => Off` packages and C wrappers. The codebase has not yet been verified end-to-end with `gnatprove`. Running the prover and discharging the remaining VCs is on the to-do list, not a finished claim.\n\nThere are two API tiers. `Get` and `Detect` give you a fast snapshot (sub-50 ms in the worst case). `Get_Full` and `Detect_Full` add the active probes; worst case is around 6 s if every probe times out, but a local PTY usually answers in well under 50 ms. `Get` is cached per stream and thread-safe; `Detect` always re-runs every sub-detector, which is the version you want after `SIGWINCH`, after the override changes, or anywhere a long-running process can't trust a stale snapshot.\n\nLinux, macOS, BSD, and Windows are all supported. Platform-specific bodies are dispatched via GPR `Source_Dirs`. The Windows layer classifies the console (`Legacy_Conhost`, `ConPTY_VT_Enabled`, `Not_A_Console`) and gates active probes accordingly; Cygwin / MSYS2 PTY handles are detected by inspecting the underlying named-pipe name through `NtQueryObject`.\n\nNo exceptions are raised by library code. Errors come back as `Result` variants or safe defaults. Dependencies stay minimal: `sparklib` for the SPARK formal containers, plus `win32ada` on Windows only.\n\n## Quick start\n\n```ada\nwith Ada.Text_IO;\nwith Termicap.Capabilities;\nwith Termicap.Color;\n\nprocedure Hello is\n   Caps : constant Termicap.Capabilities.Terminal_Capabilities :=\n     Termicap.Capabilities.Get;\nbegin\n   if Caps.TTY_Stdout\n     and then Caps.Color >= Termicap.Color.Extended_256\n   then\n      Ada.Text_IO.Put_Line\n        (ASCII.ESC & \"[38;5;208mHello, 256-color world\"\n         & ASCII.ESC & \"[0m\");\n   else\n      Ada.Text_IO.Put_Line (\"Hello, monochrome world\");\n   end if;\nend Hello;\n```\n\nThe repository ships with a couple of dozen runnable demos in `examples/`, arc42-lite architecture docs in `docs/architecture/`, a Diátaxis-style user guide in `docs/guide/`, MADR-format ADRs in `docs/adr/`, StrictDoc-format requirements in `docs/requirements/`, and a cross-language conformance harness in `tools/conformance/` that cross-checks Termicap against reference shims in C, Go, Rust, Python, Node.js, Java, Haskell, Ruby, C#, and Swift.\n\nLicensed Apache-2.0 WITH LLVM-exception, which keeps it safe for static linking into closed-source binaries without forcing license propagation.\n",
  "maintainers": [
    "Quentin DAUPRAT (Heziode) <contact@adarium.dev>"
  ],
  "maintainers-logins": [
    "heziode"
  ],
  "name": "termicap",
  "origin": {
    "commit": "bb43f2cf563ac29f45c91124eee859b76776764f",
    "url": "git+https://github.com/adarium-labs/termicap.git"
  },
  "tags": [
    "terminal",
    "capability",
    "detection",
    "color",
    "tty",
    "is-tty",
    "spark",
    "cross-platform",
    "windows",
    "linux",
    "macos",
    "bsd"
  ],
  "version": "1.0.0",
  "website": "https://github.com/adarium-labs/termicap"
}
