Implementation guide
Adoption
The fastest path to adoption is consistent emitter behavior, clear local overrides, and documentation that users can actually reason about.
For CLI tools
- Check local flags or config before reading environment variables.
-
Honor
NO_HYPERLINKSas a non-empty disable switch. -
Honor
FORCE_HYPERLINKSas a non-empty force-enable switch. - Fall back to normal support detection when neither variable applies.
- When disabled, print a useful visible URL instead of a link-only label.
For shared libraries
- Offer one small decision function so downstream tools inherit consistent behavior.
- Keep the decision surface narrow: local mode, env vars, auto-detection result.
- Document exact precedence so application authors do not invent their own variants.
Suggested interface
Recommended tool-facing behavior uses auto, always, and
never. This model maps cleanly onto the convention:
| Local mode | Behavior |
|---|---|
never |
Disable hyperlinks regardless of environment or detection. |
always |
Enable hyperlinks regardless of environment or detection. |
auto |
Apply environment precedence, then capability detection. |
Pseudocode
if local_mode == "never":
return disabled
if local_mode == "always":
return enabled
if env.NO_HYPERLINKS is non-empty:
return disabled
if env.FORCE_HYPERLINKS is non-empty:
return enabled
return detect_hyperlink_support()
For terminal emulators, multiplexers, and pagers
- Preserve OSC 8 pass-through behavior when your styled-output mode allows it.
- Strip safely when hyperlinks are unsupported or disabled.
- Document how hyperlink handling interacts with passthrough, alternate screens, and paged output.
- Do not reinterpret the environment variables as terminal-side policy unless you explicitly advertise that behavior.
Compatibility notes
This convention does not replace existing hyperlink flags. It gives them a shared global context. Projects with legacy booleans or config keys can map them into the same decision order without renaming public APIs immediately.