Skip to content

fix(help): honor NO_HYPERLINKS in root-help header (#63) - #71

Merged
kjanat merged 3 commits into
masterfrom
fix/help-header-hyperlinks-env
Jul 20, 2026
Merged

kjanat merged 3 commits into
masterfrom
fix/help-header-hyperlinks-env

Conversation

@kjanat

@kjanat kjanat commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Closes #63.

Problem

The root-help header hyperlink gate defaulted to raw out.isTTY:

hyperlinks: options?.help?.hyperlinks ?? this.schema.helpConfig?.hyperlinks ?? out.isTTY,

So NO_HYPERLINKS=1 <cli> --help still emitted OSC 8 links in the header. ansispeck resolves hyperlink support while honoring NO_HYPERLINKS/FORCE_HYPERLINKS and --no-hyperlinks/--hyperlinks, but the help gate never consulted that path.

Fix

The output channel now resolves a new isHyperlinkSupported property, mirroring how color is resolved:

  • explicit hyperlinks output option wins,
  • then NO_HYPERLINKS/FORCE_HYPERLINKS and the --no-hyperlinks/--hyperlinks argv flags,
  • then falls back to the channel's isTTY.

The env/argv override reads the same signals ansispeck does, but leaves the TTY fallback to the channel so an explicitly-configured isTTY (e.g. .execute({ isTTY: true })) still applies. The header gate consults out.isHyperlinkSupported instead of out.isTTY. out.isHyperlinkSupported is also exposed on the public Out interface for consumers rendering their own out.color.link(...) output.

Tests

  • output.test.ts — resolution matrix: TTY fallback, explicit option override, NO_HYPERLINKS/FORCE_HYPERLINKS, and explicit-option-beats-env.
  • cli-links.test.ts — end-to-end: NO_HYPERLINKS suppresses header links on a TTY; FORCE_HYPERLINKS emits them without one.

Full typecheck, biome, dprint, and the output/cli/schema suites (919 tests) pass.

Bumps to 3.0.0-rc.12.

The header hyperlink gate defaulted to raw `out.isTTY`, so
`NO_HYPERLINKS`/`FORCE_HYPERLINKS` and the `--no-hyperlinks`/`--hyperlinks`
flags were ignored. Resolve OSC 8 support on the output channel as a new
`out.isHyperlinkSupported` property (explicit `hyperlinks` option, then the
env/argv overrides, then `isTTY`) and gate the header on it.

Bump to 3.0.0-rc.12.
@kjanat kjanat added kind: bug Broken behavior or regression area: cli CLI dispatch, planning, root UX, or plugins area: output Output channels, tables, spinners, and JSON mode cr:review Allow CodeRabbit review labels Jul 20, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

bun add https://pkg.pr.new/@kjanat/dreamcli@71
npm i https://pkg.pr.new/@kjanat/dreamcli@71

commit: 8b41c6b

@kjanat kjanat self-assigned this Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: c7e11096-265e-4ca5-a3ef-6018f7cedcee

📥 Commits

Reviewing files that changed from the base of the PR and between 6abe443 and 8b41c6b.

📒 Files selected for processing (3)
  • src/core/cli/cli-links.test.ts
  • src/core/output/index.ts
  • src/core/output/output.test.ts
📝 Walkthrough

Walkthrough

The release updates package versions to 3.0.0-rc.12. Output channels now resolve OSC 8 hyperlink support from explicit options, environment or CLI overrides, and TTY status, exposing the result through OutputChannel and Out. CLI help rendering uses this capability for header links, with tests covering forced and disabled hyperlink environments. Release notes and comparison references are updated, alongside test fixtures for the expanded output contract.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EnvironmentAndArgv
  participant OutputChannel
  participant CLIBuilder
  participant RootHelp
  EnvironmentAndArgv->>OutputChannel: resolve OSC 8 support
  OutputChannel->>CLIBuilder: provide isHyperlinkSupported
  CLIBuilder->>RootHelp: configure help hyperlinks
  RootHelp-->>CLIBuilder: render or suppress header links
Loading

Possibly related issues

  • KAJ-309 — Directly addresses help hyperlink gating through out.isHyperlinkSupported and override coverage.
  • Issue 63 — Directly addresses TTY-based help hyperlink gating and hyperlink overrides.

Possibly related PRs

  • kjanat/dreamcli#24 — Adds related root-help hyperlink rendering and link derivation.
  • kjanat/dreamcli#43 — Modifies related help hyperlink configuration and fallback resolution.

Poem

OSC eight links now know when to shine,
TTY or flags draw the line.
Help headers behave just right,
Forced on, or hidden from sight.
A tidy release sails tonight.

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Semver Version Bump Validation ⚠️ Warning Code changed in src/core/cli/index.ts and src/core/output/index.ts, but HEAD^ and HEAD both still show 3.0.0-rc.12 in package.json/deno.json, so the PR has no version bump. Add a version bump in one allowed file (package.json, deno.json, or VERSION) within the PR, matching the code change before merging.
Agents.Md Documentation Updated ⚠️ Warning src/core/cli/AGENTS.md and src/core/output/AGENTS.md exist, but the PR changed those areas without updating either AGENTS file. Update the affected AGENTS.md files alongside the CLI/output changes, or explain why the guidance no longer needs a change.
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, uses fix:, and clearly matches the NO_HYPERLINKS root-help hyperlink bug.
Description check ✅ Passed The description directly describes the hyperlink gating fix, behaviour, and tests for issue #63.
Linked Issues check ✅ Passed The PR implements the root-help hyperlink gate fix and honours NO_HYPERLINKS, --no-hyperlinks, FORCE_HYPERLINKS, and --hyperlinks.
Out of Scope Changes check ✅ Passed The changes stay focused on hyperlink gating, related tests, and the version/changelog bump.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 30.00%.
Release Metadata Sync ✅ Passed package.json and deno.json both say 3.0.0-rc.12; CHANGELOG.md has a matching 3.0.0-rc.12 heading and aligned compare links.
Runtime Support Sync ✅ Passed PASS: the diff only changes hyperlink/output code and tests; package.json, src/runtime/support.ts, and all runtime support docs are unchanged.
No Generated Docs Artifacts ✅ Passed No files under docs/.vitepress/dist/ or docs/.vitepress/cache/ were changed in the PR diff.
Changelog Update ✅ Passed PASS: CHANGELOG.md adds a dated 3.0.0-rc.12 section, and the version bumps in package.json/deno.json are matched by the new entry.
📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #63


Comment @coderabbitai help to get the list of available commands.

… access

CodeRabbit flagged direct `globalThis.process` reads in the output layer,
which violates the "no process.* in src/core" rule and can throw under Deno's
permission model. Move the NO_HYPERLINKS/FORCE_HYPERLINKS (and argv-flag)
decision into a pure `resolveHyperlinkOverride(env, argv)` helper; the CLI
layer feeds it the adapter's env/argv and passes the result to the output
channel as the `hyperlinks` option. The channel now only resolves
`hyperlinks ?? isTTY`, staying process-free.
@kjanat

kjanat commented Jul 20, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Addressed the process-access finding: the NO_HYPERLINKS/FORCE_HYPERLINKS (and --no-hyperlinks/--hyperlinks) decision now lives in a pure resolveHyperlinkOverride(env, argv) helper fed by the adapter, so src/core/output/ no longer touches process. Prior review timed out before posting its inline comments.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

@kjanat Aye—excellent cleanup on the process boundary. I’ll re-review the entire PR, including the resolver wiring, precedence behaviour, and test coverage.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot added the area: resolve Argv, env, config, prompt, and default resolution label Jul 20, 2026
coderabbitai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot removed the area: resolve Argv, env, config, prompt, and default resolution label Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

@kjanat Arrr, excellent—keeping process out of the core output layer is the right boundary. I’ve queued a full re-review of #71, with particular attention to override precedence, adapter wiring, and the resolution-matrix/end-to-end coverage.

✅ Action performed

Full review finished.


You're currently rate limited under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. Your next review will be available in 23 minutes.

Per CodeRabbit review: `resolveHyperlinkOverride` matched `--no-hyperlinks`/
`--hyperlinks` anywhere in argv, so a positional after `--` (e.g.
`mycli deploy -- --no-hyperlinks`) wrongly toggled the header gate. Only
consider tokens before the separator. Add helper coverage for the post-`--`
case and an e2e test for the `--hyperlinks` force-on-without-TTY path.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
dreamcli 8b41c6b Commit Preview URL

Branch Preview URL
Jul 20 2026, 01:49 AM

@kjanat
kjanat merged commit 53ed821 into master Jul 20, 2026
25 of 26 checks passed
@kjanat
kjanat deleted the fix/help-header-hyperlinks-env branch July 20, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli CLI dispatch, planning, root UX, or plugins area: output Output channels, tables, spinners, and JSON mode cr:review Allow CodeRabbit review kind: bug Broken behavior or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Help header hyperlinks ignore NO_HYPERLINKS (gated on out.isTTY)

1 participant