Skip to content

test: add unit tests for CSP utility functions#167

Open
gabrypavanello wants to merge 6 commits intomainfrom
kaizen/2026-02-12
Open

test: add unit tests for CSP utility functions#167
gabrypavanello wants to merge 6 commits intomainfrom
kaizen/2026-02-12

Conversation

@gabrypavanello
Copy link
Contributor

Kaizen 2026-02-12

Adds 16 unit tests for packages/core/src/utils/csp.ts — a previously untested pure utility module.

What's tested

  • generateMcpCSPMetadata — empty config, field mapping, ChatGPT-only field filtering, empty array omission
  • generateOpenAICSPMetadata — snake_case mapping, all 4 CSP fields, empty array omission
  • generateMcpUIMetadata — name fallback from key, description, CSP inclusion/omission, prefersBorder
  • generateOpenAIUIMetadata — widgetCSP with snake_case, domain field, empty CSP omission

Why

Test gap: csp.ts (203 lines, 4 exported functions) had zero test coverage. Pure functions with no side effects — ideal for unit testing.

Build ✅ | Tests ✅ (1669 passing)

Sirius added 6 commits February 10, 2026 09:03
…SK-037-02)

Replace all raw console.log/warn/error calls across 17 inspector/src
files with scoped logger instances using createLogger(). Each module
gets a descriptive source name for log filtering.

- 17 files migrated to structured logger
- Stale eslint-disable no-console comments removed
- Tests updated to match new console.info output format
- bin/mcp-inspector.ts and widget-server-templates.ts untouched
- proxy-resources.ts skipped (console call is in client-side template)
Add comprehensive tests for all 4 exported functions in utils/csp.ts:
- generateMcpCSPMetadata: empty config, field mapping, ChatGPT-only field filtering
- generateOpenAICSPMetadata: snake_case mapping, all 4 CSP fields
- generateMcpUIMetadata: name fallback, description, CSP inclusion/omission, prefersBorder
- generateOpenAIUIMetadata: widgetCSP with snake_case, domain field, empty CSP omission

Covers 16 test cases for previously untested pure utility module.

Kaizen: daily incremental improvement.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Structured logging with ISO timestamps across the application
    • Log level control via MCP_APPS_LOG_LEVEL environment variable (debug/info/warn/error/silent)
  • Tests

    • Added unit tests for CSP and UI metadata generation utilities
    • Added comprehensive logger functionality and environment variable handling tests

Walkthrough

This pull request introduces a structured, level-aware logger module across the codebase, replacing direct console logging with a centralized logger respecting the MCP_APPS_LOG_LEVEL environment variable. The logger supports debug/info/warn/error levels with ISO timestamp prefixes and source tags. All affected modules now route their logs through this logger instead of console.

Changes

Cohort / File(s) Summary
Core Logger Infrastructure
packages/inspector/src/debug/logger.ts, packages/inspector/src/index.ts
Introduces new Logger interface, LogLevel type, createLogger factory, and defaultLogger export. Public API extended to expose logger utilities for external use.
Inspector Module Logging Migration
packages/inspector/src/connection.ts, packages/inspector/src/dashboard/cdp-streamer.ts, packages/inspector/src/dual-server.ts, packages/inspector/src/hosts/..., packages/inspector/src/oauth/..., packages/inspector/src/proxy-tools.ts, packages/inspector/src/session/..., packages/inspector/src/standalone-server.ts, packages/inspector/src/tools/..., packages/inspector/src/widget-*.ts
Systematically replaces console.log/warn/error with logger.info/warn/error across 16 modules. All modules initialize module-scoped loggers with contextual source names. Behavior and control flow unchanged; logging mechanism standardized.
Test Coverage for CSP and UI Metadata
packages/core/tests/unit/utils/csp.test.ts
Adds comprehensive unit tests for generateMcpCSPMetadata, generateOpenAICSPMetadata, generateMcpUIMetadata, and generateOpenAIUIMetadata functions. Tests verify field mappings, empty array handling, snake_case conversions, and metadata generation logic.
Logger Test Suite
packages/inspector/tests/logger.test.ts
Adds 108 lines of tests validating defaultLogger exports, log methods, timestamp formatting, log level gating, MCP_APPS_LOG_LEVEL environment variable handling, and fallback behavior for invalid levels.
Existing Test Updates
packages/inspector/tests/widget-session-manager.test.ts
Updates logging expectations to match new logger behavior, expecting console.info and prefixed log messages with "[widget-session-manager]" context.
Additional Package Logging
packages/codegen/src/watcher.ts, packages/testing/src/eval/mcp/evaluator.ts, packages/ui-react/src/hooks.ts
Introduces level-gated loggers in codegen watcher, testing evaluator, and ui-react hooks. Each replaces inline console calls with module-scoped logger instances, respecting environment-based log level controls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding unit tests for CSP utility functions, which aligns with the primary focus evident in the PR objectives and description.
Description check ✅ Passed The description is directly related to the changeset, providing context about the test coverage gap, the specific functions tested, and build/test results.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 kaizen/2026-02-12

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

