-
Notifications
You must be signed in to change notification settings - Fork 4
feat: Extract utility functions from various modules into a dedicated utils package #182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
| Status | Scanner | 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.
📝 WalkthroughWalkthroughAdds a new shared package Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
Comment |
There was a problem hiding this 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 accessfs.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,
readJSONreturnsnullfor 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:
- Keeping MCP in the names and docs if these are MCP-specific validators
- Renaming to generic names like
isValidUri,isValidUriTemplatewith aliases for backward compatibilitylibs/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.,
textorplaintext) 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,.tarThese are optional nice-to-haves to improve robustness.
There was a problem hiding this 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
stringand 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
gflag 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
📒 Files selected for processing (6)
libs/sdk/src/common/metadata/agent.metadata.tslibs/utils/jest.config.tslibs/utils/src/crypto/index.tslibs/utils/src/fs/fs.spec.tslibs/utils/src/fs/fs.tslibs/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 noanytypes without strong justification - useunknowninstead 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.tslibs/utils/src/path/path.tslibs/utils/jest.config.tslibs/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 ofunknown
Use specific error classes with MCP error codes instead of generic errors
UsegetCapabilities()method for dynamic capability exposure instead of hardcoding capabilities
UsechangeScopeproperty instead ofscopein 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.tslibs/utils/src/path/path.tslibs/utils/jest.config.tslibs/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.tslibs/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
transformIgnorePatternscorrectly 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
encryptAesGcmanddecryptAesGcmnow 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.
There was a problem hiding this 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
📒 Files selected for processing (2)
libs/utils/src/crypto/__tests__/crypto.spec.tslibs/utils/src/crypto/index.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Use strict TypeScript mode with noanytypes without strong justification - useunknowninstead 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.tslibs/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.tslibs/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 assertionsrandomBytes(): Validates positive integer lengthhkdfSha256(): Validates length range (1-8160 bytes)encryptAesGcm(): Validates 32-byte key and 12-byte IVdecryptAesGcm(): Validates 32-byte key, 12-byte IV, and 16-byte tagtimingSafeEqual(): Validates equal-length arraysAll error messages are descriptive and include actual values, following TypeScript strict mode guidelines without using
anyor 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 conversionbase64urlEncode/base64urlDecode: Correctly handles Buffer (Node) vs btoa/atob (browser)- Base64url transformations follow RFC 4648 Section 5 (URL-safe alphabet)
sha256Base64url: Useful composition for PKCE flowsThe defensive
?? 0fallback in line 210 is good practice, thoughcodePointAt(0)shouldn't return undefined in normal usage.
…ncoding utilities
Summary by CodeRabbit
New Features
Public API
Dependencies
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.