Skip to content

fix: resolve 4 bugs in termui - #3521

Open
saurabhhhcodes wants to merge 1 commit into
Karanjot786:mainfrom
saurabhhhcodes:fix/termui-18651
Open

fix: resolve 4 bugs in termui#3521
saurabhhhcodes wants to merge 1 commit into
Karanjot786:mainfrom
saurabhhhcodes:fix/termui-18651

Conversation

@saurabhhhcodes

@saurabhhhcodes saurabhhhcodes commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description

This PR fixes real bugs found in the codebase:

  • Simplified empty-string validation: comparing trim() to '' misses whitespace-only input; .trim().length === 0 is explicit.
  • Added explicit radix to parseInt: without 10, strings like '0x1F' or '08' parse in unintended bases.
  • Prevented interval leak: repeated mounts now clear the previous interval before scheduling a new one.
  • Fixed default sort: .sort() coerces elements to strings, so [10, 9, 2] sorts as [10, 2, 9]; numeric comparator sorts correctly.

Type of Change

  • Bug fix (non-breaking change fixing an issue)

How Has This Been Tested?

  • Local manual testing

Checklist

  • My code follows the style guidelines
  • I have performed a self-review

Related Issue

Ref: #3520

Summary by CodeRabbit

  • Bug Fixes
    • Prevented duplicate timers during AI streaming updates.
    • Improved paragraph detection in the chat app when blank lines contain whitespace.
    • Ensured numeric tab selections are interpreted consistently in the widget gallery.
    • Improved value comparison in tree selection controls for numeric arrays.

@github-actions github-actions Bot added type:bug +10 pts. Bug fix. area:examples Example apps. area:ui @termuijs/ui labels Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This change applies four targeted correctness fixes: interval cleanup in AI streaming, whitespace-only paragraph detection, explicit decimal key parsing, and numeric sorting in TreeSelect value comparison.

Changes

Example correctness fixes

Layer / File(s) Summary
Streaming interval cleanup
examples/ai-streaming/src/index.tsx
The constructor clears the existing interval before assigning a new interval.
Whitespace and key parsing
examples/chat-app/src/index.tsx, examples/widget-gallery/src/index.ts
Paragraph parsing recognizes whitespace-only lines. Tab-key parsing uses radix 10 explicitly.

TreeSelect value comparison

Layer / File(s) Summary
Numeric value sorting
packages/ui/src/TreeSelect.ts
The first value array is sorted numerically before comparison. The second array remains lexicographically sorted.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: karanjot786

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the fixes and testing, but it omits required package information, GSSoC details, and a closing issue link. Add the missing template sections, list affected packages, complete GSSoC details, and replace “Ref: #3520” with a valid closing issue link such as “Closes #3520”.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the four bug fixes and follows the required type-prefixed format.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
examples/ai-streaming/src/index.tsx (1)

43-43: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Keep the streaming interval per AIStreamingApp instance.

This file only constructs a single AIStreamingApp, so the global window.__interval does not cancel another mounted instance here. Store the handle on the instance instead for self-contained lifecycle management.

🤖 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/ai-streaming/src/index.tsx` at line 43, Update the interval setup in
AIStreamingApp to store and clear the timer handle on that component instance
rather than using the global window.__interval property. Preserve the existing
clear-and-restart behavior while ensuring each AIStreamingApp manages only its
own streaming interval.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@packages/ui/src/TreeSelect.ts`:
- Around line 185-186: Update the sorting logic used by _valuesEqual so sortedA
and sortedB both use the same comparator compatible with the arrays’ value type.
Ensure equivalent string inputs such as ["2", "10"] receive identical ordering
and avoid numeric subtraction that violates TypeScript strict typing.

---

Nitpick comments:
In `@examples/ai-streaming/src/index.tsx`:
- Line 43: Update the interval setup in AIStreamingApp to store and clear the
timer handle on that component instance rather than using the global
window.__interval property. Preserve the existing clear-and-restart behavior
while ensuring each AIStreamingApp manages only its own streaming interval.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 73fe7ae1-9c1d-45cc-a97b-ddf8aef6fc18

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7584e and 51637ff.

📒 Files selected for processing (4)
  • examples/ai-streaming/src/index.tsx
  • examples/chat-app/src/index.tsx
  • examples/widget-gallery/src/index.ts
  • packages/ui/src/TreeSelect.ts

Comment on lines +185 to 186
const sortedA = [...a].sort((a, b) => a - b);
const sortedB = [...b].sort();

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate TreeSelect.ts =="
fd -a 'TreeSelect\.ts$' . || true

