Skip to content

lint fixes#108

Closed
InfinityBowman wants to merge 25 commits into
mainfrom
107-add-a-test-function-to-mcp
Closed

lint fixes#108
InfinityBowman wants to merge 25 commits into
mainfrom
107-add-a-test-function-to-mcp

Conversation

@InfinityBowman
Copy link
Copy Markdown
Owner

@InfinityBowman InfinityBowman commented Dec 19, 2025

Summary by CodeRabbit

  • New Features

    • Documentation updated with guidance for linting and testing (CoRATES MCP).
  • Bug Fixes

    • Fixed profile redirect behavior in authentication flows.
    • Restored consistent button styling in sign-in UI.
    • Improved file upload handling and directory detection; better file size display.
  • Refactor

    • Modernized DOM and export handling for more reliable downloads and prefetching.
    • General modernization of code patterns for improved stability.

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

@InfinityBowman InfinityBowman linked an issue Dec 19, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 19, 2025

Walkthrough

A comprehensive codebase modernization updating ESLint configuration with unicorn and sonarjs plugins, refactoring import paths from kebab-case to camelCase (e.g., google-drive.jsgoogleDrive.js), and standardizing JavaScript patterns throughout the project with modern ES features (Number.parseInt, structuredClone, .at(), .toSorted(), for-of loops, replaceAll).

Changes

Cohort / File(s) Summary
Configuration & Tooling
\.clauderc, \.cursorrules, \.github/copilot-instructions.md
Documentation clarifications about Zod usage and preferring the CoRATES MCP for linting/testing.
ESLint Configuration
eslint.config.js
Enables eslint-plugin-unicorn and eslint-plugin-sonarjs, adds recommended configs and many per-scope unicorn/sonarjs rule overrides.
Import Path & Route Renames
packages/web/src/**, packages/workers/src/routes/googleDrive.js, packages/workers/src/routes/accountMerge.js, packages/workers/scripts/generate-openapi.mjs, packages/workers/src/index.js
Bulk rename/casing of imports (e.g., @api/...@/..., google-drive.jsgoogleDrive.js, account-merge.jsaccountMerge.js) across many modules and updated route registration/OpenAPI mappings.
Workers Response / DOs Modernization
packages/workers/src/durable-objects/ProjectDoc.js, packages/workers/src/durable-objects/UserSession.js, packages/workers/src/durable-objects/EmailQueue.js
Replace manual new Response(JSON.stringify(...)) with Response.json(...), iterate using for-of, add explicit switch/default handling, and small behavior-conservative restructurings.
Numeric Parsing & Literals
packages/workers/src/config/validation.js, packages/workers/src/routes/*.js, packages/mcp/*, packages/web/src/**, packages/workers/src/config/constants.js, packages/workers/src/middleware/*
Replace global parseInt/isNaN with Number.parseInt/Number.isNaN and add digit separators to numeric literals (e.g., 3000030_000) across many files.
Deep Clone & StructuredClone
packages/web/src/ROBINS-I/*, packages/web/src/AMSTAR2/*, packages/web/src/components/checklist-ui/compare/*
Replace JSON-based deep clones with structuredClone in reconciliation and checklist logic; adjust signatures where metadata defaulting added.
Loop & Iteration Modernization
packages/mcp/*, packages/web/src/**, packages/workers/src/**
Replace forEach/index loops with for...of or for (const ... of Object.entries(...)) patterns across dozens of files.
Array Access / Search Modernization
packages/web/src/**/compare/*, packages/web/src/**/checklist*, packages/web/src/lib/*
Replace arr[arr.length-1] with .at(-1), .findIndex(v=>v===true) with .indexOf(true), .some(...) with .includes(...).
Immutable Sorting & Spread
packages/mcp/tools/*.js, packages/web/src/components/**/Pdf*.jsx, packages/web/src/components/project-ui/**
Replace in-place sorts and Array.from(...) with .toSorted() and spread [...] to avoid mutation and modernize creation.
String Replacement Modernization
packages/workers/src/docs.js, packages/web/src/lib/*, packages/web/src/components/**/TwoFactor*.jsx, packages/workers/src/routes/contact.js
Replace regex .replace(...) global chains with replaceAll and use String.raw escapes for script tag JSON escaping.
DOM & API Modernization
packages/landing/public/sw.js, packages/landing/src/components/PrefetchLink.jsx, packages/landing/src/entry-client.jsx, packages/web/src/main.jsx, packages/web/src/stores/projectActionsStore/pdfs.js, packages/web/src/lib/googlePicker.js
DOM API modernizations: appendChild/removeChildappend/remove, getElementByIdquerySelector, and more spread usage in arrays.
Top-level Await & CLI Changes
packages/mcp/scrape-icons.js, packages/mcp/server.js, packages/mcp/tools/lint.js
Switch to top-level await main() and minor import changes (default → named import for util).
Functional Refactors & Helpers
packages/web/src/stores/projectActionsStore/studies.js, packages/ui/src/zag/FileUpload.jsx, packages/web/src/components/checklist-ui/*
Extract/move helpers (createStudyFromInput, attachPdfToStudy, showBatchResultToast, formatFileSize), minor behavior-conservative refactors (e.g., Set for ALLOWED_TYPES).
API/Export Adjustments
packages/workers/src/middleware/requireAdmin.js, packages/workers/src/index.js
Replace local isAdmin export with re-export from auth module; move/re-export durable-object symbols to bottom-level re-exports.
Tests & Test Setup Updates
packages/web/TESTING.md, packages/web/src/**/__tests__/*, packages/workers/src/config/__tests__/*
Update mocks, module paths in tests, remove explicit undefined args, minor test API/access pattern updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50–70 minutes

Key areas to focus during review:

  • eslint.config.js rule scope and unintended rule suppression.
  • Large-scale import/path renames and bundler/alias resolution (ensure resolution of @/ aliases and filename casing).
  • ProjectDoc durable-object changes (broadcast, disconnect, Response.json usage) — ensure Yjs/WebSocket semantics preserved.
  • structuredClone usage in reconciliation/state code vs prior JSON cloning (types like Uint8Array, Maps, Sets, circular refs).
  • Top-level await changes in MCP scripts that remove centralized .catch() behavior.

Possibly related PRs

Poem

🐰
I nibbled old forEach and parseInt too,
Hopped to .toSorted and structuredClone anew,
Swapped kebab to camel, imports tidy and bright,
Spread my little paws—for-of loops take flight,
A carrot for modern JS, code hopped just right! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.10% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'lint fixes' is vague and generic, using non-descriptive terminology that doesn't convey specific information about the changeset. Use a more descriptive title that specifies the primary linting fix or modernization applied (e.g., 'Modernize codebase with ES features and numeric literal formatting' or 'Replace deprecated APIs and refactor loops').
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 107-add-a-test-function-to-mcp

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b7167c and ea593ee.

📒 Files selected for processing (1)
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js (17 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates

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

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 19, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates ea593ee Commit Preview URL Dec 19 2025, 05:52 PM

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be8bf45 and b76c99e.

📒 Files selected for processing (19)
  • .clauderc (1 hunks)
  • .cursorrules (1 hunks)
  • .github/copilot-instructions.md (1 hunks)
  • eslint.config.js (4 hunks)
  • packages/landing/public/sw.js (1 hunks)
  • packages/workers/src/__tests__/admin.test.js (1 hunks)
  • packages/workers/src/auth/routes.js (1 hunks)
  • packages/workers/src/config/validation.js (1 hunks)
  • packages/workers/src/durable-objects/ProjectDoc.js (14 hunks)
  • packages/workers/src/index.js (1 hunks)
  • packages/workers/src/middleware/rate-limit.js (2 hunks)
  • packages/workers/src/routes/account-merge.js (1 hunks)
  • packages/workers/src/routes/admin.js (1 hunks)
  • packages/workers/src/routes/contact.js (1 hunks)
  • packages/workers/src/routes/email.js (1 hunks)
  • packages/workers/src/routes/google-drive.js (1 hunks)
  • packages/workers/src/routes/pdfs.js (1 hunks)
  • packages/workers/src/routes/projects.js (1 hunks)
  • packages/workers/src/routes/users.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/pdfs.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/config/validation.js
  • packages/workers/src/middleware/rate-limit.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/auth/routes.js
  • packages/landing/public/sw.js
  • packages/workers/src/routes/email.js
  • packages/workers/src/durable-objects/ProjectDoc.js
  • packages/workers/src/routes/projects.js
  • packages/workers/src/routes/users.js
  • eslint.config.js
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/pdfs.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/config/validation.js
  • packages/workers/src/middleware/rate-limit.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/auth/routes.js
  • packages/landing/public/sw.js
  • packages/workers/src/routes/email.js
  • packages/workers/src/durable-objects/ProjectDoc.js
  • packages/workers/src/routes/projects.js
  • packages/workers/src/routes/users.js
packages/workers/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/workers/**/*.{js,ts}: Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/pdfs.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/config/validation.js
  • packages/workers/src/middleware/rate-limit.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/auth/routes.js
  • packages/workers/src/routes/email.js
  • packages/workers/src/durable-objects/ProjectDoc.js
  • packages/workers/src/routes/projects.js
  • packages/workers/src/routes/users.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/pdfs.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/config/validation.js
  • packages/workers/src/middleware/rate-limit.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/auth/routes.js
  • packages/landing/public/sw.js
  • packages/workers/src/routes/email.js
  • packages/workers/src/durable-objects/ProjectDoc.js
  • packages/workers/src/routes/projects.js
  • packages/workers/src/routes/users.js
  • eslint.config.js
packages/workers/src/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/workers/src/**/*.{js,ts}: Use Zod for schema and input validation on the backend
Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/pdfs.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/config/validation.js
  • packages/workers/src/middleware/rate-limit.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/auth/routes.js
  • packages/workers/src/routes/email.js
  • packages/workers/src/durable-objects/ProjectDoc.js
  • packages/workers/src/routes/projects.js
  • packages/workers/src/routes/users.js
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/workers/src/routes/account-merge.js
  • .clauderc
  • packages/workers/src/routes/admin.js
  • packages/workers/src/routes/users.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/workers/src/routes/account-merge.js
  • .clauderc
  • packages/workers/src/routes/admin.js
  • .cursorrules
  • packages/workers/src/routes/users.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/workers/src/index.js
  • packages/workers/src/__tests__/admin.test.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/auth/routes.js
  • .cursorrules
  • packages/workers/src/routes/users.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/workers/src/index.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/auth/routes.js
  • packages/workers/src/routes/users.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use Zod for schema and input validation

Applied to files:

  • .clauderc
  • packages/workers/src/config/validation.js
  • .cursorrules
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Zod for schema and input validation on the backend

Applied to files:

  • .clauderc
  • packages/workers/src/config/validation.js
  • .cursorrules
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Use the Corates MCP for documentation about Better-Auth, Drizzle, Icons, and Zag

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Use the Corates MCP tools to explore local documentation sources for Better-Auth, Drizzle, Icons, and Zag documentation

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Zag component exist in `packages/web/src/components/zag/*` and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Zag components exist in `packages/web/src/components/zag/*` and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging

Applied to files:

  • .clauderc
  • .github/copilot-instructions.md
  • .cursorrules
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: corates-workers-prod
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (27)
.cursorrules (2)

36-36: LGTM!

Good clarification that Zod is specifically for backend validation. This aligns with the coding guidelines that specify "Use Zod for schema and input validation on the backend."


43-43: LGTM!

Helpful addition pointing developers to the CoRATES MCP for linting and testing documentation.

.clauderc (1)

36-36: LGTM!

Documentation updates are consistent with the changes in .cursorrules, maintaining alignment across AI instruction files.

Also applies to: 43-43

packages/landing/public/sw.js (1)

76-76: LGTM!

Using spread syntax [...discovered] is the idiomatic ES6+ approach for converting a Set to an array. This aligns with the coding guidelines preference for modern ES6+ syntax.

packages/workers/src/routes/pdfs.js (1)

106-106: LGTM!

Using Number.parseInt instead of the global parseInt is the modern ES6+ approach. The radix parameter (10) is correctly provided.

packages/workers/src/routes/projects.js (1)

277-277: LGTM!

Using let cursor; instead of let cursor = undefined; is a stylistic improvement. Uninitialized variables are implicitly undefined in JavaScript.

packages/workers/src/config/validation.js (1)

88-88: LGTM!

Consistent use of Number.parseInt across the codebase. The transform logic correctly clamps the limit between 1 and 20. As per coding guidelines, Zod is used for backend validation.

packages/workers/src/durable-objects/ProjectDoc.js (6)

73-79: LGTM!

Response.json() is a cleaner, more modern API compared to manually constructing responses with JSON.stringify. This pattern is correctly applied throughout the file.


181-225: LGTM!

Refactoring to a switch statement with explicit add, update, and remove cases improves readability. The // No default comment is appropriate for ESLint when all expected cases are handled.


343-343: LGTM!

Using spread syntax [...fullState] to convert the Uint8Array for storage is consistent with the ES6+ modernization across this PR.


355-355: LGTM!

Spread syntax [...added, ...updated, ...removed] is cleaner than using Array.prototype.concat for combining arrays.


474-486: LGTM!

Good improvements:

  • Renamed len to length for clarity
  • Added default case to log unknown message types, which aids debugging

600-604: LGTM!

Using for...of loops over Map.entries() is more readable than forEach and allows proper use of break/continue if needed. The underscore prefix on unused variables (_sessionData) follows convention for intentionally unused bindings.

Also applies to: 614-618, 627-631

packages/workers/src/index.js (1)

12-12: File rename verified and correct.

The security-headers.js middleware file has been successfully renamed to kebab-case convention. The import path in index.js correctly reflects this change, and the old file has been removed.

eslint.config.js (2)

4-15: LGTM! Plugin configuration is correct.

The unicorn recommended config is properly positioned in the export array so that the custom rule overrides in the main configuration block (lines 107-312) will take precedence.


337-382: Well-structured file-specific configurations.

The targeted config blocks appropriately relax rules for different contexts (durable objects, scripts, MCP tooling, service workers).

.github/copilot-instructions.md (1)

43-43: Documentation update aligns with ESLint configuration changes.

The addition of linting guidance is consistent with the new ESLint configuration introduced in this PR.

packages/workers/src/middleware/rate-limit.js (1)

13-13: Improved numeric literal readability with separators.

The addition of numeric separators (60_000 instead of 60000) improves readability without changing functionality.

Also applies to: 54-54

packages/workers/src/routes/admin.js (1)

19-19: Import path updated to reflect kebab-case file naming.

The import path correctly reflects the middleware file rename from requireAdmin.js to require-admin.js.

packages/workers/src/routes/account-merge.js (1)

29-29: Import path updated to reflect kebab-case file naming.

The import path correctly reflects the middleware file rename from rateLimit.js to rate-limit.js.

packages/workers/src/routes/users.js (2)

20-20: Import path updated to reflect kebab-case file naming.

The import path correctly reflects the middleware file rename from rateLimit.js to rate-limit.js.


50-50: Modern ES6+ syntax adopted for parseInt.

Using Number.parseInt is the modern approach and aligns with the project's preference for ES6+ syntax.

Based on learnings, prefer modern ES6+ syntax and features.

packages/workers/src/auth/routes.js (1)

13-13: Import path updated to reflect kebab-case file naming.

The import path correctly reflects the middleware file rename from rateLimit.js to rate-limit.js.

packages/workers/src/routes/contact.js (1)

9-9: Import path updated to reflect kebab-case file naming.

The import path correctly reflects the middleware file rename from rateLimit.js to rate-limit.js.

packages/workers/src/routes/google-drive.js (1)

243-243: LGTM! Modern ES6+ syntax improvement.

The change from parseInt to Number.parseInt and the explicit > 0 check improve code clarity while maintaining the same behavior. This aligns with the project's preference for modern ES6+ syntax.

Based on coding guidelines and learnings, prefer modern ES6+ syntax and features.

packages/workers/src/__tests__/admin.test.js (1)

28-28: LGTM. The mock import path update from requireAdmin.js to require-admin.js aligns with the kebab-case naming convention. The renamed middleware file exists at the expected location.

packages/workers/src/routes/email.js (1)

7-7: Import path correctly updated to kebab-case. The rename from rateLimit.js to rate-limit.js aligns with the naming convention, the file exists at the new location, and the emailRateLimit export is valid and properly used.

Comment thread eslint.config.js Outdated
'unicorn/switch-case-braces': 'warn',

// Response static JSON - Cloudflare Workers pattern
'unicorn/prefer-response-static-json': 'off',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider enabling prefer-response-static-json or update the rationale.

Cloudflare Workers has supported the static Response.json() method since May 2022, and current documentation examples use Response.json(). The "Cloudflare Workers pattern" comment on line 224 is outdated and no longer applies as a reason to disable this rule.

🤖 Prompt for AI Agents
In eslint.config.js around line 224, the rule
'unicorn/prefer-response-static-json' is disabled with an outdated "Cloudflare
Workers pattern" rationale; either re-enable the rule (set it to 'error' or
'warn') so Response.json() is preferred throughout the codebase, or update the
comment to reflect current Cloudflare Workers support (mentioning
Response.json() has been supported since May 2022) and provide a concrete,
project-specific reason to keep it off; apply the change and run ESLint to fix
any resulting violations or confirm the rationale update.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
eslint.config.js (1)

225-225: Address the outdated rationale for disabling prefer-response-static-json.

As noted in the previous review, Cloudflare Workers has supported the static Response.json() method since May 2022. The comment "Cloudflare Workers pattern" is no longer a valid justification for disabling this rule. Either enable the rule or update the comment with a current, project-specific reason to keep it disabled.

🧹 Nitpick comments (1)
packages/mcp/tools/drizzle.js (1)

43-56: Consider modernizing for consistency (optional).

The traditional for loop starting at line 43 could also be refactored to use for...of with .entries() for consistency with the loop at lines 30-31. Since it starts at a dynamic position (headerEnd), you could slice first:

for (const [idx, line] of lines.slice(headerEnd).entries()) {
  const i = idx + headerEnd;
  // ... rest of logic
}

However, the current traditional loop is clear and the dynamic start position makes it a reasonable choice to keep as-is.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b76c99e and fc6dd02.

