Skip to content

Conversation

@frontegg-david
Copy link
Contributor

@frontegg-david frontegg-david commented Jan 4, 2026

Summary by CodeRabbit

  • New Features

    • Adds a centralized utils package (crypto, FS, content, path, naming, HTTP) and CLI templates now apply placeholders to destination paths.
  • Public API

    • oauth:register state includes isDev; DevClientRegistry exposes get(client_id).
    • New public errors: SessionMissingError and UnsupportedClientVersionError.
  • Dependencies

    • Adds @frontmcp/utils, @noble/hashes, @noble/ciphers.
  • Documentation

    • Replaces detailed ERROR_HANDLING.md with a consolidated errors README.

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

@frontegg-david
Copy link
Contributor Author

frontegg-david commented Jan 4, 2026

⚠️ Snyk checks are incomplete.

Status Scanner Critical High Medium Low Total (0)
⚠️ Open Source Security 0 0 0 0 See details
Code Security 0 0 0 0 0 issues

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

Adds a new shared package @frontmcp/utils and migrates many local utilities across CLI, SDK, adapters, and UI to use it; updates tsconfig/build externals, adjusts several SDK exports/errors, and adds tests for the new utils package.

Changes

Cohort / File(s) Summary
New utils package
libs/utils/*
package.json, project.json, tsconfig*.json, src/**, README.md, CHANGELOG.md, jest.config.ts
Introduces @frontmcp/utils with naming, uri, path, content, http, fs, escape, serialization, and crypto (node/browser) modules, tests, build/publish config, and consolidated index exports.
Repo root deps & TS paths
package.json, tsconfig.base.json
Adds @noble/hashes and @noble/ciphers deps; introduces @frontmcp/utils path alias in base tsconfig.
Package manifests & build externals
libs/*/package.json, libs/*/project.json, libs/*/tsconfig.lib.json
Adds @frontmcp/utils runtime dependency to multiple packages and marks it external in esbuild; per-package tsconfig paths updated.
CLI: migrate FS helpers & internals
libs/cli/src/**, libs/cli/src/utils/fs.ts
Replaces local FS helpers with imports from @frontmcp/utils (fileExists, readJSON, writeJSON, ensureDir, runCmd), removes local implementations, and tightens resolveEntry behavior.
Adapters: OpenAPI validator
libs/adapters/src/openapi/openapi.utils.ts, .../__tests__/openapi-edge-cases.spec.ts
Removes local validateBaseUrl and imports validateBaseUrl from @frontmcp/utils; tests updated to use external validator.
SDK-wide utility & crypto migrations
libs/sdk/src/** (auth, session, context, flows, transport, prompt, resource, tool, utils barrels)
Replaces many local/node crypto and helper usages (randomUUID, sha256Hex, hmacSha256, base64url helpers, trimSlashes, joinPath, inferMimeType, validateBaseUrl, idFromString) with @frontmcp/utils equivalents; reorganizes and removes several local re-exports.
Errors & exceptions
libs/sdk/src/errors/*, libs/sdk/src/exceptions/*
Adds PublicMcpError subclasses (SessionMissingError, UnsupportedClientVersionError), updates exports, removes legacy exception classes, replaces long ERROR_HANDLING.md with a new README.
Public API / re-exports changed
libs/sdk/src/common/constants.ts, libs/sdk/src/common/index.ts, libs/sdk/src/utils/*.ts, libs/sdk/src/resource/resource.utils.ts, libs/sdk/src/prompt/prompt.utils.ts
Removes several exported constants and many local re-exports (DI helpers, naming/uri/template helpers, withResponseHandler, idFromString), and where applicable delegates to @frontmcp/utils.
SDK utils additions
libs/sdk/src/utils/content.utils.ts, libs/sdk/src/tool/tool.utils.ts
Adds toStructuredContent + ResourceContent types and updates buildResourceContent; adds buildAgentToolDefinitions helper.
Flow & typing updates
libs/sdk/src/auth/flows/oauth.register.flow.ts, libs/sdk/src/auth/flows/oauth.token.flow.ts
Adds DevClientRegistry.get(); extends oauth.register stateSchema with isDev: boolean; updates related typings and imports.
UI package migrations
libs/uipack/src/utils/index.ts, libs/uipack/package.json, libs/uipack/project.json, libs/uipack/tsconfig.lib.json
Re-exports escape/safeJson utilities from @frontmcp/utils, adds dependency and externals, updates tsconfig paths and build dependency.
Tests & lint adjustments
libs/utils/src/**/*.spec.ts, various SDK & adapter tests
Adds extensive unit tests for new utils (crypto, naming, path, content, fs, http), updates existing test imports, and removes some ESLint disables in tests.

