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

🧩 Analysis chain

🏁 Script executed:

node <<'NODE'
const value = 29 / 200;
const current = Math.round(value * 100 + Number.EPSILON);
const corrected = Math.round((value + Number.EPSILON) * 100);
console.log({ current, corrected });
if (current === 15 || corrected !== 15) process.exit(1);
NODE

Repository: Karanjot786/TermUI

Length of output: 187


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate target file and class:"
fd -a 'index.tsx$' . | sed 's#^\./##' | grep 'examples/pomodoro-timer/src/index.tsx' || true

echo
echo "Relevant file context:"
sed -n '160,200p' examples/pomodoro-timer/src/index.tsx | cat -n | sed 's/^/165+/'

echo
echo "Search for GradientProgressBar setValue:"
rg -n "class GradientProgressBar|_value|setValue|Number\.EPSILON|percent|showLabel" examples/pomodoro-timer/src/index.tsx

Repository: Karanjot786/TermUI

Length of output: 3046


Apply the epsilon before scaling the percentage value.

Number.EPSILON is too small after multiplying by 100. For example, this._value = 29 / 200 can produce 14.499999999999998, so the current expression displays 14% instead of 15%.

Proposed fix
-        const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
+        const label = this._showLabel ? ` ${Math.round((this._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 label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
const label = this._showLabel ? ` ${Math.round((this._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/pomodoro-timer/src/index.tsx` at line 185, Update the percentage
calculation in the label expression within the timer display so Number.EPSILON
is added to this._value before multiplying by 100, then round the scaled result
as before. Preserve the existing conditional label behavior and formatting.

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

node <<'NODE'
const truncated = Number.parseInt('000000041'.slice(0, 8), 16);
console.log({ truncated });

try {
  String.fromCodePoint(Number.parseInt('110000', 16));
  process.exit(1);
} catch (error) {
  console.log(error.name);
}
NODE

Repository: Karanjot786/TermUI

Length of output: 184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Files matching index.tsx:\n'
fd -a 'index\.tsx$' . | sed 's#^\./##'

printf '\nRelevant excerpt from examples/rss-reader/src/index.tsx:\n'
if [ -f examples/rss-reader/src/index.tsx ]; then
  nl -ba examples/rss-reader/src/index.tsx | sed -n '1,80p'
else
  echo 'not found'
fi

printf '\nSearch for decodeEntities usages:\n'
rg -n "decodeEntities|decodeEntity|&`#x`|`#x`|String\.fromCodePoint|fromCodePoint" examples/rss-reader/src || true

Repository: Karanjot786/TermUI

Length of output: 2181


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Relevant excerpt from examples/rss-reader/src/index.tsx:\n'
awk '{printf "%6d  %s\n", NR, $0}' examples/rss-reader/src/index.tsx | sed -n '1,100p'

printf '\nSearch for decodeEntities and code-point parsing usages:\n'
grep -RInE "decodeEntities|decodeEntity|&`#x`|`#x`|String\.fromCodePoint|fromCodePoint|Number\.parseInt" examples/rss-reader/src || true

Repository: Karanjot786/TermUI

Length of output: 5050


Reject invalid hexadecimal entities before decoding.

entity.slice(2, 10) drops digits after the eighth, so &#x000000041; decodes as U+00000004 instead of U+0041. The Number.isFinite check also allows overlong entities like &#x110000; to call String.fromCodePoint, which throws RangeError. Parse the full entity value, reject more than eight hex digits, and keep valid code points only within 0x10FFFF; apply the same range check to the decimal branch.

🤖 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 the hexadecimal and decimal branches to parse the complete
numeric value without truncating digits, reject hexadecimal entities with more
than eight digits, and only decode values in the valid Unicode range
0x0–0x10FFFF. Apply the same range validation before String.fromCodePoint in the
decimal branch, returning match for invalid or out-of-range entities.

}

Expand Down
2 changes: 1 addition & 1 deletion examples/showcase/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class ShowcaseApp extends Widget {
if (event.key === 'q' || (event.ctrl && event.key === 'c')) return false;

// Tab switching: 1-5
const num = parseInt(event.key);
const num = parseInt(event.key, 10);
if (num >= 1 && num <= 5) {
this.switchTab(num - 1);
return true;
Expand Down
2 changes: 1 addition & 1 deletion examples/weather/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ async function fetchWeather() {
}
}

setInterval(fetchWeather, 5000);
clearInterval(window.__interval); window.__interval = setInterval(fetchWeather, 5000);

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:

#!/bin/bash
set -euo pipefail

rg -n -C 3 '__interval|interface Window|declare global' examples/weather --glob '*.{ts,tsx,d.ts}' || true
rg -n -C 2 '"strict"[[:space:]]*:[[:space:]]*true' --glob 'tsconfig*.json' --glob '!node_modules' || true

Repository: Karanjot786/TermUI

Length of output: 582


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)tsconfig.*\.json$|examples/weather/src/index\.tsx$|\.d\.ts$|package\.json$|pnpm-lock\.yaml$|yarn\.lock$|package-lock\.json$' || true

echo "== example index relevant section =="
sed -n '180,215p' examples/weather/src/index.tsx | cat -n -v

echo "== ts configs =="
for f in $(git ls-files '*tsconfig*.json' 'packages/**/tsconfig*.json' 'apps/**/tsconfig*.json' '**/tsconfig*.json' | rg -v node_modules || true); do
  echo "--- $f"
  sed -n '1,80p' "$f"
done

echo "== window declarations repo-wide =="
rg -n -C 3 '^\s*(declare )?(interface|type|namespace)\s+Window\s*|declare global|__interval|interface\s+Global.*Window|--extends|--skipLibCheck|--noImplicitAny|--strict' . --glob '*.{ts,tsx,d.ts,json,yaml,yml}' --glob '!node_modules/**' || true

Repository: Karanjot786/TermUI

Length of output: 21330


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== weather package metadata =="
cat examples/weather/package.json

echo "== root package scripts/typecheck =="
sed -n '1,160p' package.json

echo "== lockfile TS version candidates =="
for f in pnpm-lock.yaml package-lock.json yarn.lock; do
  [ -f "$f" ] || continue
  echo "--- $f"
  rg -n 'typescript|`@types/node`|`@types/react`|`@termuijs`' "$f" | head -80 || true
done

echo "== examples/weather typecheck if TS is available =="
if command -v npx >/dev/null 2>&; then
  (set -x; npx --package typescript -- tsc --version 2>&1);
  npx --package typescript -- tsc --noEmit --strict --module ESNext --moduleResolution Bundler --target ES2022 examples/weather/src/index.tsx 2>&1 | sed -n '1,120p' || true
else
  echo "npx not available"
fi

echo "== declare global occurrences excluding node_modules =="
rg -n -C 2 'declare global|interface Window|declare module' . --glob '!node_modules/**' || true

Repository: Karanjot786/TermUI

Length of output: 1965


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cd examples/weather

if command -v bun >/dev/null 2>&1; then
  echo "== bun tsc if available =="
  bun tsc --version 2>&1 || true
  bun tsc --noEmit 2>&1 | sed -n '1,160p'
else
  echo "bun not available"
fi

echo "== node_modules/typescript availability =="
if [ -x node_modules/.bin/tsc ]; then
  ./node_modules/.bin/tsc --version
  ./node_modules/.bin/tsc --noEmit 2>&1 | sed -n '1,160p' || true
else
  echo "node_modules/.bin/tsc not available"
fi

Repository: Karanjot786/TermUI

Length of output: 253


Declare window.__interval.

examples/weather runs strict: true, but window.__interval has no TypeScript declaration. Add a Window augmentation for this timer handle, or avoid attaching it directly to window.

🤖 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/weather/src/index.tsx` at line 204, Declare the __interval property
used by the weather polling setup in index.tsx by adding a global Window
augmentation with the appropriate timer-handle type, or replace the window
attachment with a typed module-level variable. Ensure both clearInterval and
setInterval calls remain type-safe under strict TypeScript checking.

Source: Coding guidelines

fetchWeather();

// Gauge does not expose a public setColor() method, so dynamic color
Expand Down
Loading