📒 Files selected for processing (17)
  • eslint.config.js (4 hunks)
  • packages/landing/src/components/PrefetchLink.jsx (1 hunks)
  • packages/landing/src/entry-client.jsx (1 hunks)
  • packages/mcp/iconSearch.js (1 hunks)
  • packages/mcp/tools/drizzle.js (1 hunks)
  • packages/mcp/tools/local-docs.js (2 hunks)
  • packages/mcp/tools/zag.js (2 hunks)
  • packages/ui/src/__tests__/setup.js (1 hunks)
  • packages/ui/src/zag/Avatar.jsx (3 hunks)
  • packages/ui/src/zag/FileUpload.jsx (4 hunks)
  • packages/web/src/components/UserYjsProvider.jsx (2 hunks)
  • packages/web/src/components/auth-ui/AuthLayout.jsx (1 hunks)
  • packages/web/src/components/auth-ui/CheckEmail.jsx (1 hunks)
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx (1 hunks)
  • packages/web/src/components/auth-ui/SignIn.jsx (1 hunks)
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx (1 hunks)
  • packages/web/src/main.jsx (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/ui/src/tests/setup.js
  • packages/web/src/components/auth-ui/SignIn.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
🧰 Additional context used
📓 Path-based instructions (10)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/mcp/tools/drizzle.js
  • packages/mcp/tools/local-docs.js
  • packages/ui/src/zag/FileUpload.jsx
  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • eslint.config.js
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/ui/src/zag/Avatar.jsx
  • packages/web/src/main.jsx
  • packages/mcp/tools/zag.js
  • packages/mcp/iconSearch.js
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
  • packages/landing/src/entry-client.jsx
  • packages/landing/src/components/PrefetchLink.jsx
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/mcp/tools/drizzle.js
  • packages/mcp/tools/local-docs.js
  • packages/ui/src/zag/FileUpload.jsx
  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/ui/src/zag/Avatar.jsx
  • packages/web/src/main.jsx
  • packages/mcp/tools/zag.js
  • packages/mcp/iconSearch.js
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
  • packages/landing/src/entry-client.jsx
  • packages/landing/src/components/PrefetchLink.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/mcp/tools/drizzle.js
  • packages/mcp/tools/local-docs.js
  • packages/ui/src/zag/FileUpload.jsx
  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • eslint.config.js
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/ui/src/zag/Avatar.jsx
  • packages/web/src/main.jsx
  • packages/mcp/tools/zag.js
  • packages/mcp/iconSearch.js
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
  • packages/landing/src/entry-client.jsx
  • packages/landing/src/components/PrefetchLink.jsx
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/main.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/main.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/main.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/main.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/UserYjsProvider.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/mcp/tools/drizzle.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/mcp/tools/drizzle.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components

Applied to files:

  • packages/ui/src/zag/FileUpload.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components

Applied to files:

  • packages/ui/src/zag/FileUpload.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : When you need to compute a value based on props or state in SolidJS, use `createMemo` to ensure it updates reactively

Applied to files:

  • packages/ui/src/zag/Avatar.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Zag components exist in `packages/web/src/components/zag/*` and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging

Applied to files:

  • packages/mcp/tools/zag.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Zag component exist in `packages/web/src/components/zag/*` and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging

Applied to files:

  • packages/mcp/tools/zag.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • packages/mcp/tools/zag.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • packages/mcp/tools/zag.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
  • packages/landing/src/entry-client.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/landing/src/entry-client.jsx
🧬 Code graph analysis (4)
packages/mcp/tools/drizzle.js (1)
packages/mcp/tools/zag.js (3)
  • i (30-30)
  • i (45-45)
  • lines (26-26)
packages/web/src/components/UserYjsProvider.jsx (3)
packages/web/src/primitives/useProject/sync.js (1)
  • checklistsMap (91-91)
packages/web/src/lib/yjsUtils.js (1)
  • applyObjectToYMap (30-55)
packages/web/src/stores/projectActionsStore/studies.js (1)
  • updates (29-29)
packages/web/src/components/auth-ui/AuthLayout.jsx (17)
packages/workers/src/routes/account-merge.js (4)
  • currentUser (70-70)
  • currentUser (194-194)
  • currentUser (293-293)
  • currentUser (494-494)
packages/workers/src/routes/users.js (3)
  • currentUser (47-47)
  • currentUser (155-155)
  • currentUser (188-188)
packages/web/src/components/auth-ui/CheckEmail.jsx (1)
  • navigate (19-19)
packages/web/src/components/auth-ui/SignIn.jsx (1)
  • navigate (26-26)
packages/web/src/components/auth-ui/TwoFactorVerify.jsx (1)
  • navigate (13-13)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1)
  • navigate (17-17)
packages/web/src/components/project-ui/ProjectView.jsx (1)
  • navigate (34-34)
packages/web/src/components/project-ui/ProjectDashboard.jsx (1)
  • navigate (14-14)
packages/web/src/components/Navbar.jsx (1)
  • navigate (11-11)
packages/web/src/components/auth-ui/CompleteProfile.jsx (1)
  • navigate (25-25)
packages/web/src/components/auth-ui/ResetPassword.jsx (2)
  • navigate (32-32)
  • navigate (153-153)
packages/web/src/components/auth-ui/SignUp.jsx (1)
  • navigate (24-24)
packages/web/src/components/checklist-ui/ChecklistsDashboard.jsx (1)
  • navigate (10-10)
packages/web/src/components/checklist-ui/LocalChecklistView.jsx (1)
  • navigate (20-20)
packages/web/src/components/sidebar/ChecklistTreeItem.jsx (1)
  • navigate (10-10)
packages/web/src/components/sidebar/LocalChecklistItem.jsx (1)
  • navigate (9-9)
packages/web/src/components/sidebar/Sidebar.jsx (1)
  • navigate (18-18)
packages/mcp/tools/zag.js (1)
packages/mcp/tools/drizzle.js (2)
  • lines (26-26)
  • sections (39-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (26)
packages/landing/src/components/PrefetchLink.jsx (1)

12-12: LGTM! Modern DOM API usage.

The change from appendChild to append aligns with the coding guidelines to prefer modern ES6+ syntax and features. Both methods are functionally equivalent for this use case.

Based on coding guidelines, prefer modern ES6+ syntax and features.

packages/mcp/iconSearch.js (1)

19-19: LGTM! Modern syntax improvement.

The change from parseInt to Number.parseInt follows modern ES6+ best practices and is consistent with similar updates across the PR.

Based on learnings, prefer modern ES6+ syntax.

packages/mcp/tools/drizzle.js (1)

30-31: LGTM! Cleaner iteration with modern syntax.

The refactor to for...of with .entries() destructuring is more idiomatic and aligns with ES6+ best practices while maintaining identical behavior.

Based on learnings, prefer modern ES6+ syntax.

packages/web/src/components/UserYjsProvider.jsx (3)

120-129: LGTM! Clearer branching logic.

The reordered conditional makes the update-vs-create logic more explicit and easier to follow. The behavior is correct for both cases.

Based on learnings, this aligns with the preference for modern, readable ES6+ patterns.


134-134: LGTM! Modern spread syntax.

The spread operator [...update] is more concise than Array.from(update) and correctly converts the Uint8Array to a plain array for JSON serialization.

Based on learnings, this change aligns with the preference for modern ES6+ syntax and features.


169-173: LGTM! Modern for-of loop with destructuring.

The for-of loop with destructuring is cleaner and more idiomatic than the previous forEach pattern. The null check on line 170 ensures safe handling if ws is undefined.

Based on learnings, this change aligns with the preference for modern ES6+ syntax. As noted in the AI summary, this pattern matches broader project refactors favoring for-of loops over Object.values().forEach().

packages/ui/src/zag/FileUpload.jsx (3)

43-48: LGTM! Clean utility extraction.

The top-level formatFileSize helper eliminates duplication and provides a reusable function for byte-to-human-readable conversions. The logic is clear and appropriate.

As per coding guidelines, this promotes modularity and follows modern ES6+ patterns.


61-61: LGTM! Modernized iteration patterns.

The changes from Array.from() to spread syntax ([...]) and from traditional for loops to for-of loops follow modern ES6+ conventions. These iterations work on FileList and DataTransferItemList, which are iterable in modern browsers—consistent with the ES6+ features already used throughout this codebase.

As per coding guidelines and learnings, these changes align with the preference for modern ES6+ syntax and features.

Also applies to: 65-65, 173-173


121-121: LGTM! Improved naming consistency.

Renaming allowDirs to allowDirectories improves clarity and aligns the internal function name with the component's prop name, making the code more self-documenting.

Also applies to: 179-179

packages/mcp/tools/local-docs.js (2)

79-79: LGTM: More explicit condition.

The change from available.length to available.length > 0 makes the intent clearer and is more explicit, improving readability.


18-18: The .toSorted() modernization aligns with the coding guidelines for modern ES6+ syntax and is fully supported by the project's runtime. The project requires Node.js 24.0.0+, which includes support for ES2023 features like .toSorted() (available since Node.js 20.0.0). No runtime compatibility concern exists.

Likely an incorrect or invalid review comment.

packages/mcp/tools/zag.js (2)

68-73: LGTM: Cleaner conditional logic.

The refactored conditional logic is more readable by collapsing the nested conditions. The boundary check j - 1 > marker.lineNum properly guards against invalid array access.


97-97: Verify runtime support for toSorted().

Consistent with the modernization in local-docs.js, this change to .toSorted() aligns with coding guidelines. Same runtime verification applies as noted in the other file.

packages/landing/src/entry-client.jsx (1)

60-60: LGTM! Modern DOM selector API.

The switch to querySelector is consistent with modern JavaScript practices and aligns with similar changes throughout this PR.

packages/web/src/main.jsx (1)

15-15: LGTM! Consistent modernization.

The querySelector update aligns with the modernization pattern applied across the codebase and follows ES6+ best practices.

packages/web/src/components/auth-ui/TwoFactorVerify.jsx (1)

93-93: LGTM! Modernized string replacement.

The switch to replaceAll() is more explicit and aligns with the unicorn/prefer-string-replace-all rule being adopted in this PR.

packages/web/src/components/auth-ui/AuthLayout.jsx (1)

35-39: LGTM! Critical redirect logic correction.

This change fixes the inverted redirect logic. Now users with completed profiles correctly go to /dashboard, and users with incomplete profiles are directed to /complete-profile. This is an important behavioral fix beyond just linting.

packages/web/src/components/auth-ui/CheckEmail.jsx (1)

51-55: LGTM! Consistent redirect logic fix.

This aligns with the corrected redirect logic in AuthLayout.jsx, ensuring consistent routing behavior across the authentication flow based on profile completion status.

eslint.config.js (5)

4-15: LGTM! Clean integration of new linting plugins.

The unicorn and sonarjs plugins are properly imported and configured using ESLint's flat config format. The structure applies the recommended unicorn config first, then customizes rules below.


112-222: LGTM! Pragmatic gradual adoption strategy.

The rule customizations strike a good balance:

  • Reasonable exceptions for project patterns (e.g., no-null off for API compatibility, prefer-global-this off for browser idioms)
  • Comprehensive abbreviation allowlist covering common patterns
  • Many rules downgraded to warn for gradual adoption rather than blocking development
  • File naming rules accommodate React/SolidJS component conventions

This approach enables incremental improvement without overwhelming the team.


228-314: LGTM! Comprehensive gradual adoption rules.

The extensive list of rules set to warn provides a clear path for code quality improvements without blocking current development. This pragmatic approach is well-suited for a large codebase adopting stricter linting standards.


338-365: LGTM! Well-scoped configuration overrides.

The targeted config blocks make appropriate exceptions:

  • Durable objects: Allows PascalCase for class-based patterns
  • Scripts/config: Disables all unicorn rules for tooling files (reasonable since they don't ship to production)
  • MCP package: Relaxes rules appropriately for CLI tools (e.g., allowing process.exit)

Each override has clear rationale and proper file path scoping.


367-383: LGTM! Correct service worker configuration.

Disabling prefer-global-this for service workers is correct, as self is the standard global object in service worker scope, not globalThis. The globals are also properly configured.

packages/ui/src/zag/Avatar.jsx (3)

6-6: LGTM: Improved variable naming.

The rename from src to source improves clarity and avoids potential confusion with the JSX src attribute.


37-37: LGTM: Consistent with variable rename.

Correctly updated to use the renamed source() function.


23-23: Array.prototype.at() is incompatible with the Safari 14 build target.

The change from parts[parts.length - 1][0] to parts.at(-1)[0] uses ES2022 syntax, but the vite.config.js specifies a build target of Safari 14 and ES2020, neither of which support Array.prototype.at(). This will cause runtime errors in Safari 14 browsers unless additional transpilation is configured.

Either revert to the previous array indexing syntax or update the build target to ES2022+ if Safari 14 support is no longer required.

⛔ Skipped due to learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts,css} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
eslint.config.js (1)

224-225: Remove the outdated comment.

The rule is currently active (not explicitly disabled), which is correct since Cloudflare Workers has supported Response.json() since May 2022. The commented-out code and outdated rationale should be removed entirely to avoid confusion.

Proposed fix
-      // Response static JSON - Cloudflare Workers pattern
-      // 'unicorn/prefer-response-static-json': 'off',
-
🧹 Nitpick comments (3)
packages/workers/src/routes/members.js (1)

128-153: Consider extracting duplicate field selection and reassessing the ternary pattern.

While the ternary consolidates the branching logic, the ~25-line ternary with duplicated field selections may be harder to read and maintain than the original if/else. Consider:

  1. Extract the duplicate field selection into a constant to follow DRY principles
  2. Evaluate readability trade-offs — long ternaries can be harder to scan than simple if/else blocks
Proposed refactor to reduce duplication
+    const userFieldSelection = {
+      id: user.id,
+      name: user.name,
+      email: user.email,
+      username: user.username,
+      displayName: user.displayName,
+      image: user.image,
+    };
+
-    let userToAdd;
-    userToAdd = await (userId ?
-      db
-        .select({
-          id: user.id,
-          name: user.name,
-          email: user.email,
-          username: user.username,
-          displayName: user.displayName,
-          image: user.image,
-        })
-        .from(user)
-        .where(eq(user.id, userId))
-        .get()
-    : db
-        .select({
-          id: user.id,
-          name: user.name,
-          email: user.email,
-          username: user.username,
-          displayName: user.displayName,
-          image: user.image,
-        })
-        .from(user)
-        .where(eq(user.email, email.toLowerCase()))
-        .get());
+    const userToAdd = await db
+      .select(userFieldSelection)
+      .from(user)
+      .where(userId ? eq(user.id, userId) : eq(user.email, email.toLowerCase()))
+      .get();

This approach eliminates duplication while maintaining clarity by isolating the conditional logic to just the where clause.

Based on learnings, modern ES6+ syntax is preferred.

packages/workers/src/routes/avatars.js (1)

24-24: Good ES6+ modernization, but include Number.parseInt change and note consistency issue.

The Set conversion with .has() is the right modern JavaScript pattern for membership checks. While arrays can be faster for items under 10-20 because memory is close together, the idiomatic approach for 4 MIME types is to use Set.

Also good: the Number.parseInt change on line 75 modernizes away from the global parseInt.

However, packages/web/src/components/profile-ui/ProfilePage.jsx (line 9-140) still uses an array for ALLOWED_TYPES with .includes(). Consider updating it to match for consistency across the codebase.

eslint.config.js (1)

128-167: Consider the value of prevent-abbreviations with extensive exceptions.

The rule allows 33 common abbreviations, which is quite permissive. While this aligns with pragmatic development practices, consider whether the rule still provides meaningful value or if it could be simplified.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6dd02 and 9414784.

📒 Files selected for processing (22)
  • eslint.config.js (4 hunks)
  • packages/web/src/ROBINS-I/checklist-compare.js (4 hunks)
  • packages/web/src/ROBINS-I/checklist-map.js (1 hunks)
  • packages/web/src/primitives/useProject/reconciliation.js (2 hunks)
  • packages/web/src/stores/projectActionsStore/pdfs.js (3 hunks)
  • packages/web/src/stores/projectActionsStore/studies.js (2 hunks)
  • packages/web/src/stores/projectStore.js (1 hunks)
  • packages/workers/src/auth/routes.js (2 hunks)
  • packages/workers/src/config/__tests__/origins.test.js (2 hunks)
  • packages/workers/src/config/constants.js (1 hunks)
  • packages/workers/src/config/origins.js (1 hunks)
  • packages/workers/src/docs.js (1 hunks)
  • packages/workers/src/durable-objects/EmailQueue.js (5 hunks)
  • packages/workers/src/durable-objects/UserSession.js (8 hunks)
  • packages/workers/src/index.js (2 hunks)
  • packages/workers/src/middleware/cors.js (1 hunks)
  • packages/workers/src/middleware/require-admin.js (1 hunks)
  • packages/workers/src/routes/account-merge.js (3 hunks)
  • packages/workers/src/routes/avatars.js (3 hunks)
  • packages/workers/src/routes/contact.js (2 hunks)
  • packages/workers/src/routes/google-drive.js (2 hunks)
  • packages/workers/src/routes/members.js (3 hunks)
✅ Files skipped from review due to trivial changes (4)
  • packages/workers/src/config/constants.js
  • packages/web/src/stores/projectStore.js
  • packages/workers/src/config/tests/origins.test.js
  • packages/workers/src/middleware/cors.js
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/workers/src/auth/routes.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/routes/google-drive.js
  • packages/workers/src/routes/account-merge.js
  • packages/workers/src/index.js
🧰 Additional context used
📓 Path-based instructions (10)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/workers/src/config/origins.js
  • packages/workers/src/docs.js
  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/avatars.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/durable-objects/EmailQueue.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • eslint.config.js
  • packages/workers/src/middleware/require-admin.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/workers/src/config/origins.js
  • packages/workers/src/docs.js
  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/avatars.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/durable-objects/EmailQueue.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/workers/src/middleware/require-admin.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/web/src/ROBINS-I/checklist-map.js
  • packages/workers/src/config/origins.js
  • packages/workers/src/docs.js
  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/avatars.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/durable-objects/EmailQueue.js
  • packages/web/src/primitives/useProject/reconciliation.js
  • packages/web/src/stores/projectActionsStore/studies.js
  • eslint.config.js
  • packages/workers/src/middleware/require-admin.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
packages/workers/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/workers/**/*.{js,ts}: Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/config/origins.js
  • packages/workers/src/docs.js
  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/avatars.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/durable-objects/EmailQueue.js
  • packages/workers/src/middleware/require-admin.js
packages/workers/src/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/workers/src/**/*.{js,ts}: Use Zod for schema and input validation on the backend
Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/config/origins.js
  • packages/workers/src/docs.js
  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/avatars.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/durable-objects/EmailQueue.js
  • packages/workers/src/middleware/require-admin.js
packages/web/src/primitives/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/useProject/reconciliation.js
packages/web/src/stores/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Solid's createStore for complex state or state objects for better performance and reactivity

Files:

  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/stores/projectActionsStore/pdfs.js
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts,css} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/workers/src/durable-objects/UserSession.js
  • packages/workers/src/routes/members.js
  • packages/workers/src/middleware/require-admin.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/workers/src/routes/members.js
  • packages/workers/src/middleware/require-admin.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
🧬 Code graph analysis (4)
packages/web/src/ROBINS-I/checklist-map.js (2)
packages/web/src/components/checklist-ui/ROBINSIChecklist/DomainSection.jsx (1)
  • domain (18-18)
packages/web/src/ROBINS-I/checklist.js (2)
  • domain (133-133)
  • domain (177-177)
packages/workers/src/config/origins.js (1)
packages/workers/src/index.js (1)
  • origin (140-140)
packages/workers/src/routes/avatars.js (2)
packages/web/src/components/profile-ui/ProfilePage.jsx (1)
  • ALLOWED_TYPES (9-9)
packages/workers/src/routes/pdfs.js (2)
  • contentLength (106-106)
  • file (126-126)
packages/workers/src/routes/members.js (6)
packages/workers/src/routes/avatars.js (2)
  • userId (177-177)
  • db (31-31)
packages/workers/src/routes/users.js (6)
  • userId (119-119)
  • userId (157-157)
  • db (56-56)
  • db (126-126)
  • db (156-156)
  • db (189-189)
packages/workers/src/routes/google-drive.js (4)
  • db (112-112)
  • db (129-129)
  • db (161-161)
  • db (192-192)
packages/workers/src/routes/pdfs.js (1)
  • db (33-33)
packages/workers/src/routes/projects.js (4)
  • db (49-49)
  • db (84-84)
  • db (176-176)
  • db (227-227)
