color.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. /**
  2. * Terminal color detection for CLI output (issue #1281).
  3. *
  4. * One switch decides whether any codegraph-authored output carries ANSI
  5. * color codes. Precedence, strongest first:
  6. *
  7. * 1. `--no-color` anywhere on the command line -> off
  8. * 2. `--color` anywhere on the command line -> on
  9. * 3. `NO_COLOR` set and non-empty (no-color.org) -> off
  10. * 4. `FORCE_COLOR` set and non-empty -> on ('0'/'false' -> off)
  11. * 5. stdout is a TTY and TERM != 'dumb' -> on
  12. * 6. `CI` set and non-empty -> on (CI log viewers render ANSI)
  13. * 7. otherwise (piped/redirected stdout) -> off
  14. *
  15. * This intentionally tracks the detection @clack/prompts inherits from
  16. * picocolors closely enough that one run never mixes colored clack frames
  17. * with uncolored codegraph lines (or vice versa) for the common cases:
  18. * both honor NO_COLOR, --no-color/--color, FORCE_COLOR, TTY, and CI.
  19. */
  20. export function ansiColorsEnabled(): boolean {
  21. if (process.argv.includes('--no-color')) return false;
  22. if (process.argv.includes('--color')) return true;
  23. const noColor = process.env.NO_COLOR;
  24. if (noColor !== undefined && noColor !== '') return false;
  25. const forceColor = process.env.FORCE_COLOR;
  26. if (forceColor !== undefined && forceColor !== '') {
  27. return forceColor !== '0' && forceColor.toLowerCase() !== 'false';
  28. }
  29. if (process.stdout.isTTY === true && process.env.TERM !== 'dumb') return true;
  30. const ci = process.env.CI;
  31. if (ci !== undefined && ci !== '') return true;
  32. return false;
  33. }