Sequence Diagram(s)

sequenceDiagram
    participant Consumer as App (SDK / CLI / Adapter)
    participant Utils as `@frontmcp/utils` (index)
    participant Runtime as Env Detector
    participant Impl as Provider Impl (node/browser)

    Consumer->>Utils: call util (e.g. randomUUID, sha256Hex, validateBaseUrl)
    activate Utils
    Utils->>Runtime: detect environment
    activate Runtime
    Runtime-->>Utils: env (node/browser)
    deactivate Runtime

    Utils->>Impl: delegate call to node/browser provider
    activate Impl
    Impl-->>Utils: result (UUID/hash/URL)
    deactivate Impl

    Utils-->>Consumer: return result
    deactivate Utils
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

Poem

🐰 I hopped through code and stitched a seam,

I gathered hashes, paths and scheme;
A utils burrow, tidy and bright,
Now packages share a single light.
Hop—reused bits take flight!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main objective: extracting utility functions from various modules into a dedicated utils package, which aligns with the substantial changeset adding a new libs/utils package and consolidating utilities across the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 80.49% which is sufficient. The required threshold is 65.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 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 173df43 and 8cddcda.

📒 Files selected for processing (1)
  • libs/utils/src/crypto/__tests__/crypto.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/utils/src/crypto/tests/crypto.spec.ts
⏰ 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). (2)
  • GitHub Check: Build Libraries
  • GitHub Check: Lint & Format Checks

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (9)
libs/utils/src/http/http.ts (1)

21-34: Consider refactoring error handling for clearer control flow.

The error handling logic on lines 29-30 checks if the error message includes 'Unsupported protocol' to re-throw the same error that was just thrown on line 25. While this works, it relies on string matching and could be more explicit.

🔎 Proposed refactor for clearer error handling
 export function validateBaseUrl(url: string): URL {
+  let parsed: URL;
   try {
-    const parsed = new URL(url);
-    if (!['http:', 'https:'].includes(parsed.protocol)) {
-      throw new Error(`Unsupported protocol: ${parsed.protocol}. Only http: and https: are supported.`);
-    }
-    return parsed;
+    parsed = new URL(url);
   } catch (err) {
-    if (err instanceof Error && err.message.includes('Unsupported protocol')) {
-      throw err;
-    }
     throw new Error(`Invalid base URL: ${url}`);
   }
+  
+  if (!['http:', 'https:'].includes(parsed.protocol)) {
+    throw new Error(`Unsupported protocol: ${parsed.protocol}. Only http: and https: are supported.`);
+  }
+  
+  return parsed;
 }

This separates URL parsing errors from protocol validation, making the control flow more explicit and avoiding string-based error matching.

libs/utils/src/naming/naming.ts (1)

24-46: Consider handling consecutive uppercase letters (e.g., acronyms).

The current implementation doesn't split consecutive uppercase letters, so "XMLParser" becomes ["XMLParser"] rather than ["XML", "Parser"]. This is a common edge case in naming utilities.

If this is intentional for simplicity, consider documenting it. If acronym splitting is desired:

