Skip to content

Dev tazi 002#2

Merged
swoosh1337 merged 4 commits intomainfrom
dev-tazi-002
Aug 15, 2025
Merged

Dev tazi 002#2
swoosh1337 merged 4 commits intomainfrom
dev-tazi-002

Conversation

@swoosh1337
Copy link
Collaborator

@swoosh1337 swoosh1337 commented Aug 13, 2025

Summary by CodeRabbit

  • New Features

    • Chat can render diagrams (Mermaid/React Flow) inline and fullscreen, and generate visuals on demand.
    • Interactive algorithm demos via a new canvas modal.
    • Problem Solver UI revamped with tabs, improved example/test-case rendering, and clearer results.
    • Python runner supports linked-list (ListNode) inputs/outputs.
    • Friendlier error messages and normalized JSON outputs.
  • Chores

    • Robust dev start script; pre-commit hook with secrets scan and formatting.
    • Scripts to reset/backfill test cases; database migrations to JSON fields with seeded data.
    • Added diagram/runtime dependencies.
  • Style

    • Updated favicon and social images.

@coderabbitai
Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

Adds JSON-native test case handling end-to-end (DB migrations, server parsing, backfill/reset scripts), enhances Python executor with ListNode scaffolding and I/O normalization, introduces diagram generation/visualization (Mermaid/React Flow) across edge function, hook, and UI, adds interactive component compiler/modal, development scripts, and formatting/linting tooling.

Changes

Cohort / File(s) Summary
Code Executor API
code-executor-api/server.js
Expands test-case JSON support, robust legacy parsing, ListNode scaffolding/injection, runner generation for ListNode I/O, output normalization, and detailed logging.
AI Edge Function (Diagrams & Snippets)
supabase/functions/ai-chat/index.ts
Extends request/response types to carry diagrams and visualization, adds React Flow validation, Mermaid support, Responses API helpers, refined snippet insertion flow, and chat clear action.
DB Migrations & Seed SQL
supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql, supabase/migrations/20250111000001_replace_test_cases_with_json.sql, scripts/reset-test-cases.sql
Adds input_json/expected_json columns with GIN indexes, functions to migrate/backfill from legacy text, and bulk inserts of JSON-backed test cases (notes a malformed JSON line in one insert).
Data Backfill/Seed Scripts
scripts/backfill-json-test-cases.js, scripts/reset-test-cases.js
Node scripts to parse legacy inputs, backfill JSON fields, reset and verify seeded test cases via Supabase.
Dev/Tooling Scripts
scripts/dev-start.sh, .husky/pre-commit, scripts/check-secrets.sh
Hardened dev start (health checks, env bootstrap, parallel API/frontend), pre-commit formatting and secrets scan, and a secrets checker.
Diagram Components
src/components/diagram/Mermaid.tsx, src/components/diagram/FlowCanvas.tsx, src/components/diagram/mermaid.d.ts
Adds Mermaid renderer with dynamic import/fallbacks and error handling, React Flow canvas with minimap/controls, and minimal TS typings for Mermaid.
Canvas Runtime (Interactive Demos)
src/components/canvas/CanvasModal.tsx, src/components/canvas/ComponentCompiler.tsx, src/components/canvas/CanvasContainer.tsx, src/components/canvas/index.tsx
Fullscreen modal, client-side component compiler via Babel standalone, and container wiring for live previews with error boundaries.
Chat Hook & UI
src/hooks/useChatSession.ts, src/components/AIChat.tsx
Adds diagram payload types/guards, requestDiagram flow, storage/rendering of diagrams, and fullscreen diagram overlay; AIChat accepts optional problem context.
Problem Solver Page
src/pages/ProblemSolver.tsx
Refactors insertion to backend-driven flow, typed Monaco operations with highlight, reworked tabs/layout, unified value renderer, and updated test results UI.
Types
src/types/index.ts
Introduces FlowGraph/edges/nodes types; extends ChatMessage with optional diagram and suggestDiagram.
Tooling & Assets
package.json, index.html
Adds formatting/typecheck scripts and diagram/runtime deps; updates favicon/social meta paths.

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant UI as Frontend (AIChat/ProblemSolver)
  participant H as useChatSession
  participant F as Supabase Edge (ai-chat)
  participant L as LLM

  U->>UI: Click "Visualize"
  UI->>H: requestDiagram(sourceText, problem?)
  H->>F: POST /ai-chat { diagram: true, preferredEngines, problem?, message? }
  F->>L: Prompt for diagram (ReactFlow→Mermaid fallback)
  L-->>F: Diagram payload (graph/code)
  F-->>H: { diagram, suggestDiagram?, diagramDebug? }
  H-->>UI: Store message with diagram
  UI-->>U: Render inline + Expand overlay
Loading
sequenceDiagram
  participant FE as Frontend
  participant API as code-executor-api
  participant DB as Supabase (test_cases)
  participant PY as Python Runner

  FE->>API: Run tests for problem
  API->>DB: SELECT test_cases (input_json/expected_json, fallbacks)
  DB-->>API: Rows
  API->>API: Parse inputs (JSON or legacy)
  API->>PY: Generate runner (inject ListNode if needed) + execute
  PY-->>API: Results (stdout/stderr/status)
  API->>API: Normalize outputs (JSON/string), map errors/timeouts
  API-->>FE: Test results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Dev tazi 001 #1 — Also modifies code-executor-api/server.js around test-case parsing and comparison logic; overlaps with this PR’s executor/test-case changes.

Poem

I nibble on graphs with whiskers bright,
Sketching flows in moonlit byte,
Lists entwine—nodes in a chain,
JSON seeds sprout after rain.
With taps and hops I press “Run” true—
Diagrams bloom, green checks accrue.
Thump! A happy merge for you. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev-tazi-002

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

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

🔭 Outside diff range comments (1)
src/pages/ProblemSolver.tsx (1)

165-194: Critical issue: No fallback for AI placement failure.

The code now exclusively relies on backend GPT-guided insertion without any local fallback. If the backend fails, users are left with an error message and no code insertion capability.

Consider adding a local fallback mechanism for better user experience:

 if (!newCodeFromBackend) {
+  // Fallback to simple cursor-based insertion
+  try {
+    const lines = currentCode.split('\n');
+    lines.splice(cursorPosition.line + 1, 0, snippet.code);
+    newCodeFromBackend = lines.join('\n');
+    insertedAtLine = cursorPosition.line + 1;
+    console.log('🔄 Using local fallback insertion');
+  } catch (fallbackError) {
     toast.error('AI placement failed. Please try again.');
     return;
+  }
 }
♻️ Duplicate comments (1)
src/components/AIChat.tsx (1)

250-268: Duplicate comment: Type casting issue for React Flow diagrams

Same type casting issue exists for React Flow diagrams as mentioned for Mermaid diagrams.

🧹 Nitpick comments (16)
scripts/dev-start.sh (2)

48-56: Unused variable flagged by shellcheck.

The loop variable i is flagged as unused in the health check loops, but this is a false positive as it's used implicitly in the range iteration for retry logic.

To silence the shellcheck warning while maintaining readability, you could replace the variable with an underscore:

-for i in {1..60}; do
+for _ in {1..60}; do

64-72: Apply the same unused variable fix for consistency.

Similar to the API health check loop, the frontend readiness loop also triggers the same shellcheck warning.

Apply the same fix for consistency:

-for i in {1..60}; do
+for _ in {1..60}; do
src/pages/ProblemSolver.tsx (1)

223-230: Type assertion for Monaco Range construction.

The Monaco Range construction uses type assertions to satisfy TypeScript, which is necessary but could be more robust.

Consider a more type-safe approach:

-const Monaco = (window as unknown as { monaco?: { Range: new (startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number) => unknown } }).monaco;
+const Monaco = (window as any).monaco;
+if (!Monaco?.Range) {
+  console.warn('Monaco Range not available, skipping highlight');
+  return;
+}
 const decorations = editor.deltaDecorations([], [{
-  range: new (Monaco as { Range: new (a: number, b: number, c: number, d: number) => unknown }).Range(
+  range: new Monaco.Range(
     Math.max(1, result.newCursorPosition.line - snippet.code.split('\n').length + 2),
     1,
     result.newCursorPosition.line + 1,
     result.newCursorPosition.column + 1
   ),
code-executor-api/server.js (1)

814-823: Consider more specific error messages for debugging

The friendly error messages are helpful, but they could be more specific. For example, the timeout message could suggest checking for infinite loops specifically in while loops with ListNode traversal.

-      if (/time limit exceeded|timeout/i.test(statusDesc)) {
-        friendlyError = 'Execution timed out. For pointer-based problems, ensure pointers advance each iteration (e.g., ptr1 = ptr1.next or ptr2 = ptr2.next).';
+      if (/time limit exceeded|timeout/i.test(statusDesc)) {
+        const hasListNode = problemId && problemId.includes('list');
+        friendlyError = hasListNode 
+          ? 'Execution timed out. Check for infinite loops in ListNode traversal - ensure all pointers advance (e.g., current = current.next) and have proper termination conditions.'
+          : 'Execution timed out. Check for infinite loops, ensure loop variables are properly incremented, and verify termination conditions.';
src/components/diagram/FlowCanvas.tsx (1)

11-11: Consider making height prop more flexible

The height prop accepts number | string but the default is a string. Consider standardizing to always use strings with units for consistency.

-  height?: number | string;
+  height?: string;

Then update line 20 to handle the prop consistently:

-      <div className="rounded-lg overflow-hidden border border-accent/30 bg-background" style={{ height }}>
+      <div className="rounded-lg overflow-hidden border border-accent/30 bg-background" style={{ height: typeof height === 'number' ? `${height}px` : height }}>
scripts/reset-test-cases.sql (1)

1-58: Add file newline for proper Git handling

The file is missing a newline at the end, which can cause issues with some Git operations and text editors.

Add a newline character at the end of the file after line 58.

supabase/migrations/20250111000001_replace_test_cases_with_json.sql (1)

112-112: Missing newline at end of file.

The file should end with a newline character for POSIX compliance and better compatibility with version control systems.

Add a newline at the end of the file.

scripts/reset-test-cases.js (1)

38-40: Remove misleading comment about JSONB columns.

The comment on line 40 is misleading as the script doesn't actually add JSONB columns - it only logs that they're being added. The actual column creation happens in the SQL migration.

-    // Add JSONB columns (ignore if already exist)
-    console.log('🔧 Adding JSONB columns...');
-    // Note: We'll handle this through raw SQL if needed, but columns might already exist
+    // Note: JSONB columns are added via SQL migrations
scripts/backfill-json-test-cases.js (1)

22-98: Consider simplifying the complex parsing logic.

The parseLegacyInput function has high cyclomatic complexity with nested conditions and manual string parsing. Consider breaking it down into smaller helper functions for better maintainability.

Example refactor:

+function splitByCommaOutsideQuotesAndBrackets(inputString) {
+  const parts = [];
+  let current = '';
+  let bracketDepth = 0;
+  let insideQuotes = false;
+  
+  for (let i = 0; i < inputString.length; i++) {
+    const char = inputString[i];
+    
+    if (char === '"' && inputString[i-1] !== '\\') {
+      insideQuotes = !insideQuotes;
+    } else if (!insideQuotes) {
+      if (char === '[' || char === '{') bracketDepth++;
+      else if (char === ']' || char === '}') bracketDepth--;
+    }
+    
+    if (char === ',' && !insideQuotes && bracketDepth === 0) {
+      parts.push(current.trim());
+      current = '';
+    } else {
+      current += char;
+    }
+  }
+  if (current.trim()) parts.push(current.trim());
+  return parts;
+}
+
+function parseParameterValue(value) {
+  const cleanValue = value.trim();
+  try {
+    return JSON.parse(cleanValue);
+  } catch {
+    // Remove quotes if it's a quoted string
+    return cleanValue.replace(/^"(.*)"$/, '$1');
+  }
+}

 function parseLegacyInput(inputString, functionSignature) {
   // ... existing parameter extraction logic ...
   
   if (inputString.includes(' = ')) {
-    // Split by comma but handle arrays properly
-    const parts = [];
-    let current = '';
-    let bracketDepth = 0;
-    let insideQuotes = false;
-    
-    for (let i = 0; i < inputString.length; i++) {
-      const char = inputString[i];
-      
-      if (char === '"' && inputString[i-1] !== '\\') {
-        insideQuotes = !insideQuotes;
-      } else if (!insideQuotes) {
-        if (char === '[' || char === '{') bracketDepth++;
-        else if (char === ']' || char === '}') bracketDepth--;
-      }
-      
-      if (char === ',' && !insideQuotes && bracketDepth === 0) {
-        parts.push(current.trim());
-        current = '';
-      } else {
-        current += char;
-      }
-    }
-    if (current.trim()) parts.push(current.trim());
+    const parts = splitByCommaOutsideQuotesAndBrackets(inputString);
     
     console.log('Split into parts:', parts);
     
     for (const part of parts) {
       if (part.includes(' = ')) {
         const [paramName, paramValue] = part.split(' = ', 2);
         const cleanParamName = paramName.trim();
-        const cleanParamValue = paramValue.trim();
-        
-        try {
-          inputParams[cleanParamName] = JSON.parse(cleanParamValue);
-        } catch {
-          // Remove quotes if it's a quoted string
-          inputParams[cleanParamName] = cleanParamValue.replace(/^"(.*)"$/, '$1');
-        }
+        inputParams[cleanParamName] = parseParameterValue(paramValue);
       }
     }
   }
   // ... rest of the function
 }
src/components/diagram/Mermaid.tsx (3)

35-37: Consider more explicit error handling for dynamic imports.

The fallback chain for importing Mermaid is good, but consider logging which import succeeded for debugging purposes.

-        const mod: any = await import('mermaid/dist/mermaid.esm.min.mjs')
-          .catch(() => import('mermaid/dist/mermaid.esm.mjs'))
-          .catch(() => import('mermaid'));
+        let mod: any;
+        try {
+          mod = await import('mermaid/dist/mermaid.esm.min.mjs');
+          console.debug('Loaded mermaid from esm.min.mjs');
+        } catch {
+          try {
+            mod = await import('mermaid/dist/mermaid.esm.mjs');
+            console.debug('Loaded mermaid from esm.mjs');
+          } catch {
+            mod = await import('mermaid');
+            console.debug('Loaded mermaid from package entry');
+          }
+        }

50-50: Consider using Tailwind classes for error message styling.

For consistency with the dark mode requirement, use Tailwind classes directly instead of inline classes in the error message HTML.

-          containerRef.current.innerHTML = '<div class="text-destructive text-xs">Failed to render diagram</div>';
+          const errorDiv = document.createElement('div');
+          errorDiv.className = 'text-destructive text-xs dark:text-destructive-foreground';
+          errorDiv.textContent = 'Failed to render diagram';
+          containerRef.current.innerHTML = '';
+          containerRef.current.appendChild(errorDiv);

67-68: Remove extra blank lines at end of file.

Multiple blank lines at the end of the file should be reduced to a single newline.

Remove the extra blank lines (67-68) and keep only one newline at the end.

src/hooks/useChatSession.ts (2)

123-130: Consider using a proper database type definition.

Instead of defining DbMessage inline, consider using generated types from your database schema for better type safety.

Consider using Supabase's type generation or a shared types file for database response types:

// In a types file or generated from Supabase
export interface DatabaseMessage {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  created_at: string;
  session_id: string;
  code_snippets?: CodeSnippet[] | null;
}

336-336: Consider adding descriptive content for diagram messages.

The assistant message for diagrams has an empty content field, which might confuse users viewing the chat history.

         content: '',
+        content: diagramPayload.title || `Generated ${diagramPayload.engine} diagram`,
src/components/AIChat.tsx (2)

29-29: Move type definition outside component scope

The ActiveDiagram type is defined inside the component function. This should be moved to the top of the file or to a types file for better maintainability and reusability.

Apply this diff to move the type definition outside the component:

+type ActiveDiagram = { engine: 'mermaid'; code: string } | { engine: 'reactflow'; graph: FlowGraph };
+
 const AIChat = ({ problemId, problemDescription, onInsertCodeSnippet, problemTestCases }: AIChatProps) => {
   const [input, setInput] = useState('');
   const scrollAreaRef = useRef<HTMLDivElement>(null);
-  type ActiveDiagram = { engine: 'mermaid'; code: string } | { engine: 'reactflow'; graph: FlowGraph };
   const [isDiagramOpen, setIsDiagramOpen] = useState(false);

191-191: Add explicit type annotation for ReactMarkdown component props

The code prop in the ReactMarkdown components object uses inline type annotations which could be improved by extracting to a proper type definition.

Consider extracting the type definition for better type safety:

type CodeComponentProps = {
  inline?: boolean;
  className?: string;
  children?: React.ReactNode;
  [key: string]: any;
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78c162a and 2a9361d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • code-executor-api/server.js (11 hunks)
  • package.json (3 hunks)
  • scripts/backfill-json-test-cases.js (1 hunks)
  • scripts/dev-start.sh (1 hunks)
  • scripts/reset-test-cases.js (1 hunks)
  • scripts/reset-test-cases.sql (1 hunks)
  • src/components/AIChat.tsx (8 hunks)
  • src/components/diagram/FlowCanvas.tsx (1 hunks)
  • src/components/diagram/Mermaid.tsx (1 hunks)
  • src/components/diagram/mermaid.d.ts (1 hunks)
  • src/hooks/useChatSession.ts (7 hunks)
  • src/pages/ProblemSolver.tsx (10 hunks)
  • src/types/index.ts (1 hunks)
  • supabase/functions/ai-chat/index.ts (10 hunks)
  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql (1 hunks)
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql (1 hunks)
  • test-connection.js (0 hunks)
  • test-dynamic-problems.js (0 hunks)
  • test-judge0.js (0 hunks)
  • test-leetcode-style.js (0 hunks)
  • test-supabase-integration.js (0 hunks)
💤 Files with no reviewable changes (5)
  • test-judge0.js
  • test-dynamic-problems.js
  • test-leetcode-style.js
  • test-connection.js
  • test-supabase-integration.js
🧰 Additional context used
📓 Path-based instructions (5)
src/types/index.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Define and use the CodeSnippet interface in src/types/index.ts for typed code snippet objects

Files:

  • src/types/index.ts
{src/components/**/*.tsx,tailwind.config.ts}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Ensure all UI components are compatible with dark mode using Tailwind CSS dark mode classes and custom color variables defined in tailwind.config.ts

Files:

  • src/components/diagram/FlowCanvas.tsx
  • src/components/diagram/Mermaid.tsx
  • src/components/AIChat.tsx
src/components/AIChat.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/components/AIChat.tsx: AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons
Use react-markdown with react-syntax-highlighter and @tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Files:

  • src/components/AIChat.tsx
supabase/functions/ai-chat/index.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Files:

  • supabase/functions/ai-chat/index.ts
src/pages/ProblemSolver.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/pages/ProblemSolver.tsx: In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs
Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Files:

  • src/pages/ProblemSolver.tsx
🧠 Learnings (12)
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/migrations/20250106000001_add_code_snippets_to_messages.sql : Add code_snippets JSONB column to messages table in supabase/migrations/20250106000001_add_code_snippets_to_messages.sql with proper indexing for performance

Applied to files:

  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/migrations/20250807224236_create_notes_table.sql : Create notes table with user-specific notes linked to problem IDs, automatic timestamps, RLS policies, and unique constraint per user-problem in supabase/migrations/20250807224236_create_notes_table.sql

Applied to files:

  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : Use react-markdown with react-syntax-highlighter and tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Applied to files:

  • src/components/AIChat.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs

Applied to files:

  • src/components/AIChat.tsx
  • supabase/functions/ai-chat/index.ts
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeSnippetButton.tsx : Reusable CodeSnippetButton component in src/components/CodeSnippetButton.tsx should provide visual loading states, success feedback, and integrate with insertion callbacks

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/functions/ai-chat/index.ts : Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Applied to files:

  • supabase/functions/ai-chat/index.ts
  • src/hooks/useChatSession.ts
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/utils/codeInsertion.ts : Implement smart code insertion logic in src/utils/codeInsertion.ts, including function scope detection, indentation matching, and insertion point analysis

Applied to files:

  • supabase/functions/ai-chat/index.ts
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Use React Hooks extensively for state management throughout the application

Applied to files:

  • src/hooks/useChatSession.ts
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeEditor.tsx : Monaco code editor in src/components/CodeEditor.tsx must support custom themes synced with system dark mode, Vim mode via monaco-vim, and auto-save with visual indicators

Applied to files:

  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Resizable panel management with keyboard shortcuts (Ctrl/Cmd+B/J/L) must be implemented for left, bottom, and right panels

Applied to files:

  • src/pages/ProblemSolver.tsx
🧬 Code Graph Analysis (8)
scripts/backfill-json-test-cases.js (1)
code-executor-api/server.js (9)
  • supabase (38-38)
  • i (250-250)
  • i (335-335)
  • i (451-451)
  • lines (221-221)
  • lines (441-441)
  • line (235-235)
  • line (452-452)
  • testCases (118-122)
src/components/diagram/FlowCanvas.tsx (1)
src/types/index.ts (1)
  • FlowGraph (63-63)
src/components/AIChat.tsx (3)
src/types/index.ts (1)
  • FlowGraph (63-63)
src/components/diagram/Mermaid.tsx (1)
  • Mermaid (26-65)
src/components/diagram/FlowCanvas.tsx (1)
  • FlowCanvas (14-32)
scripts/reset-test-cases.js (2)
scripts/backfill-json-test-cases.js (2)
  • __filename (8-8)
  • __dirname (9-9)
code-executor-api/server.js (2)
  • __filename (10-10)
  • __dirname (11-11)
code-executor-api/server.js (3)
scripts/backfill-json-test-cases.js (4)
  • testCases (118-133)
  • supabase (14-17)
  • i (49-49)
  • i (87-87)
scripts/reset-test-cases.js (1)
  • supabase (15-18)
src/integrations/supabase/client.ts (1)
  • supabase (11-17)
supabase/functions/ai-chat/index.ts (1)
src/types/index.ts (5)
  • FlowNode (61-61)
  • FlowEdge (62-62)
  • FlowGraph (63-63)
  • ChatMessage (65-84)
  • CodeSnippet (45-56)
src/hooks/useChatSession.ts (4)
src/types/index.ts (3)
  • CodeSnippet (45-56)
  • ChatMessage (65-84)
  • FlowGraph (63-63)
scripts/backfill-json-test-cases.js (1)
  • supabase (14-17)
code-executor-api/server.js (1)
  • supabase (38-38)
scripts/reset-test-cases.js (1)
  • supabase (15-18)
src/pages/ProblemSolver.tsx (1)
src/components/ui/sonner.tsx (1)
  • toast (29-29)
🪛 Shellcheck (0.10.0)
scripts/dev-start.sh

[warning] 65-65: i appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (41)
src/components/diagram/mermaid.d.ts (1)

2-13: LGTM! Well-defined TypeScript declarations for Mermaid.

The type definitions provide appropriate typing for the Mermaid library's core functionality used in the diagram components. The interface covers the essential configuration options and methods needed for initialization and rendering.

scripts/dev-start.sh (2)

3-3: LGTM! Proper error handling configuration.

The set -euo pipefail directive ensures the script exits on errors, undefined variables, and pipe failures, providing robust error handling.


20-25: LGTM! Proper cleanup handling with signal trapping.

The cleanup function and trap setup ensure background processes are terminated gracefully when the script exits, preventing orphaned processes.

src/types/index.ts (2)

58-63: LGTM! Well-structured React Flow diagram types.

The diagram type definitions provide clear interfaces for React Flow components with appropriate property types. The separation of concerns between nodes, edges, and the overall graph structure is well designed.


72-84: LGTM! Flexible diagram union type design.

The diagram property uses a discriminated union pattern that allows for multiple diagram engines (Mermaid and React Flow) while maintaining type safety. The optional suggestDiagram flag provides good UX control for diagram generation.

supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql (6)

5-7: LGTM! Proper column additions with backward compatibility.

Adding JSONB columns while keeping legacy text columns ensures a smooth migration path and backward compatibility during the transition period.


9-11: LGTM! Appropriate indexing for JSON queries.

GIN indexes on JSONB columns are the correct choice for efficient querying of JSON data structures, providing good performance for both containment and existence operations.


32-48: Robust parameter extraction logic.

The regex-based parameter extraction correctly handles function signatures and excludes self parameters. The approach using string manipulation and array operations is appropriate for the PostgreSQL environment.


60-91: Sophisticated array parsing with bracket counting.

The algorithm properly handles comma-separated parameters that contain arrays by counting brackets to determine when a parameter segment is complete. This prevents incorrect splitting on commas within array literals.


100-107: Proper JSON parsing with graceful fallback.

The exception handling ensures that values are parsed as JSON when possible, but gracefully falls back to string representation when JSON parsing fails, providing robust data migration.


140-164: Efficient backfill procedure with progress logging.

The backfill function processes rows systematically and provides progress feedback through NOTICE statements, making the migration process transparent and monitorable.

src/pages/ProblemSolver.tsx (8)

16-16: LGTM! Added useCallback import for optimization.

The addition of useCallback to the import list supports the memoization of panel toggle functions, which is good for performance optimization.


31-38: LGTM! Properly typed editor ref interface.

The explicit interface definition for the code editor ref provides clear typing for Monaco editor methods, improving type safety and IDE support.


55-71: LGTM! Optimized panel toggle functions with useCallback.

The use of useCallback with proper dependency arrays prevents unnecessary re-renders and follows React best practices for performance optimization.


104-104: LGTM! Complete dependency array for useEffect.

Including all the toggle callbacks in the dependency array ensures the effect updates correctly when the callbacks change, preventing stale closure issues.


195-203: LGTM! Improved cursor positioning logic.

The cursor positioning calculation properly accounts for multi-line snippets and provides a reasonable fallback when insertion line information is not available.


312-332: LGTM! Improved renderValue function with compact JSON formatting.

The function properly handles different data types and provides consistent compact JSON formatting that aligns with the UI requirements. The fallback handling for JSON parsing is robust.


419-428: LGTM! Enhanced example display with proper formatting.

The use of pre blocks and renderValue function provides consistent formatting for inputs and outputs in problem examples, improving readability.


648-664: LGTM! Consistent formatting in test results.

The application of renderValue to test inputs, expected outputs, and actual outputs ensures consistent formatting across all test result displays.

code-executor-api/server.js (2)

379-433: Excellent comprehensive ListNode support implementation!

The implementation properly handles:

  • Automatic detection of ListNode problems via function signature analysis
  • Addition of ListNode class definition and helper functions when needed
  • Clean separation of imports, ListNode scaffolding, and user code
  • Proper code restructuring for classes with self parameters

This provides seamless support for LeetCode-style linked list problems.


610-633: Good addition of ListNode helpers in test harness

The embedded ListNode class and helper functions ensure that generated test execution code can handle linked list inputs/outputs independently of the user's code. This provides redundancy and ensures tests run correctly even if the user's ListNode implementation is incomplete.

supabase/functions/ai-chat/index.ts (3)

298-316: Good React Flow validation implementation

The validateFlowGraph function provides comprehensive validation including:

  • Type checking for nodes and edges arrays
  • Validation of required node properties (id, position, data.label)
  • Validation of required edge properties (id, source, target)
  • Duplicate ID detection

This ensures that only valid React Flow graphs are accepted.


625-650: Smart anchor-based insertion logic

The anchor-based insertion is a clever optimization that:

  1. Finds exact matches of the first line
  2. Checks if the snippet is already present
  3. Preserves indentation from the matched line
  4. Falls back to LLM-based placement if anchor not found

This deterministic approach reduces LLM calls and improves insertion accuracy.


789-796: Clean diagram-only response path

When a diagram is explicitly requested, the code efficiently:

  1. Generates the diagram with forced=true
  2. Provides appropriate explanation text based on engine type
  3. Returns early without unnecessary snippet analysis

This optimizes performance for diagram-specific requests.

package.json (2)

55-55: Good library choices for diagram support

The addition of mermaid (v10.9.1) and reactflow (v11.10.0) are solid choices:

  • Both are mature, well-maintained libraries
  • They provide complementary visualization capabilities (declarative vs interactive)
  • Version choices are recent stable releases

Also applies to: 68-68


8-8: dev:all script is executable and portable
The scripts/dev-start.sh file exists with -rwxr-xr-x permissions, includes a proper #!/usr/bin/env bash shebang, and contains no Windows-specific commands. No changes needed.

scripts/reset-test-cases.sql (1)

7-9: ALTER TABLE idempotence confirmed – no action required

The ADD COLUMN IF NOT EXISTS input_json jsonb, expected_json jsonb in scripts/reset-test-cases.sql matches earlier migrations and won’t error if the columns already exist. Both columns are consistently defined as jsonb in:

  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql

Data types align, so the idempotent guard is sufficient.

supabase/migrations/20250111000001_replace_test_cases_with_json.sql (3)

1-3: LGTM!

The comment clearly describes the migration intent to replace existing test cases with a clean JSON structure.


8-10: LGTM!

The ALTER TABLE statement correctly adds the JSON columns with IF NOT EXISTS clause, preventing errors if columns already exist.


12-14: LGTM!

GIN indexes are appropriate for JSONB columns and will improve query performance.

scripts/reset-test-cases.js (2)

1-1: LGTM!

Proper shebang for Node.js scripts.


148-153: LGTM!

Good verification logic that shows sample data and validates the insertion with proper error handling.

scripts/backfill-json-test-cases.js (1)

177-180: Good summary output!

The migration summary with success/error counts and total is helpful for monitoring the migration process.

src/components/diagram/Mermaid.tsx (2)

11-24: LGTM!

Good security configuration with securityLevel: 'strict' to mitigate XSS risks when rendering user-provided diagrams.


42-42: Good sanitization approach for bracketed labels.

The regex pattern correctly handles newlines within bracketed labels to prevent parser errors, which is a common issue with Mermaid diagrams.

src/hooks/useChatSession.ts (1)

3-3: LGTM!

The FlowGraph import aligns with the new diagram functionality requirements.

src/components/AIChat.tsx (5)

182-183: Good implementation of dark mode compatibility

The updated dark mode classes for user and assistant message bubbles correctly use Tailwind's dark mode utilities with appropriate border and background colors, ensuring proper visibility in both light and dark themes.


188-188: Correct dark mode prose styling applied

The dark:prose-invert class ensures proper text visibility in dark mode for the Markdown content, which aligns with the coding guidelines.


193-197: Excellent integration of Mermaid diagrams in Markdown

The implementation correctly detects Mermaid code blocks and renders them using the Mermaid component. This seamless integration within the Markdown rendering flow provides a great user experience.


215-219: Correct list styling with proper dark mode support

The list styles (list-disc, list-decimal, list-outside) with appropriate padding ensure proper formatting and readability in both light and dark modes, aligning with the requirement to use react-markdown with proper formatting.


294-340: Code snippet rendering implementation looks good

The code snippet cards with syntax highlighting, insertion buttons, and proper styling are well-implemented and align with the requirements for dedicated code snippet cards with 'Add to Editor' functionality.

Copy link

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

🔭 Outside diff range comments (1)
src/pages/ProblemSolver.tsx (1)

165-193: Critical: No fallback for backend insertion failure.

The code now requires backend GPT-guided insertion to succeed, but there's no fallback mechanism when the backend fails. This creates a poor user experience where snippet insertion completely fails if the backend is unavailable or returns an error.

According to the coding guidelines, the handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion. Consider implementing a local fallback strategy that at least attempts basic insertion at the cursor position when the backend fails.

Consider adding a local fallback:

 if (!newCodeFromBackend) {
-  toast.error('AI placement failed. Please try again.');
-  return;
+  // Fallback to simple insertion at cursor
+  console.warn('Using fallback insertion at cursor position');
+  const lines = currentCode.split('\n');
+  const beforeLines = lines.slice(0, cursorPosition.line);
+  const currentLine = lines[cursorPosition.line] || '';
+  const beforeCursor = currentLine.slice(0, cursorPosition.column);
+  const afterCursor = currentLine.slice(cursorPosition.column);
+  const afterLines = lines.slice(cursorPosition.line + 1);
+  
+  const insertedLines = snippet.code.split('\n');
+  const newLines = [
+    ...beforeLines,
+    beforeCursor + insertedLines[0],
+    ...insertedLines.slice(1),
+    afterCursor,
+    ...afterLines
+  ];
+  
+  newCodeFromBackend = newLines.join('\n');
+  insertedAtLine = cursorPosition.line;
+  toast.warning('Using basic insertion. Position may not be optimal.');
 }
♻️ Duplicate comments (11)
scripts/reset-test-cases.sql (1)

56-56: Fix JSON syntax error in test case

Line 56 has an extra quote that creates invalid JSON: {"s": "()[]{}""}

-((SELECT id FROM problems WHERE id = 'valid-parentheses'), 's = "()[]{}"', 'true',
- '{"s": "()[]{}""}', 'true', false),
+((SELECT id FROM problems WHERE id = 'valid-parentheses'), 's = "()[]{}"', 'true',
+ '{"s": "()[]{}"}', 'true', false),
scripts/backfill-json-test-cases.js (1)

14-17: Add validation for required environment variables

The script uses SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY without checking if they exist, which could lead to cryptic errors.

+if (!process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
+  console.error('❌ Missing required environment variables: SUPABASE_URL and/or SUPABASE_SERVICE_ROLE_KEY');
+  process.exit(1);
+}
+
 const supabase = createClient(
   process.env.SUPABASE_URL,
   process.env.SUPABASE_SERVICE_ROLE_KEY
 );
supabase/migrations/20250111000001_replace_test_cases_with_json.sql (2)

5-5: Data loss warning: No backup strategy for existing test cases.

This migration deletes all existing test cases without creating a backup. This could lead to unrecoverable data loss if rollback is needed.


54-54: Fix invalid JSON syntax in test data.

Line 54 contains malformed JSON with an extra quote: '{"s": "()[]{}""}' should be '{"s": "()[]{}"}'.

Apply this fix:

- '{"s": "()[]{}""}', 'true', false),
+ '{"s": "()[]{}"}', 'true', false),
src/components/AIChat.tsx (4)

78-82: Add error handling for diagram generation requests.

The handleVisualize function lacks error handling for the async requestDiagram call, which could lead to unhandled promise rejections.

Add proper error handling:

 const handleVisualize = async (sourceMessageContent: string, messageId: string) => {
   // Request a diagram separately without adding a user message bubble
   setHiddenVisualizeForIds(prev => new Set(prev).add(messageId));
-  await requestDiagram(sourceMessageContent);
+  try {
+    await requestDiagram(sourceMessageContent);
+  } catch (error) {
+    console.error('Failed to generate diagram:', error);
+    // Remove from hidden set to allow retry
+    setHiddenVisualizeForIds(prev => {
+      const newSet = new Set(prev);
+      newSet.delete(messageId);
+      return newSet;
+    });
+  }
 };

229-247: Fix type safety issues with diagram payload access.

The repeated type casting (message as unknown as { diagram?: ... }) indicates missing proper TypeScript definitions for the diagram field in ChatMessage.

Update the ChatMessage type to properly include the diagram field and remove unsafe type assertions.


273-293: Extract complex inline logic to improve maintainability.

The complex logic for determining when to show the Visualize button is embedded in JSX, reducing readability and testability.

Consider extracting this logic into a separate helper function for better maintainability.


436-453: Add accessibility features to fullscreen dialog.

The custom fullscreen overlay lacks proper accessibility features like focus management, ARIA attributes, and keyboard navigation.

Implement proper accessibility:

  • Add dialog semantics (role="dialog", aria-modal="true")
  • Include focus management and keyboard event handling (ESC key)
  • Add proper ARIA labels and descriptions
  • Ensure focus trapping within the modal
code-executor-api/server.js (2)

151-178: Validate both JSON columns before using JSON-native path.

The code doesn't validate that both input_json and expected_json are non-null before using them, which could lead to issues if only one column is populated.

Update the condition to ensure both columns are present:

- // Prefer JSON columns if available
- if (tc.input_json && tc.expected_json) {
+ // Prefer JSON columns if available (both must be present)
+ if (tc.input_json !== null && tc.expected_json !== null) {

239-298: Protect bracket depth tracking from underflow.

The bracket depth counters can go negative when unmatched closing brackets are encountered, potentially causing incorrect parsing behavior.

Guard against underflow:

         } else if (char === ']' && !insideQuotes) {
           current += char;
-          squareBracketDepth--;
-          bracketDepth--;
+          squareBracketDepth = Math.max(0, squareBracketDepth - 1);
+          bracketDepth = Math.max(0, bracketDepth - 1);

Apply similar changes to all closing bracket handlers.

supabase/functions/ai-chat/index.ts (1)

69-155: Complex model routing logic needs simplification.

The unified LLM caller has complex nested conditions and type casting that makes it hard to maintain. Consider extracting model-specific request builders and response parsers into separate functions.

The complex inline request construction and response parsing makes this function difficult to maintain and test.

🧹 Nitpick comments (6)
src/pages/ProblemSolver.tsx (2)

195-203: Type safety improvement needed for result object.

The result object construction is verbose and could benefit from a proper type definition to ensure type safety and maintainability.

Consider extracting the result type:

+interface InsertionResult {
+  newCode: string;
+  newCursorPosition: {
+    line: number;
+    column: number;
+  };
+}
+
-const result: { newCode: string; newCursorPosition: { line: number; column: number } } = {
+const result: InsertionResult = {
   newCode: newCodeFromBackend,
   newCursorPosition: {
     line: typeof insertedAtLine === 'number' && insertedAtLine >= 0
       ? insertedAtLine + (snippet.code.split('\n').length - 1)
       : cursorPosition.line,
     column: 0
   }
 };

149-242: Consider adding debug logs as per coding guidelines.

According to the coding guidelines, handleInsertCodeSnippet must include debugging logs for the Monaco editor manipulation. While there are some console.log statements, consider adding more comprehensive debugging for cursor positioning and visual highlighting operations.

Add more detailed debugging logs:

 setTimeout(() => {
   const newPosition = {
     lineNumber: result.newCursorPosition.line + 1,
     column: result.newCursorPosition.column + 1
   };
   
+  console.log('🎯 Setting cursor position:', newPosition);
   editor.setPosition(newPosition);
   editor.focus();
+  console.log('✨ Editor focused');
   
   // Add temporary highlight
   const Monaco = (window as unknown as { monaco?: { Range: new (startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number) => unknown } }).monaco;
+  const highlightRange = {
+    start: Math.max(1, result.newCursorPosition.line - snippet.code.split('\n').length + 2),
+    end: result.newCursorPosition.line + 1
+  };
+  console.log('🎨 Adding highlight range:', highlightRange);
   const decorations = editor.deltaDecorations([], [{
scripts/dev-start.sh (2)

49-56: Unused loop variable in readiness check

The loop variable i is declared but never used in the API readiness check loop. While this doesn't affect functionality, it can be cleaned up.

-for i in {1..60}; do
+for _ in {1..60}; do

65-72: Unused loop variable in readiness check

Similar to the API readiness check, the loop variable i is declared but never used here.

-for i in {1..60}; do
+for _ in {1..60}; do
supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql (1)

61-61: Inefficient array reconstruction logic

The current approach of splitting by comma and then reconstructing based on bracket counting is inefficient. Consider using a single-pass parser instead.

Here's a more efficient single-pass approach:

-      -- Simple split for now - can be enhanced with proper bracket counting
-      parts := string_to_array(input_text, ',');
-      
-      -- Try to reconstruct split parameters that got broken by commas in arrays
-      DECLARE
-        reconstructed_parts text[] := '{}';
-        current_part text := '';
-        bracket_count int := 0;
-        i int;
-      BEGIN
-        FOR i IN 1..array_length(parts, 1) LOOP
-          current_part := current_part || CASE WHEN current_part = '' THEN '' ELSE ',' END || parts[i];
-          
-          -- Count brackets to determine if we're inside an array
-          bracket_count := bracket_count + 
-            (length(parts[i]) - length(replace(parts[i], '[', ''))) -
-            (length(parts[i]) - length(replace(parts[i], ']', '')));
-          
-          -- If brackets are balanced and we have an equals sign, this is a complete parameter
-          IF bracket_count = 0 AND current_part ~ '=' THEN
-            reconstructed_parts := reconstructed_parts || current_part;
-            current_part := '';
-          END IF;
-        END LOOP;
-        
-        -- Add any remaining part
-        IF current_part != '' THEN
-          reconstructed_parts := reconstructed_parts || current_part;
-        END IF;
-        
-        parts := reconstructed_parts;
-      END;
+      -- Parse parameters with proper bracket/quote handling in a single pass
+      DECLARE
+        parts text[] := '{}';
+        current_part text := '';
+        bracket_count int := 0;
+        in_quotes boolean := false;
+        i int;
+        ch char;
+      BEGIN
+        FOR i IN 1..length(input_text) LOOP
+          ch := substr(input_text, i, 1);
+          
+          -- Handle quotes
+          IF ch = '"' AND (i = 1 OR substr(input_text, i-1, 1) != '\') THEN
+            in_quotes := NOT in_quotes;
+          END IF;
+          
+          -- Track bracket depth when not in quotes
+          IF NOT in_quotes THEN
+            IF ch IN ('[', '{') THEN
+              bracket_count := bracket_count + 1;
+            ELSIF ch IN (']', '}') THEN
+              bracket_count := bracket_count - 1;
+            END IF;
+          END IF;
+          
+          -- Split on comma when not nested and not in quotes
+          IF ch = ',' AND bracket_count = 0 AND NOT in_quotes THEN
+            IF current_part ~ '=' THEN
+              parts := parts || trim(current_part);
+            END IF;
+            current_part := '';
+          ELSE
+            current_part := current_part || ch;
+          END IF;
+        END LOOP;
+        
+        -- Add the last part
+        IF current_part != '' AND current_part ~ '=' THEN
+          parts := parts || trim(current_part);
+        END IF;
+      END;
scripts/backfill-json-test-cases.js (1)

77-81: Consider preserving boolean values during parsing

The current implementation converts all non-JSON-parseable values to strings. Boolean values like true and false should be preserved as booleans.

 try {
   inputParams[cleanParamName] = JSON.parse(cleanParamValue);
 } catch {
-  // Remove quotes if it's a quoted string
-  inputParams[cleanParamName] = cleanParamValue.replace(/^"(.*)"$/, '$1');
+  // Handle booleans and remove quotes from strings
+  if (cleanParamValue === 'true') {
+    inputParams[cleanParamName] = true;
+  } else if (cleanParamValue === 'false') {
+    inputParams[cleanParamName] = false;
+  } else {
+    // Remove quotes if it's a quoted string
+    inputParams[cleanParamName] = cleanParamValue.replace(/^"(.*)"$/, '$1');
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a9361d and 3ff3bd5.

📒 Files selected for processing (16)
  • code-executor-api/server.js (11 hunks)
  • package.json (2 hunks)
  • scripts/backfill-json-test-cases.js (1 hunks)
  • scripts/dev-start.sh (1 hunks)
  • scripts/reset-test-cases.js (1 hunks)
  • scripts/reset-test-cases.sql (1 hunks)
  • src/components/AIChat.tsx (8 hunks)
  • src/components/diagram/FlowCanvas.tsx (1 hunks)
  • src/components/diagram/Mermaid.tsx (1 hunks)
  • src/components/diagram/mermaid.d.ts (1 hunks)
  • src/hooks/useChatSession.ts (7 hunks)
  • src/pages/ProblemSolver.tsx (11 hunks)
  • src/types/index.ts (1 hunks)
  • supabase/functions/ai-chat/index.ts (10 hunks)
  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql (1 hunks)
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/types/index.ts
  • src/components/diagram/mermaid.d.ts
  • src/hooks/useChatSession.ts
  • src/components/diagram/Mermaid.tsx
  • scripts/reset-test-cases.js
  • src/components/diagram/FlowCanvas.tsx
🧰 Additional context used
📓 Path-based instructions (4)
{src/components/**/*.tsx,tailwind.config.ts}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Ensure all UI components are compatible with dark mode using Tailwind CSS dark mode classes and custom color variables defined in tailwind.config.ts

Files:

  • src/components/AIChat.tsx
src/components/AIChat.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/components/AIChat.tsx: AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons
Use react-markdown with react-syntax-highlighter and @tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Files:

  • src/components/AIChat.tsx
src/pages/ProblemSolver.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/pages/ProblemSolver.tsx: In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs
Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Files:

  • src/pages/ProblemSolver.tsx
supabase/functions/ai-chat/index.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Files:

  • supabase/functions/ai-chat/index.ts
🧠 Learnings (11)
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/migrations/20250106000001_add_code_snippets_to_messages.sql : Add code_snippets JSONB column to messages table in supabase/migrations/20250106000001_add_code_snippets_to_messages.sql with proper indexing for performance

Applied to files:

  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/migrations/20250807224236_create_notes_table.sql : Create notes table with user-specific notes linked to problem IDs, automatic timestamps, RLS policies, and unique constraint per user-problem in supabase/migrations/20250807224236_create_notes_table.sql

Applied to files:

  • supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql
  • supabase/migrations/20250111000001_replace_test_cases_with_json.sql
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : Use react-markdown with react-syntax-highlighter and tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Applied to files:

  • src/components/AIChat.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
  • supabase/functions/ai-chat/index.ts
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeSnippetButton.tsx : Reusable CodeSnippetButton component in src/components/CodeSnippetButton.tsx should provide visual loading states, success feedback, and integrate with insertion callbacks

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeEditor.tsx : Monaco code editor in src/components/CodeEditor.tsx must support custom themes synced with system dark mode, Vim mode via monaco-vim, and auto-save with visual indicators

Applied to files:

  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Resizable panel management with keyboard shortcuts (Ctrl/Cmd+B/J/L) must be implemented for left, bottom, and right panels

Applied to files:

  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/utils/codeInsertion.ts : Implement smart code insertion logic in src/utils/codeInsertion.ts, including function scope detection, indentation matching, and insertion point analysis

Applied to files:

  • src/pages/ProblemSolver.tsx
  • supabase/functions/ai-chat/index.ts
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/functions/ai-chat/index.ts : Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Applied to files:

  • supabase/functions/ai-chat/index.ts
🧬 Code Graph Analysis (5)
src/components/AIChat.tsx (3)
src/types/index.ts (1)
  • FlowGraph (63-63)
src/components/diagram/Mermaid.tsx (1)
  • Mermaid (26-65)
src/components/diagram/FlowCanvas.tsx (1)
  • FlowCanvas (14-32)
code-executor-api/server.js (3)
scripts/backfill-json-test-cases.js (11)
  • testCases (118-133)
  • supabase (14-17)
  • i (49-49)
  • i (87-87)
  • parts (44-44)
  • current (45-45)
  • insideQuotes (47-47)
  • bracketDepth (46-46)
  • char (50-50)
  • lines (86-86)
  • params (32-35)
scripts/reset-test-cases.js (1)
  • supabase (15-18)
src/integrations/supabase/client.ts (1)
  • supabase (11-17)
scripts/backfill-json-test-cases.js (1)
code-executor-api/server.js (23)
  • supabase (38-38)
  • paramMatch (205-205)
  • paramMatch (549-549)
  • params (212-215)
  • params (550-553)
  • inputParams (219-219)
  • parts (243-243)
  • current (244-244)
  • i (252-252)
  • i (337-337)
  • i (453-453)
  • paramName (304-304)
  • paramName (322-322)
  • paramName (338-338)
  • paramValue (339-339)
  • cleanParamName (305-305)
  • cleanParamName (323-323)
  • cleanParamValue (306-306)
  • lines (222-222)
  • lines (443-443)
  • line (237-237)
  • line (454-454)
  • testCases (119-123)
src/pages/ProblemSolver.tsx (6)
src/hooks/useAuth.ts (1)
  • useAuth (5-41)
src/hooks/useProblems.ts (1)
  • useProblems (34-188)
src/types/index.ts (1)
  • TestResult (6-14)
src/components/ui/sonner.tsx (1)
  • toast (29-29)
code-executor-api/server.js (2)
  • result (84-84)
  • problem (104-108)
src/components/ui/tabs.tsx (2)
  • Tabs (53-53)
  • TabsContent (53-53)
supabase/functions/ai-chat/index.ts (1)
src/types/index.ts (5)
  • FlowNode (61-61)
  • FlowEdge (62-62)
  • FlowGraph (63-63)
  • ChatMessage (65-84)
  • CodeSnippet (45-56)
🪛 Shellcheck (0.10.0)
scripts/dev-start.sh

[warning] 65-65: i appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (34)
src/pages/ProblemSolver.tsx (6)

55-59: LGTM! Proper memoization of toggle functions.

The toggle functions are correctly wrapped with useCallback to prevent unnecessary re-renders. The dependency arrays are appropriately set to their respective state values.

Also applies to: 61-65, 67-71


104-104: LGTM! Correct dependencies for keyboard shortcuts.

The effect dependencies now properly include all state values and memoized callbacks, ensuring the keyboard shortcuts always work with the current state.


312-332: LGTM! Clean renderValue implementation.

The renderValue function provides consistent formatting for various data types, properly handling JSON-like strings and objects with compact one-line output. This aligns well with the test results display requirements.


383-544: Notes component integration verified.

The Notes component is correctly integrated into the ProblemSolver tabs as required by the coding guidelines, replacing the static textarea with the dynamic component. The implementation properly passes the problemId for persistent storage per user per problem.


415-440: renderValue usage in examples is appropriate.

The examples section properly uses the renderValue function to display inputs and outputs in pre blocks, ensuring consistent formatting across the UI.


648-665: Test results rendering uses renderValue consistently.

The test results section correctly uses renderValue for inputs, expected outputs, and actual outputs, maintaining consistent formatting throughout the component.

package.json (1)

57-57: Dependencies Verified: mermaid@10.9.1 & reactflow@11.10.0 Compatible with React 18.3.1

Both packages support React 18 out of the box (React Flow’s v11 line runs on React 17+ and mermaid is framework-agnostic). No breaking peer-dependency concerns were found.

• Ensure you’re using react-dom@18.3.1 alongside react@18.3.1
• If you encounter any peer-dependency errors, align the versions or use npm’s legacy-peer-deps flag temporarily

supabase/migrations/20250111000000_add_json_columns_to_test_cases.sql (1)

1-18: Well-structured migration with proper backward compatibility

The migration correctly adds JSONB columns while preserving legacy text columns, includes appropriate GIN indexes for JSON query performance, and provides clear documentation via column comments.

scripts/backfill-json-test-cases.js (1)

49-65: Well-implemented bracket-aware string splitting

The parsing logic correctly handles nested arrays and objects while respecting quote boundaries. This approach ensures that comma-separated parameters containing arrays or objects are not incorrectly split.

src/components/AIChat.tsx (6)

4-4: LGTM: Proper icon imports for diagram functionality.

Good addition of DiagramIcon (ChartNetwork alias) and Maximize2 icons to support the new diagram visualization features.


11-13: LGTM: Well-structured diagram component imports.

The imports for Mermaid, FlowCanvas, and FlowGraph types are properly organized and follow the established component structure.


29-32: LGTM: Clean state management for diagram functionality.

Good use of proper TypeScript union types for ActiveDiagram and appropriate state variables for managing diagram overlay and visualization controls.


84-87: LGTM: Simple and effective dialog state management.

The openDiagramDialog function provides a clean API for opening diagram overlays with proper state management.


182-184: LGTM: Improved dark mode compatibility for message bubbles.

Good implementation of dark mode classes with proper border and background styling that maintains visual hierarchy.


188-223: LGTM: Excellent Mermaid integration in ReactMarkdown.

Great implementation that:

  • Properly detects language-mermaid code blocks
  • Renders Mermaid diagrams inline seamlessly
  • Maintains existing syntax highlighting for other languages
  • Uses consistent styling with dark mode support
code-executor-api/server.js (6)

118-121: LGTM: Enhanced query to support JSON-native test case columns.

Good addition of input_json and expected_json columns to the SELECT query, enabling the dual-path approach for both legacy and modern test case formats.


381-435: LGTM: Comprehensive ListNode scaffolding integration.

Excellent implementation that:

  • Properly detects when ListNode definitions are needed
  • Adds helper functions for array-to-ListNode conversion
  • Maintains clean separation between imports, definitions, helpers, and user code
  • Includes appropriate logging for debugging

This addresses a key requirement for LeetCode-style problems involving linked lists.


562-600: LGTM: Smart ListNode problem detection and handling.

Great implementation that:

  • Correctly identifies ListNode problems from function signatures
  • Generates appropriate function calls with ListNode conversion
  • Handles both standalone functions and class methods
  • Provides comprehensive logging for debugging

The automatic conversion between arrays and ListNodes will greatly improve the user experience for linked list problems.


612-635: LGTM: Embedded ListNode utilities in test execution.

Good approach to include ListNode class and helper functions directly in the generated test execution code, ensuring they're available regardless of the user's code structure.


819-825: LGTM: User-friendly error messages for common issues.

Excellent addition of friendly error hints for no-output and timeout scenarios, which will help users understand common pitfalls like infinite loops or incorrect return statements.


837-866: LGTM: Consistent JSON formatting for outputs.

Good implementation that normalizes both expected and actual outputs to compact JSON format for better readability and consistency in the test results display.

supabase/functions/ai-chat/index.ts (13)

34-37: LGTM: Well-designed API extension for diagram requests.

Good addition of optional diagram boolean and preferredEngines array to the RequestBody interface, providing flexible control over diagram generation.


49-57: LGTM: Comprehensive diagram response types.

Excellent type design that:

  • Supports both Mermaid and React Flow diagram engines
  • Includes optional titles and debugging information
  • Provides proper union types for different diagram formats
  • Adds suggestDiagram flag for UI hints

63-67: LGTM: Flexible model configuration with proper fallbacks.

Good implementation of configurable model selection with automatic detection of Responses API compatibility and sensible defaults.


157-166: LGTM: Clean wrapper for JSON-formatted LLM calls.

Simple and effective wrapper that delegates to the main llmText function with proper JSON response format configuration.


168-222: LGTM: Optimized fast JSON calls for lightweight operations.

Good implementation of a fast-path JSON helper that:

  • Uses lightweight models for tool-style operations
  • Has proper fallback mechanisms
  • Includes appropriate error handling and logging
  • Optimizes for common placement and analysis tasks

235-236: LGTM: Proper admin client configuration.

Good conditional setup of admin Supabase client with service role key, providing elevated permissions when needed while falling back gracefully.


294-316: LGTM: Robust React Flow graph validation.

Excellent validation function that:

  • Checks all required fields and types
  • Validates node/edge structure and relationships
  • Prevents duplicate node IDs
  • Ensures data integrity before rendering

318-448: LGTM: Comprehensive diagram generation with proper fallbacks.

Excellent implementation that:

  • Supports configurable engine preferences
  • Has robust error handling and debugging
  • Provides clear separation between React Flow and Mermaid generation
  • Includes proper JSON parsing with fallback strategies
  • Validates generated content before returning

The dual-engine approach with preference ordering is well-designed.


450-463: LGTM: Concise Mermaid diagram explanation generation.

Good helper function that generates brief, educational explanations for Mermaid diagrams without being overly verbose.


468-613: LGTM: Enhanced code snippet analysis with better filtering.

Excellent improvements to the analysis logic:

  • Disables vague code auto-detection to reduce false positives
  • Implements stricter validation criteria
  • Provides better filtering based on user intent
  • Includes comprehensive deduplication logic
  • Has appropriate length and complexity constraints

The balance between being helpful and avoiding unwanted suggestions is well-handled.


615-718: LGTM: Sophisticated two-path insertion strategy.

Excellent implementation that:

  • Uses fast anchor-based insertion when possible
  • Falls back to LLM-guided placement for complex scenarios
  • Provides deterministic insertion with only the requested snippet
  • Includes proper indentation handling
  • Has comprehensive error handling and logging

The hybrid approach balances speed with intelligence effectively.


788-796: LGTM: Efficient diagram-prioritized request handling.

Good optimization that prioritizes diagram generation when explicitly requested, avoiding unnecessary snippet analysis and providing faster response times.


799-817: LGTM: Intelligent parallel processing with smart suggestion logic.

Excellent implementation that:

  • Processes conversation, snippets, and diagrams in parallel for efficiency
  • Uses sophisticated heuristics to suggest diagrams based on context
  • Considers both explicit user requests and problem domain hints
  • Provides appropriate response structure with optional fields

@gitguardian
Copy link

gitguardian bot commented Aug 15, 2025

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link

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

🔭 Outside diff range comments (7)
src/components/CodeSnippetButton.tsx (1)

59-79: Add success feedback state and a11y to the button.

Per the component guideline, surface a short-lived “Added” state with a check icon, and expose aria-busy. Keep the spinner for loading.

Apply this diff within the rendered button:

-    <Button
-      onClick={handleInsert}
-      disabled={isInserting}
-      size='sm'
-      variant='secondary'
-      className={`ml-2 h-7 px-2 text-xs bg-primary/10 hover:bg-primary/20 text-primary border border-primary/20 ${className}`}
-      title={getInsertionDescription()}
-    >
-      {isInserting ? (
-        <>
-          <div className='w-3 h-3 border border-primary border-t-transparent rounded-full animate-spin mr-1' />
-          Adding...
-        </>
-      ) : (
-        <>
-          <Plus className='w-3 h-3 mr-1' />
-          Add to Editor
-        </>
-      )}
-    </Button>
+    <Button
+      onClick={handleInsert}
+      disabled={isInserting || isSuccess}
+      aria-busy={isInserting || undefined}
+      aria-live='polite'
+      size='sm'
+      variant='secondary'
+      className={`ml-2 h-7 px-2 text-xs bg-primary/10 hover:bg-primary/20 text-primary border border-primary/20 ${className}`}
+      title={getInsertionDescription()}
+    >
+      {isSuccess ? (
+        <>
+          <Check className='w-3 h-3 mr-1' />
+          Added
+        </>
+      ) : isInserting ? (
+        <>
+          <div className='w-3 h-3 border border-primary border-t-transparent rounded-full animate-spin mr-1' />
+          Adding...
+        </>
+      ) : (
+        <>
+          <Plus className='w-3 h-3 mr-1' />
+          Add to Editor
+        </>
+      )}
+    </Button>

Add these supporting changes elsewhere in the file:

// imports
import { Code, Plus, Check } from 'lucide-react';

// state
const [isInserting, setIsInserting] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);

// handler
const handleInsert = async () => {
  if (isInserting || isSuccess) return;

  setIsInserting(true);
  try {
    await onInsert(snippet);
    setIsSuccess(true);
  } catch (error) {
    console.error('Failed to insert code snippet:', error);
  } finally {
    setIsInserting(false);
    setTimeout(() => setIsSuccess(false), 1200); // brief success window
  }
};
src/components/ui/card.tsx (1)

32-45: Fix ref/prop type mismatch for CardTitle (h3): use HTMLHeadingElement for both

forwardRef currently declares HTMLParagraphElement as the ref type but renders an <h3>. This breaks ref typing and may cause TS errors for consumers.

Apply this diff:

-const CardTitle = React.forwardRef<
-  HTMLParagraphElement,
-  React.HTMLAttributes<HTMLHeadingElement>
->(({ className, ...props }, ref) => (
+const CardTitle = React.forwardRef<
+  HTMLHeadingElement,
+  React.HTMLAttributes<HTMLHeadingElement>
+>(({ className, ...props }, ref) => (
   <h3
     ref={ref}
     className={cn(
       'text-2xl font-semibold leading-none tracking-tight',
       className
     )}
     {...props}
   />
 ));
code-executor-api/server.js (4)

118-129: Guard JSON-native columns for 0/false, and handle partial JSON presence

  • Using truthiness for JSON columns can wrongly skip valid 0/false values.
  • If only one JSON column is present, legacy parsing runs but may encounter null/undefined input (see parseTestCaseInput below).

Switch to explicit null checks and add a warning when only one column is present.

-      // Fetch test cases for this problem (include both legacy and JSON columns)
+      // Fetch test cases for this problem (include both legacy and JSON columns)
       const { data: testCases, error: testCasesError } = await supabase
         .from('test_cases')
-        .select('input, expected_output, input_json, expected_json, is_example')
+        .select('input, expected_output, input_json, expected_json, is_example')
         .eq('problem_id', problemId)
         .order('is_example', { ascending: false });
@@
-      // Prefer JSON columns if available
-      if (tc.input_json && tc.expected_json) {
+      // Prefer JSON columns if both are present (allow falsy JSON like 0/false)
+      const hasInputJson = tc.input_json !== null && tc.input_json !== undefined;
+      const hasExpectedJson = tc.expected_json !== null && tc.expected_json !== undefined;
+      if (hasInputJson && hasExpectedJson) {
         console.log('Using JSON-native columns');
         console.log('JSON input:', JSON.stringify(tc.input_json));
         console.log('JSON expected:', JSON.stringify(tc.expected_json));
         
         inputParams = tc.input_json;
         expectedOutput = tc.expected_json;
       } else {
+        if (hasInputJson !== hasExpectedJson) {
+          console.warn('One JSON column is missing; falling back to legacy parsing for this test case.', {
+            hasInputJson,
+            hasExpectedJson
+          });
+        }
         console.log('Using legacy text parsing');
         console.log('Raw input:', JSON.stringify(tc.input));
         console.log('Raw expected_output:', JSON.stringify(tc.expected_output));
         
         // Parse the input string to extract parameters (legacy method)
         console.log('About to parse input with function signature:', problem.function_signature);
-        inputParams = parseTestCaseInput(tc.input, problem.function_signature);
+        inputParams = parseTestCaseInput(typeof tc.input === 'string' ? tc.input : '', problem.function_signature);
         console.log('Parsed input params result:', JSON.stringify(inputParams, null, 2));
         
         // Parse expected output (handle different types)
         try {
           expectedOutput = JSON.parse(tc.expected_output);
         } catch {
           // If JSON parsing fails, treat as string/number
           expectedOutput = tc.expected_output;
         }
       }

Also applies to: 151-178


199-209: Harden parseTestCaseInput against non-string inputs

If tc.input is null/undefined (e.g., only JSON columns present for expected), inputString.split will throw. Add a guard at the start.

 function parseTestCaseInput(inputString, functionSignature) {
   console.log('Raw input string:', JSON.stringify(inputString));
   console.log('Function signature:', functionSignature);
+  
+  if (typeof inputString !== 'string') {
+    console.warn('parseTestCaseInput received non-string input; returning empty param map.');
+    return {};
+  }

Also applies to: 219-223


545-559: Bug: Python JSON embedding doesn’t convert null -> None

Embedded test_cases JSON converts true/false but not null, producing invalid Python (NameError: name 'null' is not defined). Replace JSON nulls with Python None.

   let testCasesJson = JSON.stringify(pythonTestCases, null, 2);
-  testCasesJson = testCasesJson.replace(/\btrue\b/g, 'True').replace(/\bfalse\b/g, 'False');
+  testCasesJson = testCasesJson
+    .replace(/\btrue\b/g, 'True')
+    .replace(/\bfalse\b/g, 'False')
+    .replace(/\bnull\b/g, 'None');

758-764: Improve expected_output encoding for Judge0 to avoid mismatches

String(testCase.expected) turns arrays into “1,2” (no brackets), causing Judge0 mismatches even when our own compare passes. Encode as JSON consistently.

-        expected_output: testCase.expected ? Buffer.from(String(testCase.expected)).toString('base64') : undefined
+        expected_output:
+          testCase.expected !== undefined
+            ? Buffer.from(
+                typeof testCase.expected === 'string'
+                  ? testCase.expected
+                  : JSON.stringify(testCase.expected)
+              ).toString('base64')
+            : undefined
src/components/Notes.tsx (1)

95-103: Auto-save misses the “cleared” case when user deletes text

Debounced auto-save refuses to save when the content trims to empty, so manual deletion to empty won’t persist unless the user clicks Save/Clear. This breaks the “auto-save with debounce” requirement and can lead to stale notes in DB.

-  const debouncedSave = useCallback(
-    debounce((noteContent: string) => {
-      if (noteContent.trim() !== '') {
-        saveNotes(noteContent);
-      }
-    }, 2000),
-    [saveNotes]
-  );
+  const debouncedSave = useCallback(
+    debounce((noteContent: string) => {
+      // Normalize whitespace-only to empty string so clears persist automatically.
+      const normalized = noteContent.trim() === '' ? '' : noteContent;
+      saveNotes(normalized);
+    }, 2000),
+    [saveNotes]
+  );
♻️ Duplicate comments (6)
scripts/dev-start.sh (1)

27-38: Fail fast on missing Supabase credentials to avoid 60s wait and noisy failures

The script writes blank SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY, then waits 60s for API readiness. The server exits immediately without those vars. Detect and exit early with a clear message.

 if [[ ! -f "${API_DIR}/.env" ]]; then
   echo -e "${YELLOW}⚠️  Creating ${API_DIR}/.env with defaults...${NC}"
   cat > "${API_DIR}/.env" <<EOL
 PORT=${API_PORT}
 JUDGE0_API_URL=https://judge0-extra-ce.p.rapidapi.com
 # Provide your real credentials locally if needed:
-SUPABASE_URL=
-SUPABASE_SERVICE_ROLE_KEY=
+SUPABASE_URL=YOUR_SUPABASE_URL_HERE
+SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY_HERE
 # Optional: JUDGE0_API_KEY=
 EOL
 fi
 
+SUPABASE_URL_VAL="$(awk -F= '/^SUPABASE_URL=/{print $2}' "${API_DIR}/.env" | tr -d '[:space:]')"
+SUPABASE_KEY_VAL="$(awk -F= '/^SUPABASE_SERVICE_ROLE_KEY=/{print $2}' "${API_DIR}/.env" | tr -d '[:space:]')"
+if [[ -z "${SUPABASE_URL_VAL}" || -z "${SUPABASE_KEY_VAL}" ]]; then
+  echo -e "${RED}❌ Missing Supabase credentials in ${API_DIR}/.env${NC}"
+  echo "   Please set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY."
+  exit 1
+fi

Also applies to: 40-47, 48-57

src/hooks/useChatSession.ts (1)

25-64: Complex type guards and helper functions could be simplified.

The diagram payload helpers use complex type guards with lots of type assertions. The code is duplicated between the two guard functions and could be simplified.

Extract the diagram parsing logic into a helper function as previously suggested to improve readability and maintainability.

src/pages/ProblemSolver.tsx (1)

257-280: Complex Monaco type casting needs simplification.

The Monaco Range instantiation uses complex nested type assertions that make the code hard to read and maintain.

Simplify the Monaco Range creation as previously suggested to improve readability.

src/components/AIChat.tsx (3)

831-856: Modal a11y: add dialog semantics and ESC handling (repeat from prior review).

Add role/aria attributes and close-on-ESC. Consider focus management later.

- {isDiagramOpen && (
-   <div className='fixed inset-0 z-50'>
-     <div
-       className='absolute inset-0 bg-black/80'
-       onClick={() => setIsDiagramOpen(false)}
-     />
-     <div className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[90vw] h-[90vh] bg-background border rounded-lg shadow-lg p-4 overflow-auto'>
-       <div className='flex items-center justify-between mb-2'>
-         <div className='text-sm font-medium'>Diagram</div>
-         <Button
-           size='sm'
-           variant='ghost'
-           onClick={() => setIsDiagramOpen(false)}
-         >
-           Close
-         </Button>
-       </div>
+ {isDiagramOpen && (
+   <div className='fixed inset-0 z-50' role='dialog' aria-modal='true' aria-labelledby='diagram-title'>
+     <div
+       className='absolute inset-0 bg-black/80'
+       onClick={() => setIsDiagramOpen(false)}
+       aria-hidden='true'
+     />
+     <div className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[90vw] h-[90vh] bg-background border rounded-lg shadow-lg p-4 overflow-auto'
+          role='document'>
+       <div className='flex items-center justify-between mb-2'>
+         <div id='diagram-title' className='text-sm font-medium'>Diagram</div>
+         <Button
+           size='sm'
+           variant='ghost'
+           onClick={() => setIsDiagramOpen(false)}
+           aria-label='Close diagram'
+         >
+           Close
+         </Button>
+       </div>

Add ESC handler:

useEffect(() => {
  const onKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'Escape' && isDiagramOpen) setIsDiagramOpen(false);
  };
  if (isDiagramOpen) {
    document.addEventListener('keydown', onKeyDown);
    return () => document.removeEventListener('keydown', onKeyDown);
  }
}, [isDiagramOpen]);

113-121: Handle requestDiagram errors in handleVisualize (repeat from prior review).

Uncaught rejections will surface as noisy console errors and stale hidden IDs. Wrap in try/catch and roll back UI state on failure.

 const handleVisualize = async (
   sourceMessageContent: string,
   messageId: string
 ) => {
   // Request a diagram separately without adding a user message bubble
   setHiddenVisualizeForIds(prev => new Set(prev).add(messageId));
-  await requestDiagram(sourceMessageContent);
+  try {
+    await requestDiagram(sourceMessageContent);
+  } catch (error) {
+    console.error('Failed to generate diagram:', error);
+    // rollback hidden state so user can retry
+    setHiddenVisualizeForIds(prev => {
+      const next = new Set(prev);
+      next.delete(messageId);
+      return next;
+    });
+  }
 };

531-571: Stop unsafe casts; model ChatMessage.diagram properly and use it directly (summary claims types were added).

The repeated (message as unknown as ...) casts are brittle. The PR summary says ChatMessage now has an optional diagram payload; use it and remove casts in this component.

Proposed refactor (representative changes shown):

- {message.role === 'assistant' &&
-  (message as unknown as { diagram?: { engine: 'mermaid'; code: string } }).diagram?.engine === 'mermaid' && (
+ {message.role === 'assistant' && message.diagram?.engine === 'mermaid' && (
    ...
-   onClick={() =>
-     openDiagramDialog({
-       engine: 'mermaid',
-       code: (message as unknown as { diagram: { code: string } }).diagram.code,
-     })
-   }
+   onClick={() => openDiagramDialog({ engine: 'mermaid', code: message.diagram!.code })}
    ...
-   <Mermaid chart={(message as unknown as { diagram: { code: string } }).diagram.code} />
+   <Mermaid chart={message.diagram!.code} />
  )}
 
- {message.role === 'assistant' &&
-  (message as unknown as { diagram?: { engine: 'reactflow'; graph: FlowGraph } }).diagram?.engine === 'reactflow' && (
+ {message.role === 'assistant' && message.diagram?.engine === 'reactflow' && (
    ...
-   onClick={() =>
-     openDiagramDialog({
-       engine: 'reactflow',
-       graph: (message as unknown as { diagram: { graph: FlowGraph } }).diagram.graph,
-     })
-   }
+   onClick={() => openDiagramDialog({ engine: 'reactflow', graph: message.diagram!.graph })}
    ...
-   <FlowCanvas graph={(message as unknown as { diagram: { graph: FlowGraph } }).diagram.graph} />
+   <FlowCanvas graph={message.diagram!.graph} />
  )}
 
- const hasDiagram = Boolean(
-   (message as unknown as { diagram?: unknown }).diagram
- );
+ const hasDiagram = Boolean(message.diagram);

If the ChatMessage type is not yet updated, add something like:

  • In src/types (or wherever ChatMessage lives):
    • diagram?: { engine: 'mermaid'; code: string } | { engine: 'reactflow'; graph: FlowGraph }
    • suggestDiagram?: boolean

Run this to verify and locate the type:

#!/bin/bash
# Locate ChatMessage type and check if it includes `diagram?` and `suggestDiagram?`
rg -nP -C3 '^(interface|type)\s+ChatMessage\b'
rg -nP -C2 '\bdiagram\?\s*:\s*' 
rg -nP -C2 '\bsuggestDiagram\?\s*:\s*' 

Also applies to: 577-626, 639-641

Comment on lines +28 to +31
if (initialCode) {
setCode(initialCode);
}
}, [initialCode]);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Bug: initialCode cannot be cleared

The effect ignores empty strings, so switching to empty code won’t update the preview. Also clear stale errors when code changes.

-  React.useEffect(() => {
-    if (initialCode) {
-      setCode(initialCode);
-    }
-  }, [initialCode]);
+  React.useEffect(() => {
+    setCode(initialCode ?? '');
+    setCompileError(null);
+  }, [initialCode]);
📝 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
if (initialCode) {
setCode(initialCode);
}
}, [initialCode]);
React.useEffect(() => {
setCode(initialCode ?? '');
setCompileError(null);
}, [initialCode]);
🤖 Prompt for AI Agents
In src/components/canvas/CanvasContainer.tsx around lines 28 to 31, the effect
currently skips empty string initialCode due to a truthy check and doesn't clear
previous errors; change the guard so empty strings are applied (e.g., check for
initialCode !== undefined && initialCode !== null or simply always call
setCode(initialCode) when initialCode is provided), and also clear stale error
state when code changes (call the error-clearing setter such as setError(null)
or setErrors([]) inside the same effect after updating code).

onClose: () => void;
title?: string;
children: React.ReactNode;
componentCode?: string;
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Unused prop componentCode.

The componentCode prop is defined in the interface but never used in the component. If it's intended for future use with the View Code/Download actions, consider either implementing its usage or removing it until needed.


🏁 Script executed:

#!/bin/bash
# Check if componentCode prop is used in the consuming component
rg -n "componentCode" src/components/canvas/CanvasContainer.tsx

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Search for any occurrences of componentCode across the entire repository
rg -n "componentCode" -n .

Length of output: 155


Remove unused componentCode prop

The componentCode prop is declared and destructured in CanvasModal but never referenced elsewhere. Please either implement its intended use (e.g., for View Code/Download) or remove it until needed.

Locations to address:

  • src/components/canvas/CanvasModal.tsx
    • Line 11: componentCode?: string;
    • Line 21: componentCode,
🤖 Prompt for AI Agents
In src/components/canvas/CanvasModal.tsx around lines 11 and 21, the prop
declaration componentCode?: string and its destructuring are unused; remove both
the prop from the component's prop type at line 11 and the componentCode entry
from the destructuring at line 21 (or alternatively implement its use if
intended: wire it into the View Code/Download UI and handlers), ensuring
TypeScript types and any downstream uses are updated accordingly and the
component still compiles.

Comment on lines 5 to 7
const SUPABASE_URL = 'https://fmdhrylburlniimoaokq.supabase.co';
const SUPABASE_PUBLISHABLE_KEY =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZtZGhyeWxidXJsbmlpbW9hb2txIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTM0NzAwMDQsImV4cCI6MjA2OTA0NjAwNH0.oMdyCL05_NAFRlpiiUDCB4fW6vgA6hkMOKtvpp075pw';
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Don’t hardcode Supabase URL/Anon key; use environment variables and guard for missing config

Even for anon keys (which can be public), committing project-specific keys/URLs ties builds to a single environment and complicates rotation. Prefer NEXT_PUBLIC_* env vars and fail fast in dev if missing.

Apply this diff:

-const SUPABASE_URL = 'https://fmdhrylburlniimoaokq.supabase.co';
-const SUPABASE_PUBLISHABLE_KEY =
-  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZtZGhyeWxidXJsbmlpbW9hb2txIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTM0NzAwMDQsImV4cCI6MjA2OTA0NjAwNH0.oMdyCL05_NAFRlpiiUDCB4fW6vgA6hkMOKtvpp075pw';
+const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL || '';
+const SUPABASE_PUBLISHABLE_KEY =
+  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '';
+if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) {
+  // Fail fast in dev; in production ensure env vars are set at build time.
+  throw new Error(
+    'Missing NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY'
+  );
+}
📝 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
const SUPABASE_URL = 'https://fmdhrylburlniimoaokq.supabase.co';
const SUPABASE_PUBLISHABLE_KEY =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZtZGhyeWxidXJsbmlpbW9hb2txIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTM0NzAwMDQsImV4cCI6MjA2OTA0NjAwNH0.oMdyCL05_NAFRlpiiUDCB4fW6vgA6hkMOKtvpp075pw';
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL || '';
const SUPABASE_PUBLISHABLE_KEY =
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '';
if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) {
// Fail fast in dev; in production ensure env vars are set at build time.
throw new Error(
'Missing NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY'
);
}
🧰 Tools
🪛 Gitleaks (8.27.2)

7-7: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🤖 Prompt for AI Agents
In src/integrations/supabase/client.ts around lines 5-7, the Supabase URL and
anon key are hardcoded; replace them with environment variables (e.g.
process.env.NEXT_PUBLIC_SUPABASE_URL and
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY), export those env-derived constants,
and add a guard that logs a clear error and exits (or throws) early in
development if either value is missing so builds/localhost fail fast and keys
can be rotated per environment.

Copy link

@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

🔭 Outside diff range comments (1)
src/pages/ProblemSolver.tsx (1)

165-194: Backend GPT-guided insertion now lacks fallback, making insertion fragile

Lines 190-193 reject the insertion completely if backend fails, removing the previous local fallback logic. This makes the feature unusable when the backend is unavailable or returns errors.

Consider keeping a minimal local fallback for basic cursor insertion:

 if (!newCodeFromBackend) {
-  toast.error('AI placement failed. Please try again.');
-  return;
+  // Fallback to simple cursor insertion
+  console.warn('Backend insertion failed, using simple cursor placement');
+  const lines = currentCode.split('\n');
+  const insertLine = cursorPosition.line;
+  lines.splice(insertLine, 0, snippet.code);
+  newCodeFromBackend = lines.join('\n');
+  insertedAtLine = insertLine;
+  toast.warning('Using simple insertion due to AI unavailability');
 }
♻️ Duplicate comments (5)
src/pages/ProblemSolver.tsx (2)

462-468: Hardcoded Two Sum solutions remain misleading

The Solution tab still shows static Two Sum code examples regardless of the actual problem being viewed. This issue was flagged in previous reviews but hasn't been addressed.

Also applies to: 495-503


519-539: Static submission entries persist without real data

The Submissions tab continues to show fake "Accepted" entries that don't reflect actual user submissions, which was previously identified as misleading.

src/components/AIChat.tsx (2)

487-505: Remove unsafe type casting for diagram field

Multiple unsafe type casts (message as unknown as { diagram?: ... }) indicate the ChatMessage type doesn't include the diagram field. Update the type definition instead of using unsafe assertions.


705-722: Fullscreen diagram dialog needs accessibility improvements

The custom overlay lacks proper ARIA attributes, focus management, and keyboard navigation support.

supabase/functions/ai-chat/index.ts (1)

457-512: Consider adding retry logic for diagram generation

Both React Flow and Mermaid generation could fail due to transient issues with the LLM API. Adding retry logic would improve reliability.

#!/bin/bash
# Check if retry utilities are available in the codebase
echo "Checking for existing retry utilities or patterns..."
rg -n "retry|exponential.*backoff|RetryOptions" --type ts --type js

# Check Deno std library version for retry support
echo -e "\nChecking Deno std library imports..."
rg "deno\.land/std@" --type ts | head -5

# Check if there are other places using retry logic we could follow
echo -e "\nChecking for existing retry patterns in edge functions..."
fd -e ts -e js . supabase/functions -x grep -l "retry\|attempt" {} \;
🧹 Nitpick comments (2)
src/components/AIChat.tsx (1)

532-562: Extract complex Visualize button logic to improve readability

The inline IIFE with complex conditions for showing the Visualize button reduces readability. Consider extracting this to a separate function.

+ const shouldShowVisualize = (
+   message: ChatMessage,
+   messages: ChatMessage[],
+   hiddenIds: Set<string>
+ ): boolean => {
+   const lastUserMsg = [...messages].reverse().find(m => m.role === 'user')?.content || '';
+   const userAsked = /(visualize|diagram|draw|flowchart|mermaid)/i.test(lastUserMsg);
+   const hasDiagram = Boolean((message as any).diagram);
+   return !hasDiagram && (userAsked || message.suggestDiagram === true) && !hiddenIds.has(message.id);
+ };
+ 
+ const shouldShowInteractive = (message: ChatMessage): boolean => {
+   const algorithmContext = /(algorithm|sort|search|tree|graph|dynamic programming|dp|binary search|merge|quick|bubble|heap|bfs|dfs|two pointer|sliding window|approach|solution)/i.test(message.content);
+   return message.role === 'assistant' && algorithmContext && !Boolean((message as any).diagram);
+ };

  {message.role === 'assistant' && (
    <div className="mt-3 space-y-3">
-     {(() => {
-       const lastUserMsg = [...messages].reverse().find(m => m.role === 'user')?.content || '';
-       const userAsked = /(visualize|diagram|draw|flowchart|mermaid)/i.test(lastUserMsg);
-       const hasDiagram = Boolean((message as unknown as { diagram?: unknown }).diagram);
-       const shouldShow = !hasDiagram && (userAsked || (message as unknown as { suggestDiagram?: boolean }).suggestDiagram === true) && !hiddenVisualizeForIds.has(message.id);
-       return shouldShow ? (
+     {(shouldShowVisualize(message, messages, hiddenVisualizeForIds) || shouldShowInteractive(message)) && (
        <div className="flex items-center gap-2">
+         {shouldShowVisualize(message, messages, hiddenVisualizeForIds) && (
+           <Button onClick={() => handleVisualize(message.content, message.id)} ...>
+             <DiagramIcon className="w-4 h-4" />
+             <span>Visualize</span>
+           </Button>
+         )}
+         {shouldShowInteractive(message) && (
+           <Button onClick={() => handleGenerateComponent(message.content)} ...>
+             <Sparkles className="w-4 h-4" />
+             <span>Interactive Demo</span>
+           </Button>
+         )}
        </div>
-     ) : null;
-     })()}
+     )}
supabase/functions/ai-chat/index.ts (1)

575-592: React Flow is disabled but code suggests temporary nature

Line 581 indicates React Flow is "temporarily disabled". Consider adding a TODO comment with timeline or tracking issue for re-enabling it.

 if (engine === 'reactflow') {
   // Temporarily disable React Flow - use Mermaid only for now
+  // TODO: Re-enable React Flow after validation issues are resolved (track in issue #XXX)
   tried.push('reactflow');
   console.log('[Diagram Generation] React Flow disabled, skipping');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4689706 and 752d008.

📒 Files selected for processing (4)
  • CI_CD_README.md (0 hunks)
  • src/components/AIChat.tsx (7 hunks)
  • src/pages/ProblemSolver.tsx (12 hunks)
  • supabase/functions/ai-chat/index.ts (9 hunks)
💤 Files with no reviewable changes (1)
  • CI_CD_README.md
🧰 Additional context used
📓 Path-based instructions (4)
{src/components/**/*.tsx,tailwind.config.ts}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Ensure all UI components are compatible with dark mode using Tailwind CSS dark mode classes and custom color variables defined in tailwind.config.ts

Files:

  • src/components/AIChat.tsx
src/components/AIChat.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/components/AIChat.tsx: AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons
Use react-markdown with react-syntax-highlighter and @tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Files:

  • src/components/AIChat.tsx
supabase/functions/ai-chat/index.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Files:

  • supabase/functions/ai-chat/index.ts
src/pages/ProblemSolver.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

src/pages/ProblemSolver.tsx: In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs
Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Files:

  • src/pages/ProblemSolver.tsx
🧠 Learnings (9)
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : AIChat component in src/components/AIChat.tsx should render chat messages left-aligned, use react-markdown with syntax highlighting, and display code snippets with dedicated cards and 'Add to Editor' buttons

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/AIChat.tsx : Use react-markdown with react-syntax-highlighter and tailwindcss/typography for proper code block highlighting and text formatting in chat messages

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : Integrate Notes component into ProblemSolver tabs, replacing static textarea with dynamic component and ensuring persistent storage per user per problem

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeSnippetButton.tsx : Reusable CodeSnippetButton component in src/components/CodeSnippetButton.tsx should provide visual loading states, success feedback, and integrate with insertion callbacks

Applied to files:

  • src/components/AIChat.tsx
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to supabase/functions/ai-chat/index.ts : Supabase Edge Function in supabase/functions/ai-chat/index.ts must integrate with OpenAI GPT-4o-mini, process conversations and code analysis in parallel, and handle CORS and errors comprehensively

Applied to files:

  • supabase/functions/ai-chat/index.ts
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/utils/codeInsertion.ts : Implement smart code insertion logic in src/utils/codeInsertion.ts, including function scope detection, indentation matching, and insertion point analysis

Applied to files:

  • supabase/functions/ai-chat/index.ts
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/pages/ProblemSolver.tsx : In src/pages/ProblemSolver.tsx, handleInsertCodeSnippet must manipulate the Monaco editor for real-time code insertion, cursor positioning, and visual highlighting with debugging logs

Applied to files:

  • supabase/functions/ai-chat/index.ts
  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Applies to src/components/CodeEditor.tsx : Monaco code editor in src/components/CodeEditor.tsx must support custom themes synced with system dark mode, Vim mode via monaco-vim, and auto-save with visual indicators

Applied to files:

  • src/pages/ProblemSolver.tsx
📚 Learning: 2025-08-10T18:55:50.844Z
Learnt from: CR
PR: swoosh1337/simplyalgo.dev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-10T18:55:50.844Z
Learning: Resizable panel management with keyboard shortcuts (Ctrl/Cmd+B/J/L) must be implemented for left, bottom, and right panels

Applied to files:

  • src/pages/ProblemSolver.tsx
🧬 Code Graph Analysis (3)
src/components/AIChat.tsx (5)
src/types/index.ts (3)
  • CodeSnippet (45-56)
  • Problem (16-31)
  • FlowGraph (63-63)
src/hooks/useProblems.ts (1)
  • Problem (4-25)
src/components/diagram/Mermaid.tsx (1)
  • Mermaid (26-65)
src/components/diagram/FlowCanvas.tsx (1)
  • FlowCanvas (14-32)
src/components/canvas/CanvasContainer.tsx (1)
  • CanvasContainer (17-56)
supabase/functions/ai-chat/index.ts (1)
src/types/index.ts (5)
  • ChatMessage (65-84)
  • CodeSnippet (45-56)
  • FlowNode (61-61)
  • FlowEdge (62-62)
  • FlowGraph (63-63)
src/pages/ProblemSolver.tsx (6)
src/hooks/useAuth.ts (1)
  • useAuth (5-41)
src/hooks/useProblems.ts (1)
  • useProblems (34-188)
src/hooks/useUserStats.ts (1)
  • useUserStats (19-270)
src/types/index.ts (1)
  • TestResult (6-14)
code-executor-api/server.js (2)
  • result (84-84)
  • problem (104-108)
src/components/ui/tabs.tsx (2)
  • Tabs (53-53)
  • TabsContent (53-53)
🔇 Additional comments (9)
src/pages/ProblemSolver.tsx (4)

223-238: Monaco Range instantiation uses safer typing approach

Good improvement over the previous complex type assertions. The code now checks for monaco?.Range existence before using it and provides a fallback when unavailable.


315-335: renderValue implementation handles various data types correctly

The new renderValue function properly handles null/undefined, primitives, JSON strings, and objects with appropriate formatting and error handling.


543-544: Notes component integration looks good

The Notes component is properly integrated with the problemId prop, enabling persistent storage per problem as specified in the requirements.


708-709: New problem prop added to AIChat

The addition of the problem prop to AIChat enables proper context for visualization generation as implemented in the AIChat component changes.

supabase/functions/ai-chat/index.ts (5)

84-86: Model configuration logging is helpful

Good addition of model source tracking for debugging and monitoring which model configuration is being used.


89-153: Excellent refactoring of LLM response handling

The extraction of buildResponsesRequest and extractResponsesText functions significantly improves code maintainability and readability. The response text extraction handles multiple response formats comprehensively.


773-798: Smart anchor-based insertion is a good optimization

The deterministic anchor-based insertion provides a fast path for common cases where the first line of the snippet already exists in the code. Good defensive checks for already-inserted snippets.


872-952: Visualization component generation is comprehensive

The prompt structure for generating interactive visualizations is well-designed with clear requirements and constraints. Good use of specific UI component imports and animation libraries.


626-744: Snippet analysis has good safety constraints

The code properly filters out complex control flow structures and enforces size limits to prevent insertion of overly complex code blocks. The deduplication logic prevents duplicate snippets.

- Add Husky for Git hooks management
- Create comprehensive secrets detection script
- Configure pre-commit hook for:
  - Hardcoded secrets detection
  - Code formatting with Prettier
  - Prevention of .env file commits
- Add timeout handling for LLM requests in edge function

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

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@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

🧹 Nitpick comments (4)
scripts/check-secrets.sh (4)

17-20: Consider strengthening the OpenAI API key pattern.

The current pattern sk_[a-zA-Z0-9] may produce false positives since it only requires one character after the prefix. OpenAI API keys typically follow the format sk- followed by a longer alphanumeric string.

Apply this diff to improve the pattern specificity:

-if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "sk_[a-zA-Z0-9]" . 2>/dev/null; then
+if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "sk-[a-zA-Z0-9]{20,}" . 2>/dev/null; then

23-26: Consider strengthening the Stripe API key pattern.

Similar to the OpenAI pattern, pk_[a-zA-Z0-9] may be too broad. Stripe publishable keys typically follow pk_test_ or pk_live_ format with longer strings.

Apply this diff to improve the pattern specificity:

-if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "pk_[a-zA-Z0-9]" . 2>/dev/null; then
+if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "pk_(test|live)_[a-zA-Z0-9]{20,}" . 2>/dev/null; then

35-38: Consider strengthening the GitHub token pattern.

The pattern ghp_[0-9A-Za-z] may be too broad. GitHub personal access tokens have a more specific format with longer strings.

Apply this diff to improve the pattern specificity:

-if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "ghp_[0-9A-Za-z]" . 2>/dev/null; then
+if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" "ghp_[0-9A-Za-z]{36}" . 2>/dev/null; then

62-65: Consider improving the API key detection pattern.

The regex api.key.*=.*['\"][a-z0-9] has several issues:

  1. The dot should be escaped to match literal periods
  2. The character class only includes lowercase letters and numbers
  3. The pattern may be too broad and catch legitimate code

Apply this diff to improve the pattern:

-if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" -i "api.key.*=.*['\"][a-z0-9]" . 2>/dev/null | grep -v "your_api_key_here" | grep -v "your_key_here" | grep -v "api_key_placeholder"; then
+if grep -r --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --exclude-dir="node_modules" --exclude-dir="dist" --exclude-dir="build" -i "api\.key.*=.*['\"][a-zA-Z0-9_-]{16,}" . 2>/dev/null | grep -v "your_api_key_here" | grep -v "your_key_here" | grep -v "api_key_placeholder"; then
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 752d008 and 2bc9efb.

📒 Files selected for processing (2)
  • .husky/pre-commit (1 hunks)
  • scripts/check-secrets.sh (1 hunks)
🔇 Additional comments (9)
scripts/check-secrets.sh (6)

1-1: LGTM!

The shebang is correct for a portable bash script.


3-7: LGTM!

Color constants are properly defined using ANSI escape codes for clear output formatting.


29-32: LGTM!

The AWS access key pattern AKIA[0-9A-Z] correctly identifies the standard AWS access key format.


41-49: LGTM!

Database connection string patterns effectively detect credentials in URLs for both PostgreSQL and MySQL.


51-58: LGTM!

Proper detection of staged .env files using git diff to prevent accidental commits of environment files.


67-76: LGTM!

Proper exit handling with informative messages and appropriate exit codes for integration with pre-commit hooks.

.husky/pre-commit (3)

1-2: LGTM!

Standard Husky pre-commit hook setup with proper shebang and initialization.


6-11: LGTM!

Proper integration with the secrets check script and appropriate error handling with exit code propagation.


22-23: LGTM!

Appropriate success message for completed pre-commit checks.

@swoosh1337 swoosh1337 merged commit 7dbf902 into main Aug 15, 2025
2 checks passed
swoosh1337 added a commit that referenced this pull request Aug 25, 2025
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