packages/workers/src/routes/database.js (1)
  • db (19-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: corates
  • GitHub Check: Workers Builds: corates-workers-prod
🔇 Additional comments (21)
packages/workers/src/config/origins.js (1)

51-55: LGTM! Clean modernization to for...of loop.

The replacement of forEach with a for...of loop maintains identical behavior while aligning with the project's linting standards. The deduplication logic and conditional checks remain unchanged.

packages/web/src/ROBINS-I/checklist-map.js (1)

572-574: LGTM! Modernized to for...of loop.

The refactor from forEach to for...of follows modern ES6+ best practices and aligns with the project's coding guidelines. The transformation is functionally equivalent and maintains the same aggregation behavior.

Based on coding guidelines, prefer modern ES6+ syntax and features.

packages/web/src/ROBINS-I/checklist-compare.js (2)

80-91: LGTM! Modernized to for...of loop.

The refactor from forEach to for...of improves code consistency with modern JavaScript patterns while maintaining identical behavior for stats calculation.

Based on coding guidelines, prefer modern ES6+ syntax and features.


395-407: LGTM! Modernized to for...of loop with destructuring.

The refactor improves readability by using for...of with destructuring, maintaining the same aggregation logic for disagreements tracking.

Based on coding guidelines, prefer modern ES6+ syntax and features.

packages/web/src/primitives/useProject/reconciliation.js (1)

55-74: LGTM! Modernized to for...of loop with destructuring.

The refactor from forEach to for...of maintains the same Y.Map population logic while following modern ES6+ conventions. The collaborative editing behavior remains unchanged.

Based on coding guidelines, prefer modern ES6+ syntax and features.

packages/web/src/stores/projectActionsStore/pdfs.js (2)

61-63: LGTM! Modern DOM API usage.

The changes from appendChild/removeChild to append/remove align with modern JavaScript practices and improve code readability. Both methods are well-supported in modern browsers (Safari 10+ for append(), Safari 7+ for remove()).

As per coding guidelines, please verify that these APIs meet your minimum browser compatibility requirements, especially for Safari.

Based on learnings, modern ES6+ syntax is preferred.


99-99: LGTM! Improved conditional readability.

The refactored conditional logic (hasPdfs ? tag : 'primary') is more readable than the previous version (!hasPdfs ? 'primary' : tag). The new format naturally expresses "if PDFs exist, use the provided tag, otherwise default to primary." Behavior remains unchanged, and both instances are consistently updated.

Also applies to: 194-194

packages/workers/src/middleware/require-admin.js (1)

38-39: LGTM! Clean re-export pattern.

The re-export of isAdminUser as isAdmin provides a cleaner public API. The pattern of importing for internal use (line 7) while re-exporting for external consumers is standard and appropriate.

Filename migration from requireAdmin.js to require-admin.js is complete across the codebase—all imports use the correct new path with no legacy references remaining.

packages/workers/src/routes/avatars.js (1)

75-75: LGTM! Modern ES6+ syntax.

Using Number.parseInt instead of the global parseInt is a good modernization that's consistent with ES6+ best practices and matches the pattern used elsewhere in the codebase (e.g., packages/workers/src/routes/pdfs.js line 105).

Based on learnings, prefer modern ES6+ syntax and features.

packages/workers/src/durable-objects/UserSession.js (1)

43-49: Excellent modernization to Response.json().

The migration from new Response(JSON.stringify(...), {...}) to Response.json(..., {...}) across all response paths is a clean improvement. This modern API is more concise and aligns with the project's preference for ES6+ idioms.

Based on learnings, this follows the guideline to prefer modern ES6+ syntax and features.

Also applies to: 58-64, 89-95, 98-104, 124-135, 155-167, 177-183, 194-205, 213-227, 321-335

packages/workers/src/docs.js (1)

17-18: Good modernization to replaceAll().

The migration from regex-based .replace(/pattern/g, ...) to .replaceAll('literal', ...) improves readability for literal string replacements. The escape order in escapeHtml is correct (ampersand first), and the String.raw usage on line 20, while unconventional, produces the same correctly-escaped output.

Based on learnings, this follows the guideline to prefer modern ES6+ syntax and features.

Also applies to: 20-20

packages/workers/src/durable-objects/EmailQueue.js (1)

26-26: Great modernization across multiple idioms.

All changes here are solid improvements:

  • Lines 26, 32, 35, 159: Response.json() is cleaner and more modern
  • Line 82: Numeric separator 60_000 improves readability
  • Lines 145-151: Multi-line condition with inline comment improves clarity
  • Line 186: Spread syntax [...values()] is more idiomatic than Array.from()

These changes align well with modern JavaScript best practices and maintain identical behavior.

Based on learnings, this follows the guideline to prefer modern ES6+ syntax and features.

Also applies to: 32-32, 35-35, 82-82, 145-151, 159-159, 186-186

packages/web/src/stores/projectActionsStore/studies.js (2)

24-98: LGTM! Excellent refactoring.

The extraction of these three helper functions to module scope significantly improves code organization and eliminates duplication. The functions are well-documented, properly structured, and follow the DRY principle.


234-234: replaceAll is safe for this project's browser support targets.

The replaceAll method is supported in Safari 13.1, and the project targets Safari 14+ per vite.config.ts (build: { target: ['es2020', 'safari14'] }). The change aligns with the ES2020 build target and the coding guideline preference for modern ES6+ syntax. No browser compatibility issue exists.

eslint.config.js (7)

4-5: LGTM! Clean plugin integration.

The unicorn and sonarjs plugins are properly imported and the recommended unicorn configuration is correctly applied at the top level. The subsequent rule overrides (lines 107-314) will appropriately customize the recommended defaults.

Also applies to: 10-10


112-125: Well-configured filename casing.

The filename-case rule appropriately balances consistency with practical exceptions for component files, config files, and constants. The 'warn' severity supports gradual adoption.


170-183: Well-justified rule overrides.

Each override has a clear rationale. The decisions to allow null, prefer window over globalThis for browser code, and allow event handler properties for IndexedDB align with practical JavaScript patterns.


187-314: Pragmatic gradual adoption strategy.

The extensive use of 'warn' severity (30+ rules) enables incremental adoption of unicorn's recommendations. While this will generate numerous warnings, it's a deliberate strategy to avoid blocking development while improving code quality over time.


338-365: Excellent file-scope overrides.

The targeted exemptions are well-justified:

  • Durable objects allow PascalCase naming for class files
  • Scripts disable all unicorn rules using a maintainable Object.fromEntries pattern
  • MCP tooling code gets appropriate relaxations for CLI patterns

The approach is both pragmatic and maintainable.


379-382: Correct service worker configuration.

Disabling prefer-global-this for service workers is appropriate, as self is the standard global object in the Web Workers specification.


13-15: Consider removing unused sonarjs plugin or enabling its rules.

The sonarjs plugin is typically configured either with its recommended config or with explicitly selected rules. Currently, the plugin is registered in the configuration but has zero active rules, making it non-functional. Either remove the plugin registration and import if it's not ready to be used, or enable at least the recommended rules. If gradual adoption is intended, explicitly set specific rules (e.g., 'sonarjs/cognitive-complexity': 'warn') rather than leaving them commented out with the plugin inactive.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
eslint.config.js (1)

227-228: The rule is now using the default (recommended), but the comment is still misleading.

The rule is now commented out, which means the recommended config's default will apply (likely enabled). However, the comment "Cloudflare Workers pattern" is still present and outdated. Consider removing the commented line entirely or updating the comment to reflect that Response.json() is now the preferred pattern.

🧹 Nitpick comments (5)
packages/workers/src/routes/googleDrive.js (1)

82-83: Add braces for the if statement or move return to same line.

The if statement spanning multiple lines without braces can be confusing and is typically flagged by linters. For better readability and maintainability, either add braces or move the return statement to the same line as the condition.

🔎 Suggested fix

Option 1: Single line (if statement is simple enough)

-  if ((!expiresAt || Number.isNaN(new Date(expiresAt).getTime())) && tokens.accessToken)
-    return tokens.accessToken;
+  if ((!expiresAt || Number.isNaN(new Date(expiresAt).getTime())) && tokens.accessToken) return tokens.accessToken;

Option 2: Add braces (preferred for multi-line conditions)

-  if ((!expiresAt || Number.isNaN(new Date(expiresAt).getTime())) && tokens.accessToken)
-    return tokens.accessToken;
+  if ((!expiresAt || Number.isNaN(new Date(expiresAt).getTime())) && tokens.accessToken) {
+    return tokens.accessToken;
+  }
packages/workers/src/middleware/requireAdmin.js (2)

7-7: Consider consolidating the duplicate import.

The module imports isAdminUser from '../auth/admin.js' on line 7 for internal use, then re-exports it again from the same module on line 39. Since the import already exists, you can simplify the re-export without the module path:

🔎 Proposed refactor to eliminate duplicate import
 import { createAuth } from '../auth/config.js';
 import { isAdminUser } from '../auth/admin.js';
+export { isAdminUser as isAdmin };

Then remove line 39:

   }
 }
-
-export { isAdminUser as isAdmin } from '../auth/admin.js';

This avoids redundant module resolution while maintaining the same public API.

Also applies to: 39-39


13-37: Consider adding Zod validation for session and user objects.

The middleware correctly uses Better-Auth for authentication, but per coding guidelines, backend code should use Zod for schema and input validation. Consider validating the session structure and user properties to catch unexpected data shapes early.

This is pre-existing code and outside the scope of this lint-fixes PR, but worth considering for future improvements. Based on coding guidelines, backend code should use Zod for validation.

eslint.config.js (2)

13-15: sonarjs plugin is imported but has no active rules.

The sonarjs plugin is added to the plugins object, but the only sonarjs rule (sonarjs/cognitive-complexity on line 105) is commented out. Consider either enabling at least one sonarjs rule or removing the unused plugin import and configuration to avoid unnecessary dependencies.


355-357: Consider adding a defensive check for eslintPluginUnicorn.rules.

The dynamic generation of rule overrides assumes eslintPluginUnicorn.rules is always defined and iterable. While this is currently the case, adding a defensive check would prevent runtime errors if the plugin's structure changes in a future version.

🔎 Proposed defensive check
     rules: Object.fromEntries(
-      Object.keys(eslintPluginUnicorn.rules).map(rule => [`unicorn/${rule}`, 'off']),
+      Object.keys(eslintPluginUnicorn.rules ?? {}).map(rule => [`unicorn/${rule}`, 'off']),
     ),
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9414784 and ddbf9e2.

📒 Files selected for processing (45)
  • eslint.config.js (4 hunks)
  • packages/web/src/api/__tests__/better-auth-store.test.js (11 hunks)
  • packages/web/src/api/betterAuthStore.js (1 hunks)
  • packages/web/src/components/Dashboard.jsx (1 hunks)
  • packages/web/src/components/HomePage.jsx (1 hunks)
  • packages/web/src/components/Navbar.jsx (1 hunks)
  • packages/web/src/components/auth-ui/AuthLayout.jsx (2 hunks)
  • packages/web/src/components/auth-ui/CheckEmail.jsx (2 hunks)
  • packages/web/src/components/auth-ui/CompleteProfile.jsx (1 hunks)
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx (1 hunks)
  • packages/web/src/components/auth-ui/ProtectedGuard.jsx (1 hunks)
  • packages/web/src/components/auth-ui/ResetPassword.jsx (1 hunks)
  • packages/web/src/components/auth-ui/SignIn.jsx (2 hunks)
  • packages/web/src/components/auth-ui/SignUp.jsx (1 hunks)
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (1 hunks)
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx (1 hunks)
  • packages/web/src/components/profile-ui/LinkedAccountsSection.jsx (1 hunks)
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx (1 hunks)
  • packages/web/src/components/profile-ui/ProfilePage.jsx (1 hunks)
  • packages/web/src/components/profile-ui/SettingsPage.jsx (1 hunks)
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx (1 hunks)
  • packages/web/src/components/project-ui/ProjectContext.jsx (1 hunks)
  • packages/web/src/components/project-ui/ProjectDashboard.jsx (1 hunks)
  • packages/web/src/components/project-ui/ProjectView.jsx (1 hunks)
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx (1 hunks)
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx (1 hunks)
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx (1 hunks)
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (1 hunks)
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx (1 hunks)
  • packages/web/src/components/sidebar/Sidebar.jsx (1 hunks)
  • packages/web/src/stores/projectActionsStore/index.js (1 hunks)
  • packages/web/src/stores/projectActionsStore/pdfs.js (4 hunks)
  • packages/web/src/stores/projectActionsStore/studies.js (3 hunks)
  • packages/workers/scripts/generate-openapi.mjs (1 hunks)
  • packages/workers/src/auth/routes.js (1 hunks)
  • packages/workers/src/index.js (3 hunks)
  • packages/workers/src/middleware/rateLimit.js (2 hunks)
  • packages/workers/src/middleware/requireAdmin.js (1 hunks)
  • packages/workers/src/routes/accountMerge.js (2 hunks)
  • packages/workers/src/routes/admin.js (1 hunks)
  • packages/workers/src/routes/contact.js (1 hunks)
  • packages/workers/src/routes/googleDrive.js (2 hunks)
  • packages/workers/src/routes/users.js (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/web/src/components/auth-ui/ProtectedGuard.jsx
  • packages/web/src/components/profile-ui/LinkedAccountsSection.jsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/workers/src/routes/users.js
  • packages/workers/src/routes/contact.js
  • packages/workers/src/auth/routes.js
  • packages/web/src/components/auth-ui/SignIn.jsx
  • packages/web/src/components/auth-ui/TwoFactorVerify.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
🧰 Additional context used
📓 Path-based instructions (13)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/workers/src/middleware/rateLimit.js
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/workers/src/middleware/requireAdmin.js
  • packages/workers/src/routes/accountMerge.js
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/workers/src/routes/admin.js
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/workers/src/index.js
  • packages/web/src/components/HomePage.jsx
  • packages/workers/scripts/generate-openapi.mjs
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • eslint.config.js
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/workers/src/routes/googleDrive.js
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/workers/src/middleware/rateLimit.js
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/workers/src/middleware/requireAdmin.js
  • packages/workers/src/routes/accountMerge.js
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/workers/src/routes/admin.js
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/workers/src/index.js
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/workers/src/routes/googleDrive.js
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/workers/src/middleware/rateLimit.js
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/workers/src/middleware/requireAdmin.js
  • packages/workers/src/routes/accountMerge.js
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/workers/src/routes/admin.js
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/workers/src/index.js
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • eslint.config.js
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/workers/src/routes/googleDrive.js
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/add-studies/GoogleDriveSection.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
packages/web/src/stores/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Solid's createStore for complex state or state objects for better performance and reactivity

Files:

  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/stores/projectActionsStore/studies.js
packages/workers/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/workers/**/*.{js,ts}: Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/middleware/rateLimit.js
  • packages/workers/src/middleware/requireAdmin.js
  • packages/workers/src/routes/accountMerge.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/googleDrive.js
packages/workers/src/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/workers/src/**/*.{js,ts}: Use Zod for schema and input validation on the backend
Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/middleware/rateLimit.js
  • packages/workers/src/middleware/requireAdmin.js
  • packages/workers/src/routes/accountMerge.js
  • packages/workers/src/routes/admin.js
  • packages/workers/src/index.js
  • packages/workers/src/routes/googleDrive.js
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : For complex state or state objects in SolidJS, use Solid's `createStore` for better performance and reactivity

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/stores/**/*.{js,ts} : Use Solid's `createStore` for complex state or state objects for better performance and reactivity

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/workers/src/middleware/requireAdmin.js
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/workers/src/index.js
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/auth-ui/CheckEmail.jsx
  • packages/workers/src/routes/googleDrive.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/workers/src/middleware/requireAdmin.js
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/workers/src/index.js
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/workers/src/routes/googleDrive.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/MagicLinkForm.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/GoogleDriveSettings.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/auth-ui/AuthLayout.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/api/betterAuthStore.js
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/stores/projectActionsStore/index.js
  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : When you need to compute a value based on props or state in SolidJS, use `createMemo` to ensure it updates reactively

Applied to files:

  • packages/web/src/components/auth-ui/CompleteProfile.jsx
  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/auth-ui/ResetPassword.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • packages/web/src/components/auth-ui/SignUp.jsx
  • packages/web/src/components/profile-ui/SettingsPage.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context

Applied to files:

  • packages/web/src/components/project-ui/ProjectContext.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives

Applied to files:

  • packages/web/src/components/project-ui/ProjectContext.jsx
  • packages/web/src/components/Navbar.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives

Applied to files:

  • packages/web/src/components/project-ui/ProjectContext.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `createMemo` for derived values to ensure they update reactively

Applied to files:

  • packages/web/src/components/project-ui/ProjectContext.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx,js} : Group related components in subdirectories with an `index.js` barrel export

Applied to files:

  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/HomePage.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Group related components in subdirectories with an index.js barrel export

Applied to files:

  • packages/web/src/components/Dashboard.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/workers/src/index.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Drizzle ORM for database interactions and migrations

Applied to files:

  • packages/workers/src/index.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Applied to files:

  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/primitives/**/*.{js,ts} : Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Applied to files:

  • packages/web/src/components/sidebar/Sidebar.jsx
🧬 Code graph analysis (2)
packages/workers/src/routes/admin.js (1)
packages/workers/src/routes/users.js (1)
  • limit (50-50)
packages/web/src/api/__tests__/better-auth-store.test.js (1)
packages/web/src/api/authClient.js (4)
  • authClient (10-29)
  • authClient (10-29)
  • authClient (32-44)
  • authClient (32-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: corates-workers-prod
  • GitHub Check: Workers Builds: corates

Comment thread packages/web/src/components/auth-ui/AuthLayout.jsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
eslint.config.js (1)

228-229: Remove the outdated comment for enabled rule.

The commented-out rule means unicorn/prefer-response-static-json is now enabled (inheriting from the recommended config), which is correct for Cloudflare Workers. However, the "Cloudflare Workers pattern" comment is misleading and outdated. Remove these lines entirely since the default behavior is appropriate.

🔎 Proposed fix
-      // Response static JSON - Cloudflare Workers pattern
-      // 'unicorn/prefer-response-static-json': 'off',
-
🧹 Nitpick comments (1)
packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (1)

242-243: Consider modernizing similar patterns in related files.

The modernization in this file improves readability. For consistency, consider applying the same pattern updates to related files that still use [array.length - 1]:

  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (line 14)
  • packages/web/src/AMSTAR2/checklist-compare.js (line 189)
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js (lines 21, 27)

This would maintain a uniform modern style across the checklist reconciliation components. Based on learnings, prefer modern ES6+ syntax and features.

Also applies to: 248-249

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddbf9e2 and 7d6319f.

📒 Files selected for processing (13)
  • eslint.config.js (4 hunks)
  • packages/web/src/api/betterAuthStore.js (3 hunks)
  • packages/web/src/components/charts/AMSTARDistribution.jsx (4 hunks)
  • packages/web/src/components/charts/AMSTARRobvis.jsx (5 hunks)
  • packages/web/src/components/checklist-ui/AMSTAR2Checklist.jsx (19 hunks)
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx (2 hunks)
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/web/src/components/checklist-ui/AMSTAR2Checklist.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/api/betterAuthStore.js
🧰 Additional context used
📓 Path-based instructions (10)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • eslint.config.js
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • eslint.config.js
  • packages/web/src/components/charts/AMSTARRobvis.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/LocalChecklistView.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use responsive design principles for UI components

Applied to files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/common/NoteEditor.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Use responsive design principles for UI components

Applied to files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/web/src/components/profile-ui/MergeAccountsDialog.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
🧬 Code graph analysis (5)
packages/web/src/components/checklist-ui/LocalChecklistView.jsx (1)
packages/web/src/checklist-registry/index.js (3)
  • checklist (70-70)
  • getChecklistTypeFromState (91-110)
  • scoreChecklistOfType (81-84)
packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1)
packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1)
  • layout (33-33)
packages/web/src/components/charts/AMSTARDistribution.jsx (1)
packages/web/src/components/charts/AMSTARRobvis.jsx (1)
  • data (62-62)
packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (5)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)
  • lastCol (15-15)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (2)
  • lastCol (22-22)
  • lastCol (28-28)
packages/web/src/AMSTAR2/checklist-compare.js (1)
  • lastCol (190-190)
packages/workers/src/routes/pdfs.js (3)
  • key (193-193)
  • key (249-249)
  • key (297-297)
packages/web/src/components/checklist-ui/compare/Navbar.jsx (1)
  • key (38-38)
packages/web/src/components/charts/AMSTARRobvis.jsx (1)
packages/web/src/components/charts/AMSTARDistribution.jsx (1)
  • data (24-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (20)
packages/web/src/components/checklist-ui/CreateLocalChecklist.jsx (1)

69-79: LGTM! Clean readability improvement.

The extraction of searchParams.from into a descriptive fromParameter variable improves code clarity without altering behavior. This aligns well with the PR's lint-fix objective.

Based on learnings, this follows the preference for modern ES6+ syntax and improved readability.

packages/web/src/components/checklist-ui/LocalChecklistView.jsx (2)

145-149: LGTM! Variable naming improvement.

Renaming curr to current improves readability and aligns with modern coding practices.


152-157: LGTM! Consistent naming improvement.

The variable renaming from curr to current maintains consistency with the checklistType function and enhances code clarity.

packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx (2)

97-97: LGTM! Variable rename improves clarity.

The parameter rename from arr to array makes the mapping operation more readable and self-documenting.


113-113: LGTM! Consistent naming improvement.

Same beneficial rename as line 97, maintaining consistency across similar array operations.

packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1)

52-55: LGTM! Clean modernization of ratio calculation.

The refactor from if-else to a ternary expression is appropriate for this simple conditional assignment. The logic correctly uses horizontal offset (clientX) for vertical layout and vertical offset (clientY) for horizontal layout, and the multi-line formatting maintains readability.

Based on learnings, this aligns with the preference for modern ES6+ syntax.

packages/web/src/components/charts/AMSTARDistribution.jsx (4)

94-94: LGTM: Guard clause clarified

Making the empty check explicit improves code clarity.


125-136: Excellent modernization to for-of loops

The conversion from forEach to for-of loops improves readability and aligns with modern ES6+ best practices. As per coding guidelines and learnings, preferring modern syntax enhances code quality.


170-213: Well-structured nested for-of loops

The nested loop refactoring maintains the same iteration order and logic while improving readability. The explicit iteration pattern is clearer than the previous forEach approach.


94-213: Clean lint fixes improve code quality

This refactoring successfully modernizes loop patterns throughout the component while preserving all functionality. The changes align well with the project's coding guidelines and learnings about preferring modern ES6+ syntax.

packages/web/src/components/charts/AMSTARRobvis.jsx (3)

112-112: LGTM: Explicit zero-length check improves clarity.

The explicit comparison data().length === 0 is more readable and defensive than the falsy check. This aligns with modern ESLint rules and improves code clarity.


128-137: LGTM: Modern for...of loop improves consistency.

The conversion from forEach to for...of aligns with modern JavaScript best practices and ESLint unicorn rules. This provides better control flow options and maintains identical logic. Based on coding guidelines emphasizing modern ES6+ syntax.


192-216: LGTM: Modern iteration with entries() maintains clarity.

The conversion to for (const [rowIdx, row] of data().entries()) is a clean, modern pattern that provides both the index and element. The nested traditional for loop for colIdx is appropriately retained for numeric iteration. This change aligns with ESLint rules and coding guidelines. Based on learnings and guidelines emphasizing modern ES6+ syntax.

packages/web/src/components/checklist-ui/common/NoteEditor.jsx (1)

119-119: LGTM - Clean CSS class refactoring.

The conditional class logic is correct and consistent with the disabled attribute above. This refactoring maintains the same visual behavior while consolidating the conditionals.

eslint.config.js (3)

13-15: Verify the intent for sonarjs plugin.

The sonarjs plugin is imported and registered but no rules are actively configured (line 105 is commented out). If you plan to enable sonarjs rules in this PR, please uncomment and configure them. If it's for future use, consider adding a comment explaining the intent.

Also applies to: 105-105


107-318: Well-structured unicorn rule configuration.

The gradual adoption strategy using 'warn' for most rules is pragmatic for introducing unicorn to an existing codebase. The rules explicitly disabled ('off') have clear justifications (API compatibility, idiomatic browser patterns, etc.), and the extensive comments make the configuration maintainable.


342-369: Appropriate file-specific overrides.

The scoped rule overrides are well-justified:

  • Durable objects use PascalCase file names (pattern-based naming)
  • Scripts/config files need flexibility for tooling
  • MCP package relaxations are appropriate for CLI tools
  • Service worker correctly uses self over globalThis

Each override block has clear scope and rationale.

Also applies to: 383-386

packages/web/src/components/profile-ui/MergeAccountsDialog.jsx (2)

115-115: Explicit length check improves clarity.

The explicit > 0 comparison is clearer than relying on truthy evaluation of the length property. This modernization improves code readability.


19-19: Verify the updated import path and filename.

The import path update to @/api/accountMerge.js (camelCase) is correct. The file exists at packages/web/src/api/accountMerge.js, all required exports are present, and no references to the old account-merge.js filename remain in the codebase. The alias is properly configured in both vite.config.js and jsconfig.json.

packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (1)

242-243: Modernization looks good — changes are safe and align with project guidelines.

The changes modernize array access patterns effectively:

  • Array.prototype.at() has been available across browsers since March 2022, making it well-established for modern browser support
  • at(-1) is cleaner than [array.length - 1] for accessing the last element
  • includes(true) is more concise and semantically equivalent to some(v => v === true)
  • Optional chaining ?.at(-1) safely handles undefined/null arrays

These changes align with the coding guideline to prefer modern ES6+ syntax. Since your project has no explicit constraints on older browser versions and uses modern patterns (SolidJS, TypeScript), Array.at() is a safe modernization choice.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (1)
packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (1)

194-200: Auto-generation detection heuristic doesn't match actual label format.

The logic checks for " - " to detect auto-generated labels (line 196), but the actual label format on line 171 is just the study name without a separator or reviewer name. This mismatch means auto-generated labels will never be detected, preventing label updates when underlying data changes.

Proposed fix: Update detection heuristic
         if (customItem && customItem.label !== rawItem.label) {
-          // Check if the label was likely auto-generated (contains " - ")
-          const wasAutoGenerated = customItem.label.includes(' - ');
+          // Check if the label was auto-generated by comparing structure
+          // Auto-generated labels are just the study name (possibly truncated with "...")
+          const wasAutoGenerated = !customItem.label.includes('\n') && 
+            (customItem.label.endsWith('...') || customItem.label.length <= 20);
           if (wasAutoGenerated) {
             setCustomLabels(i, 'label', rawItem.label);
           }

Alternatively, if labels should include reviewer names, update line 171:

-          label: `${study.name.length > 20 ? study.name.slice(0, 20) + '...' : study.name}`,
+          label: `${study.name.length > 20 ? study.name.slice(0, 20) + '...' : study.name} - ${reviewerName}`,
♻️ Duplicate comments (1)
eslint.config.js (1)

229-230: Remove or update the outdated comment.

The commented-out rule and its "Cloudflare Workers pattern" comment are outdated. Since the rule is commented out, prefer-response-static-json is active at the 'error' level from the recommended config, which is correct for modern Cloudflare Workers (Response.json() has been supported since May 2022).

Remove the commented line and outdated comment, or add a clarifying note if there's a specific project reason to document this.

Based on past review comments indicating this rationale is outdated.

🧹 Nitpick comments (6)
packages/ui/src/zag/__tests__/RadioGroup.test.jsx (1)

230-230: Consider direct indexing for NodeList access.

While the spread syntax is consistent with the modernization theme, NodeList already supports bracket notation for index access. You could simplify these lines slightly:

🔎 Optional simplification
-      const option1Control = [...controls][0];
+      const option1Control = controls[0];
-      const option2Control = [...controls][1];
+      const option2Control = controls[1];

This avoids the unnecessary array conversion when only accessing by index. The performance difference in tests is negligible, so this is purely a stylistic suggestion.

Also applies to: 240-240

packages/web/src/lib/yjsUtils.js (1)

14-16: Consider using for...of for consistency with modernization theme.

The traditional for loop works correctly but is inconsistent with the modernization applied elsewhere in this PR (lines 33, 41, 67). Y.Array is iterable, so you can use the modern for...of syntax.

Suggested refactor for consistency
-    const array = [];
-    for (let i = 0; i < value.length; i++) array.push(yToPlain(value.get(i)));
-    return array;
+    const array = [];
+    for (const item of value) array.push(yToPlain(item));
+    return array;

Based on coding guidelines emphasizing modern ES6+ syntax.

eslint.config.js (3)

350-360: Consider selectively disabling unicorn rules instead of all rules.

Disabling all unicorn rules for scripts and config files is overly broad. Many rules (like prefer-includes, prefer-string-replace-all, no-array-for-each) provide value for code quality in scripts and configs.

Consider disabling only the specific rules that are problematic for tooling code:

  • unicorn/filename-case (config files have specific naming)
  • unicorn/prefer-top-level-await (may not work in all config contexts)
  • unicorn/prevent-abbreviations (more lenient for tooling)
  • unicorn/no-process-exit (needed in CLI tools)
  • unicorn/prefer-node-protocol (if using standard imports)
More selective approach
   {
     // Scripts and config files - disable problematic unicorn rules
     files: [
       '**/scripts/**/*.{js,jsx,ts,tsx,mjs}',
       '**/vite.config.{js,ts,mjs}',
       '**/*.config.{js,ts,mjs}',
     ],
-    rules: Object.fromEntries(
-      Object.keys(eslintPluginUnicorn.rules).map(rule => [`unicorn/${rule}`, 'off']),
-    ),
+    rules: {
+      'unicorn/filename-case': 'off',
+      'unicorn/prefer-top-level-await': 'off',
+      'unicorn/prevent-abbreviations': 'off',
+      'unicorn/no-process-exit': 'off',
+      'unicorn/prefer-node-protocol': 'off',
+    },
   },

130-172: Consider reducing allowed abbreviations for better code clarity.

The prevent-abbreviations configuration allows 36 different abbreviations, which significantly reduces the rule's effectiveness. While flexibility for common terms like props, args, and params is reasonable, allowing single letters (i, j, e) and generic abbreviations (tmp, val, num, cb) undermines the clarity this rule promotes.

For a "lint fixes" PR that's modernizing patterns, consider being more selective about which abbreviations to allow, keeping only the most domain-specific or framework-required ones (like props, req, res, ctx).


107-318: Document the timeline for graduating warnings to errors.

Most unicorn rules are configured as 'warn' for gradual adoption (lines 196-318). While this is a reasonable strategy, warnings are often ignored in development and don't provide strong quality gates.

Consider:

  • Documenting a timeline or process for upgrading warnings to errors
  • Enabling a subset of non-controversial rules as 'error' immediately (e.g., no-zero-fractions, number-literal-case, no-useless-undefined)
  • Adding a tracking issue for graduating rules from warn to error

This ensures the linting investment provides long-term value rather than accumulating ignored warnings.

packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)

115-115: Minor readability improvement.

Renaming arr to array in the map callbacks improves clarity without changing behavior.

Also applies to: 129-129

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d6319f and 1c422ec.

📒 Files selected for processing (40)
  • eslint.config.js (4 hunks)
  • packages/ui/src/zag/__tests__/Dialog.test.jsx (2 hunks)
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx (9 hunks)
  • packages/web/TESTING.md (1 hunks)
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js (4 hunks)
  • packages/web/src/AMSTAR2/checklist-compare.js (3 hunks)
  • packages/web/src/AMSTAR2/checklist.js (6 hunks)
  • packages/web/src/ROBINS-I/checklist.js (7 hunks)
  • packages/web/src/api/__tests__/better-auth-store.test.js (11 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js (17 hunks)
  • packages/web/src/components/profile-ui/ProfilePage.jsx (2 hunks)
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx (2 hunks)
  • packages/web/src/components/project-ui/AddStudiesForm.jsx (1 hunks)
  • packages/web/src/components/project-ui/ProjectDashboard.jsx (2 hunks)
  • packages/web/src/components/project-ui/ProjectView.jsx (4 hunks)
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (4 hunks)
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (6 hunks)
  • packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx (1 hunks)
  • packages/web/src/lib/__tests__/pdfUtils.test.js (1 hunks)
  • packages/web/src/lib/__tests__/referenceLookup.test.js (1 hunks)
  • packages/web/src/lib/accountLinkingErrors.js (1 hunks)
  • packages/web/src/lib/googlePicker.js (1 hunks)
  • packages/web/src/lib/pdfUtils.js (4 hunks)
  • packages/web/src/lib/referenceLookup.js (6 hunks)
  • packages/web/src/lib/referenceParser.js (5 hunks)
  • packages/web/src/lib/yjsUtils.js (3 hunks)
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js (4 hunks)
  • packages/web/src/primitives/__tests__/useProject.test.js (5 hunks)
  • packages/web/src/primitives/avatarCache.js (1 hunks)
  • packages/web/src/primitives/useAddStudies.js (4 hunks)
  • packages/web/src/primitives/useNotifications.js (2 hunks)
  • packages/web/src/primitives/useProject/checklists.js (12 hunks)
  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js (5 hunks)
✅ Files skipped from review due to trivial changes (5)
  • packages/workers/src/durable-objects/tests/ProjectDoc.test.js
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/primitives/useNotifications.js
  • packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx
  • packages/web/src/primitives/useAddStudies.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/api/tests/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • eslint.config.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/web/TESTING.md
  • packages/ui/src/zag/__tests__/Dialog.test.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/ui/src/zag/__tests__/Dialog.test.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/lib/__tests__/referenceLookup.test.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/AMSTAR2/checklist.js
  • eslint.config.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/ui/src/zag/__tests__/Dialog.test.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/primitives/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/TESTING.md
  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/TESTING.md
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : For complex state or state objects in SolidJS, use Solid's `createStore` for better performance and reactivity

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : For UI icons, use the `solid-icons` library or SVGs only. Do not use emojis

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : For UI icons, use the `solid-icons` library or SVGs only. Do not use emojis

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/stores/**/*.{js,ts} : Use Solid's `createStore` for complex state or state objects for better performance and reactivity

Applied to files:

  • packages/web/src/components/profile-ui/ProfilePage.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
🧬 Code graph analysis (10)
packages/web/src/AMSTAR2/__tests__/checklist.test.js (2)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (2)
  • lastCol (22-22)
  • lastCol (28-28)
packages/web/src/AMSTAR2/checklist-compare.js (1)
  • lastCol (190-190)
packages/web/src/primitives/useProject/checklists.js (2)
packages/web/src/components/checklist-ui/AMSTAR2Checklist.jsx (1)
  • questionKey (669-673)
packages/web/src/checklist-registry/types.js (2)
  • CHECKLIST_TYPES (11-18)
  • CHECKLIST_TYPES (11-18)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (5)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (2)
  • lastCol (22-22)
  • lastCol (28-28)
packages/web/src/AMSTAR2/checklist-compare.js (2)
  • lastCol (190-190)
  • idx (193-193)
packages/web/src/components/checklist-ui/compare/AnswerPanel.jsx (2)
  • answers (31-31)
  • question (28-28)
packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx (2)
  • question (13-13)
  • questionKey (12-12)
packages/web/src/components/checklist-ui/AMSTAR2Checklist.jsx (15)
  • question (10-10)
  • question (41-41)
  • question (74-74)
  • question (105-105)
  • question (140-140)
  • question (170-170)
  • question (200-200)
  • question (234-234)
  • question (269-269)
  • question (371-371)
  • question (402-402)
  • question (501-501)
  • question (539-539)
  • question (569-569)
  • questionKey (669-673)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (1)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)
  • lastCol (15-15)
packages/web/src/AMSTAR2/checklist-compare.js (3)
packages/web/src/AMSTAR2/checklist.js (3)
  • lastCol (191-191)
  • answers (276-276)
  • idx (193-193)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (2)
  • lastCol (15-15)
  • idx (17-17)
packages/web/src/components/checklist-ui/compare/AnswerPanel.jsx (1)
  • answers (31-31)
packages/web/src/AMSTAR2/checklist.js (1)
packages/web/src/AMSTAR2/checklist-compare.js (4)
  • lastCol (190-190)
  • idx (193-193)
  • questionKeys (54-54)
  • questionKeys (244-244)
packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1)
packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1)
  • layout (16-16)
packages/web/src/components/project-ui/AddStudiesForm.jsx (1)
packages/ui/src/zag/FileUpload.jsx (2)
  • files (14-14)
  • files (56-56)
packages/web/src/components/profile-ui/ProfilePage.jsx (2)
packages/workers/src/routes/avatars.js (2)
  • ALLOWED_TYPES (24-24)
  • file (92-92)
packages/ui/src/zag/FileUpload.jsx (2)
  • file (28-30)
  • file (75-77)
packages/web/src/components/project-ui/ProjectView.jsx (2)
packages/web/src/components/project-ui/reconcile-tab/ReconcileStudyCard.jsx (1)
  • completedChecklists (17-19)
packages/web/src/components/project-ui/reconcile-tab/ReconcileStatusTag.jsx (1)
  • completedChecklists (11-12)
🪛 Biome (2.1.2)
packages/web/src/AMSTAR2/checklist.js

[error] 305-305: Do not shadow the global "escape" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (66)
packages/web/TESTING.md (1)

159-164: Documentation updated correctly to reflect standardized import paths.

The mocking example has been updated from @api/better-auth-store to @api/betterAuthStore, keeping the documentation in sync with the codebase changes for import path standardization.

packages/web/src/lib/googlePicker.js (1)

30-30: LGTM! Modern DOM API usage.

Replacing appendChild with append aligns with modern ES6+ standards and the codebase's preference for contemporary syntax.

packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1)

64-67: LGTM: Clean refactor to ternary expression.

The replacement of the if-else block with a ternary expression maintains the same logic while following modern ES6+ practices. The multi-line formatting preserves readability, and the logic correctly computes the ratio based on layout orientation.

packages/ui/src/zag/__tests__/Dialog.test.jsx (2)

185-185: LGTM! Improved parameter naming.

The rename from btn to button improves readability and aligns with modern ES6+ coding standards.


293-295: LGTM! Modern iteration pattern.

The conversion from forEach to for-of loop modernizes the code and aligns with ES6+ best practices from the coding guidelines.

packages/web/src/primitives/avatarCache.js (1)

242-242: LGTM! Modern ES6+ syntax adopted.

Using Number.parseInt over the global parseInt is more explicit and aligns with modern JavaScript best practices. As per coding guidelines, this improves consistency across the codebase.

packages/web/src/primitives/__tests__/useProject.test.js (3)

236-236: LGTM! Modern catch syntax.

Removing unused error bindings follows ES2019+ standards and aligns with the coding guideline to prefer modern ES6+ syntax.

Also applies to: 263-263


298-298: LGTM! Improved numeric readability.

Using numeric separators (ES2021+) enhances readability while maintaining identical values. This follows the coding guideline to prefer modern ES6+ syntax.

Also applies to: 319-319


749-749: LGTM! Cleaner edge case testing.

Omitting the argument instead of explicitly passing undefined is more idiomatic while testing the same behavior.

Also applies to: 757-757

packages/web/src/components/project-ui/ProjectView.jsx (4)

12-15: LGTM!

Import paths updated to use consistent @/api/... alias pattern with camelCase filenames. This aligns with the coding guidelines for using aliases to improve readability. Based on learnings, this follows the preferred modern ES6+ import style.


92-96: LGTM!

The || {} fallback was redundant—spreading undefined or null in an object literal is valid in JavaScript (it simply adds no properties). This simplification is correct and cleaner.


152-155: Consistent simplification.

Same valid pattern as the earlier metadata spread change. The fallback removal is correct.


200-202: LGTM!

> 0 and >= 1 are semantically equivalent for array lengths. Using > 0 is the more idiomatic "non-empty" check and aligns with common lint rule preferences.

packages/web/src/components/project-ui/AddStudiesForm.jsx (1)

118-118: LGTM! Modern syntax standardization.

The change from Array.from() to spread syntax is functionally equivalent and aligns with the project's preference for modern ES6+ syntax. Both approaches correctly convert the FileList to an array with proper null/undefined handling.

Based on learnings and coding guidelines emphasizing modern ES6+ syntax preferences.

packages/web/src/lib/__tests__/referenceLookup.test.js (1)

32-35: LGTM! Clean consolidation of the condition.

The refactoring from nested checks to a combined condition is correct and improves readability. The logic and behavior remain unchanged.

packages/ui/src/zag/__tests__/RadioGroup.test.jsx (2)

64-64: LGTM! Modern spread syntax for NodeList conversion.

The replacement of Array.from() with spread syntax [...inputs] correctly modernizes the code while maintaining identical functionality. This pattern is consistently applied across all NodeList-to-Array conversions before .find() operations.

Also applies to: 77-77, 89-89, 149-149, 218-218


134-136: LGTM! Modern for-of loops improve readability.

The conversion from .forEach() to for (const ... of ...) loops modernizes the iteration style and improves readability for simple iteration patterns in tests.

Also applies to: 191-193

packages/web/src/primitives/__tests__/useAddStudies.sync.test.js (2)

32-32: LGTM! Modern string replacement.

The use of replaceAll() is more explicit in intent and aligns with modern JavaScript practices.


580-580: LGTM! Modern array access pattern.

The use of .at(-1) to access the last mock call is cleaner and more readable than traditional array indexing. This modern ES2022 syntax aligns well with the project's preference for modern JavaScript features.

Also applies to: 626-626, 671-671