🔎 Optional: Handle acronyms like "XMLParser" → ["XML", "Parser"]
 export function splitWords(input: string): string[] {
   const parts: string[] = [];
   let buff = '';
   for (let i = 0; i < input.length; i++) {
     const ch = input[i];
     const isAlphaNum = /[A-Za-z0-9]/.test(ch);
     if (!isAlphaNum) {
       if (buff) {
         parts.push(buff);
         buff = '';
       }
       continue;
     }
-    if (buff && /[a-z]/.test(buff[buff.length - 1]) && /[A-Z]/.test(ch)) {
+    const prevIsLower = buff && /[a-z]/.test(buff[buff.length - 1]);
+    const currIsUpper = /[A-Z]/.test(ch);
+    const nextIsLower = i + 1 < input.length && /[a-z]/.test(input[i + 1]);
+    // Split on: lowercase→uppercase OR uppercase→uppercase+lowercase (acronym end)
+    if (prevIsLower && currIsUpper) {
+      parts.push(buff);
+      buff = ch;
+    } else if (buff.length > 1 && /[A-Z]/.test(buff[buff.length - 1]) && currIsUpper && nextIsLower) {
       parts.push(buff);
       buff = ch;
     } else {
       buff += ch;
     }
   }
   if (buff) parts.push(buff);
   return parts;
 }
libs/sdk/src/auth/flows/oauth.register.flow.ts (1)

195-207: Consider tightening the localhost/IP validation regex.

The current regex /^https?:\/\/(localhost|\d+\.\d+\.\d+\.\d+|127\.0\.0\.1)/ accepts any string matching the IP pattern (e.g., 999.999.999.999). While this is dev-only, consider a stricter pattern if you want to restrict to actual local addresses.

🔎 Optional: Stricter local address validation
-    const bad = redirect_uris.find((u) => !/^https?:\/\/(localhost|\d+\.\d+\.\d+\.\d+|127\.0\.0\.1)/.test(u));
+    // Allow localhost, 127.x.x.x, and common private ranges for dev
+    const localPattern = /^https?:\/\/(localhost|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|10\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d+)?/;
+    const bad = redirect_uris.find((u) => !localPattern.test(u));
libs/utils/src/fs/fs.ts (2)

55-64: Minor: getFs() called only for constant.

getFs() is invoked solely to access fs.constants.F_OK. Consider caching the constant or using the numeric value directly (0) to avoid the extra lazy-load call.

🔎 Optional: Avoid extra getFs() call
 export async function fileExists(p: string): Promise<boolean> {
   try {
-    const fs = getFs();
     const fsp = getFsp();
-    await fsp.access(p, fs.constants.F_OK);
+    await fsp.access(p); // F_OK (0) is the default
     return true;
   } catch {
     return false;
   }
 }

77-85: Consider distinguishing "file not found" from "invalid JSON".

Currently, readJSON returns null for both missing files and JSON parse errors. Callers may need to differentiate these cases. If this is intentional for simplicity, the current behavior is acceptable given the docstring mentions "file doesn't exist or is invalid."

🔎 Optional: Throw on parse errors, return null only for missing files
 export async function readJSON<T = unknown>(jsonPath: string): Promise<T | null> {
+  const fsp = getFsp();
+  let buf: string;
   try {
-    const fsp = getFsp();
-    const buf = await fsp.readFile(jsonPath, 'utf8');
-    return JSON.parse(buf) as T;
-  } catch {
+    buf = await fsp.readFile(jsonPath, 'utf8');
+  } catch (e: unknown) {
+    if ((e as NodeJS.ErrnoException)?.code === 'ENOENT') return null;
+    throw e;
+  }
+  try {
+    return JSON.parse(buf) as T;
+  } catch (e) {
+    throw new Error(`Invalid JSON in ${jsonPath}: ${(e as Error).message}`);
-    return null;
   }
 }
libs/utils/src/uri/uri-validation.ts (1)

2-5: Consider aligning function naming with generic documentation.

The documentation now emphasizes "generic" RFC 3986 compliance and removes MCP-specific references, but the function names still contain "Mcp" (e.g., isValidMcpUri, isValidMcpUriTemplate). This creates a naming/documentation mismatch.

For a shared utils package with generic utilities, consider either:

  1. Keeping MCP in the names and docs if these are MCP-specific validators
  2. Renaming to generic names like isValidUri, isValidUriTemplate with aliases for backward compatibility
libs/sdk/src/errors/README.md (1)

20-50: Add language specification to fenced code block.

The error hierarchy diagram should specify a language identifier (e.g., text or plaintext) for the fenced code block to comply with Markdown best practices.

🔎 Proposed fix
-```
+```text
 McpError (abstract base)
 ├── PublicMcpError (safe to expose to clients)
libs/utils/src/content/content.spec.ts (2)

4-106: Good test coverage for sanitizeToJson.

The tests comprehensively cover the main sanitization cases including primitives, special types, circular references, and nested structures.

Consider adding tests for additional edge cases:

  • RegExp objects
  • URL objects
  • Custom class instances
  • Very deep nesting (to verify no stack overflow)
  • WeakMap/WeakSet (if applicable)

These are optional and depend on whether the utility is expected to handle them.


108-191: Solid coverage for inferMimeType.

The tests effectively cover extension-based and content-based MIME type inference, including edge cases and fallback behavior.

Consider adding tests for additional common formats:

  • Image formats: .gif, .svg, .webp
  • Text formats: .csv, .txt
  • Archive formats: .zip, .tar

These are optional nice-to-haves to improve robustness.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
libs/utils/jest.config.ts (1)

30-37: Coverage thresholds now meet project standards.

The branches threshold has been updated to 95%, resolving the concern from the previous review. All coverage metrics now meet the required 95%+ standard.

libs/utils/src/path/path.ts (1)

18-20: Past review concern addressed, but stricter approach recommended.

The type signature now matches the implementation, resolving the previous type mismatch issue. However, the past review recommended Option 1 (accepting only string and removing the nullish coalescing) as preferred for strict TypeScript mode.

As per coding guidelines, strict TypeScript mode is preferred. The current approach (Option 2) is valid but forces the utility to handle nullish values defensively rather than requiring callers to handle them explicitly.

🔎 Stricter implementation (if nullable input isn't required)
-export function trimSlashes(s: string | null | undefined): string {
-  return (s ?? '').replace(/^\/+|\/+$/g, '');
+export function trimSlashes(s: string): string {
+  return s.replace(/^\/+|\/+$/g, '');
 }

This approach forces callers to handle nullable values explicitly, improving type safety across the codebase.

🧹 Nitpick comments (1)
libs/utils/src/path/path.ts (1)

35-38: LGTM! Clean implementation with comprehensive documentation.

The function correctly handles path joining with proper edge cases. The logic is sound:

  • Trims slashes from each part
  • Filters out empty segments
  • Adds leading slash consistently
  • Returns empty string when no parts remain

Minor nitpick: The g flag in the regex /^\/+|\/+$/g (line 19) is technically unnecessary since the anchors ^ and $ limit matches to beginning/end. However, it's harmless and doesn't affect functionality.

📜 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 5531984 and 175696c.

📒 Files selected for processing (6)
  • libs/sdk/src/common/metadata/agent.metadata.ts
  • libs/utils/jest.config.ts
  • libs/utils/src/crypto/index.ts
  • libs/utils/src/fs/fs.spec.ts
  • libs/utils/src/fs/fs.ts
  • libs/utils/src/path/path.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/utils/src/fs/fs.ts
  • libs/utils/src/fs/fs.spec.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.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/sdk/src/common/metadata/agent.metadata.ts
  • libs/utils/src/path/path.ts
  • libs/utils/jest.config.ts
  • libs/utils/src/crypto/index.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/common/metadata/agent.metadata.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/sdk/src/common/metadata/agent.metadata.ts
  • libs/utils/src/path/path.ts
  • libs/utils/jest.config.ts
  • libs/utils/src/crypto/index.ts
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/**/*.{ts,tsx} : Never import React-free utilities from frontmcp/ui; use frontmcp/uipack for bundling, build tools, platform adapters, and theme utilities
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/bundler/**/*.{ts,tsx} : The bundler module must re-export utilities from frontmcp/uipack/bundler and provide SSR component bundling functionality
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to libs/*/package.json : Each library in /libs/* is independent and publishable under frontmcp/* scope
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/*/index.ts : Implement entry point re-exports in index.ts files for each module (adapters, build, bundler, etc.)
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/**/*.{ts,tsx,js,jsx} : No React dependency in frontmcp/uipack - use frontmcp/ui for React components and hooks
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: FrontMCP is a TypeScript-first schema validation framework - all types should align with MCP protocol definitions
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to libs/sdk/src/**/*.ts : MCP response types should use strict MCP protocol types (GetPromptResult, ReadResourceResult) instead of `unknown`

Applied to files:

  • libs/sdk/src/common/metadata/agent.metadata.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
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/common/metadata/agent.metadata.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to libs/sdk/src/**/*.ts : Validate URIs per RFC 3986 at metadata level using proper validation

Applied to files:

  • libs/utils/src/path/path.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to **/*.ts : Avoid non-null assertions (`!`) - use proper error handling and throw specific errors instead

Applied to files:

  • libs/utils/src/path/path.ts
  • libs/utils/src/crypto/index.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/{adapters,theme,build}/**/*.test.{ts,tsx,js,jsx} : Test component behavior across all platform configurations (OpenAI, Claude, etc.)

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-24T00:41:41.819Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/**/*.test.{ts,tsx} : Test coverage must be 95%+ across statements, branches, functions, and lines

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to **/*.test.{ts,tsx} : Achieve 95%+ test coverage across all metrics (statements, branches, functions, lines)

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-24T00:41:41.819Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/**/*.test.{ts,tsx} : Use React Testing Library for component tests and include SSR/hydration tests for all interactive components

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/{renderers,utils,base-template,tool-template,runtime}/**/*.test.{ts,tsx,js,jsx} : Test HTML escaping for user-provided content in security-critical paths

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to **/*.test.{ts,tsx} : Test all code paths including error cases and constructor validation

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Achieve 95%+ test coverage across statements, branches, functions, and lines

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Ensure all builds complete without TypeScript warnings and 100% test pass rate is required

Applied to files:

  • libs/utils/jest.config.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
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/utils/src/crypto/index.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/*/index.ts : Implement entry point re-exports in index.ts files for each module (adapters, build, bundler, etc.)

Applied to files:

  • libs/utils/src/crypto/index.ts
⏰ 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). (2)
  • GitHub Check: Build Libraries
  • GitHub Check: Lint & Format Checks
🔇 Additional comments (4)
libs/utils/jest.config.ts (1)

1-38: Well-configured Jest setup for the utils package.

The configuration is appropriate for a utility library:

  • testEnvironment: 'node' is correct for non-DOM utilities
  • SWC transformer with TypeScript support and es2022 target
  • transformIgnorePatterns correctly allows transformation of @noble packages (ESM-only dependencies)
  • Coverage directory and thresholds properly configured
libs/sdk/src/common/metadata/agent.metadata.ts (1)

32-32: LGTM: Documentation improvement clarifies declaration merging support.

The added comment accurately documents that this uses an interface to enable TypeScript declaration merging, allowing consumers to augment agent metadata. This clarifies the design decision and aligns with the extensibility requirement mentioned in the JSDoc above.

libs/utils/src/crypto/index.ts (2)

18-33: Past review concern has been addressed.

The non-null assertion issue flagged in previous reviews has been resolved. Lines 29-31 now include explicit null checking with a descriptive error message, following the coding guideline to avoid non-null assertions.


79-119: Past review concern has been addressed.

The parameter validation for AES-GCM functions requested in previous reviews has been fully implemented. Both encryptAesGcm and decryptAesGcm now validate:

  • Key length (32 bytes for AES-256)
  • IV length (12 bytes for optimal GCM security)
  • Tag length (16 bytes for authentication)

The error messages include actual lengths received, which aids debugging.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 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 fba7477 and 173df43.

📒 Files selected for processing (2)
  • libs/utils/src/crypto/__tests__/crypto.spec.ts
  • libs/utils/src/crypto/index.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/utils/src/crypto/__tests__/crypto.spec.ts
  • libs/utils/src/crypto/index.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/utils/src/crypto/__tests__/crypto.spec.ts
  • libs/utils/src/crypto/index.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/bundler/**/*.{ts,tsx} : The bundler module must re-export utilities from frontmcp/uipack/bundler and provide SSR component bundling functionality
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/**/*.{ts,tsx} : Never import React-free utilities from frontmcp/ui; use frontmcp/uipack for bundling, build tools, platform adapters, and theme utilities
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/*/index.ts : Implement entry point re-exports in index.ts files for each module (adapters, build, bundler, etc.)
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/**/*.{ts,tsx,js,jsx} : No React dependency in frontmcp/uipack - use frontmcp/ui for React components and hooks
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to libs/sdk/src/**/index.ts : Export public API through barrel files - export users' needed items, no legacy exports with different names
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to libs/*/package.json : Each library in /libs/* is independent and publishable under frontmcp/* scope
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: FrontMCP is a TypeScript-first schema validation framework - all types should align with MCP protocol definitions
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/{adapters,theme,build}/**/*.test.{ts,tsx,js,jsx} : Test component behavior across all platform configurations (OpenAI, Claude, etc.)
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/{adapters,theme,build}/**/*.test.{ts,tsx,js,jsx} : Test component behavior across all platform configurations (OpenAI, Claude, etc.)

Applied to files:

  • libs/utils/src/crypto/__tests__/crypto.spec.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/{renderers,utils,base-template,tool-template,runtime}/**/*.test.{ts,tsx,js,jsx} : Test HTML escaping for user-provided content in security-critical paths

Applied to files:

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

Applied to files:

  • libs/utils/src/crypto/__tests__/crypto.spec.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
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/utils/src/crypto/index.ts
📚 Learning: 2025-12-24T00:41:55.397Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:55.397Z
Learning: Applies to libs/uipack/src/*/index.ts : Implement entry point re-exports in index.ts files for each module (adapters, build, bundler, etc.)

Applied to files:

  • libs/utils/src/crypto/index.ts
📚 Learning: 2025-12-19T02:04:46.475Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T02:04:46.475Z
Learning: Applies to **/*.ts : Avoid non-null assertions (`!`) - use proper error handling and throw specific errors instead

Applied to files:

  • libs/utils/src/crypto/index.ts
🧬 Code graph analysis (1)
libs/utils/src/crypto/__tests__/crypto.spec.ts (3)
libs/utils/src/crypto/index.ts (12)
  • isNode (224-224)
  • isBrowser (224-224)
  • getCrypto (18-33)
  • randomUUID (40-42)
  • randomBytes (49-54)
  • sha256Hex (66-68)
  • sha256 (59-61)
  • hmacSha256 (73-75)
  • hkdfSha256 (88-96)
  • encryptAesGcm (105-117)
  • decryptAesGcm (127-138)
  • timingSafeEqual (146-151)
libs/utils/src/crypto/node.ts (1)
  • nodeCrypto (30-101)
libs/utils/src/crypto/browser.ts (1)
  • browserCrypto (72-124)
🔇 Additional comments (2)
libs/utils/src/crypto/index.ts (2)

18-151: LGTM! All previous input validation issues have been properly addressed.

The implementation now includes comprehensive input validation:

  • getCrypto(): Explicit error handling without non-null assertions
  • randomBytes(): Validates positive integer length
  • hkdfSha256(): Validates length range (1-8160 bytes)
  • encryptAesGcm(): Validates 32-byte key and 12-byte IV
  • decryptAesGcm(): Validates 32-byte key, 12-byte IV, and 16-byte tag
  • timingSafeEqual(): Validates equal-length arrays

All error messages are descriptive and include actual values, following TypeScript strict mode guidelines without using any or non-null assertions.

As per coding guidelines, the implementation avoids non-null assertions and uses proper error handling with specific error messages.


160-220: LGTM! Encoding utilities are correctly implemented.

The encoding utilities properly handle both Node.js and browser environments:

  • bytesToHex: Simple, correct hex conversion
  • base64urlEncode/base64urlDecode: Correctly handles Buffer (Node) vs btoa/atob (browser)
  • Base64url transformations follow RFC 4648 Section 5 (URL-safe alphabet)
  • sha256Base64url: Useful composition for PKCE flows

The defensive ?? 0 fallback in line 210 is good practice, though codePointAt(0) shouldn't return undefined in normal usage.

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