Skip to content

Add environment variables panel for system diagnostics#1

Merged
jbingham17 merged 1 commit intomainfrom
feature/environment-diagnostics-default
Dec 16, 2025
Merged

Add environment variables panel for system diagnostics#1
jbingham17 merged 1 commit intomainfrom
feature/environment-diagnostics-default

Conversation

@jbingham17
Copy link
Copy Markdown
Contributor

@jbingham17 jbingham17 commented Dec 13, 2025

Summary

This PR adds a new Environment Variables panel to the btop dashboard that displays system environment variables. This feature helps developers quickly understand the runtime environment when debugging issues or verifying configuration.

Changes

  • Server: Added new /api/environment endpoint that returns all environment variables
  • Frontend: Created EnvironmentPanel component with:
    • Displays environment variable names and values
    • Supports filtering via the global filter input
    • Expandable list (shows first 10 by default)
    • Styled consistently with other dashboard panels
  • Styling: Added CSS for the new panel matching existing design system

Screenshots

The new panel appears below the process table and shows environment variables in a clean, scrollable list.

Test plan

  • Start the server with bun run server
  • Start the frontend with bun run dev
  • Verify the Environment Variables panel appears
  • Test filtering works for environment variable names and values
  • Test the "Show all" toggle expands the full list

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new Environment Panel that displays all environment variables.
    • Integrated with the existing filter functionality for case-insensitive searching.
    • Includes expand/collapse toggle when more than 10 variables are present.
    • Shows loading state while fetching environment data.
  • UI/Style

    • Added comprehensive styling for the Environment Panel.

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

Adds a new Environment Variables panel to the dashboard that displays
system environment variables for debugging and diagnostics purposes.
This helps developers understand the runtime environment when
troubleshooting issues.

Changes:
- Add /api/environment endpoint to server
- Create EnvironmentPanel component with filtering support
- Add CSS styles for the new panel
- Integrate panel into main App layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 13, 2025

Walkthrough

A new Environment Panel component was introduced to display server environment variables. The backend exposes a GET /api/environment endpoint, while the frontend component fetches and renders variables with optional filtering and expandable view for large result sets.

Changes

Cohort / File(s) Summary
Backend API
server/index.ts
New GET /api/environment endpoint returns environment variables as JSON with CORS headers
Frontend Component
src/components/EnvironmentPanel.tsx
New React component that fetches environment variables from the API, supports case-insensitive filtering via filter prop, and displays results with expand/collapse toggle for >10 items
Frontend Integration
src/App.tsx
Imports and renders EnvironmentPanel component with filter prop, positioned after ProcessTable
Frontend Styling
src/App.css
Adds complete Environment Panel styling for panel, header, title, count, list, rows, and toggle button with hover states; contains duplicate CSS rule blocks

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EnvironmentPanel
    participant API as /api/environment
    participant Server

    User->>EnvironmentPanel: Mount component
    activate EnvironmentPanel
    EnvironmentPanel->>EnvironmentPanel: Set loading = true
    EnvironmentPanel->>API: GET /api/environment
    activate API
    API->>Server: Request env vars
    Server-->>API: Return all env variables
    deactivate API
    API-->>EnvironmentPanel: JSON array of {name, value}
    EnvironmentPanel->>EnvironmentPanel: Set loading = false<br/>Store variables
    EnvironmentPanel->>EnvironmentPanel: Apply filter (if provided)<br/>Compute memoized results
    EnvironmentPanel-->>User: Display filtered list<br/>(with toggle if >10 items)
    deactivate EnvironmentPanel
    
    User->>EnvironmentPanel: Toggle expand/collapse
    EnvironmentPanel-->>User: Show all / show first 10
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • CSS duplication: src/App.css contains repeated Environment Panel styling blocks that should be consolidated
  • EnvironmentPanel logic: Component integrates fetch, filtering, expansion state, and memoization—verify filtering logic handles edge cases and that error handling (currently silent console.log) is adequate
  • API endpoint security: Confirm whether exposing all environment variables via /api/environment is intentional and necessary
  • Filter integration: Verify filter prop integration and ensure useMemo dependencies are complete

Poem

🐰 A panel springs forth, green and spry,
Fetching secrets from on high,
Variables dance when filters play,
Toggle and scroll the listed display,
More variables bloom with each expand—hop, hooray! 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add environment variables panel for system diagnostics' directly and clearly describes the main change: introducing a new Environment Panel component for displaying environment variables. It accurately summarizes the primary feature addition.
✨ 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 feature/environment-diagnostics-default

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

Copy link
Copy Markdown

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
server/index.ts (1)

260-266: Blocker: /api/environment + Access-Control-Allow-Origin: * enables cross-site secret exfiltration
Right now any website can fetch http://localhost:3001/api/environment from a user’s browser and read all env vars (often includes secrets). Please restrict CORS and redact/guard the endpoint.

Suggested patch (minimal, keeps dev UX):

