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/ai-streaming/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class AIStreamingApp extends Widget {
this.addChild(this._toolCall);
this.addChild(this._streamingText);

setInterval(() => {
clearInterval(window.__interval); window.__interval = setInterval(() => {
this._streamingText.tick();
}, 50);
}
Expand Down
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 = 0.145;
const current = Math.round(value * 100 + Number.EPSILON);
const corrected = Math.round((value + Number.EPSILON) * 100);

console.log({ current, corrected });

if (current !== 14 || corrected !== 15) process.exit(1);
NODE

Repository: Karanjot786/TermUI

Length of output: 187


🏁 Script executed:

#!/bin/bash
set -euo pipefail
printf '--- candidate file ---\n'
wc -l examples/pomodoro-timer/src/index.tsx
printf '\n--- relevant lines ---\n'
sed -n '1,230p' examples/pomodoro-timer/src/index.tsx
printf '\n--- _value references ---\n'
rg -n "_value|set(Value|Interval)" examples/pomodoro-timer/src/index.tsx

Repository: Karanjot786/TermUI

Length of output: 247


🏁 Script executed:

#!/bin/bash
set -euo pipefail
printf '%s\n' '--- candidate file ---'
wc -l examples/pomodoro-timer/src/index.tsx || true
printf '%s\n' ''
printf '%s\n' '--- relevant lines ---'
sed -n '1,230p' examples/pomodoro-timer/src/index.tsx || true
printf '%s\n' ''
printf '%s\n' '--- _value and setValue references ---'
rg -n '_value|setValue|setInterval|setInterval' examples/pomodoro-timer/src/index.tsx || true

Repository: Karanjot786/TermUI

Length of output: 7114


Apply Number.EPSILON before converting to percentage.

setValue() stores values in the 0–1 range, but Number.EPSILON is added after _value * 100. The added value is too small to affect rounding for inputs just below half-integer percentage boundaries. Add it to _value before multiplication, or use a scale-aware correction.

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
label calculation in the timer’s label-rendering logic so the floating-point
correction is applied to the 0–1 value before multiplying by 100, or use an
equivalent scale-aware adjustment. Preserve the existing conditional label
behavior and rounding.

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: 2 additions & 0 deletions packages/ui/src/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,5 @@ export class Form extends Widget {
}
}
}

.catch(err => console.error("Promise.all failed:", err));
Comment on lines +141 to +142

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 | 🔴 Critical | ⚡ Quick win

Fix the invalid .catch placement before merging.

Line 142 starts a standalone .catch expression, so packages/ui/src/Form.ts does not parse. Attach the handler to the Promise.all(...) expression at Line 83, or use try/catch around await Promise.all(...).

When validation rejects, also reset _isValidating and call markDirty(). The cleanup at Lines 92 and97 runs only after a successful await. Logging the error alone leaves the form in the validating state.

As per coding guidelines, every state-mutating method on a widget calls this.markDirty().

🧰 Tools
🪛 Biome (2.5.6)

[error] 142-142: Expected a statement but instead found '.catch(err => console.error("Promise.all failed:", err))'.

(parse)

🪛 GitHub Actions: CI / 0_build-and-test.txt

[error] 142-142: Build failed during 'tsup' due to a syntax error: Unexpected '.' at '.catch(err => console.error("Promise.all failed:", err));'. TypeScript also reported TS1128, TS1005, and TS2304.

🪛 GitHub Actions: CI / build-and-test

[error] 142-142: tsup/esbuild build failed: Unexpected '.' at the standalone '.catch(err => console.error("Promise.all failed:", err));'. TypeScript also reports TS1128, TS1005, and TS2304 syntax errors. The failing command was 'bun run build'.

🤖 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/Form.ts` around lines 141 - 142, Fix the Promise.all
error-handling flow in Form by attaching the catch to the Promise.all expression
or wrapping its await in try/catch, removing the standalone invalid .catch
syntax. On validation rejection, reset _isValidating and call markDirty(),
ensuring every state-mutating path follows the widget state-update convention.

Sources: Coding guidelines, Linters/SAST tools

2 changes: 1 addition & 1 deletion scripts/build-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function collectDeps(content: string): string[] {
const deps = new Set<string>();
let m: RegExpExecArray | null;
while ((m = re.exec(content)) !== null) deps.add(m[1]!);
return [...deps].sort();
return [...deps].sort((a, b) => a - b);

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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)scripts/(build-registry|build-registry\.test)\.(ts|tsx)$|(^|/)tsconfig.*\.json$|(^|/)package\.json$' || true

echo "== build-registry outline =="
ast-grep outline scripts/build-registry.ts 2>/dev/null || true

echo "== relevant build-registry lines =="
sed -n '1,140p' scripts/build-registry.ts

echo "== relevant build-registry test lines =="
sed -n '110,155p' scripts/build-registry.test.ts

echo "== tsconfig strict settings =="
for f in $(git ls-files | rg '(^|/)tsconfig.*\.json$'); do
  echo "-- $f"
  sed -n '1,220p' "$f"
done

Repository: Karanjot786/TermUI

Length of output: 28868


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
deps = ['`@termuijs/core`', '`@termuijs/motion`', '`@termuijs/widgets`']
print("numeric comparator returns:", [(a, b, a < b or a > b or a == b, a == b or a > b) for a, b in zip(deps, deps[1:])])
print("NaN comparison behavior:", (float('nan') < 0), (float('nan') > 0), (float('nan') == float('nan')))
print("local compare:", sorted(deps, key=None))
PY

Repository: Karanjot786/TermUI

Length of output: 412


🌐 Web query:

TypeScript string subtraction compile error strict comparison operators

💡 Result:

In TypeScript, attempting to perform subtraction on strings (e.g., "10" - "5") results in a compilation error because the language restricts arithmetic operations to specific types [1][2][3]. Why TypeScript Prevents String Subtraction The TypeScript compiler enforces strict type checking for arithmetic operators, including subtraction (-). To prevent common programming errors and unintended implicit type coercion—which is a common source of bugs in JavaScript—TypeScript requires that both the left-hand side and right-hand side of an arithmetic operation be of type number, bigint, any, or a numeric enum [1][2][3]. When you attempt to subtract strings, the compiler throws error TS2362 or TS2363, stating that the operand must be of one of these permitted types [1][4][2]. If you need to perform numeric subtraction with string data, you must explicitly convert the strings to a numeric type using functions like Number, parseFloat, parseInt, or the unary plus (+) operator [4][2][5]. Strict Comparison Operators Regarding comparison, TypeScript distinguishes between strict (===) and loose (==) operators, and leverages them for type narrowing [6][7]. 1. Strict Equality (===): This operator checks both value and type without performing implicit coercion [8][9]. In TypeScript, if the compiler can statically determine that the types of the two operands have no overlap (e.g., comparing a string literal to a number), it will issue a compile-time error (ts(2367)) [8]. 2. Loose Equality (==): This operator performs type coercion before comparison [6][9]. While this can sometimes be useful (e.g., the common null-check idiom value == null), it is generally discouraged in TypeScript because it can mask type-related bugs [6][10]. Best Practices - Arithmetic: Always ensure operands are explicitly numeric before performing subtraction [2][3]. - Comparisons: Default to using strict equality (===) throughout your code to avoid the pitfalls of implicit type coercion [10][9]. If you need to safely handle data of varying types, utilize Type Guards (e.g., typeof, instanceof) to narrow types before performing operations [6][7].

Citations:


Use a string comparator for dependency names.

collectDeps returns string package names, so a - b is invalid in strict TypeScript and can produce NaN at runtime. Array.sort needs a comparator returning a negative value, zero, or a positive value; use a.localeCompare(b) so @termuijs/core, @termuijs/motion, and @termuijs/widgets stay in tested alphabetical order.

🤖 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 `@scripts/build-registry.ts` at line 47, Update the sorting in collectDeps to
compare dependency names with a string comparator using localeCompare,
preserving the tested alphabetical order of package names.

}

export function toSlug(name: string): string {
Expand Down
Loading