Skip to content

Conversation

@frontegg-david
Copy link
Contributor

@frontegg-david frontegg-david commented Dec 21, 2025

Summary by CodeRabbit

  • New Features

    • Added template utility functions: date formatting, currency formatting, unique ID generation, and JSON embedding for templates.
    • Enhanced static badge rendering with improved template system.
  • Bug Fixes

    • Improved null/undefined handling in HTML escaping to return empty strings safely.
  • Tests

    • Added comprehensive test coverage for template helpers, HTML escaping, and static widget rendering scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Walkthrough

Changes migrate the template system to Handlebars, expand escapeHtml to accept unknown types with null/undefined handling, introduce new template helper utilities (formatDate, formatCurrency, uniqueId, jsonEmbed), and add comprehensive test coverage for template rendering and HTML escaping.

Changes

Cohort / File(s) Summary
Handlebars Template Migration
apps/e2e/demo-e2e-ui/src/apps/widgets/tools/static-badge.tool.ts
Converts static badge template from dynamic function returning HTML string to Handlebars template string with conditional blocks for color classes and property interpolation.
Template Helpers Implementation
libs/sdk/src/tool/ui/template-helpers.ts
Adds new public utilities (formatDate, formatCurrency, uniqueId, jsonEmbed, createTemplateHelpersLocal, resetIdCounter); imports escapeHtml from @frontmcp/ui/utils and re-exports for backwards compatibility.
Template Helpers Testing
libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
Comprehensive test suite covering escapeHtml (null/undefined, type coercion, XSS), formatDate, formatCurrency, uniqueId, jsonEmbed, and createTemplateHelpersLocal with edge cases.
Type Signature Updates
libs/ui/src/runtime/types.ts, libs/ui/src/types/ui-config.ts, libs/ui/src/types/ui-runtime.ts
Updates escapeHtml signature from (str: string) => string to (str: unknown) => string across TemplateHelpers interfaces; adds documentation noting null/undefined returns empty string and non-string coercion behavior.
HTML Escaping Testing
libs/ui/src/utils/__tests__/escape-html.test.ts
Adds test suite for escapeHtml, escapeHtmlAttr, and escapeJsString, covering null/undefined handling, type coercion, HTML entity escaping, and edge cases.
Handlebars Rendering Tests
libs/ui/src/handlebars/__tests__/handlebars.test.ts
Adds "Static Widget Template Scenarios" test suite validating static mode rendering, empty output handling, conditional classes, data-driven templates, XSS escaping, and nested control flow.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Type signature consistency: Verify escapeHtml null/undefined handling is correctly implemented across all affected interfaces and implementations
  • Template helper implementations: Review formatDate, formatCurrency, uniqueId, and jsonEmbed logic for correctness and edge case handling, particularly type coercion and escaping behavior
  • Test coverage alignment: Ensure test assertions match documented behavior for escapeHtml and new helpers, especially around null/undefined and type coercion
  • Handlebars migration: Confirm static-badge.tool.ts template correctly replaces manual CSS class logic and Handlebars properly escapes output

Possibly related PRs

Poem

🐰 Templates dance with Handlebars so grand,
Helpers escape what's risky, understand,
formatDate, formatCurrency in hand,
uniqueId hops where logic once just ran,
Safe strings sing as tests expand! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'fix: Fix UI widget build' is vague and generic, using redundant language ('fix: Fix') without clearly describing the specific changes made to the codebase. Use a more descriptive title that clearly explains the main change, such as 'fix: Update template helpers and escapeHtml handling' or 'fix: Refactor static badge tool to use Handlebars templates'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-ui-widget-build

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 885b454 and 09946e9.

⛔ Files ignored due to path filters (2)
  • libs/ui/src/build/__tests__/manifest-builder.test.ts is excluded by !**/build/**
  • libs/ui/src/build/widget-manifest.ts is excluded by !**/build/**
📒 Files selected for processing (8)
  • apps/e2e/demo-e2e-ui/src/apps/widgets/tools/static-badge.tool.ts (1 hunks)
  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts (1 hunks)
  • libs/sdk/src/tool/ui/template-helpers.ts (2 hunks)
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts (1 hunks)
  • libs/ui/src/runtime/types.ts (1 hunks)
  • libs/ui/src/types/ui-config.ts (1 hunks)
  • libs/ui/src/types/ui-runtime.ts (1 hunks)
  • libs/ui/src/utils/__tests__/escape-html.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
libs/ui/src/**/*.ts

📄 CodeRabbit inference engine (libs/ui/CLAUDE.md)

libs/ui/src/**/*.ts: Always use escapeHtml() utility for all user-provided content to prevent XSS vulnerabilities
Hard-code CDN URLs only in theme presets; always reference theme.cdn configuration in component code