@claude
Copy link
Contributor

claude bot commented Feb 12, 2026

Code Review: PR #167 - CSP Utility Tests & Structured Logger Migration

Overview

This PR adds comprehensive unit tests for previously untested CSP utilities and migrates console logging to a structured logger across multiple packages. The changes are well-structured and improve code quality.


✅ Strengths

1. Excellent Test Coverage for CSP Utilities (packages/core/tests/unit/utils/csp.test.ts)

  • 16 comprehensive test cases covering all 4 exported functions
  • Tests cover edge cases: empty configs, empty arrays, field filtering, snake_case mapping
  • Clear test descriptions following the AAA pattern
  • Properly tests protocol-specific behavior (MCP vs OpenAI/ChatGPT)
  • Line 29-37: Good test for ChatGPT-only field filtering in MCP context
  • Line 51-64: Thorough testing of snake_case mapping for OpenAI protocol

2. Clean Structured Logger Implementation (packages/inspector/src/debug/logger.ts)

  • Simple, focused API with level-based gating
  • Environment variable control via MCP_APPS_LOG_LEVEL
  • ISO timestamps for consistency
  • Scoped loggers with source prefixes enable filtering
  • Proper TypeScript types with variadic args support
  • Falls back gracefully to "info" for invalid log levels (line 46)

3. Consistent Logger Migration

  • Systematic replacement of raw console.* calls across 17+ files
  • Removes stale eslint-disable no-console comments
  • Each module gets appropriately scoped logger instances
  • Debug mode (if (this.debug)) pattern preserved throughout

4. Good Test Coverage for Logger (packages/inspector/tests/logger.test.ts)

  • Tests all log levels and suppression behavior
  • Verifies timestamp and prefix formatting
  • Tests environment variable handling and fallback
  • Proper test isolation with beforeEach/afterEach cleanup
  • Tests variadic argument passing (line 99-107)

🔍 Issues & Concerns

1. Logger Level Resolution Timing Issue ⚠️ IMPORTANT

File: packages/inspector/src/debug/logger.ts:57-58

The log level is resolved once when createLogger() is called, meaning environment variable changes after logger creation won't be reflected. This differs from the pattern in packages/codegen/src/watcher.ts:28-31 where level is resolved on each log call.

Impact: In long-running processes or tests that modify process.env.MCP_APPS_LOG_LEVEL, the logger won't respect dynamic level changes.

Recommendation: Either resolve level on each log call OR document this behavior clearly in the JSDoc comment.


2. Inconsistent Logger Pattern (packages/codegen/src/watcher.ts:24-46)

The defaultLogger implementation in watcher.ts uses an IIFE with inline level checking that differs significantly from the new createLogger() factory:

  • Uses inline ok() function with level checking per call
  • Defines LEVELS locally vs. the shared LEVEL_ORDER
  • Missing debug() method entirely

Recommendation: Migrate to use the new createLogger() from inspector package OR extract logger to a shared utility package to ensure consistency.


3. Missing Export in Public API

File: packages/inspector/src/index.ts

The logger module is added but may not be exported in the package's public API.

Question: Should createLogger be part of the inspector package's public API? If yes, add to exports. If no (internal-only), add @internal JSDoc tag.


4. Test Coverage Gap: Logger Edge Cases