@@
-    // CORS headers
-    const corsHeaders = {
-      "Access-Control-Allow-Origin": "*",
-      "Access-Control-Allow-Methods": "GET, OPTIONS",
-      "Access-Control-Allow-Headers": "Content-Type",
-    };
+    // CORS headers (avoid "*" to prevent cross-site reads from arbitrary origins)
+    const origin = req.headers.get("Origin");
+    const allowedOrigins = (process.env.BTOP_ALLOWED_ORIGINS ?? "http://localhost:5173")
+      .split(",")
+      .map(s => s.trim())
+      .filter(Boolean);
+    const corsHeaders: Record<string, string> = {
+      "Access-Control-Allow-Methods": "GET, OPTIONS",
+      "Access-Control-Allow-Headers": "Content-Type",
+      ...(origin && allowedOrigins.includes(origin) ? { "Access-Control-Allow-Origin": origin, "Vary": "Origin" } : {}),
+    };
@@
     if (url.pathname === "/api/environment") {
+      if (req.method !== "GET") {
+        return new Response("Method Not Allowed", { status: 405, headers: corsHeaders });
+      }
+      // Disable by default in production unless explicitly enabled
+      if (process.env.NODE_ENV === "production" && process.env.BTOP_EXPOSE_ENV !== "true") {
+        return new Response("Not Found", { status: 404, headers: corsHeaders });
+      }
       // Return environment variables for system diagnostics
-      const envVars = Object.entries(process.env).map(([key, value]) => ({
-        name: key,
-        value: value || "",
-      }));
+      const redact = (name: string) => /(pass(word)?|secret|token|api[_-]?key|private[_-]?key|session|cookie)/i.test(name);
+      const envVars = Object.entries(process.env)
+        .sort(([a], [b]) => a.localeCompare(b))
+        .map(([key, value]) => ({
+          name: key,
+          value: redact(key) ? "<redacted>" : (value ?? ""),
+        }));
       return new Response(JSON.stringify({ variables: envVars }), {
         headers: {
           "Content-Type": "application/json",
           ...corsHeaders,
         },
       });
     }

Also applies to: 290-302

🧹 Nitpick comments (2)
src/App.css (1)

568-673: Consider small-screen responsiveness for fixed .env-name width; also verify no duplicate env-panel blocks

Potential tweak:

@@
 .env-name {
@@
   min-width: 180px;
@@
 }
+
+@media (max-width: 800px) {
+  .env-name { min-width: 120px; }
+}

Quick verification (within this file): ensure there’s only one /* Environment Panel */ block / .env-panel { definition.

src/components/EnvironmentPanel.tsx (1)

56-78: Displaying raw env values is risky; consider masking/reveal UX (even if server redacts)

At minimum, consider masking values by default and revealing on click (per-row), since secrets can still slip through (or be present in non-obvious variable names).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fbfa8e and 735bab6.

📒 Files selected for processing (4)
  • server/index.ts (1 hunks)
  • src/App.css (1 hunks)
  • src/App.tsx (2 hunks)
  • src/components/EnvironmentPanel.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/EnvironmentPanel.tsx (1)
server/index.ts (1)
  • fetch (257-305)
src/App.tsx (1)
src/components/EnvironmentPanel.tsx (1)
  • EnvironmentPanel (12-80)
🔇 Additional comments (1)
src/App.tsx (1)

1-9: EnvironmentPanel integration looks correct (placement + prop wiring)

Also applies to: 72-73

Comment on lines +17 to +32
useEffect(() => {
async function fetchEnvironment() {
try {
const response = await fetch('http://localhost:3001/api/environment');
const data = await response.json();
setEnvVars(data.variables);
} catch (error) {
console.error('Failed to fetch environment variables:', error);
} finally {
setLoading(false);
}
}

fetchEnvironment();
}, []);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid hard-coded API origin; handle non-2xx responses

Suggested patch:

@@
   useEffect(() => {
     async function fetchEnvironment() {
       try {
-        const response = await fetch('http://localhost:3001/api/environment');
+        const apiBase = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3001';
+        const response = await fetch(new URL('/api/environment', apiBase));
+        if (!response.ok) throw new Error(`HTTP ${response.status}`);
         const data = await response.json();
         setEnvVars(data.variables);
       } catch (error) {
         console.error('Failed to fetch environment variables:', error);
       } finally {
         setLoading(false);
       }
     }
📝 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
useEffect(() => {
async function fetchEnvironment() {
try {
const response = await fetch('http://localhost:3001/api/environment');
const data = await response.json();
setEnvVars(data.variables);
} catch (error) {
console.error('Failed to fetch environment variables:', error);
} finally {
setLoading(false);
}
}
fetchEnvironment();
}, []);
useEffect(() => {
async function fetchEnvironment() {
try {
const apiBase = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3001';
const response = await fetch(new URL('/api/environment', apiBase));
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
setEnvVars(data.variables);
} catch (error) {
console.error('Failed to fetch environment variables:', error);
} finally {
setLoading(false);
}
}
fetchEnvironment();
}, []);

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