Files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use strict TypeScript mode with no any types without strong justification - use unknown instead for generic type defaults
Avoid non-null assertions (!) - use proper error handling and throw specific errors instead
Use type parameters with constraints instead of unconstrained generics
Do not mutate rawInput in flows - use state.set() for managing flow state instead

Files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • apps/e2e/demo-e2e-ui/src/apps/widgets/tools/static-badge.tool.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Achieve 95%+ test coverage across all metrics (statements, branches, functions, lines)
Test all code paths including error cases and constructor validation
Include error class instanceof checks in tests to validate error handling

Files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
libs/sdk/src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

libs/sdk/src/**/*.ts: MCP response types should use strict MCP protocol types (GetPromptResult, ReadResourceResult) instead of unknown
Use specific error classes with MCP error codes instead of generic errors
Use getCapabilities() method for dynamic capability exposure instead of hardcoding capabilities
Use changeScope property instead of scope in change events to avoid confusion with Scope class
Validate URIs per RFC 3986 at metadata level using proper validation
Validate hook flows and fail fast on invalid hook configurations with specific error messages

Files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
libs/ui/src/**/*.test.ts

📄 CodeRabbit inference engine (libs/ui/CLAUDE.md)

libs/ui/src/**/*.test.ts: Maintain 95%+ test coverage across statements, branches, functions, and lines
Test HTML escaping for user-provided content to prevent XSS attacks
Test behavior across platform configurations (OpenAI, Claude, Gemini, ngrok) where applicable

Files:

  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
🧠 Learnings (10)
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/**/*.ts : Always use `escapeHtml()` utility for all user-provided content to prevent XSS vulnerabilities

Applied to files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/**/*.test.ts : Test HTML escaping for user-provided content to prevent XSS attacks

Applied to files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/components/**/*.ts : Use pure HTML string generation without React/Vue/JSX - components return HTML strings only

Applied to files:

  • libs/ui/src/runtime/types.ts
  • libs/ui/src/types/ui-runtime.ts
  • apps/e2e/demo-e2e-ui/src/apps/widgets/tools/static-badge.tool.ts
  • libs/sdk/src/tool/ui/template-helpers.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
  • libs/ui/src/types/ui-config.ts
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/**/*.test.ts : Test behavior across platform configurations (OpenAI, Claude, Gemini, ngrok) where applicable

Applied to files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/components/**/*.test.ts : Write validation tests covering invalid variant/options, unknown properties, and valid option acceptance

Applied to files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
📚 Learning: 2025-12-19T02:04:46.464Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.464Z
Learning: Applies to **/*.test.{ts,tsx} : Test all code paths including error cases and constructor validation

Applied to files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
📚 Learning: 2025-11-26T15:23:04.965Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-11-26T15:23:04.965Z
Learning: Applies to libs/ui/src/**/*.test.ts : Maintain 95%+ test coverage across statements, branches, functions, and lines

Applied to files:

  • libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts
  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
  • libs/ui/src/utils/__tests__/escape-html.test.ts
📚 Learning: 2025-12-19T02:04:46.464Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.464Z
Learning: Applies to **/*.test.{ts,tsx} : Achieve 95%+ test coverage across all metrics (statements, branches, functions, lines)

Applied to files:

  • libs/ui/src/handlebars/__tests__/handlebars.test.ts
📚 Learning: 2025-12-19T02:04:46.464Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.464Z
Learning: Applies to libs/sdk/src/**/index.ts : Export public API through barrel files - export users' needed items, no legacy exports with different names

Applied to files:

  • libs/sdk/src/tool/ui/template-helpers.ts
📚 Learning: 2025-12-19T02:04:46.464Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.464Z
Learning: Applies to libs/sdk/src/**/*.ts : Use `changeScope` property instead of `scope` in change events to avoid confusion with Scope class

Applied to files:

  • libs/sdk/src/tool/ui/template-helpers.ts
🧬 Code graph analysis (2)
libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts (1)
libs/sdk/src/tool/ui/template-helpers.ts (7)
  • escapeHtml (24-24)
  • formatDate (33-49)
  • formatCurrency (56-61)
  • resetIdCounter (101-103)
  • uniqueId (67-69)
  • jsonEmbed (75-81)
  • createTemplateHelpersLocal (87-95)