While packages/inspector/tests/logger.test.ts is solid, consider adding:

  1. Case sensitivity test: What happens with MCP_APPS_LOG_LEVEL=INFO (uppercase)?
  2. Multiple logger instances: Do they all respect the same environment variable?
  3. Browser environment: Line 39 checks typeof process !== "undefined" but no test verifies browser behavior

📋 Minor Observations

1. Type Imports

Line 8 in csp.test.ts uses type imports correctly - aligns with repo's verbatimModuleSyntax requirement. ✅

2. Logger Variadic Args

The logger uses ...args: unknown[] which is great for flexibility and future-proofs for objects, numbers, etc.


🔒 Security

No security concerns identified. The logger doesn't log sensitive data by default, and CSP utilities correctly filter domains based on protocol requirements.


🎯 Recommendations

Before merging:

  1. CRITICAL: Address the logger level resolution timing issue (either fix or document)
  2. HIGH: Decide on logger consistency strategy across packages
  3. MEDIUM: Clarify whether logger should be in public API
  4. LOW: Add edge case tests for logger

After merging:

  1. Monitor for any logging-related issues in production/testing
  2. Consider extracting logger to a shared package if more packages need it
  3. Update contribution docs to mention the structured logger for new code

✅ Final Verdict

APPROVE with recommendations - The CSP tests are excellent and the logger migration is systematic. The level resolution issue should be addressed (either fixed or documented), but it doesn't block merging if the current behavior is intentional.

Test Quality: ⭐⭐⭐⭐⭐ (5/5)
Code Quality: ⭐⭐⭐⭐ (4/5) - minor consistency issues
Documentation: ⭐⭐⭐ (3/5) - could use more inline docs

Great work on addressing the test coverage gap! 🎉

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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/inspector/src/session/session-renderer.ts (1)

206-219: ⚠️ Potential issue | 🔴 Critical

logger is not available inside page.evaluate() — this will throw ReferenceError at runtime.

The page.evaluate() callback executes in the browser context (Chromium), not in Node.js. The logger variable from the module scope is not serialized or available there. This code will fail with ReferenceError: logger is not defined when the MCP host context update runs.

The same issue exists at lines 255, 286, 303, 312, and 331.

🐛 Proposed fix: revert to console.log inside browser context
   /* eslint-disable no-undef */
   await page.evaluate((ctx: typeof hostContext) => {
     const iframe = document.getElementById("widget-frame") as HTMLIFrameElement | null;
     if (iframe?.contentWindow) {
       const message = {
         jsonrpc: "2.0",
         method: "ui/notifications/host-context-changed",
         params: { hostContext: ctx },
       };
       iframe.contentWindow.postMessage(message, "*");
-      logger.info("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
+      console.log("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
     }
   }, hostContext);
   /* eslint-enable no-undef */

Apply similar changes at lines 255, 286, 303, 312, and 331.

🤖 Fix all issues with AI agents
In `@packages/inspector/src/hosts/mcp-host.ts`:
- Line 222: The embedded Playwright init script returned by
getPlaywrightInitScript() uses logger.info calls that do not exist in the
browser context; update the script string to use console (e.g.,
console.log/console.warn/console.error as appropriate) instead of logger.info at
each occurrence inside the string (the occurrences originally at the logger.info
calls around ui/initialize and the other noted spots). Locate the
getPlaywrightInitScript() method and replace those in-string logger.* references
with console.* so the code runs in the browser context without ReferenceError.

In `@packages/inspector/src/hosts/openai-host.ts`:
- Around line 248-249: The injected script returned by getPlaywrightInitScript
contains a browser-side call to logger (see the requestDisplayMode block), but
logger is a Node-only variable and will cause a ReferenceError in the Playwright
page; replace the logger usage with console.log (or remove the log) inside the
template so the browser-executed code uses the global console instead of the
undefined logger. Ensure the change targets the getPlaywrightInitScript()
template string where requestDisplayMode returns { mode: mode } and references
logger.

In `@packages/inspector/src/oauth/preset-config.ts`:
- Around line 397-400: The catch block that logs the authorization URL currently
uses logger.info which can be filtered out by MCP_APPS_LOG_LEVEL; update the
catch handler where browser auto-open is attempted to emit the URL with
console.log (or logger.warn) instead of logger.info so users always see the
fallback URL (replace the logger.info(`\nOpen this URL... ${urlStr}\n`) call
with console.log(...) keeping the same message/format).

In `@packages/inspector/src/widget-session-manager.ts`:
- Line 412: The calls to logger inside page.evaluate are invalid because logger
is a Node-side module not available in the browser context; locate the
page.evaluate(...) callbacks (references: page.evaluate used where messages are
sent such as the MCP/OpenAI host ui/notifications and synced events) and replace
those logger.info calls with console.log/console.info (or remove the logging)
inside the evaluate callback so the code runs in the Playwright browser context
without ReferenceError; ensure you update all occurrences that the reviewer
listed (the evaluate blocks that emit "[MCP Host] Sent
ui/notifications/host-context-changed", "[OpenAI Host] Sent globals sync:",
"[MCP Host] Stored hostContext update...", "[MCP Host] Sent synced event:",
"[OpenAI Host] Sent synced event:") to use console instead of logger.

In `@packages/ui-react/src/hooks.ts`:
- Around line 22-40: The check for process in the uiReactLogger factory is
triggering ESLint because accessing process.env inside the ternary can be
transformed by bundlers; update the envLevel calculation in uiReactLogger to
avoid direct property access on process by using safe optional chaining or a
guarded accessor (e.g. use process?.env?.MCP_APPS_LOG_LEVEL or wrap the
retrieval in a try/catch/helper function), leaving ts, LEVELS, threshold and ok
as-is so the logger still computes the threshold correctly.
🧹 Nitpick comments (1)
packages/codegen/src/watcher.ts (1)

24-46: Consider consolidating with existing logger utility.

This file introduces a new structured logger while packages/codegen/src/utils/logger.ts already exports a defaultLogger with a different format ([mcp-apps-plugin] ${message} vs the new timestamped format). This creates:

  1. Inconsistent log formats within the same package — some modules will log with timestamps and level tags, others won't
  2. Duplicate logger implementations to maintain

If the goal is to migrate to structured logging, consider updating the centralized utils/logger.ts to support the new format and reusing it here, rather than defining a parallel logger.

// Handle ui/initialize request
if (message && message.jsonrpc === '2.0' && message.method === 'ui/initialize') {
console.log('[MCP Host Emulator] Received ui/initialize, responding...');
logger.info('[MCP Host Emulator] Received ui/initialize, responding...');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: logger is not available in Playwright init script browser context.

The getPlaywrightInitScript() method returns a JavaScript string that executes in the Playwright browser context. The logger.info(...) calls embedded in this string template (lines 222, 247, 251, 280) reference a logger variable that doesn't exist in the browser—only console is available there.

This will cause ReferenceError: logger is not defined when the init script runs.

🐛 Proposed fix: use console.log in the init script string
               // Line 222
-                logger.info('[MCP Host Emulator] Received ui/initialize, responding...');
+                console.log('[MCP Host Emulator] Received ui/initialize, responding...');
               // Line 247
-                logger.info('[MCP Host Emulator] Sent ui/initialize response');
+                console.log('[MCP Host Emulator] Sent ui/initialize response');
                 // Line 251
-                  logger.info('[MCP Host Emulator] Sending ui/notifications/tool-result...');
+                  console.log('[MCP Host Emulator] Sending ui/notifications/tool-result...');
                   // Line 280
-                  logger.info('[MCP Host Emulator] Display mode changed to:', requestedMode, 'sizing:', sizing);
+                  console.log('[MCP Host Emulator] Display mode changed to:', requestedMode, 'sizing:', sizing);

Also applies to: 247-247, 251-251, 280-280

🤖 Prompt for AI Agents
In `@packages/inspector/src/hosts/mcp-host.ts` at line 222, The embedded
Playwright init script returned by getPlaywrightInitScript() uses logger.info
calls that do not exist in the browser context; update the script string to use
console (e.g., console.log/console.warn/console.error as appropriate) instead of
logger.info at each occurrence inside the string (the occurrences originally at
the logger.info calls around ui/initialize and the other noted spots). Locate
the getPlaywrightInitScript() method and replace those in-string logger.*
references with console.* so the code runs in the browser context without
ReferenceError.

Comment on lines +248 to 249
logger.info('[OpenAI Host] requestDisplayMode:', mode, 'sizing:', sizing);
return { mode: mode };
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: logger is undefined in Playwright browser context.

Line 248 is inside the getPlaywrightInitScript() template string that gets injected into the browser page. The logger variable only exists in the Node.js context — it won't be defined when this JavaScript executes in the browser, causing a ReferenceError.

This should use console.log (or be removed entirely) since it's browser-side code:

🐛 Proposed fix
-            logger.info('[OpenAI Host] requestDisplayMode:', mode, 'sizing:', sizing);
+            console.log('[OpenAI Host] requestDisplayMode:', mode, 'sizing:', sizing);
📝 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
logger.info('[OpenAI Host] requestDisplayMode:', mode, 'sizing:', sizing);
return { mode: mode };
console.log('[OpenAI Host] requestDisplayMode:', mode, 'sizing:', sizing);
return { mode: mode };
🤖 Prompt for AI Agents
In `@packages/inspector/src/hosts/openai-host.ts` around lines 248 - 249, The
injected script returned by getPlaywrightInitScript contains a browser-side call
to logger (see the requestDisplayMode block), but logger is a Node-only variable
and will cause a ReferenceError in the Playwright page; replace the logger usage
with console.log (or remove the log) inside the template so the browser-executed
code uses the global console instead of the undefined logger. Ensure the change
targets the getPlaywrightInitScript() template string where requestDisplayMode
returns { mode: mode } and references logger.

Comment on lines 397 to 400
} catch {
// If browser open fails, log the URL for manual copy
// eslint-disable-next-line no-console
console.log(`\nOpen this URL in your browser to authorize:\n ${urlStr}\n`);
logger.info(`\nOpen this URL in your browser to authorize:\n ${urlStr}\n`);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

User-facing fallback message may be filtered by log level.

This message provides the authorization URL when browser auto-open fails — it's critical for CLI users to complete OAuth. Using logger.info subjects it to MCP_APPS_LOG_LEVEL filtering. If the level is set to warn or higher, users won't see the URL they need to manually open.

Consider using console.log directly (as it was before) or logger.warn to ensure visibility, since this is a user-facing fallback rather than debug output.

🔧 Suggested fix
     } catch {
       // If browser open fails, log the URL for manual copy
-      logger.info(`\nOpen this URL in your browser to authorize:\n  ${urlStr}\n`);
+      // Use warn level to ensure visibility even with elevated log levels
+      logger.warn(`\nOpen this URL in your browser to authorize:\n  ${urlStr}\n`);
     }
🤖 Prompt for AI Agents
In `@packages/inspector/src/oauth/preset-config.ts` around lines 397 - 400, The
catch block that logs the authorization URL currently uses logger.info which can
be filtered out by MCP_APPS_LOG_LEVEL; update the catch handler where browser
auto-open is attempted to emit the URL with console.log (or logger.warn) instead
of logger.info so users always see the fallback URL (replace the
logger.info(`\nOpen this URL... ${urlStr}\n`) call with console.log(...) keeping
the same message/format).

iframe.contentWindow.postMessage(message, "*");
// eslint-disable-next-line no-console
console.log("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
logger.info("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: logger is not available inside page.evaluate() browser context.

The logger object is a Node.js module-level variable, but page.evaluate() executes code in the Playwright browser context where logger doesn't exist. These calls will throw ReferenceError: logger is not defined at runtime.

The original console.log calls worked because console exists in both Node.js and browser contexts. You should revert these specific lines to use console.log/console.info or remove the logging from within page.evaluate() callbacks entirely.

Affected locations:

  • Line 412: logger.info("[MCP Host] Sent ui/notifications/host-context-changed"...)
  • Line 442: logger.info("[OpenAI Host] Sent globals sync:"...)
  • Line 747: logger.info("[MCP Host] Stored hostContext update...")
  • Line 760: logger.info("[MCP Host] Sent synced event:"...)
  • Line 796: logger.info("[OpenAI Host] Sent synced event:"...)
🐛 Proposed fix: revert to console.log inside page.evaluate
         // Line 412
-            logger.info("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
+            console.log("[MCP Host] Sent ui/notifications/host-context-changed", ctx);
         // Line 442
-            logger.info("[OpenAI Host] Sent globals sync:", message.data);
+            console.log("[OpenAI Host] Sent globals sync:", message.data);
         // Line 747
-          logger.info("[MCP Host] Stored hostContext update for ui/initialize:", p);
+          console.log("[MCP Host] Stored hostContext update for ui/initialize:", p);
         // Line 760
-          logger.info("[MCP Host] Sent synced event:", m, p);
+          console.log("[MCP Host] Sent synced event:", m, p);
         // Line 796
-        logger.info("[OpenAI Host] Sent synced event:", message.syncType, message.data);
+        console.log("[OpenAI Host] Sent synced event:", message.syncType, message.data);

Also applies to: 442-442, 747-747, 760-760, 796-796

🤖 Prompt for AI Agents
In `@packages/inspector/src/widget-session-manager.ts` at line 412, The calls to
logger inside page.evaluate are invalid because logger is a Node-side module not
available in the browser context; locate the page.evaluate(...) callbacks
(references: page.evaluate used where messages are sent such as the MCP/OpenAI
host ui/notifications and synced events) and replace those logger.info calls
with console.log/console.info (or remove the logging) inside the evaluate
callback so the code runs in the Playwright browser context without
ReferenceError; ensure you update all occurrences that the reviewer listed (the
evaluate blocks that emit "[MCP Host] Sent
ui/notifications/host-context-changed", "[OpenAI Host] Sent globals sync:",
"[MCP Host] Stored hostContext update...", "[MCP Host] Sent synced event:",
"[OpenAI Host] Sent synced event:") to use console instead of logger.

Comment on lines +22 to +40
// Lightweight scoped logger (mirrors inspector's createLogger, avoids cross-package dep)
const uiReactLogger = (() => {
const source = "ui-react:hooks";
const ts = () => new Date().toISOString();
const LEVELS: Record<string, number> = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
// eslint-disable-next-line no-undef, @typescript-eslint/no-unnecessary-condition
const envLevel =
typeof process !== "undefined"
? ((process.env?.MCP_APPS_LOG_LEVEL as string | undefined) ?? "").toLowerCase()
: "";
const threshold: number = LEVELS[envLevel] ?? 1; // 1 = info
const ok = (l: string): boolean => (LEVELS[l] ?? 1) >= threshold;
return {
// eslint-disable-next-line no-console
warn: (...args: unknown[]) => {
if (ok("warn")) console.warn(`${ts()} [WARN] [${source}]`, ...args);
},
};
})();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

ESLint flags process as undefined — guard needs adjustment.

The static analysis reports 'process' is not defined on line 30. While you have typeof process !== "undefined" check, accessing process.env inside the ternary can still cause issues in some bundler configurations where process is stripped entirely.

Consider using optional chaining on the environment access:

🔧 Suggested fix
-  // eslint-disable-next-line no-undef, `@typescript-eslint/no-unnecessary-condition`
-  const envLevel =
-    typeof process !== "undefined"
-      ? ((process.env?.MCP_APPS_LOG_LEVEL as string | undefined) ?? "").toLowerCase()
-      : "";
+  // eslint-disable-next-line no-undef
+  const envLevel = (
+    typeof process !== "undefined" && typeof process.env !== "undefined"
+      ? ((process.env.MCP_APPS_LOG_LEVEL as string | undefined) ?? "")
+      : ""
+  ).toLowerCase();

Alternatively, wrap the entire access in a try-catch to handle edge cases where bundlers transform process checks unexpectedly.

🧰 Tools
🪛 ESLint

[error] 30-30: 'process' is not defined.

(no-undef)

🤖 Prompt for AI Agents
In `@packages/ui-react/src/hooks.ts` around lines 22 - 40, The check for process
in the uiReactLogger factory is triggering ESLint because accessing process.env
inside the ternary can be transformed by bundlers; update the envLevel
calculation in uiReactLogger to avoid direct property access on process by using
safe optional chaining or a guarded accessor (e.g. use
process?.env?.MCP_APPS_LOG_LEVEL or wrap the retrieval in a try/catch/helper
function), leaving ts, LEVELS, threshold and ok as-is so the logger still
computes the threshold correctly.

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.

1 participant