packages/web/src/lib/yjsUtils.js (2)

33-54: Excellent modernization from forEach to for...of.

The conversion from Object.entries().forEach to for...of is well-executed, with correct use of continue statements (replacing return from forEach context) and consistent modern iteration patterns throughout.


67-67: Good modernization to for...of syntax.

The change from value.forEach to for...of aligns with modern ES6+ patterns and maintains correct Yjs API usage.

packages/web/src/lib/__tests__/pdfUtils.test.js (1)

58-58: LGTM - Test mirrors implementation change.

The update from replace to replaceAll correctly reflects the change in the production code. Both methods are functionally equivalent for global regex replacements.

packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx (1)

92-92: LGTM - Explicit namespace usage.

The change from parseInt to Number.parseInt is functionally equivalent and aligns with modern JavaScript best practices for explicit namespace usage.

packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (2)

50-50: LGTM - Consistent parsing namespace.

Both changes from parseInt to Number.parseInt are functionally equivalent and maintain the same validation logic for page and zoom inputs.

Also applies to: 61-61


187-187: LGTM - Simplified numeric literal.

The change from 3.0 to 3 is functionally equivalent for the comparison. JavaScript automatically handles the type coercion, and the zoom boundary check remains correct.

packages/web/src/lib/pdfUtils.js (4)

13-14: LGTM - Improved readability with numeric separators.

The underscore separators in 10_000 improve readability without changing the numeric value. This is a welcome ES2021 feature for large numbers.


189-189: LGTM - Modern string replacement.

The change from replace(/\s+/g, ' ') to replaceAll(/\s+/g, ' ') is functionally equivalent and uses the more explicit modern API.


249-251: LGTM - More descriptive variable name.

The rename from valueStr to valueString is more explicit and improves code readability. The logic remains unchanged.


312-313: LGTM - Consistent use of replaceAll.

Both replacements in normalizeTitle now use replaceAll for consistency with the rest of the file. Functionally equivalent to the global regex replace pattern.

packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (3)

113-113: LGTM - Explicit parsing namespace.

Both conversions from parseInt to Number.parseInt are functionally equivalent and align with modern JavaScript conventions.

Also applies to: 124-124


141-143: LGTM - Modern iteration pattern.

The change from forEach to for...of with .entries() modernizes the iteration style while preserving the index-based distribution logic. The remainder calculation (i < remainder ? 1 : 0) works correctly with the destructured index.

Also applies to: 155-157


199-208: LGTM - Consistent iteration modernization.

The conversion to for...of with .entries() maintains the correct assignment distribution logic where the last reviewer in each pool receives any remaining studies. The control flow and calculations remain identical.

Also applies to: 212-219

packages/web/src/components/profile-ui/ProfilePage.jsx (4)

2-2: LGTM - Import path standardization.

The import path change aligns with the project's module aliasing conventions. Functionally equivalent.


9-9: LGTM - Performance improvement with Set.

Converting ALLOWED_TYPES from an array to a Set and using .has() instead of .includes() provides O(1) lookup performance instead of O(n). For a small set of 4 items, the performance difference is negligible, but this aligns with best practices.

Also applies to: 140-140


19-29: LGTM - Background profile synchronization.

The new syncProfileToProjects function handles propagating profile changes to all related projects. The silent error handling is appropriate for a non-critical background operation, though the console.error provides debugging visibility.


109-109: LGTM - Non-blocking sync integration.

The calls to syncProfileToProjects() are fire-and-forget, ensuring the user experience isn't blocked by background synchronization. This correctly places the sync after the primary operations complete.

Also applies to: 187-187

packages/web/src/components/checklist-ui/pdf/usePdfJs.js (4)

24-24: LGTM - Simplified numeric literals.

All changes from decimal notation (e.g., 1.0, 3.0) to integer notation (e.g., 1, 3) are functionally equivalent. JavaScript handles the type coercion seamlessly for scale calculations and comparisons.

Also applies to: 93-93, 103-103, 121-121, 602-602, 610-610, 619-619, 622-622


192-192: LGTM - Modern array cloning.

The spread syntax [...savedData] is more idiomatic than .slice(0) for shallow array cloning. Both produce identical results.

Also applies to: 306-306


135-146: LGTM - Modern iteration patterns.

The conversion from forEach to for...of loops modernizes the iteration style throughout the file. The semantics remain identical, and the code is more concise. The use of .entries() where index access is needed (lines 238-242) correctly preserves the original functionality.

Also applies to: 238-242, 246-246, 280-286, 316-321, 526-532, 546-553, 629-635, 649-656


332-333: LGTM - Array initialization unchanged.

While the formatting may appear different, new Array(pdf.numPages).fill(null) remains functionally equivalent to Array(pdf.numPages).fill(null). Both create arrays of the specified length filled with null values.

packages/web/src/lib/accountLinkingErrors.js (1)

69-69: Browser compatibility for replaceAll is confirmed.

The project's vite.config.js explicitly targets safari14, which supports replaceAll since version 13.1. The change is safe and aligns with the coding guideline preference for modern ES6+ syntax.

packages/web/src/lib/referenceLookup.js (6)

207-207: LGTM!

The use of replaceAll with a global regex correctly strips HTML/JATS tags from the abstract text.


237-237: LGTM!

The use of replaceAll with a global regex correctly removes all non-digit characters from the PMID.


305-305: LGTM!

Using Number.parseInt is more explicit and aligns with modern ES6+ best practices. The radix parameter (10) is correctly specified.


314-320: LGTM!

The for...of loop over the NodeList is clean and modern. This pattern is well-supported in contemporary browsers.


286-299: NodeList.entries() is well-supported across all modern browsers. Safari 10 added support for this method, and it's been available across browsers since October 2017. The code requires no changes.


365-365: No action required; Array.at() is safe for modern browsers.

Array.at() is a well-established feature available across browsers since March 2022. Safari is bundled with the operating system and receives updates through OS releases. iOS devices can automatically download and install updates overnight while charging, making older Safari versions extremely unlikely among users. The use of at(-1) is appropriate and requires no changes.

packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (2)

70-70: LGTM! More explicit empty array check.

The change from !pdfs.length to pdfs.length === 0 makes the intent clearer and is more explicit. This aligns with the lint fixes objective and improves code readability.


11-11: LGTM! Import path modernization verified and correct.

The update from @api/pdf-api.js to @/api/pdfApi.js is verified to be correct. The new file exists at packages/web/src/api/pdfApi.js, the old path has no remaining references, and the camelCase filename convention aligns with modern JavaScript practices and the codebase-wide standardization effort.

packages/web/src/lib/referenceParser.js (3)

116-116: LGTM! Good modernization to explicit Number.parseInt.

Using Number.parseInt instead of global parseInt is more explicit and avoids potential issues with global scope pollution.

Also applies to: 122-122


271-271: Verify browser compatibility for Array.at() (ES2022).

The use of Array.at(-1) is cleaner than parts[parts.length - 1]. However, Array.at() is an ES2022 feature (Safari 15.4+, March 2022) and requires verification against your browser support targets.

Note: This verification can be combined with the browser compatibility check requested for replaceAll() above.


219-228: Verify the project's browser support configuration before using replaceAll() (ES2021).

While replaceAll() is well-supported in modern browsers (Chrome 85+, Firefox 77+, Safari 13.1+, Edge 85+ since 2020), the coding guidelines require verifying browser compatibility for frontend code. Check the project's .browserslistrc, package.json, or build configuration (Vite, Babel) to confirm that ES2021 is within the supported scope before merging these changes.

packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (1)

190-190: LGTM! Clean loop modernization.

The refactor to for-of with entries() is more idiomatic and aligns with modern ES6+ practices.

packages/web/src/primitives/useProject/checklists.js (1)

52-181: LGTM! Clean refactor to modern iteration patterns.

The forEach-to-for...of conversions throughout the checklist creation logic are correct and maintain functional equivalence. The changes improve readability and align with modern ES6+ practices.

packages/web/src/AMSTAR2/checklist-compare.js (2)

116-122: LGTM! Improved iteration pattern.

The conversion from indexed for loop to for...of with entries() is cleaner while maintaining the same behavior.


223-230: LGTM! Modern iteration pattern.

The conversion to for...of with entries() improves readability and maintains the same logic.

packages/web/src/AMSTAR2/__tests__/checklist.test.js (3)

134-157: LGTM! Test iteration updates match source changes.

The forEach-to-for...of conversions in the test setup are correct and align with the modern iteration patterns used in the source code.


162-170: Good use of continue for control flow.

The switch to for...of with continue to skip non-matching entries is cleaner than the previous pattern and matches the refactored source code.


181-205: Test helper correctly uses at(-1).

The test helper properly mirrors the source code's use of at(-1) for last element access.

packages/web/src/ROBINS-I/checklist.js (2)

129-131: LGTM! Consistent modernization of iteration patterns.

All forEach-to-for...of conversions maintain functional equivalence and improve code clarity. The use of continue for early loop skipping is appropriate.

Also applies to: 228-235, 277-298, 316-323, 367-413


416-416: Verify browser compatibility for String.replaceAll() method.

The change from regex-based replace to replaceAll is cleaner and more readable. The function is aptly named csvEscape to avoid shadowing issues.

Note: String.prototype.replaceAll() was introduced in Safari 13.1 (March 2020).

Based on learnings, prefer modern ES6+ syntax and features.

packages/web/src/AMSTAR2/checklist.js (4)

164-175: LGTM! Improved control flow with for...of and continue.

The refactor from forEach to for...of with explicit continue statements is clearer and maintains the same filtering logic.


191-194: Modern array access pattern.

The changes to use at(-1) and indexOf are cleaner than the previous patterns. Same browser compatibility note as checklist-compare.js applies.


205-211: LGTM! Consistent iteration pattern.

The for...of conversion with continue maintains the same behavior while being more explicit.


271-302: Clean nested loop refactor.

The conversion of nested forEach loops to for...of improves readability and is functionally equivalent.

packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)

15-21: LGTM! Modernized array operations.

The refactor improves readability:

  • .at(-1) is more concise than manual length indexing
  • .indexOf(true) is clearer than .findIndex(v => v === true) for finding a specific primitive value

These changes follow the ES6+ modernization pattern applied consistently across the PR.

Comment thread eslint.config.js
Comment on lines +4 to +5
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
import sonarjs from 'eslint-plugin-sonarjs';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

sonarjs plugin imported but not configured.

The eslint-plugin-sonarjs is imported and registered in the plugins object, but no sonarjs rules are actively configured (line 105 shows the only sonarjs rule commented out). This adds an unnecessary dependency without providing linting value.

Consider either:

  • Enabling useful sonarjs rules like sonarjs/cognitive-complexity, sonarjs/no-duplicate-string, etc.
  • Removing the sonarjs import and plugin registration until you're ready to configure it

Also applies to: 13-15

🤖 Prompt for AI Agents
In eslint.config.js around lines 4-5 and 13-15 the sonarjs plugin is imported
and registered but no sonarjs rules are enabled (the only rule is commented
out), leaving an unused dependency; either remove the import and plugin entry to
drop the unused dependency, or enable a sensible set of sonarjs rules (for
example sonarjs/cognitive-complexity, sonarjs/no-duplicate-string,
sonarjs/no-identical-expressions) by adding them to the rules object with
appropriate severity and thresholds so the plugin provides linting value.

Comment on lines +190 to 194
const lastCol = answers.at(-1);
if (!Array.isArray(lastCol)) return null;

const idx = lastCol.findIndex(v => v === true);
const idx = lastCol.indexOf(true);
if (idx === -1) return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for browser configuration files in the project
echo "=== Looking for browserslist config ==="
find . -type f \( -name ".browserslistrc" -o -name "browserslist" \) 2>/dev/null | head -20

echo ""
echo "=== Checking package.json for browserslist ==="
fd -e json "package.json" -exec grep -l "browserslist" {} \; 2>/dev/null | head -5

echo ""
echo "=== Checking build configuration files ==="
fd -e "js\|ts\|json" "vite.config\|webpack.config\|tsconfig\|postcss" 2>/dev/null | head -20

echo ""
echo "=== Checking root package.json ==="
if [ -f "package.json" ]; then
  head -50 package.json
fi

Repository: InfinityBowman/corates

Length of output: 2266


🏁 Script executed:

#!/bin/bash
# Search for other uses of Array.at() or similar modern Array methods
echo "=== Checking for Array.at() usage ==="
rg "\.at\(" -t js -t ts -t jsx -t tsx --max-count 20 2>/dev/null

echo ""
echo "=== Checking for target browser hints in comments ==="
rg "safari|browser|compat|target" -t js -t ts -t jsx -t tsx -i packages/web/src/AMSTAR2/ 2>/dev/null | head -20

Repository: InfinityBowman/corates

Length of output: 158


🏁 Script executed:

#!/bin/bash
echo "=== Finding vite config in packages/web ==="
find packages/web -name "vite.config.*" -type f 2>/dev/null

echo ""
echo "=== Checking packages/web package.json ==="
if [ -f "packages/web/package.json" ]; then
  cat packages/web/package.json
fi

Repository: InfinityBowman/corates

Length of output: 1376


🏁 Script executed:

#!/bin/bash
echo "=== Contents of packages/web/vite.config.js ==="
cat packages/web/vite.config.js

echo ""
echo "=== Checking for TypeScript/build target in packages/web ==="
if [ -f "packages/web/tsconfig.json" ]; then
  cat packages/web/tsconfig.json | head -50
fi

Repository: InfinityBowman/corates

Length of output: 1491


Array.at() is incompatible with the declared browser target (Safari 14).

The project's vite.config.js specifies target: ['es2020', 'safari14']. Array.at() became available across browsers in March 2022, specifically in Safari 15.4 (March 14, 2022). Safari 14 does not support this method, so using answers.at(-1) will break for users on Safari 14. Use answers[answers.length - 1] instead.

🤖 Prompt for AI Agents
In packages/web/src/AMSTAR2/checklist-compare.js around lines 190 to 194, the
code uses Array.at() (answers.at(-1)) which is unsupported by the declared
Safari 14 target; replace it with a compatible expression such as const lastCol
= answers[answers.length - 1]; and keep the existing Array.isArray check and
subsequent null returns so behavior is unchanged for empty or non-array values.

Comment thread packages/web/src/AMSTAR2/checklist.js Outdated
Comment on lines +22 to +29
const lastCol = final[dk].answers?.at(-1);
if (!lastCol || !lastCol.includes(true)) return false;
}
return true;
}

const lastCol = final.answers?.[final.answers.length - 1];
return lastCol && lastCol.some(v => v === true);
const lastCol = final.answers?.at(-1);
return lastCol && lastCol.includes(true);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "navbar-utils.js" -type f 2>/dev/null | head -20

Repository: InfinityBowman/corates

Length of output: 132


🏁 Script executed:

ls -la | grep -E '^\.' && git remote -v 2>/dev/null || echo "Not a git repo or no remotes"

Repository: InfinityBowman/corates

Length of output: 94


🏁 Script executed:

head -35 packages/web/src/components/checklist-ui/compare/navbar-utils.js 2>/dev/null || echo "File not found"

Repository: InfinityBowman/corates

Length of output: 1251


Verify browser compatibility for Array.prototype.at() — requires Safari 15.4+.

The refactor to .at(-1) and .includes(true) improves readability and uses modern ES6+ syntax appropriately. Array.prototype.at() has been available across browsers since March 2022, which includes Safari 15.4+. Before merging, confirm your project's minimum Safari version supports this, or revert to the [array.length - 1] pattern for older Safari targets.

🤖 Prompt for AI Agents
In packages/web/src/components/checklist-ui/compare/navbar-utils.js around lines
22 to 29, the use of Array.prototype.at(-1) may break on targets that include
older Safari versions; either ensure your browserslist/minimum Safari version
includes Safari 15.4+ (update package.json browserslist or CI config) or revert
the two .at(-1) calls to the compatible pattern using array[array.length - 1]
(and keep the existing null/undefined guards) so the code works on older Safari.

Comment on lines +40 to +42
document.body.append(link);
link.click();
document.body.removeChild(link);
link.remove();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cd packages/web/src/components/project-ui/overview-tab && wc -l ChartSection.jsx

Repository: InfinityBowman/corates

Length of output: 86


🏁 Script executed:

cd packages/web && cat package.json | grep -A 20 '"browserslist"' || echo "No browserslist in package.json"

Repository: InfinityBowman/corates

Length of output: 97


🏁 Script executed:

cd packages/web && ls -la .browserslistrc 2>/dev/null || echo "No .browserslistrc file"

Repository: InfinityBowman/corates

Length of output: 89


🏁 Script executed:

cd packages/web/src/components/project-ui/overview-tab && sed -n '35,85p' ChartSection.jsx

Repository: InfinityBowman/corates

Length of output: 1743


🏁 Script executed:

cat packages/web/package.json | jq '.browserslist // "No browserslist field"'

Repository: InfinityBowman/corates

Length of output: 89


🏁 Script executed:

cat package.json | jq '.browserslist // "No browserslist at root"'

Repository: InfinityBowman/corates

Length of output: 91


🏁 Script executed:

cd packages/web/src/components/project-ui/overview-tab && sed -n '160,210p' ChartSection.jsx

Repository: InfinityBowman/corates

Length of output: 2126


Fix label auto-generation detection logic.

The DOM modernization from appendChild()/removeChild() to append()/remove() is fine (well-supported in modern browsers). However, there's a bug in the label update logic: auto-generated labels (line 171) only contain the study name, not the "studyName - reviewerName" pattern that the detection on line 196 checks for with includes(' - '). This means wasAutoGenerated will always be false and labels won't update when assignees change. Update line 196 to match the actual label format (e.g., check if the label equals the previous auto-generated value, or store a flag tracking which labels were auto-generated).

Also applies to: 77-79

🤖 Prompt for AI Agents
packages/web/src/components/project-ui/overview-tab/ChartSection.jsx lines 40-42
(and related spots at 77-79, ~171, ~196): the label auto-generation detection is
wrong — the code checks for ' - ' in the label but auto-generated labels only
contain the study name, so wasAutoGenerated is always false and assignee updates
don't change labels; fix by changing the detection on line ~196 to compare the
current label to the previous auto-generated value (e.g., label ===
generateAutoLabel(studyName, previousReviewer) or store a boolean flag on the
label object when it is auto-generated) and apply the same comparison/flagging
logic where similar detection occurs at lines 77-79; ensure when updating
assignee you only replace labels that were flagged/generated rather than those
containing ' - '.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

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

⚠️ Outside diff range comments (3)
packages/web/src/api/__tests__/better-auth-store.test.js (1)

11-11: Critical: Mock path doesn't match import paths.

The mock is set up for @api/auth-client.js, but all actual imports throughout the test file use @/api/authClient.js (lines 101, 165, 227, 297, 332, 401, 491, 535, 599). Since these paths don't match, the mock won't be applied, causing tests to attempt importing the real authClient module instead of the mocked version.

🔎 Proposed fix
-vi.mock('@api/auth-client.js', () => ({
+vi.mock('@/api/authClient.js', () => ({
   authClient: {
packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (2)

190-201: Auto-generated label detection doesn't match actual label format.

The detection logic at line 196 checks if the label includes(' - '), but the actual auto-generated label format at line 171 is just the truncated study name without any ' - ' separator:

label: `${study.name.length > 20 ? study.name.slice(0, 20) + '...' : study.name}`

This means:

  • Auto-generated labels will never be detected as such
  • Updates to underlying data (e.g., study name changes) won't propagate to labels even when they should
  • The update logic in this block becomes unreachable
Proposed fix

Either update the detection logic to match the actual format, or remove the detection check entirely if all labels in the matching-IDs case should be updated:

-        // Check if the label was likely auto-generated (contains " - ")
-        const wasAutoGenerated = customItem.label.includes(' - ');
-        if (wasAutoGenerated) {
+        // Check if the label matches the auto-generated format (truncated study name)
+        const autoGeneratedLabel = rawItem.label;
+        const wasAutoGenerated = customItem.label === autoGeneratedLabel || 
+                                 customItem.label.endsWith('...') && rawItem.label.endsWith('...');
+        if (wasAutoGenerated || customItem.label.startsWith(rawItem.reviewName.slice(0, 20))) {
           setCustomLabels(i, 'label', rawItem.label);
         }

Or, if the intent is to update labels that haven't been manually customized, consider tracking which labels have been user-modified separately.


187-204: The label detection logic doesn't match the actual auto-generated format, breaking the update mechanism.

The auto-generated labels at line 171 contain only the study name (truncated if necessary). However, the condition at line 196 checks whether a custom label contains " - " to detect if it was auto-generated. Since the actual auto-generated labels never include " - ", this detection will never match, and the label update logic at line 198 will never execute. This breaks the intended synchronization when underlying data changes (e.g., assignee changes). Either the auto-generated label format should include the reviewer name with the " - " separator, or the detection logic should match the actual label format.

♻️ Duplicate comments (2)
packages/web/src/components/checklist-ui/pdf/usePdfJs.js (2)

526-532: Critical: Same Map iteration error (see lines 280-286).

This location has the identical bug flagged at lines 280-286.

🔎 Proposed fix
-    for (const task of currentRenderTasks) {
+    for (const task of currentRenderTasks.values()) {
       try {
         task.cancel();

629-635: Critical: Same Map iteration error (see lines 280-286).

This is the third location with the identical bug flagged at lines 280-286.

🔎 Proposed fix
-    for (const task of currentRenderTasks) {
+    for (const task of currentRenderTasks.values()) {
       try {
         task.cancel();
🧹 Nitpick comments (10)
packages/ui/src/zag/__tests__/RadioGroup.test.jsx (1)

230-230: Consider direct bracket notation on NodeList.

The spread syntax works correctly here. However, since NodeList objects support bracket notation directly, you could simplify to controls[0] and controls[1] without the array conversion. This is a minor optimization for test code, so it's optional.

Optional micro-optimization
-      const option1Control = [...controls][0];
+      const option1Control = controls[0];
-      const option2Control = [...controls][1];
+      const option2Control = controls[1];

Also applies to: 240-240

packages/web/src/api/__tests__/better-auth-store.test.js (1)

2-2: Update test descriptions to match the new module name.

The file header comment and all describe blocks still reference better-auth-store (kebab-case), but the module has been renamed to betterAuthStore (camelCase). For consistency with the modernized naming convention, consider updating these descriptions.

🔎 Proposed updates
 /**
- * Tests for better-auth-store - Authentication flows and state management
+ * Tests for betterAuthStore - Authentication flows and state management
  *
  * Note: These tests focus on the business logic and state management.
  * Better Auth client internals are mocked.
  */
-describe('better-auth-store - Signup Flow', () => {
+describe('betterAuthStore - Signup Flow', () => {

Apply similar changes to all other describe blocks (lines 156, 218, 289, 325, 394, 484, 526, 580).

Also applies to: 92-92, 156-156, 218-218, 289-289, 325-325, 394-394, 484-484, 526-526, 580-580

eslint.config.js (3)

13-15: Consider enabling SonarJS rules or removing the plugin.

The SonarJS plugin is imported and registered, but no rules are currently enabled (line 105 has cognitive-complexity commented out). This adds the plugin as a dependency without utilizing it. Either enable specific SonarJS rules you want to enforce, or remove the plugin to reduce overhead.


130-172: Abbreviations allowlist is extremely permissive.

The prevent-abbreviations rule has 38 allowed abbreviations (lines 135-170), which significantly weakens its effectiveness. While some flexibility is reasonable, this extensive allowlist may defeat the rule's purpose of enforcing descriptive naming. Consider reviewing this list and removing entries that aren't project-critical.


350-360: Consider more targeted rule disables instead of blanket exemption.

This configuration disables ALL Unicorn rules for scripts and config files (lines 357-359). While tooling code may need flexibility, a blanket exemption might hide legitimate issues like security vulnerabilities, logic errors, or maintainability problems. Consider disabling only specific rules that conflict with tooling patterns (similar to the MCP configuration on lines 361-370).

packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (1)

1-595: Optional: Consider future refactoring for modularity.

While not related to this PR, the file at 595 lines could benefit from extraction of sub-modules in the future (e.g., pool management logic into a primitive/utility, assignment algorithm into a separate helper, preview section into a sub-component). This would improve testability and maintainability.

As per coding guidelines: "Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring..."

packages/web/src/components/checklist-ui/pdf/usePdfJs.js (1)

238-242: Optional: Fix typo in loop variable name.

The loop variable is named canvase instead of canvas. While functional, this typo reduces code readability.

🔎 Proposed fix
-    for (const [i, canvase] of canvases.entries()) {
-      if (canvase && !renderedPages.has(i + 1)) {
+    for (const [i, canvas] of canvases.entries()) {
+      if (canvas && !renderedPages.has(i + 1)) {
         pagesToRender.push(i + 1);
       }
     }
packages/web/src/lib/referenceLookup.js (2)

207-207: Optional: The global flag /g is redundant with replaceAll.

When using replaceAll, the global flag /g is unnecessary because replaceAll always replaces all matches by design. You can simplify this to abstract.replaceAll(/<[^>]*>/, '').trim().

That said, the change from replace to replaceAll improves clarity.

🔎 Proposed simplification
-    abstract = abstract.replaceAll(/<[^>]*>/g, '').trim();
+    abstract = abstract.replaceAll(/<[^>]*>/, '').trim();

237-237: Optional: The global flag /g is redundant with replaceAll.

Similar to line 207, replaceAll doesn't require the global flag. You can simplify to .replaceAll(/\D/, '').

🔎 Proposed simplification
-    .replaceAll(/\D/g, '')
+    .replaceAll(/\D/, '')
packages/web/src/AMSTAR2/checklist-compare.js (1)

223-229: Modern iteration pattern applied correctly.

The refactor to nested for...of loops is a good modernization. The variable naming (element, element_) is functional but could be more descriptive (e.g., row, cell or answer1Row, value) for improved clarity.

Optional: Improve variable naming
-  for (const [i, element] of answers1.entries()) {
-    if (!Array.isArray(element) || !Array.isArray(answers2[i])) return false;
-    if (element.length !== answers2[i].length) return false;
+  for (const [i, row] of answers1.entries()) {
+    if (!Array.isArray(row) || !Array.isArray(answers2[i])) return false;
+    if (row.length !== answers2[i].length) return false;

-    for (const [j, element_] of element.entries()) {
-      if (element_ !== answers2[i][j]) return false;
+    for (const [j, value] of row.entries()) {
+      if (value !== answers2[i][j]) return false;
    }
  }

Based on learnings, prefer modern ES6+ syntax.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d6319f and 1c422ec.

📒 Files selected for processing (40)
  • eslint.config.js (4 hunks)
  • packages/ui/src/zag/__tests__/Dialog.test.jsx (2 hunks)
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx (9 hunks)
  • packages/web/TESTING.md (1 hunks)
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js (4 hunks)
  • packages/web/src/AMSTAR2/checklist-compare.js (3 hunks)
  • packages/web/src/AMSTAR2/checklist.js (6 hunks)
  • packages/web/src/ROBINS-I/checklist.js (7 hunks)
  • packages/web/src/api/__tests__/better-auth-store.test.js (11 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js (17 hunks)
  • packages/web/src/components/profile-ui/ProfilePage.jsx (2 hunks)
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx (2 hunks)
  • packages/web/src/components/project-ui/AddStudiesForm.jsx (1 hunks)
  • packages/web/src/components/project-ui/ProjectDashboard.jsx (2 hunks)
  • packages/web/src/components/project-ui/ProjectView.jsx (4 hunks)
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (4 hunks)
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (6 hunks)
  • packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx (1 hunks)
  • packages/web/src/lib/__tests__/pdfUtils.test.js (1 hunks)
  • packages/web/src/lib/__tests__/referenceLookup.test.js (1 hunks)
  • packages/web/src/lib/accountLinkingErrors.js (1 hunks)
  • packages/web/src/lib/googlePicker.js (1 hunks)
  • packages/web/src/lib/pdfUtils.js (4 hunks)
  • packages/web/src/lib/referenceLookup.js (6 hunks)
  • packages/web/src/lib/referenceParser.js (5 hunks)
  • packages/web/src/lib/yjsUtils.js (3 hunks)
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js (4 hunks)
  • packages/web/src/primitives/__tests__/useProject.test.js (5 hunks)
  • packages/web/src/primitives/avatarCache.js (1 hunks)
  • packages/web/src/primitives/useAddStudies.js (4 hunks)
  • packages/web/src/primitives/useNotifications.js (2 hunks)
  • packages/web/src/primitives/useProject/checklists.js (12 hunks)
  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js (5 hunks)
✅ Files skipped from review due to trivial changes (4)
  • packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx
  • packages/web/src/primitives/useNotifications.js
  • packages/web/src/lib/tests/referenceLookup.test.js
  • packages/ui/src/zag/tests/Dialog.test.jsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/profile-ui/TwoFactorSetup.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/profile-ui/ProfilePage.jsx
🧰 Additional context used
📓 Path-based instructions (13)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • eslint.config.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/TESTING.md
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/lib/googlePicker.js
  • packages/web/src/lib/referenceLookup.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/lib/accountLinkingErrors.js
  • eslint.config.js
  • packages/ui/src/zag/__tests__/RadioGroup.test.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/lib/referenceParser.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/AMSTAR2/__tests__/checklist.test.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/lib/yjsUtils.js
  • packages/web/src/lib/pdfUtils.js
packages/web/src/primitives/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/useProject/checklists.js
  • packages/web/src/primitives/avatarCache.js
  • packages/web/src/primitives/__tests__/useProject.test.js
  • packages/web/src/primitives/useAddStudies.js
  • packages/web/src/primitives/__tests__/useAddStudies.sync.test.js
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx
  • packages/web/src/components/checklist-ui/compare/SummaryView.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/project-ui/AddStudiesForm.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/checklist-ui/compare/navbar-utils.js
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/ProjectView.jsx
packages/workers/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/workers/**/*.{js,ts}: Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js
packages/workers/src/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/workers/src/**/*.{js,ts}: Use Zod for schema and input validation on the backend
Use Drizzle ORM for database interactions and migrations
Use Better-Auth for authentication and user management

Files:

  • packages/workers/src/durable-objects/__tests__/ProjectDoc.test.js
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/AddStudiesForm.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/AddStudiesForm.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/TESTING.md
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/TESTING.md
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/stores/**/*.{js,ts} : Use Solid's `createStore` for complex state or state objects for better performance and reactivity

Applied to files:

  • packages/web/src/api/__tests__/better-auth-store.test.js
  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : For complex state or state objects in SolidJS, use Solid's `createStore` for better performance and reactivity

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file

Applied to files:

  • packages/web/src/components/project-ui/ProjectView.jsx
🧬 Code graph analysis (13)
packages/web/src/primitives/useProject/checklists.js (1)
packages/web/src/checklist-registry/types.js (2)
  • CHECKLIST_TYPES (11-18)
  • CHECKLIST_TYPES (11-18)
packages/web/src/components/checklist-ui/compare/SummaryView.jsx (2)
packages/web/src/AMSTAR2/checklist-compare.js (2)
  • idx (193-193)
  • lastCol (190-190)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (2)
  • idx (17-17)
  • lastCol (15-15)
packages/web/src/lib/referenceLookup.js (1)
packages/web/src/lib/referenceParser.js (1)
  • allButLast (289-289)
packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (1)
packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1)
  • layout (16-16)
packages/web/src/AMSTAR2/checklist-compare.js (2)
packages/web/src/AMSTAR2/checklist.js (3)
  • lastCol (191-191)
  • answers (276-276)
  • idx (193-193)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (2)
  • lastCol (15-15)
  • idx (17-17)
packages/web/src/AMSTAR2/checklist.js (1)
packages/web/src/AMSTAR2/checklist-compare.js (4)
  • lastCol (190-190)
  • idx (193-193)
  • questionKeys (54-54)
  • questionKeys (244-244)
packages/web/src/ROBINS-I/checklist.js (3)
packages/web/src/ROBINS-I/checklist-compare.js (7)
  • questions (142-142)
  • questions (307-307)
  • questions (429-429)
  • questionKeys (143-143)
  • questionKeys (308-308)
  • isPerProtocol (51-51)
  • isPerProtocol (215-215)
packages/web/src/components/checklist-ui/ROBINSIChecklist/DomainSection.jsx (2)
  • questions (19-19)
  • domain (18-18)
packages/web/src/ROBINS-I/checklist-map.js (5)
  • ROBINS_I_CHECKLIST (542-551)
  • ROBINS_I_CHECKLIST (542-551)
  • getActiveDomainKeys (559-562)
  • domain (566-566)
  • getDomainQuestions (565-579)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (4)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (2)
  • lastCol (22-22)
  • lastCol (28-28)
packages/web/src/AMSTAR2/checklist-compare.js (2)
  • lastCol (190-190)
  • idx (193-193)
packages/web/src/components/checklist-ui/compare/AnswerPanel.jsx (2)
  • answers (31-31)
  • question (28-28)
packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx (2)
  • question (13-13)
  • questionKey (12-12)
packages/web/src/api/__tests__/better-auth-store.test.js (1)
packages/web/src/api/authClient.js (4)
  • authClient (10-29)
  • authClient (10-29)
  • authClient (32-44)
  • authClient (32-44)
packages/web/src/lib/referenceParser.js (1)
packages/web/src/lib/referenceLookup.js (3)
  • ref (375-375)
  • authors (177-182)
  • authors (283-283)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (1)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)
  • lastCol (15-15)
packages/web/src/components/checklist-ui/pdf/usePdfJs.js (2)
packages/web/src/lib/pdfUtils.js (2)
  • pdf (79-79)
  • pdf (225-225)
packages/web/src/components/checklist-ui/pdf/PdfViewer.jsx (1)
  • pdf (29-34)
packages/web/src/components/project-ui/ProjectView.jsx (2)
packages/web/src/components/project-ui/reconcile-tab/ReconcileStudyCard.jsx (1)
  • completedChecklists (17-19)
packages/web/src/components/project-ui/reconcile-tab/ReconcileStatusTag.jsx (1)
  • completedChecklists (11-12)
🪛 Biome (2.1.2)
packages/web/src/AMSTAR2/checklist.js

[error] 305-305: Do not shadow the global "escape" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates

Comment thread packages/web/src/AMSTAR2/checklist.js Outdated
Comment thread packages/web/src/components/checklist-ui/pdf/usePdfJs.js Outdated
Comment thread packages/web/src/components/checklist-ui/pdf/usePdfJs.js Outdated
Comment thread packages/web/src/components/checklist-ui/pdf/usePdfJs.js Outdated
// More than 2 authors: "First, Second, ... and Last"
const allButLast = authors.slice(0, -1).join(', ');
return `${allButLast}, and ${authors[authors.length - 1]}`;
return `${allButLast}, and ${authors.at(-1)}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for browserslist configuration
find . -name "package.json" -o -name ".browserslistrc" -o -name "babel.config.*" | head -20

Repository: InfinityBowman/corates

Length of output: 227


🏁 Script executed:

# Check root and web package.json for browserslist config
echo "=== ROOT PACKAGE.JSON ===" && cat package.json | head -100
echo -e "\n=== WEB PACKAGE.JSON ===" && cat packages/web/package.json | head -150

Repository: InfinityBowman/corates

Length of output: 3758


🏁 Script executed:

# Check for .browserslistrc or other browser config files
echo "=== Checking for .browserslistrc ===" && [ -f ".browserslistrc" ] && cat .browserslistrc || echo "No .browserslistrc found"

# Check vite config
echo -e "\n=== Checking for vite config ===" && find . -name "vite.config.*" -type f

Repository: InfinityBowman/corates

Length of output: 191


🏁 Script executed:

# Check vite config for browser compatibility settings
echo "=== VITE CONFIG ===" && cat packages/web/vite.config.js

# Also check if there's any babel config
echo -e "\n=== Checking for babel config ===" && find . -name "babel.config.*" -o -name ".babelrc*" | head -10

Repository: InfinityBowman/corates

Length of output: 1436


Revert to authors[authors.length - 1].

The project's build configuration explicitly targets Safari 14 (vite.config.js: target: ['es2020', 'safari14']), which does not support Array.at(). Using .at(-1) will cause a TypeError in Safari 14 browsers. Maintain compatibility with the project's declared browser targets.

🤖 Prompt for AI Agents
In packages/web/src/lib/referenceLookup.js around line 365, the code uses
authors.at(-1) which isn’t supported by the project’s Safari 14 target; replace
authors.at(-1) with the equivalent indexing authors[authors.length - 1] to avoid
runtime errors in Safari 14 and keep behavior identical (ensure authors is
non-empty before accessing if not already guaranteed).

// Handle "First Last" format - take last word
const parts = firstAuthor.trim().split(/\s+/);
return parts[parts.length - 1];
return parts.at(-1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

echo "=== Checking Vite Configuration ==="
if [ -f "vite.config.ts" ] || [ -f "vite.config.js" ]; then
  echo "Vite config found:"
  cat vite.config.* 2>/dev/null | head -100
else
  echo "No vite.config found"
fi

echo -e "\n=== Checking Package.json for build config ==="
cat package.json | jq '.browserslist, .engines' 2>/dev/null || echo "No browserslist or engines in package.json"

echo -e "\n=== Checking for .browserslistrc ==="
if [ -f ".browserslistrc" ]; then
  cat .browserslistrc
else
  echo "No .browserslistrc file"
fi

echo -e "\n=== Checking tsconfig.json target ==="
if [ -f "tsconfig.json" ]; then
  cat tsconfig.json | jq '.compilerOptions.target' 2>/dev/null || echo "Could not read tsconfig"
else
  echo "No tsconfig.json found"
fi

echo -e "\n=== Checking packages/web directories ==="
ls -la packages/web/ 2>/dev/null | head -20

echo -e "\n=== Checking for babel configuration ==="
find . -maxdepth 2 -type f \( -name "babel.config.*" -o -name ".babelrc*" \) -exec echo "Found: {}" \; -exec cat {} \;

Repository: InfinityBowman/corates

Length of output: 1152


🏁 Script executed:

#!/bin/bash

echo "=== Checking referenceParser.js usage context ==="
cat -n packages/web/src/lib/referenceParser.js | sed -n '265,295p'

echo -e "\n=== Checking if parts array could be empty ==="
rg "parts\s*=" packages/web/src/lib/referenceParser.js -A 3 | head -20

Repository: InfinityBowman/corates

Length of output: 1131


🏁 Script executed:

#!/bin/bash

echo "=== Checking vite.config.js ==="
cat packages/web/vite.config.js

echo -e "\n=== Checking jsconfig.json ==="
cat packages/web/jsconfig.json

echo -e "\n=== Checking root vite.config (if exists) ==="
cat vite.config.js 2>/dev/null || echo "No root vite.config.js"

echo -e "\n=== Checking root jsconfig.json ==="
cat jsconfig.json 2>/dev/null || echo "No root jsconfig.json"

Repository: InfinityBowman/corates

Length of output: 2186


Replace Array.at(-1) with bracket notation for Safari 14 compatibility.

Your vite.config.js explicitly targets Safari 14 (build.target: ['es2020', 'safari14']), but Array.at() is not available until Safari 15.4 (March 2022). Change to parts[parts.length - 1] and authors[authors.length - 1] to support your target browsers.

🤖 Prompt for AI Agents
In packages/web/src/lib/referenceParser.js around line 271, replace the use of
Array.at(-1) with bracket indexing for Safari 14 compatibility: change return
parts.at(-1) to return parts[parts.length - 1] (and similarly replace any
authors.at(-1) occurrences with authors[authors.length - 1]); update both places
to use the length-based bracket notation so the code runs on targets that
include Safari 14.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

♻️ Duplicate comments (10)
packages/web/src/components/checklist-ui/pdf/usePdfJs.js (5)

192-192: Critical: Array.from() cannot clone ArrayBuffer.

savedData is an ArrayBuffer (per JSDoc line 15). Array.from(arrayBuffer) produces an empty array, not a clone of the buffer. This will break PDF loading.

The existing comment on this line already flagged this issue, but it remains unfixed.

🔎 Proposed fix: Use proper ArrayBuffer cloning

Option 1 (broader browser support):

-    const clonedData = Array.from(savedData);
+    const clonedData = savedData.slice(0);

Option 2 (modern approach, if browser support allows):

-    const clonedData = Array.from(savedData);
+    const clonedData = structuredClone(savedData);

280-286: Critical: Incorrect Map iteration.

currentRenderTasks is a Map (line 35). Iterating directly over a Map yields [key, value] entries, not values. Line 282's task.cancel() will throw TypeError: task.cancel is not a function.

The existing comment already flagged this issue, but it remains unfixed. The same issue appears at lines 526-532 and 629-635.

🔎 Proposed fix
-    for (const task of currentRenderTasks) {
+    for (const task of currentRenderTasks.values()) {
       try {
         task.cancel();
       } catch {
         // Ignore cancel errors
       }
     }

306-306: Critical: Cannot spread ArrayBuffer.

source.data is an ArrayBuffer (verified on line 305). The spread syntax [...source.data] will throw TypeError: source.data is not iterable. PDF.js expects an ArrayBuffer, not an array.

The existing comment already flagged this issue, but it remains unfixed.

🔎 Proposed fix
-        loadSource = { ...source, data: [...source.data] };
+        loadSource = { ...source, data: source.data.slice(0) };

526-532: Critical: Incorrect Map iteration (duplicate).

Same issue as lines 280-286: iterating directly over currentRenderTasks Map yields [key, value] entries, causing task.cancel() to fail.

🔎 Proposed fix
-    for (const task of currentRenderTasks) {
+    for (const task of currentRenderTasks.values()) {
       try {
         task.cancel();
       } catch {
         // Ignore
       }
     }

629-635: Critical: Incorrect Map iteration (duplicate).

Third occurrence of the same issue: iterating directly over currentRenderTasks Map yields [key, value] entries, causing task.cancel() to fail.

🔎 Proposed fix
-    for (const task of currentRenderTasks) {
+    for (const task of currentRenderTasks.values()) {
       try {
         task.cancel();
       } catch {
         // Ignore
       }
     }
packages/web/src/components/checklist-ui/pdf/PdfList.jsx (1)

29-29: Verify browser compatibility for .toSorted().

The .toSorted() method is an ES2023 feature supported only in Safari 16+ (September 2022), Chrome 110+, and Firefox 115+. Since the coding guidelines emphasize Safari compatibility concerns, ensure this aligns with your target browser support.

Based on coding guidelines emphasizing Safari compatibility.

packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx (1)

19-19: Verify browser compatibility for .toSorted().

The .toSorted() method is an ES2023 feature supported only in Safari 16+ (September 2022), Chrome 110+, and Firefox 115+. Since the coding guidelines emphasize Safari compatibility concerns, ensure this aligns with your target browser support.

Based on coding guidelines emphasizing Safari compatibility.

eslint.config.js (2)

4-5: sonarjs plugin imported but not configured.

The plugin is registered but no sonarjs rules are enabled (line 106 shows the only rule commented out), adding an unnecessary dependency.

Also applies to: 13-15


234-235: Outdated comment for prefer-response-static-json rule.

The "Cloudflare Workers pattern" rationale is outdated. Response.json() has been supported since May 2022.

packages/web/src/AMSTAR2/checklist-compare.js (1)

190-194: Array.at() incompatibility already flagged.

This issue has already been identified in a previous review comment for these exact lines. The Array.at(-1) usage on line 190 is incompatible with Safari 14 and needs to be replaced with answers[answers.length - 1].

🧹 Nitpick comments (3)
packages/web/src/lib/pdfUtils.js (1)

154-154: Reconsider toSorted() for Safari compatibility target.

The toSorted() method requires Safari 16 (September 2022). If your project must support Safari 15 or earlier, use the spread operator pattern [...textItems].sort() instead. If Safari 16+ is acceptable, this change is fine and reduces unnecessary array copying.

packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (1)

187-187: Minor style improvement.

Changing 3.0 to 3 is a minor style improvement. Both are functionally identical in JavaScript, but using 3 is more idiomatic.

eslint.config.js (1)

238-238: Reconsider disabling prefer-spread.

The unicorn/prefer-spread rule encourages modern spread syntax over older patterns. Disabling it contradicts the project's preference for modern ES6+ features.

Consider setting this to 'warn' for gradual adoption:

-'unicorn/prefer-spread': 'off',
+'unicorn/prefer-spread': 'warn',

Based on learnings, prefer modern ES6+ syntax and features.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6498e0a and 2b7167c.

📒 Files selected for processing (26)
  • eslint.config.js (5 hunks)
  • packages/mcp/scrape-icons.js (1 hunks)
  • packages/mcp/server.js (1 hunks)
  • packages/mcp/tools/drizzle.js (2 hunks)
  • packages/mcp/tools/lint.js (1 hunks)
  • packages/mcp/tools/zag.js (2 hunks)
  • packages/ui/src/zag/Drawer.jsx (1 hunks)
  • packages/web/src/AMSTAR2/checklist-compare.js (4 hunks)
  • packages/web/src/ROBINS-I/checklist-compare.js (8 hunks)
  • packages/web/src/ROBINS-I/checklist.js (9 hunks)
  • packages/web/src/api/__tests__/betterAuthStore.test.js (12 hunks)
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (2 hunks)
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx (5 hunks)
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (7 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (3 hunks)
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js (17 hunks)
  • packages/web/src/components/project-ui/ProjectCard.jsx (1 hunks)
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1 hunks)
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx (1 hunks)
  • packages/web/src/lib/__tests__/pdfUtils.test.js (3 hunks)
  • packages/web/src/lib/pdfUtils.js (6 hunks)
  • packages/web/src/main.jsx (2 hunks)
  • packages/web/src/primitives/__tests__/useProject.test.js (11 hunks)
  • packages/workers/src/routes/admin.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/web/src/main.jsx
  • packages/web/src/ROBINS-I/checklist-compare.js
  • packages/mcp/tools/zag.js
  • packages/web/src/primitives/tests/useProject.test.js
  • packages/workers/src/routes/admin.js
  • packages/web/src/components/checklist-ui/compare/MultiPartQuestionPage.jsx
🧰 Additional context used
📓 Path-based instructions (10)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/mcp/server.js
  • packages/mcp/tools/drizzle.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • eslint.config.js
  • packages/mcp/scrape-icons.js
  • packages/ui/src/zag/Drawer.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
  • packages/mcp/tools/lint.js
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/mcp/server.js
  • packages/mcp/tools/drizzle.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/mcp/scrape-icons.js
  • packages/ui/src/zag/Drawer.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
  • packages/mcp/tools/lint.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/mcp/server.js
  • packages/mcp/tools/drizzle.js
  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • eslint.config.js
  • packages/mcp/scrape-icons.js
  • packages/ui/src/zag/Drawer.jsx
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
  • packages/mcp/tools/lint.js
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/web/src/lib/__tests__/pdfUtils.test.js
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/ROBINS-I/checklist.js
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/lib/pdfUtils.js
  • packages/web/src/AMSTAR2/checklist-compare.js
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx
  • packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
  • packages/web/src/components/project-ui/ProjectCard.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx
  • packages/web/src/components/checklist-ui/pdf/PdfList.jsx
  • packages/web/src/components/checklist-ui/pdf/usePdfJs.js
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts,css} : Ensure browser compatibility for all frontend code (Safari is usually problematic)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
  • packages/mcp/tools/lint.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Import stores directly where needed instead of passing values through multiple components

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/workers/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use aliases for imports when appropriate to improve readability

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/stores/**/*.{js,ts} : Use Solid's `createStore` for complex state or state objects for better performance and reactivity

Applied to files:

  • packages/web/src/api/__tests__/betterAuthStore.test.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer using config files rather than hardcoding values

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Follow standard JavaScript/SolidJS/Cloudflare best practices

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Prefer modern ES6+ syntax and features

Applied to files:

  • eslint.config.js
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Ensure browser compatibility for all frontend code (Safari is usually problematic)

Applied to files:

  • packages/web/src/AMSTAR2/checklist-compare.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts,css} : Ensure browser compatibility for all frontend code (Safari is usually problematic)

Applied to files:

  • packages/web/src/AMSTAR2/checklist-compare.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Zod for schema and input validation on the backend

Applied to files:

  • packages/mcp/tools/lint.js
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/**/*.{js,jsx,ts,tsx} : Use Zod for schema and input validation

Applied to files:

  • packages/mcp/tools/lint.js
🧬 Code graph analysis (8)
packages/web/src/lib/__tests__/pdfUtils.test.js (1)
packages/web/src/lib/pdfUtils.js (2)
  • sorted (154-154)
  • textItems (93-93)
packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (3)
packages/web/src/AMSTAR2/checklist-compare.js (1)
  • lastCol (190-190)
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)
  • lastCol (15-15)
packages/web/src/components/checklist-ui/compare/navbar-utils.js (2)
  • lastCol (22-22)
  • lastCol (28-28)
packages/web/src/ROBINS-I/checklist.js (1)
packages/web/src/ROBINS-I/checklist-map.js (7)
  • INFORMATION_SOURCES (66-80)
  • INFORMATION_SOURCES (66-80)
  • ROBINS_I_CHECKLIST (542-551)
  • ROBINS_I_CHECKLIST (542-551)
  • getActiveDomainKeys (559-562)
  • domain (566-566)
  • getDomainQuestions (565-579)
packages/web/src/components/checklist-ui/pdf/PdfSelector.jsx (1)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1)
  • pdfs (23-23)
packages/web/src/components/checklist-ui/pdf/PdfList.jsx (2)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1)
  • pdfs (23-23)
packages/web/src/lib/yjsUtils.js (1)
  • a (66-66)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (2)
packages/workers/src/routes/pdfs.js (1)
  • pdfs (76-81)
packages/web/src/lib/yjsUtils.js (1)
  • a (66-66)
packages/web/src/AMSTAR2/checklist-compare.js (2)
packages/web/src/AMSTAR2/checklist.js (3)
  • lastCol (191-191)
  • answers (276-276)
  • idx (193-193)
packages/web/src/ROBINS-I/checklist-compare.js (4)
  • reconciled (208-229)
  • reconciled (266-266)
  • selection (269-269)
  • selection (298-298)
packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx (2)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1)
  • pdfs (23-23)
packages/web/src/lib/yjsUtils.js (1)
  • a (66-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: corates-workers-prod
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (35)
packages/web/src/components/project-ui/ProjectCard.jsx (1)

25-25: LGTM! Modern ES6+ improvement.

The change from isNaN() to Number.isNaN() is a proper modernization that aligns with ES6+ best practices. Since date.getTime() always returns a number or NaN, both approaches behave identically here, making this a safe refactor with no behavioral change.

Based on learnings, preferring modern ES6+ syntax and features is a project guideline.

packages/mcp/tools/drizzle.js (2)

30-35: LGTM! Modern for-of loop improves readability.

The conversion to for-of with .entries() is a clean modernization that maintains the exact same logic while being more idiomatic and readable.

Based on learnings, prefer modern ES6+ syntax and features.


89-89: Node.js version requirement is sufficient for .toSorted().

The project's minimum Node.js version (>=24.0.0) exceeds the requirement for .toSorted(), which needs Node.js 20+. The change to use .toSorted() is semantically correct and fully compatible.

packages/web/src/lib/pdfUtils.js (5)

13-14: LGTM!

Numeric separators improve readability without changing behavior.


189-189: LGTM!

The replaceAll() method with regex global flag is correctly used and has good browser support (Safari 13.1+).


202-215: LGTM!

Excellent progressive enhancement pattern. The code prefers the modern Blob.arrayBuffer() API but gracefully falls back to FileReader for older environments. The eslint-disable comment is appropriately justified.


256-258: LGTM!

The rename to valueString improves clarity and explicitly documents the type coercion.


319-320: LGTM!

Both replaceAll() calls correctly use the global flag and improve semantic clarity.

packages/web/src/lib/__tests__/pdfUtils.test.js (3)

26-26: LGTM!

The test correctly mirrors the implementation's use of toSorted() (line 154 in pdfUtils.js). Note that the same Safari 16+ compatibility consideration applies here.


58-58: LGTM!

The test correctly mirrors the implementation's use of replaceAll() (line 189 in pdfUtils.js).


293-295: LGTM!

Excellent test setup that ensures the FileReader fallback path (lines 202-215 in pdfUtils.js) is properly exercised. Deleting the arrayBuffer method correctly simulates an older environment.

packages/web/src/components/checklist-ui/pdf/usePdfJs.js (7)

24-24: LGTM: Integer literal format is idiomatic.

The changes from floating-point literals (1.0, 3.0) to integer literals (1, 3) are semantically equivalent in JavaScript and align with modern style conventions.

Also applies to: 93-93, 103-103, 121-121


135-146: LGTM: Correct Map iteration pattern.

The conversion from forEach to for...of with pageRefs.entries() is correct and maintains the same logic with modern syntax.


246-246: LGTM: Array iteration conversion.

The conversion from forEach to for...of is correct and more concise.


316-321: LGTM: Array handling conversions.

The conversion from forEach to for...of (lines 316-321) is correct for arrays. Using new Array() (lines 332-333) is more explicit than the implicit constructor form.

Also applies to: 332-333


546-553: LGTM: Array iteration conversion.

The conversion from forEach to for...of is correct for the array returned by pageCanvases().


602-602: LGTM: Consistent integer literal usage.

The changes from floating-point to integer literals for scale values are semantically equivalent and align with the pattern established earlier in the file.

Also applies to: 610-610, 619-619, 622-622


649-656: LGTM: Array iteration conversion in cleanup.

The conversion from forEach to for...of is correct for the array returned by pageCanvases().

packages/web/src/api/__tests__/betterAuthStore.test.js (4)

11-11: LGTM - Consistent path alias and naming updates.

The mock path and dynamic imports have been correctly updated to use the @/ alias prefix and camelCase naming convention (authClient.js, betterAuthStore.js). The mock structure and test logic remain unchanged.

Also applies to: 101-104


165-168: LGTM - Import paths correctly updated.

All dynamic imports in the signin test suite have been consistently updated to match the new path structure and naming conventions.


227-227: LGTM - All remaining import paths consistently updated.

All test suites have been updated with the new import paths following the camelCase naming convention and standardized path aliases. The changes are purely cosmetic with no modifications to test logic or assertions.

Also applies to: 236-236, 297-298, 300-300, 332-332, 336-336, 401-401, 403-403, 491-491, 493-493, 535-536, 541-541, 587-587, 599-599


11-11: Import paths are correctly configured and all files exist at their new locations.

All renamed files are present in the repository at their expected paths, and the vite.config.ts file properly defines the required path aliases (@/, @api, @lib, @primitives) for both development and testing environments. The old kebab-case files have been successfully removed. Imports in the test file will resolve correctly without any configuration issues.

packages/web/src/components/checklist-ui/pdf/PdfToolbar.jsx (1)

50-51: Good modernization with Number.parseInt and Number.isNaN.

Using Number.parseInt and Number.isNaN instead of the global versions is a best practice. These methods are more explicit, avoid issues with global scope pollution, and have been widely supported since ES2015.

Based on learnings emphasizing modern ES6+ syntax.

Also applies to: 61-62

packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1)

27-27: Define explicit browser targets or replace .toSorted() with a polyfill-safe alternative.

The .toSorted() method requires Safari 16+ (ES2023). The project has no explicit browserslist configuration or polyfill setup, making browser support unclear. Either add a .browserslistrc or browserslist field to package.json documenting that the project targets only modern browsers (Safari 16+, Chrome 110+, Firefox 115+), or replace .toSorted() with .slice().sort() to ensure compatibility with older Safari versions.

packages/web/src/components/checklist-ui/compare/ChecklistReconciliation.jsx (2)

242-249: LGTM! Modern syntax improves readability and consistency.

The changes to use .at(-1) and .includes(true) are correct and improve code readability:

  • .at(-1) is cleaner than array index arithmetic and already used consistently across the codebase (see checklist-compare.js, ReconciliationQuestionPage.jsx, navbar-utils.js)
  • .includes(true) is more direct than .some() for checking boolean presence

Note: .at() requires Safari 15.4+, same as structuredClone on Line 196. Since .at() is already used throughout the codebase, the project likely has addressed browser compatibility requirements.

Based on learnings, this aligns with the preference for modern ES6+ syntax and features.


196-196: This change is consistent with the codebase's established pattern. structuredClone is already used 20+ times throughout the project, including in critical files like AMSTAR2/checklist-compare.js and ReconciliationQuestionPage.jsx. The ESLint configuration explicitly allows structuredClone as a readonly global, and the coding guidelines emphasize preferring modern ES6+ syntax and features. While the vite.config.js includes a safari14 build target, the codebase's widespread reliance on structuredClone (which requires Safari 15.4+) indicates this target is either outdated or not actively enforced. The line 196 change aligns with the project's modernization direction and does not introduce a new compatibility issue.

Likely an incorrect or invalid review comment.

packages/mcp/scrape-icons.js (1)

80-80: Verify the removal of explicit error handling is intentional.

The previous error-handling wrapper provided custom error logging before exiting. With top-level await, unhandled rejections will terminate the process but with different error output formatting.

If custom error formatting is needed, consider wrapping in a try-catch:

try {
  await main();
} catch (err) {
  console.error('Error:', err);
  process.exit(1);
}
eslint.config.js (2)

28-28: LGTM! Consistent configuration for structuredClone.

Adding structuredClone to globals and enforcing unicorn/prefer-structured-clone as an error aligns with the project's preference for modern ES6+ features.

Based on learnings, prefer modern ES6+ syntax and features.

Also applies to: 213-213


348-393: Well-structured per-scope configuration blocks.

The file-pattern-specific rule overrides are well-justified:

  • Durable objects use PascalCase class names
  • Scripts/tooling need flexibility
  • Service workers correctly use self over globalThis
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx (1)

115-115: LGTM: Improved variable naming.

The rename from arr to array in the map callback improves code readability.

Also applies to: 129-129

packages/web/src/ROBINS-I/checklist.js (3)

78-78: LGTM: Cleaner initialization with Object.fromEntries().

The refactor from reduce to Object.fromEntries() is cleaner and maintains the same semantics while being compatible with Safari 14.


126-128: LGTM: Modern iteration patterns with for...of loops.

The conversion from forEach to for...of loops modernizes the code and is fully compatible with Safari 14. The logic is preserved across all conversions.

Based on learnings.

Also applies to: 225-232, 274-295, 313-320, 364-410


413-413: LGTM: replaceAll() is cleaner and Safari 14 compatible.

The use of replaceAll() is more readable than chained replace() calls and is fully supported in Safari 14.

packages/web/src/AMSTAR2/checklist-compare.js (2)

243-243: LGTM: Default parameter improves API usability.

Adding a default value for the metadata parameter makes the function more flexible and is fully compatible with Safari 14.


116-122: LGTM: Modern iteration with for...of and destructuring.

The conversion to for...of loops with array destructuring modernizes the code and is fully compatible with Safari 14. The logic is correctly preserved.

Based on learnings.

Also applies to: 223-229

Comment thread packages/mcp/server.js
console.error('Failed to start MCP server:', err);
process.exit(1);
});
await main();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add explicit error handling for the server startup.

For a long-running server process, unhandled rejections can cause unexpected termination. The previous wrapper provided controlled error logging and exit.

🔎 Restore error handling
-await main();
+try {
+  await main();
+} catch (err) {
+  console.error('Failed to start Corates MCP Server:', err);
+  process.exit(1);
+}
📝 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
await main();
try {
await main();
} catch (err) {
console.error('Failed to start Corates MCP Server:', err);
process.exit(1);
}
🤖 Prompt for AI Agents
In packages/mcp/server.js around line 48, the startup currently just calls
"await main();" without error handling; restore explicit startup error handling
by wrapping the call in a top-level try/catch (or async IIFE) that catches any
thrown errors or rejected promises, logs the error details using the appropriate
logger or console.error with clear context (e.g., "Server startup failed:"), and
exits the process with a non-zero code (process.exit(1)) to ensure controlled
termination on failure.

}

const sortedGroups = [...groups.entries()].sort((a, b) => a[0].localeCompare(b[0]));
const sortedGroups = groups.entries().toSorted((a, b) => a[0].localeCompare(b[0]));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: .toSorted() is not available on Map iterators.

groups.entries() returns a MapIterator, not an Array. The .toSorted() method only exists on Array.prototype, so this code will throw a TypeError at runtime.

Proposed fix
-  const sortedGroups = groups.entries().toSorted((a, b) => a[0].localeCompare(b[0]));
+  const sortedGroups = [...groups.entries()].toSorted((a, b) => a[0].localeCompare(b[0]));

The spread operator converts the iterator to an array first, then .toSorted() can be applied.

📝 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 sortedGroups = groups.entries().toSorted((a, b) => a[0].localeCompare(b[0]));
const sortedGroups = [...groups.entries()].toSorted((a, b) => a[0].localeCompare(b[0]));
🤖 Prompt for AI Agents
In packages/mcp/tools/drizzle.js around line 81, groups.entries() returns a
MapIterator so calling .toSorted() on it throws a TypeError; convert the
iterator to an array first (e.g. use Array.from(groups.entries()) or
[...groups.entries()]) and then call .toSorted((a,b) =>
a[0].localeCompare(b[0])) so the sorting operates on an Array rather than the
iterator.

import { z } from 'zod';
import { exec as execCallback } from 'child_process';
import util from 'util';
import { util } from 'util';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n packages/mcp/tools/lint.js | head -20

Repository: InfinityBowman/corates

Length of output: 856


🏁 Script executed:

node --input-type=module --eval "import { util } from 'util'; console.log(util);" 2>&1 || echo "Named import failed"
node --input-type=module --eval "import util from 'util'; console.log(typeof util.promisify);" 2>&1

Repository: InfinityBowman/corates

Length of output: 684


Fix the incorrect import syntax for the util module.

The import statement import { util } from 'util'; is incorrect. Built-in modules provide named exports of their public API. A default export is also provided which is the value of the CommonJS exports. The util module does not export a named export called util, and this code will fail at runtime with: "The requested module 'util' does not provide an export named 'util'".

Use the default import instead:

-import { util } from 'util';
+import util from 'util';

Or import only the specific function needed:

-import { util } from 'util';
+import { promisify } from 'util';
 
-const exec = util.promisify(execCallback);
+const exec = promisify(execCallback);
📝 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
import { util } from 'util';
import util from 'util';
🤖 Prompt for AI Agents
In packages/mcp/tools/lint.js around line 3, the current import "import { util }
from 'util';" is invalid because 'util' has no named export 'util'; replace it
with a default import from 'util' (import util from 'util') or, if only specific
helpers are used, import those named functions (e.g., import { promisify, format
} from 'util') and update any subsequent usages to match the chosen import form.

const open = () => props.open;
const side = () => props.side || 'right';
const size = () => props.size || 'md';
const size = () => props.size > 0 || 'md';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical logic error breaks size prop functionality.

The comparison props.size > 0 is incorrect for string props. When props.size is a string like 'sm', 'md', 'lg', etc., the comparison coerces the string to NaN, making NaN > 0 evaluate to false, which then returns 'md'. This causes all size values to be ignored. If a numeric value were passed, it would return the boolean true, causing the switch statement in getSizeClass() to fall through to the default case.

Proposed fix
-  const size = () => props.size > 0 || 'md';
+  const size = () => props.size || 'md';
📝 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 size = () => props.size > 0 || 'md';
const size = () => props.size || 'md';
🤖 Prompt for AI Agents
In packages/ui/src/zag/Drawer.jsx around line 25, the size function uses the
incorrect expression `props.size > 0 || 'md'` which coerces strings to NaN and
returns booleans for numbers; replace it with logic that returns the actual prop
value (as a string) when provided and falls back to 'md' otherwise — e.g. check
for non-null/undefined and non-empty string or numeric value and return
props.size (or String(props.size) for numbers), otherwise return 'md'.

Comment on lines +263 to +278
reconciled[dataKey] = structuredClone(checklist1[dataKey]);
} else if (selection === 'reviewer2') {
reconciled[dataKey] = JSON.parse(JSON.stringify(checklist2[dataKey]));
reconciled[dataKey] = structuredClone(checklist2[dataKey]);
} else if (typeof selection === 'object' && selection[dataKey]) {
reconciled[dataKey] = JSON.parse(JSON.stringify(selection[dataKey]));
reconciled[dataKey] = structuredClone(selection[dataKey]);
}
}
} else {
if (!selection || selection === 'reviewer1') {
// Default to reviewer 1 if no selection
reconciled[key] = JSON.parse(JSON.stringify(checklist1[key]));
reconciled[key] = structuredClone(checklist1[key]);
} else if (selection === 'reviewer2') {
reconciled[key] = JSON.parse(JSON.stringify(checklist2[key]));
reconciled[key] = structuredClone(checklist2[key]);
} else if (typeof selection === 'object') {
// Custom merged answer
reconciled[key] = JSON.parse(JSON.stringify(selection));
reconciled[key] = structuredClone(selection);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

structuredClone() is incompatible with Safari 14 target.

Lines 263, 265, 267, 273, 275, and 278 use structuredClone(), which requires Safari 15.4+ (March 2022). The project targets Safari 14, so this will cause runtime errors. Revert to the original JSON.parse(JSON.stringify(...)) pattern or use a polyfill.

🔎 Proposed fix to restore Safari 14 compatibility
     // Handle multi-part questions (q9 and q11)
     if (isMultiPartQuestion(key)) {
       for (const dataKey of dataKeys) {
         if (!selection || selection === 'reviewer1') {
-          reconciled[dataKey] = structuredClone(checklist1[dataKey]);
+          reconciled[dataKey] = JSON.parse(JSON.stringify(checklist1[dataKey]));
         } else if (selection === 'reviewer2') {
-          reconciled[dataKey] = structuredClone(checklist2[dataKey]);
+          reconciled[dataKey] = JSON.parse(JSON.stringify(checklist2[dataKey]));
         } else if (typeof selection === 'object' && selection[dataKey]) {
-          reconciled[dataKey] = structuredClone(selection[dataKey]);
+          reconciled[dataKey] = JSON.parse(JSON.stringify(selection[dataKey]));
         }
       }
     } else {
       if (!selection || selection === 'reviewer1') {
         // Default to reviewer 1 if no selection
-        reconciled[key] = structuredClone(checklist1[key]);
+        reconciled[key] = JSON.parse(JSON.stringify(checklist1[key]));
       } else if (selection === 'reviewer2') {
-        reconciled[key] = structuredClone(checklist2[key]);
+        reconciled[key] = JSON.parse(JSON.stringify(checklist2[key]));
       } else if (typeof selection === 'object') {
         // Custom merged answer
-        reconciled[key] = structuredClone(selection);
+        reconciled[key] = JSON.parse(JSON.stringify(selection));
       }
     }

Based on learnings and coding guidelines.

📝 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
reconciled[dataKey] = structuredClone(checklist1[dataKey]);
} else if (selection === 'reviewer2') {
reconciled[dataKey] = JSON.parse(JSON.stringify(checklist2[dataKey]));
reconciled[dataKey] = structuredClone(checklist2[dataKey]);
} else if (typeof selection === 'object' && selection[dataKey]) {
reconciled[dataKey] = JSON.parse(JSON.stringify(selection[dataKey]));
reconciled[dataKey] = structuredClone(selection[dataKey]);
}
}
} else {
if (!selection || selection === 'reviewer1') {
// Default to reviewer 1 if no selection
reconciled[key] = JSON.parse(JSON.stringify(checklist1[key]));
reconciled[key] = structuredClone(checklist1[key]);
} else if (selection === 'reviewer2') {
reconciled[key] = JSON.parse(JSON.stringify(checklist2[key]));
reconciled[key] = structuredClone(checklist2[key]);
} else if (typeof selection === 'object') {
// Custom merged answer
reconciled[key] = JSON.parse(JSON.stringify(selection));
reconciled[key] = structuredClone(selection);
reconciled[dataKey] = JSON.parse(JSON.stringify(checklist1[dataKey]));
} else if (selection === 'reviewer2') {
reconciled[dataKey] = JSON.parse(JSON.stringify(checklist2[dataKey]));
} else if (typeof selection === 'object' && selection[dataKey]) {
reconciled[dataKey] = JSON.parse(JSON.stringify(selection[dataKey]));
}
}
} else {
if (!selection || selection === 'reviewer1') {
// Default to reviewer 1 if no selection
reconciled[key] = JSON.parse(JSON.stringify(checklist1[key]));
} else if (selection === 'reviewer2') {
reconciled[key] = JSON.parse(JSON.stringify(checklist2[key]));
} else if (typeof selection === 'object') {
// Custom merged answer
reconciled[key] = JSON.parse(JSON.stringify(selection));
🤖 Prompt for AI Agents
In packages/web/src/AMSTAR2/checklist-compare.js around lines 263 to 278,
several uses of structuredClone(...) (lines 263, 265, 267, 273, 275, 278) are
incompatible with the project target (Safari 14); replace each
structuredClone(call) with a Safari-14-safe deep clone (e.g.,
JSON.parse(JSON.stringify(call))) or add/require a structuredClone polyfill,
ensuring behavior is equivalent for the data shapes used and preserving the same
assignment locations.

Comment on lines +15 to +21
const lastCol = answers.at(-1);
if (!Array.isArray(lastCol)) return null;
const idx = lastCol.findIndex(v => v === true);
const idx = lastCol.indexOf(true);
if (idx === -1) return null;

const question = AMSTAR_CHECKLIST[questionKey];
const lastColumn = question?.columns?.[question.columns.length - 1];
const lastColumn = question?.columns?.at(-1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Array.at() is incompatible with Safari 14 target.

Lines 15 and 21 use Array.at(-1), which requires Safari 15.4+ (March 2022). The project's vite.config.js specifies target: ['es2020', 'safari14'], so this will break for Safari 14 users. Use bracket notation instead: answers[answers.length - 1] and question?.columns?.[question.columns.length - 1].

🔎 Proposed fix for Safari 14 compatibility
 function getFinalAnswerFromAnswers(answers, questionKey) {
   if (!Array.isArray(answers) || answers.length === 0) return null;
-  const lastCol = answers.at(-1);
+  const lastCol = answers[answers.length - 1];
   if (!Array.isArray(lastCol)) return null;
   const idx = lastCol.indexOf(true);
   if (idx === -1) return null;
 
   const question = AMSTAR_CHECKLIST[questionKey];
-  const lastColumn = question?.columns?.at(-1);
+  const lastColumn = question?.columns?.[question.columns.length - 1];
   return lastColumn?.options?.[idx] || null;
 }

Based on learnings and coding guidelines.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
around lines 15 to 21, Array.at(-1) is used which is incompatible with the
project's Safari 14 target; replace `answers.at(-1)` with
`answers[answers.length - 1]` (guarding for empty arrays) and replace
`question?.columns?.at(-1)` with `question?.columns?.[question.columns.length -
1]` (also guarding for undefined/empty columns) so the code uses bracket
indexing compatible with Safari 14 and es2020.

createEffect(() => {
if (props.finalAnswers) {
setLocalFinal(JSON.parse(JSON.stringify(props.finalAnswers)));
setLocalFinal(structuredClone(props.finalAnswers));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

structuredClone() is incompatible with Safari 14 target.

Lines 61, 72, 95, and 104 use structuredClone(), which requires Safari 15.4+ (March 2022). The project targets Safari 14, so this will cause runtime errors. Revert to the original JSON.parse(JSON.stringify(...)) pattern or use a polyfill.

🔎 Proposed fix to restore Safari 14 compatibility
   createEffect(() => {
     if (props.finalAnswers) {
-      setLocalFinal(structuredClone(props.finalAnswers));
+      setLocalFinal(JSON.parse(JSON.stringify(props.finalAnswers)));
       // Determine which source it matches
       if (answersEqual(props.finalAnswers, props.reviewer1Answers)) {
         setSelectedSource('reviewer1');
       } else if (answersEqual(props.finalAnswers, props.reviewer2Answers)) {
         setSelectedSource('reviewer2');
       } else {
         setSelectedSource('custom');
       }
     } else if (props.reviewer1Answers) {
       // Default to reviewer1
-      setLocalFinal(structuredClone(props.reviewer1Answers));
+      setLocalFinal(JSON.parse(JSON.stringify(props.reviewer1Answers)));
       setSelectedSource('reviewer1');
     }
   });

Apply similar changes to lines 95 and 104:

   function useReviewer1() {
     if (!props.reviewer1Answers) return;
-    const newFinal = structuredClone(props.reviewer1Answers);
+    const newFinal = JSON.parse(JSON.stringify(props.reviewer1Answers));
     setLocalFinal(newFinal);
     setSelectedSource('reviewer1');
     props.onFinalChange?.(newFinal);
   }
 
   function useReviewer2() {
     if (!props.reviewer2Answers) return;
-    const newFinal = structuredClone(props.reviewer2Answers);
+    const newFinal = JSON.parse(JSON.stringify(props.reviewer2Answers));
     setLocalFinal(newFinal);
     setSelectedSource('reviewer2');
     props.onFinalChange?.(newFinal);
   }

Based on learnings and coding guidelines.

Also applies to: 72-72, 95-95, 104-104

🤖 Prompt for AI Agents
In
packages/web/src/components/checklist-ui/compare/ReconciliationQuestionPage.jsx
around lines 61, 72, 95, and 104, structuredClone(...) is used but Safari 14 is
a target and structuredClone requires Safari 15.4+, causing runtime errors;
replace each structuredClone(props.finalAnswers) (and similar structuredClone
usages at the other lines) with a Safari-14-safe deep clone such as
JSON.parse(JSON.stringify(...)) or install/enable a structuredClone polyfill,
ensuring the replacement preserves the same cloned value semantics and updating
imports if you add a polyfill.

Comment on lines +238 to 242
for (const [i, canvase] of canvases.entries()) {
if (canvase && !renderedPages.has(i + 1)) {
pagesToRender.push(i + 1);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Variable name typo.

Line 238 has a typo: canvase should be canvas to match the naming convention used throughout the file.

🔎 Proposed fix
-    for (const [i, canvase] of canvases.entries()) {
-      if (canvase && !renderedPages.has(i + 1)) {
+    for (const [i, canvas] of canvases.entries()) {
+      if (canvas && !renderedPages.has(i + 1)) {
         pagesToRender.push(i + 1);
       }
     }
🤖 Prompt for AI Agents
In packages/web/src/components/checklist-ui/pdf/usePdfJs.js around lines 238 to
242, the for-of loop uses a misspelled loop variable `canvase`; rename it to
`canvas` in the destructuring (for (const [i, canvas] of canvases.entries()))
and update any uses inside the loop to `canvas` so the variable name matches the
rest of the file and avoids undefined reference errors.

const sortedPdfs = createMemo(() => {
const pdfs = study().pdfs || [];
return [...pdfs].sort((a, b) => {
return pdfs.toSorted((a, b) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check if the file exists and get the context
echo "=== Checking TodoStudyRow.jsx ===" 
fd TodoStudyRow.jsx -type f 2>/dev/null | head -5

# Check for browser configuration
echo -e "\n=== Checking for browser config files ===" 
fd -e .browserslistrc -e .browserslistrc 2>/dev/null | head -5
fd -e package.json 2>/dev/null | grep -E "^./package.json$|packages/web/package.json$" | head -5

# Check if project root has browserslist config
echo -e "\n=== Root directory config ===" 
ls -la .browserslistrc 2>/dev/null || echo ".browserslistrc not found"
head -10 package.json 2>/dev/null | grep -A 10 "browserslist" || echo "No browserslist in root package.json"

Repository: InfinityBowman/corates

Length of output: 236


🏁 Script executed:

#!/bin/bash

# Search more specifically for the file
echo "=== Searching for TodoStudyRow.jsx ===" 
find . -name "TodoStudyRow.jsx" -type f 2>/dev/null

# Check if packages/web exists and search there
echo -e "\n=== Checking packages/web structure ===" 
ls -la packages/web 2>/dev/null | head -20

# Search for the specific file path
echo -e "\n=== Looking for todo-tab directory ===" 
find . -type d -name "todo-tab" 2>/dev/null

# Check packages/web/package.json for browserslist
echo -e "\n=== Checking packages/web/package.json for browserslist ===" 
cat packages/web/package.json 2>/dev/null | grep -A 10 "browserslist" || echo "No browserslist found"

# Check for root .browserslistrc
echo -e "\n=== Checking all possible browserslist configs ===" 
find . -name ".browserslistrc" -o -name "browserslist" 2>/dev/null | grep -v node_modules

Repository: InfinityBowman/corates

Length of output: 1158


🏁 Script executed:

#!/bin/bash

# Read the actual file to verify the change at line 35
echo "=== TodoStudyRow.jsx content around line 35 ===" 
sed -n '30,40p' ./packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx

# Check vite config for browser targets
echo -e "\n=== vite.config.js ===" 
cat ./packages/web/vite.config.js

# Check root package.json for workspace/monorepo browser config
echo -e "\n=== Root package.json ===" 
cat ./package.json | head -50

# Check if there's any tsconfig or build config that specifies targets
echo -e "\n=== packages/web/jsconfig.json ===" 
cat ./packages/web/jsconfig.json

Repository: InfinityBowman/corates

Length of output: 4690


Update Vite build target or use polyfill for toSorted() compatibility.

The code uses Array.prototype.toSorted(), which requires Safari 16+. However, vite.config.js specifies build.target: ['es2020', 'safari14'], creating a runtime incompatibility for Safari 14 and 15 users.

Either:

  1. Update build target to ['es2020', 'safari16'] if Safari 14-15 support can be dropped
  2. Add a polyfill and revert to [...pdfs].sort(...) pattern
  3. Use the array.prototype.tosorted npm polyfill package
🤖 Prompt for AI Agents
In packages/web/src/components/project-ui/todo-tab/TodoStudyRow.jsx around line
35, the code uses Array.prototype.toSorted(), which is not supported on Safari
14/15 and conflicts with vite.config.js build.target (es2020, safari14); fix by
either (A) replace the call with a compatible pattern like
[...pdfs].sort((a,b)=>...) to avoid needing a polyfill, (B) install and import a
toSorted polyfill (e.g., array.prototype.tosorted) and include it in the app
entry so it loads before usage, or (C) if dropping Safari 14/15 support is
acceptable, update vite.config.js build.target to include 'safari16' (e.g.,
['es2020','safari16']); choose one option and apply the corresponding change
consistently across the repo.


let d = new Date(createdAt);
if (isNaN(d)) d = new Date();
if (Number.isNaN(d)) d = new Date();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Logic error: Number.isNaN() doesn't work with Date objects.

Line 35 uses Number.isNaN(d) where d is a Date object. Number.isNaN() only returns true for the primitive value NaN, not for Date objects with invalid dates. This means invalid dates will never trigger the fallback to new Date(), causing a regression from the original isNaN(d) which coerced the Date to a number first.

🔎 Proposed fix to check for invalid dates correctly
   let d = new Date(createdAt);
-  if (Number.isNaN(d)) d = new Date();
+  if (Number.isNaN(d.getTime())) d = new Date();
   const mm = String(d.getMonth() + 1).padStart(2, '0');
   const dd = String(d.getDate()).padStart(2, '0');
   const formattedDate = `${d.getFullYear()}-${mm}-${dd}`;
📝 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 (Number.isNaN(d)) d = new Date();
let d = new Date(createdAt);
if (Number.isNaN(d.getTime())) d = new Date();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
const formattedDate = `${d.getFullYear()}-${mm}-${dd}`;
🤖 Prompt for AI Agents
In packages/web/src/ROBINS-I/checklist.js around line 35, the code uses
Number.isNaN(d) to detect an invalid Date but Number.isNaN() does not coerce
Date objects so invalid dates will not be detected; replace that check with a
validation of the Date value itself, e.g. ensure d is a Date (or construct one)
and test Number.isNaN(d.getTime()) (or use isNaN(d.getTime())) and if true set d
= new Date(); this guarantees invalid Date objects trigger the fallback.

@InfinityBowman InfinityBowman deleted the 107-add-a-test-function-to-mcp branch December 24, 2025 22:40
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.

Linting adjustments

2 participants