libs/ui/src/utils/__tests__/escape-html.test.ts (1)
libs/sdk/src/tool/ui/template-helpers.ts (1)
  • escapeHtml (24-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build Libraries
🔇 Additional comments (8)
libs/ui/src/runtime/types.ts (1)

41-42: LGTM! Improved type safety for template helpers.

The signature change from (str: string) to (str: unknown) enables safer handling of template expressions that may be null, undefined, or non-string types without requiring explicit type guards at every call site.

apps/e2e/demo-e2e-ui/src/apps/widgets/tools/static-badge.tool.ts (1)

40-53: LGTM! Handlebars auto-escaping provides XSS protection.

The migration to a Handlebars string template is well-executed. The {{...}} syntax automatically escapes HTML special characters, which satisfies the coding guideline requirement to prevent XSS vulnerabilities. The explicit comment clarifying this behavior is helpful.

Note: If you ever need to output unescaped HTML, Handlebars requires explicit {{{...}}} triple-mustache syntax, making it harder to accidentally introduce XSS vulnerabilities.

Based on learnings, this aligns with the requirement to use escapeHtml() for all user-provided content.

libs/ui/src/types/ui-runtime.ts (1)

731-733: LGTM! Consistent type signature update.

The escapeHtml signature change aligns with the parallel updates in libs/ui/src/runtime/types.ts and libs/ui/src/types/ui-config.ts, ensuring consistency across the UI type system.

libs/ui/src/handlebars/__tests__/handlebars.test.ts (1)

519-684: LGTM! Comprehensive test coverage for static widget scenarios.

The new test suite thoroughly validates static widget template rendering, including:

  • Empty output handling (simulating build-time static mode)
  • Conditional class application with eq helper
  • XSS prevention through auto-escaping
  • Complex patterns (nested conditionals, loops with empty arrays)

This aligns with coding guidelines for 95%+ test coverage and XSS testing requirements.

Based on learnings, these tests properly validate HTML escaping for user-provided content.

libs/ui/src/utils/__tests__/escape-html.test.ts (1)

1-124: LGTM! Excellent comprehensive test coverage for HTML escaping.

The test suite thoroughly validates all aspects of the expanded escapeHtml API:

  • Null/undefined handling: Validates the key improvement that null/undefined return empty string
  • Type coercion: Tests numbers, booleans, and objects are properly converted
  • XSS prevention: Validates all HTML special characters are escaped
  • Edge cases: Includes the important destructured undefined properties test (lines 28-37) that directly addresses the bug scenario

The tests for escapeHtmlAttr and escapeJsString provide additional security coverage for different contexts.

Based on learnings, this meets the requirement to test HTML escaping for user-provided content to prevent XSS attacks and maintains 95%+ coverage.

libs/ui/src/types/ui-config.ts (1)

136-139: LGTM! Well-documented type signature improvement.

The updated documentation clearly explains both aspects of the new behavior:

  1. Null/undefined handling (returns empty string)
  2. Type coercion (non-string values converted before escaping)

This provides excellent guidance for API consumers.

libs/sdk/src/tool/ui/__tests__/template-helpers.test.ts (1)

1-208: LGTM! Comprehensive test suite for template helpers.

Excellent test coverage across all helper functions:

  • escapeHtml: Thoroughly tests the bug fix for undefined destructured properties (lines 28-37) and all XSS scenarios
  • formatDate/formatCurrency: Validates formatting with various inputs including edge cases
  • uniqueId: Tests determinism with proper counter reset
  • jsonEmbed: Validates JSON stringification and script-breaking character escaping
  • createTemplateHelpersLocal: Validates the helper factory returns all required functions

The tests follow coding guidelines for 95%+ coverage and test all code paths including error cases.

Based on learnings, these tests properly validate HTML escaping for user-provided content and maintain comprehensive coverage.

libs/sdk/src/tool/ui/template-helpers.ts (1)

1-103: LGTM! Well-structured consolidation and public API expansion.

Excellent refactoring that achieves multiple goals:

  • Single source of truth: escapeHtml now imported from @frontmcp/ui/utils (line 12) eliminating code duplication
  • Backwards compatibility: Re-export maintains existing API surface (line 24)
  • Public API expansion: New helper functions (formatDate, formatCurrency, uniqueId, jsonEmbed) provide a comprehensive utility set
  • Clear deprecation path: createTemplateHelpersLocal marked deprecated with guidance to use createTemplateHelpers from @frontmcp/ui/runtime
  • Testing support: resetIdCounter properly marked @internal but exported for test determinism

The implementation is clean and well-documented. All new functions have clear JSDoc comments.

Based on learnings, this consolidates the escapeHtml utility while maintaining the SDK's public API surface.


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

@frontegg-david
Copy link
Contributor Author

frontegg-david commented Dec 21, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@frontegg-david frontegg-david merged commit 527560c into main Dec 21, 2025
21 checks passed
@frontegg-david frontegg-david deleted the fix-ui-widget-build branch December 21, 2025 01:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants