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/chat-app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ function parseBlocks(text: string): Block[] {
}

// ── Handle Paragraphs ────────────────────────
if (line.trim() === '') {
if (line.trim().length === 0) {
blocks.push({
type: 'paragraph',
text: '',
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 28 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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node <<'NODE'
for (const entity of ['&`#x00000041dead`;', '&`#x110000`;']) {
  const value = entity.match(/&(`#x`?[0-9a-fA-F]+);/)[1];
  const codePoint = Number.parseInt(value.slice(2, 10), 16);
  try {
    console.log(entity, String.fromCodePoint(codePoint));
  } catch (error) {
    console.error(entity, error.name);
  }
}
NODE

Repository: Karanjot786/TermUI

Length of output: 197


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'File matches:\n'
fd -a 'index\.tsx$' . | sed 's#^\./##' | rg 'examples/rss-reader/src/index\.tsx|rss-reader' || true

printf '\nRelevant source:\n'
cat -n examples/rss-reader/src/index.tsx | sed -n '1,70p'

printf '\nBehavioral probe matching exact logic:\n'
node - <<'NODE'
function decode(value, entity) {
  const codePoint = Number.parseInt(entity.slice(2, 10), 16);
  try {
    return { ok: true, value: Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : value };
  } catch (error) {
    return { ok: false, name: error.name, message: error.message };
  }
}

for (const entity of [
  '&`#x00000041dead`;',
  '&`#x110000`;',
  '&`#x10ffff`;',
  '&`#x110001`;',
  '&`#12345`;',
  '&`#9999999`;',
  '&`#110000`;',
  '&`#x0041`;',
  '&`#xc0`;'
]) {
  const match = entity.match(/&(`#x`?[0-9a-fA-F]+);/);
  if (!match) throw new TypeError('Unexpected entity shape');
  const result = decode(entity, match[1]);
  console.log(JSON.stringify({ entity, parsed: match[1], result }));
}
NODE

Repository: Karanjot786/TermUI

Length of output: 3709


Reject out-of-range numeric entities before decoding.

The current checks allow decimal values such as &#110000;, which exceeds the Unicode code-point limit and throws in String.fromCodePoint. Reject non-integer code points and values above 0x10ffff before decoding.

🤖 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 28 - 31, Update the
entity-decoding callback in the RSS reader’s value replacement logic to validate
parsed numeric code points before calling String.fromCodePoint: require an
integer within the Unicode range 0 through 0x10ffff, and return the original
match for invalid or out-of-range values. Apply this validation to both
hexadecimal and decimal numeric entities.

}

Expand Down
2 changes: 1 addition & 1 deletion examples/todo-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class CustomMultiProgress extends (MultiProgressClass as any) {
const value = Math.max(0, Math.min(1, item.value));
const filled = Math.round(barWidth * value);

const pct = Math.round(value * 100);
const pct = Math.round(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

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

node <<'NODE'
const value = 0.145;
const current = Math.round(value * 100 + Number.EPSILON);
const corrected = Math.round((value + Number.EPSILON) * 100);

if (current !== 14 || corrected !== 15) {
  throw new Error(`Unexpected results: ${current}, ${corrected}`);
}
NODE

Repository: Karanjot786/TermUI

Length of output: 156


🌐 Web query:

MDN Number.EPSILON value JavaScript

💡 Result:

The Number.EPSILON property in JavaScript represents the difference between 1 and the smallest floating-point number greater than 1 [1][2]. Its value is 2^-52, which is approximately 2.220446049250313e-16 [1][3]. This property is a static data property of the Number object and cannot be changed, as its attributes are [[Writable]]: false, [[Enumerable]]: false, and [[Configurable]]: false [4][5]. It is primarily used to handle floating-point arithmetic inaccuracies when comparing numbers that are close in value, as standard equality operators (===) can be unreliable for floating-point calculations [2].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

node - <<'NODE'
const cases = [
  { value: 0.145, label: '0.145' },
  { value: Number.EPSILON / 100, label: 'Number.EPSILON/100' },
  { value: 0.005, label: '0.005' },
  { value: 0.999999999999999, label: 'near 1' },
 ];

for (const { value, label } of cases) {
  const current = Math.round(value * 100 + Number.EPSILON);
  const corrected = Math.round((value + Number.EPSILON) * 100);
  console.log(label.padEnd(22), 'current:', current, 'corrected:', corrected, 'same:', current === corrected, 'value:', value, '0.145*100:', 0.145 * 100, 'eps:', Number.EPSILON);
}
NODE

Repository: Karanjot786/TermUI

Length of output: 703


Add Number.EPSILON before scaling the percentage.

Number.EPSILON is too small to reliably change the result after multiplication by 100. Use the scaled input so 0.145 rounds to 15 instead of 14.

-            const pct = Math.round(value * 100 + Number.EPSILON);
+            const pct = Math.round((value + 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 pct = Math.round(value * 100 + Number.EPSILON);
const pct = Math.round((value + 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/todo-app/src/index.ts` at line 107, Update the percentage
calculation in the progress-value conversion to add Number.EPSILON after scaling
value by 100, ensuring values such as 0.145 round to 15 instead of 14 while
preserving the existing Math.round behavior.

const percentStr = ` ${pct}% `;
const showPct = barWidth >= percentStr.length;
const labelStart = showPct ? Math.floor((barWidth - percentStr.length) / 2) : -1;
Expand Down
2 changes: 1 addition & 1 deletion examples/widget-gallery/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class WidgetGalleryApp extends Widget {
}

// Tab switching: 1-6
const num = parseInt(event.key);
const num = parseInt(event.key, 10);
if (num >= 1 && num <= 6) {
this._switchTab(num - 1);
return true;
Expand Down
Loading