fix(cli): parse FORCE_HYPERLINK strictly - #5489
Conversation
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Hey @tt-a1i, thanks for the fix — the FORCE_HYPERLINK parsing bug is a real issue and the approach looks reasonable at first glance.
However, the PR body doesn't follow our pull request template. We need the standard sections to review efficiently:
- What this PR does / Why it's needed — motivation and change in prose
- Reviewer Test Plan — How to verify, Evidence (Before & After), Tested on (OS table), Environment
- Risk & Scope — tradeoffs, out-of-scope items, breaking changes
- Linked Issues —
Fixes #5487should go here (auto-close keyword) - 中文说明 — bilingual summary
Could you reformat the body to match the template? The actual code change is small and focused — shouldn't take long to fill in. Happy to re-run triage once that's done.
中文说明
@tt-a1i 你好,感谢修复 FORCE_HYPERLINK 的解析 bug,方向没问题。
但 PR 正文没有按照我们的 PR 模板 填写。我们需要标准章节来高效审查:
- What this PR does / Why it's needed — 用文字描述改动和动机
- Reviewer Test Plan — 验证步骤、前后对比证据、测试过的系统、环境
- Risk & Scope — 取舍、不涉及的范围、破坏性变更
- Linked Issues —
Fixes #5487放在这里(自动关闭关键词) - 中文说明 — 双语摘要
请按模板重新整理一下正文,代码本身改动很小,应该很快就能搞定。更新后我会重新跑 triage。
— Qwen Code · qwen3.7-max
✅ Local verification — safe to mergeI verified this PR locally before merging. Tested PR head Results — all green
The fix is load-bearing (before / after)Running the new regression test against the pre-fix That is the bug: the old Behavior is correct beyond the PR's own cases (extended check)The PR's tests are real and non-mocked (they drive
Replaying that suite on the pre-fix code, exactly 6 regress — Two design notes (non-blocking — both already handled correctly)
VerdictCorrect, minimal, well-scoped, and fully covered by tests + docs. The bug is real and the fix closes it cleanly. LGTM 👍 🇨🇳 中文版(点击展开)✅ 本地验证结论 —— 可以合并合并前我在本地做了验证。在一个独立的 git worktree 中、基于 PR 头 验证结果 —— 全部通过
该修复确实是“关键且必要的”(前后对比)把新增的回归测试跑在修复前的 这正是该 bug:旧的 行为在 PR 自身用例之外也正确(扩展验证)PR 的测试是真实、非 mock 的(直接设置
把这套用例回放到修复前的代码上,恰好有 6 个回归—— 两点设计说明(不阻塞合并,且都已正确处理)
结论正确、精简、范围清晰,且有测试与文档完整覆盖。bug 真实存在,此修复将其干净闭合。LGTM 👍 |
| if (force !== undefined) { | ||
| if (force.length === 0) return true; | ||
| return parseInt(force, 10) !== 0; | ||
| return shouldForceHyperlinks(force); |
There was a problem hiding this comment.
[Suggestion] The comment 4 lines above (lines 179–181) claims this code "Mirrors the FORCE_HYPERLINK contract from supports-hyperlinks" but the new shouldForceHyperlinks function intentionally diverges by rejecting non-numeric values like false, off, 1abc — which is the whole point of this PR. A future maintainer who trusts that comment might "restore" the old parseInt behavior and silently re-introduce the bug.
| return shouldForceHyperlinks(force); | |
| // Explicit force overrides every heuristic below — but not the opt-outs | |
| // above nor the non-TTY guard. Empty string enables. Any string that is | |
| // entirely an optionally-signed integer with value ≠ 0 enables. | |
| // Non-numeric strings (e.g. 'false', 'off') disable. |
— DeepSeek/deepseek-v4-pro via Qwen Code /review
|
updated the PR description to match the template. thanks. |
|
@qwen-code /triage |
|
Thanks for the PR, @tt-a1i! Template looks good ✓ — all required headings present, bilingual description, linked issue, test plan. On direction: this is a textbook bug fix — On approach: the scope is tight — one extracted helper ( Moving on to code review. 🔍 中文说明感谢 PR,@tt-a1i! 模板完整 ✓ — 所有必需章节齐全,双语描述,关联了 issue,测试计划完整。 方向:这是一个典型的 bug 修复 — 方案:范围紧凑 — 提取了一个辅助函数( 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewThe implementation is clean and correct. One minor note: the existing code comment at line ~178 still reads "Mirrors the TestsUnit tests: 81 passed (including the 2 new cases) ✓ Before/after behavior test — drove Before (installed build — old
|
|
This is a clean, minimal bug fix that does exactly what it says. The bug is real ( The implementation matches what I'd have written independently — extract the parsing into a named function, validate the input shape with a regex before doing numeric comparison, fail closed for anything that doesn't match. No over-engineering, no speculative features, no "let's also fix X while we're here." The only thing worth a second thought is the slightly stale code comment about "any non-zero numeric value" — after this PR, it's "any non-zero integer." But that's a polish item, not a reason to hold up the merge. LGTM. Approving. ✅ 中文说明这是一个干净、精简的 bug 修复,完全如描述所述。bug 是真实的( 实现方式与我会独立编写的方案一致 — 将解析逻辑提取为命名函数,在数值比较前用正则验证输入格式,对不匹配的输入 fail closed。没有过度工程,没有投机性功能,没有"顺便把 X 也修了"。 唯一值得再看一眼的是代码注释中"any non-zero numeric value"的措辞略显过时 — PR 之后应该是"any non-zero integer"。但这是打磨项,不是阻塞合并的理由。 LGTM。批准。✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
What this PR does
This PR parses
FORCE_HYPERLINKstrictly before force-enabling OSC 8 links. Only an empty string or a complete non-zero integer enables links; values such asfalse,off, and1abcnow fail closed instead of enabling links throughNaN !== 0.Why it's needed
Users commonly set boolean-looking environment values like
FORCE_HYPERLINK=false. The old parser treated any non-empty non-zero parse result, includingNaN, as enabled, so a value meant to disable links could unexpectedly force OSC 8 output.Reviewer Test Plan
How to verify
Run the focused OSC 8 tests and confirm invalid or boolean-looking
FORCE_HYPERLINKvalues no longer force hyperlink output, while the existing accepted values still work.Evidence (Before & After)
Before:
FORCE_HYPERLINK=false,off, or1abccould force OSC 8 hyperlinks because invalid parses producedNaN, andNaN !== 0evaluated true.After: only an empty string or a complete non-zero integer force-enables hyperlinks; malformed values fail closed.
Tested on
Environment (optional)
Local validation used the CLI package test runner for
osc8.test.ts.Risk & Scope
1abcto force links will need to switch to a complete non-zero integer or empty value.Linked Issues
Fixes #5487
Testing
npm --workspace packages/cli test -- osc8.test.ts --coverage.enabled=falsenpx prettier --check packages/cli/src/ui/utils/osc8.ts packages/cli/src/ui/utils/osc8.test.ts docs/users/configuration/settings.mdnpx eslint packages/cli/src/ui/utils/osc8.ts packages/cli/src/ui/utils/osc8.test.tsnpm --workspace packages/cli run typechecknpm run build -- --cli-onlyNote: build completed with the existing Node v26
module.register()deprecation warning.AI Assistance Disclosure
I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.
中文说明
这个 PR 做了什么
这个 PR 在强制启用 OSC 8 链接前严格解析
FORCE_HYPERLINK。现在只有空字符串或完整的非零整数会启用链接;false、off、1abc这类值会 fail closed,不再因为NaN !== 0而启用链接。为什么需要
用户经常会设置
FORCE_HYPERLINK=false这类看起来像布尔值的环境变量。旧解析逻辑会把非空且解析结果不等于 0 的值当作启用,其中包括NaN,导致本来想禁用链接的值反而强制输出 OSC 8。Reviewer 测试计划
如何验证
运行聚焦的 OSC 8 测试,确认无效或布尔风格的
FORCE_HYPERLINK不再强制启用链接,同时已有合法值仍然可用。前后证据
之前:
FORCE_HYPERLINK=false、off或1abc可能强制启用 OSC 8,因为无效解析会得到NaN,而NaN !== 0为 true。之后:只有空字符串或完整非零整数会强制启用链接;畸形值会 fail closed。
测试平台
环境
本地验证使用 CLI package test runner,目标测试为
osc8.test.ts。风险与范围
1abc这类畸形值强制启用链接,需要改用完整非零整数或空值。关联 Issue
Fixes #5487
测试
npm --workspace packages/cli test -- osc8.test.ts --coverage.enabled=falsenpx prettier --check packages/cli/src/ui/utils/osc8.ts packages/cli/src/ui/utils/osc8.test.ts docs/users/configuration/settings.mdnpx eslint packages/cli/src/ui/utils/osc8.ts packages/cli/src/ui/utils/osc8.test.tsnpm --workspace packages/cli run typechecknpm run build -- --cli-only说明:build 完成时仍有现存的 Node v26
module.register()deprecation warning。AI Assistance Disclosure
I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.