Skip to content

fix(prompts): truncate wide-character box titles by display width#578

Open
greymoth-jp wants to merge 1 commit into
bombshell-dev:mainfrom
greymoth-jp:fix/box-wide-title-width
Open

fix(prompts): truncate wide-character box titles by display width#578
greymoth-jp wants to merge 1 commit into
bombshell-dev:mainfrom
greymoth-jp:fix/box-wide-title-width

Conversation

@greymoth-jp

Copy link
Copy Markdown

What does this PR do?

box() measures the title and every line with fast-string-width, but it truncates an over-long title with title.slice(0, maxTitleLength - 3), which counts UTF-16 code units rather than display columns. maxTitleLength is a display-width budget, so for a wide-character (CJK/full-width) title the sliced result is still far too wide. The top border comes out ragged, and once getPaddingForLine returns a negative remainder, '─'.repeat(...) throws RangeError: Invalid count value.

Repro on main:

import { box } from '@clack/prompts';

// '这是一个非常长的标题' is 10 full-width chars = 20 display columns
box('message', '这是一个非常长的标题', { width: 0.2 });
// RangeError: Invalid count value: -6

The fix replaces the code-unit slice with a small truncateToWidth helper that accumulates characters by display width, the same way the rest of box() already measures. For ASCII titles it returns exactly what the old slice did, so existing snapshots are unchanged; only wide-character titles change behaviour (they now fit the box and the borders stay aligned).

No linked issue: this is a small self-contained bug fix.

Type of change

  • Bug fix
  • Feature
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset

AI-generated code disclosure

  • This PR includes AI-generated code

@changeset-bot

changeset-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2aee058

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clack/prompts Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the automated PR author detected as automated label Jun 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Automation signals

@greymoth-jp Activity patterns show signs of automation.

Classification: automation (score: 0)

Signal Points Detail
Automated fork/PR workflow +35 57/62 fork branches followed by upstream PRs within 76s
Extreme fork automation +85 52 repositories forked in rapid succession (within 24 hours)
Extreme PR spam (daily) +45 60 PRs in the last 24 hours
Very high PR spam frequency +40 60 PRs in the last 7 days

Analyzed 200 public events via @unveil/identity


function truncateToWidth(str: string, maxWidth: number): string {
const ellipsis = '...';
const target = maxWidth - stringWidth(ellipsis);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ellipsis is constant so should be moved out of the function, and the length doesn't need to use stringWidth since we know it has no wide characters

return [leftPadding, rightPadding];
}

function truncateToWidth(str: string, maxWidth: number): string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should really be in common.ts since it will be useful in other places too

Comment on lines +106 to +110
if (width + charWidth > target) {
break;
}
result += char;
width += charWidth;

@43081j 43081j Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (width + charWidth > target) {
break;
}
result += char;
width += charWidth;
width += charWidth;
if (width > target) {
break;
}
result += char;

to avoid computing it twice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated PR author detected as automated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants