Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/pomodoro-timer/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class GradientProgressBar extends Widget {

const attrs = styleToCellAttrs(this._style);

const label = this._showLabel ? ` ${Math.round(this._value * 100)}%` : '';
const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Scale the epsilon to the percentage value.

At Line 185, the calculation adds Number.EPSILON after multiplying by 100. That epsilon can be too small to change values near 28.5. For example, 0.285 * 100 can produce 28.499999999999996, so the label can still display 28% instead of 29%.

Use an epsilon scaled for the percentage range and add a boundary test.

Proposed fix
-        const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
+        const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON * 100)}%` : '';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON * 100)}%` : '';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/pomodoro-timer/src/index.tsx` at line 185, Update the percentage
label calculation in the timer’s label-rendering method to add an epsilon scaled
to the percentage value after multiplying _value by 100, so values such as 0.285
round to 29%. Add a boundary test covering this near-half percentage case and
preserve the existing conditional label behavior.

const barWidth = Math.max(0, width - label.length);
const filled = this._value <= 0 ? 0 : Math.round(barWidth * this._value);
const empty = barWidth - filled;
Expand Down
2 changes: 1 addition & 1 deletion examples/rss-reader/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function decodeEntities(value: string): string {

return value.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (match, entity: string) => {
if (entity.startsWith('#x')) {
const codePoint = Number.parseInt(entity.slice(2), 16);
const codePoint = Number.parseInt(entity.slice(2, 10), 16);
return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : match;
Comment on lines +30 to 31

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject overlong and out-of-range entities instead of truncating them.

entity contains the complete match, but slice(2, 10) discards digits after the first eight. An input such as &#x000000041; is therefore decoded as 0x4 instead of remaining unchanged. Check the digit length before parsing. Also reject values above 0x10FFFF before calling String.fromCodePoint.

Proposed fix
-      const codePoint = Number.parseInt(entity.slice(2, 10), 16);
-      return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : match;
+      const digits = entity.slice(2);
+      if (digits.length > 8) return match;
+      const codePoint = Number.parseInt(digits, 16);
+      return Number.isFinite(codePoint) && codePoint <= 0x10FFFF
+        ? String.fromCodePoint(codePoint)
+        : match;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const codePoint = Number.parseInt(entity.slice(2, 10), 16);
return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : match;
const digits = entity.slice(2);
if (digits.length > 8) return match;
const codePoint = Number.parseInt(digits, 16);
return Number.isFinite(codePoint) && codePoint <= 0x10FFFF
? String.fromCodePoint(codePoint)
: match;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/rss-reader/src/index.tsx` around lines 30 - 31, Update the
entity-decoding logic around codePoint to validate the hexadecimal digit portion
before parsing: reject entities with more than eight digits, and reject parsed
values above 0x10FFFF, returning match unchanged in both cases. Only call
String.fromCodePoint for valid Unicode scalar values while preserving the
existing finite-value check.

}

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ async function promptSelect<T = string>(options: SelectPromptOptions<T>): Promis
return;
}
const n = parseInt(trimmed, 10);
if (!isNaN(n) && n >= 1 && n <= choices.length) {
if (!Number.isNaN(n) && n >= 1 && n <= choices.length) {
rl.close();
resolve(choices[n - 1].value);
return;
Expand Down
Loading