echo "== inspect file outline =="
TREE="$(fd 'TreeSelect\.ts$' . | head -n1 || true)"
if [ -n "${TREE:-}" ]; then
  echo "TREE=$TREE"
  wc -l "$TREE"
  ast-grep outline "$TREE" --match '_valuesEqual' --view expanded || true
  echo "== relevant lines =="
  sed -n '160,200p' "$TREE" | nl -ba -v160
fi

echo "== package type script / tsconfig =="
if [ -f tsconfig.json ]; then echo "root tsconfig"; cat tsconfig.json; fi
fd -a 'tsconfig.*json$' . | while read -r f; do
  echo "-- $f --"
  sed -n '1,160p' "$f"
done

echo "== package deps mentioning typescript =="
rg -n '"typescript"|"type": "module"|strict|noImplicitAny|compilerOptions' package.json pnpm-lock.yaml package-lock.json yarn.lock . --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' | head -n 200 || true

Repository: Karanjot786/TermUI

Length of output: 490


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== behavioral probe: comparator effects for ["2","10"] =="
node - <<'JS'
const cases = {
  naiveA: ["2","10"].sort((a,b) => a - b),
  naiveB: ["2","10"].sort(),
  numeric: ["2","10"].sort((a,b) => Number(a)-Number(b)),
};
for (const [k,v] of Object.entries(cases)) console.log(`${k}: ${JSON.stringify(v)}`);

function sortedEqual(a, b) {
  const sortedA = [...a].sort((a, b) => a - b);
  const sortedB = [...b].sort();
  return sortedA.toString() === sortedB.toString();
}
console.log('sortedEqual(["2","10"],["2","10"]):', sortedEqual(["2","10"],["2","10"]));
JS

Repository: Karanjot786/TermUI

Length of output: 310


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read-only type compatibility probe for Node 18-only without installing deps.
node - <<'JS'
// This JavaScript probe cannot exercise TypeScript strict mode.
// We document the expression only because it was requested in the original comment.
console.log('Node cannot demonstrate TypeScript strict-mode typing for string subtraction without the tsc toolchain');
JS

Repository: Karanjot786/TermUI

Length of output: 259


🏁 Script executed:

#!/bin/bash
set -euo pipefail

TREE=$(fd 'TreeSelect\.ts$' . | head -n1 || true)
echo "TREE=$TREE"
echo "== relevant lines =="
awk 'NR>=160 && NR<=191 { printf "%4d\t%s\n", NR, $0 }' "$TREE"

echo "== tsconfig files =="
fd 'tsconfig.*json$' . | sort | while IFS= read -r f; do
  echo "-- $f --"
  sed -n '1,180p' "$f"
done

echo "== typecheck availability =="
command -v tsc || true
command -v npx || true
if [ -x "$(command -v npx || true 2>/dev/null)" ]; then
  npx --no-install tsc --version || true
fi

Repository: Karanjot786/TermUI

Length of output: 17646


Use one typed comparator for both arrays.

a - b rejects string operands in TypeScript strict mode, and mixing numeric and lexicographic sorting makes _valuesEqual return false for equivalent input values like ["2", "10"]. Apply the same typed comparator to both sortedA and sortedB.

Proposed fix
-    const sortedA = [...a].sort((a, b) => a - b);
-    const sortedB = [...b].sort();
+    const compareValues = (left: string, right: string) =>
+        Number(left) - Number(right);
+    const sortedA = [...a].sort(compareValues);
+    const sortedB = [...b].sort(compareValues);
🧰 Tools
🪛 GitHub Actions: CI / 0_build-and-test.txt

[error] 185-185: TypeScript DTS build failed: the left-hand side of an arithmetic operation must be any, number, bigint, or an enum type (TS2362), and the right-hand side must meet the same requirement (TS2363). Failed command: bun run build (tsup).

🪛 GitHub Actions: CI / build-and-test

[error] 185-185: TypeScript DTS build failed: TS2362 and TS2363 indicate that the operands of an arithmetic operation at columns 43 and 47 are not typed as any, number, bigint, or an enum. The @termuijs/ui build command (tsup) exited with code 1.

🤖 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 `@packages/ui/src/TreeSelect.ts` around lines 185 - 186, Update the sorting
logic used by _valuesEqual so sortedA and sortedB both use the same comparator
compatible with the arrays’ value type. Ensure equivalent string inputs such as
["2", "10"] receive identical ordering and avoid numeric subtraction that
violates TypeScript strict typing.

Source: Coding guidelines

@coderabbitai coderabbitai Bot mentioned this pull request Aug 5, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:examples Example apps. area:ui @termuijs/ui type:bug +10 pts. Bug fix.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant