Skip to content

Conversation

@Inglan
Copy link
Member

@Inglan Inglan commented Dec 3, 2025

Note

Remove bundled game assets and static tool content (Cookie Clicker, BitLife, etc.) from the repo.

  • Removal:
    • Delete static/_app/tools/cookieclicker/ assets (scripts, images, locales, HTML, mods), including major JS files (eg. DungeonGen.js, ajax.js, dungeons.js), sound/image lists, and localization files (loc/CS.js, loc/DE.js).
    • Remove BitLife web player files in static/_app/tools/bitlife/ (index.html, TemplateData/UnityProgress.js).
    • Purge assorted static tool/game resources and related content across the static/_app/tools/ directory.

Written by Cursor Bugbot for commit f92ae54. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Added authentication with social sign-in (GitHub, Google, Discord)
    • Introduced 16+ productivity tools (calculator, color picker, hash generator, JSON formatter, QR code, unit converter, and more)
    • Added backup functionality for local and cloud data
    • Implemented admin dashboard for user management
    • Added settings panel with theme customization and privacy controls
    • Introduced command palette and global search
    • Integrated PostHog analytics
  • Infrastructure

    • Migrated from pnpm to Bun package manager
    • Updated CI/CD workflows and Docker configuration
    • Restructured environment variables for Vite compatibility
  • Documentation

    • Updated setup instructions for Bun workflow

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

@vercel
Copy link

vercel bot commented Dec 3, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
edutools Ready Ready Preview Comment Dec 3, 2025 7:18am

@Inglan Inglan enabled auto-merge December 3, 2025 07:18
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This PR performs a comprehensive project restructuring: migrates from pnpm to Bun as package manager, transitions from Svelte to React Router framework, adds Convex backend with Better Auth authentication, introduces 20+ utility tool routes, establishes a complete ShadCN/UI component library, and updates all CI/CD workflows accordingly. Includes new environment variable schema for Vite/PostHog and setup scripts for worktree configuration.

Changes

Cohort / File(s) Summary
Configuration & Package Management
.coderabbit.yaml, .npmrc, .prettier*, .vscode/settings.json, components.json
Quote normalization in YAML, removed engine-strict constraint, replaced Svelte-based ShadCN schema with React/UI schema, cleared Prettier config, removed VSCode pnpm enforcement
Environment & Build Configuration
.env.example, Dockerfile, .dockerignore, .gitignore, .gitmodules
Updated env vars from PUBLIC_CONVEX_URL to VITE_CONVEX_* and added PostHog keys; added multi-stage Docker build; new gitmodule for asset submodule; refined ignore patterns
CI/CD Workflows
.github/workflows/*, .github/ISSUE_TEMPLATE/*
Replaced pnpm with Bun (setup, install, build commands); updated artifact paths to ./build/client; added submodules recursive; standardized quote styles in YAML templates
Documentation & Scripts
README.md, .github/copilot-instructions.md, convex/README.md, .cursor/setup-worktree-*, .cursor/rules/posthog-integration.mdc, .cursor/worktrees.json
Updated build/dev commands to use Bun; removed legacy copilot guide; added setup scripts for Unix/Windows; added PostHog integration rules and worktree configuration
Root Application
app/root.tsx, app/routes.ts, app/app.css
New comprehensive root layout with theming, auth integration, PostHog analytics, experimental feature flags, and global styles; added centralized route configuration
Core Route Pages
app/routes/about/page.tsx, app/routes/privacy/page.tsx, app/routes/backups/page.tsx, app/routes/admin/page.tsx, app/routes/auth/*, app/routes/g/*, app/routes/home.tsx
New pages for about, privacy, backups with cloud sync, admin user management, authentication (OTT, auth-view, account-view), game/gmae list and play views, home with saved/history sections
Tool Utility Routes
app/routes/tools/*
18 new tool pages (calculator, color-picker, hash-generator, JSON formatter, markdown preview, number-base converter, password generator, QR code, random number, regex tester, roman numeral, stopwatch/timer, text case, unit converter, URL encoder, UUID generator, word counter, base64 converter)
Admin & Game Components
app/routes/admin/columns.tsx, app/routes/admin/data-table.tsx, app/routes/g/columns.tsx, app/routes/g/data-table.tsx
Data table column and table component definitions for user and game management with sorting, filtering, pagination
Application Components
components/app-sidebar.tsx, components/header.tsx, components/command-palette.tsx, components/search.tsx, components/settings.tsx, components/hotkeys.tsx, components/loading-overlay.tsx, components/theme-*.tsx
New app chrome: collapsible sidebar, sticky header, command palette, search interface with experimental toggle, comprehensive settings (theme, panic mode, privacy, destructive actions), global hotkeys, loading overlay, theme selectors
UI Component Library
components/ui/*
40+ reusable UI components: alert-dialog, breadcrumb, button, button-group, card, checkbox, collapsible, command, dialog, drawer, dropdown-menu, empty, input, kbd, popover, separator, sheet, sidebar, skeleton, sonner (toast), spinner, switch, table, tabs, tooltip
Authentication & Backend
convex/auth.ts, convex/auth.config.ts, convex/backups.ts, convex/betterAuth/*, convex/convex.config.ts, convex/README.md
Convex backend integration: Better Auth instance with GitHub/Google/Discord providers; backup CRUD mutations/queries; adapter and schema for Better Auth; Convex app configuration
Metadata & Lists
LICENSE
Minor URL adjustment in GPL text

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Authentication and backend logic (convex/auth.ts, convex/backups.ts) — complex Better Auth integration with multiple plugins, OAuth flows, user policies, and database operations; verify permission checks and error handling
  • Admin page (app/routes/admin/page.tsx) — high interaction complexity with user management, role changes, ban/unban workflows, session management; validate all state transitions and error flows
  • Root layout (app/root.tsx) — orchestrates theming, feature flags, auth, PostHog integration, and multiple UI state providers; verify initialization order and side effects
  • CI/CD workflow updates — build path changes (./build./build/client), environment variable substitution, and Bun command changes; ensure all deployment targets are correctly updated
  • Convex schema and adapter (convex/betterAuth/schema.ts, convex/betterAuth/adapter.ts) — auto-generated or derived from external config; verify indices and relationships match expected data access patterns
  • UI component composition — while mostly wrapper patterns, verify that global state hooks (blur, theme, experimental features) are correctly passed through all modal and overlay components
  • Backup feature (app/routes/backups/page.tsx) — optimistic updates and cloud backup sync logic; validate error recovery and data consistency

Possibly related PRs

Suggested reviewers

  • nathblade16
✨ 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 main

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e00113f and f92ae54.

⛔ Files ignored due to path filters (22)
  • bun.lock is excluded by !**/*.lock
  • convex/_generated/api.d.ts is excluded by !**/_generated/**
  • convex/_generated/api.js is excluded by !**/_generated/**
  • convex/_generated/dataModel.d.ts is excluded by !**/_generated/**
  • convex/_generated/server.d.ts is excluded by !**/_generated/**
  • convex/_generated/server.js is excluded by !**/_generated/**
  • convex/betterAuth/_generated/api.ts is excluded by !**/_generated/**
  • convex/betterAuth/_generated/component.ts is excluded by !**/_generated/**
  • convex/betterAuth/_generated/dataModel.ts is excluded by !**/_generated/**
  • convex/betterAuth/_generated/server.ts is excluded by !**/_generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • public/apple-touch-icon.png is excluded by !**/*.png
  • public/edutools-black.png is excluded by !**/*.png
  • public/edutools-black.svg is excluded by !**/*.svg
  • public/edutools-white.png is excluded by !**/*.png
  • public/edutools-white.svg is excluded by !**/*.svg
  • public/favicon.ico is excluded by !**/*.ico
  • public/favicon.png is excluded by !**/*.png
  • public/icon-192-maskable.png is excluded by !**/*.png
  • public/icon-192.png is excluded by !**/*.png
  • public/icon-512-maskable.png is excluded by !**/*.png
  • public/icon-512.png is excluded by !**/*.png
📒 Files selected for processing (107)
  • .coderabbit.yaml (1 hunks)
  • .cursor/rules/posthog-integration.mdc (1 hunks)
  • .cursor/setup-worktree-unix.sh (1 hunks)
  • .cursor/setup-worktree-windows.ps1 (1 hunks)
  • .cursor/worktrees.json (1 hunks)
  • .dockerignore (1 hunks)
  • .env.example (1 hunks)
  • .github/ISSUE_TEMPLATE/bug_report.yml (1 hunks)
  • .github/ISSUE_TEMPLATE/feature_request.yml (1 hunks)
  • .github/ISSUE_TEMPLATE/gmae_request.yml (2 hunks)
  • .github/ISSUE_TEMPLATE/tool_request.yml (1 hunks)
  • .github/copilot-instructions.md (0 hunks)
  • .github/dependabot.yml (1 hunks)
  • .github/workflows/beta_deploy.yml (3 hunks)
  • .github/workflows/build.yml (1 hunks)
  • .github/workflows/deploy.yml (1 hunks)
  • .github/workflows/format.yml (1 hunks)
  • .github/workflows/issue.yml (2 hunks)
  • .github/workflows/production_deploy.yml (2 hunks)
  • .gitignore (1 hunks)
  • .gitmodules (1 hunks)
  • .npmrc (0 hunks)
  • .prettierignore (0 hunks)
  • .prettierrc (0 hunks)
  • .vscode/settings.json (0 hunks)
  • Dockerfile (1 hunks)
  • LICENSE (1 hunks)
  • README.md (1 hunks)
  • app/app.css (1 hunks)
  • app/root.tsx (1 hunks)
  • app/routes.ts (1 hunks)
  • app/routes/about/page.tsx (1 hunks)
  • app/routes/admin/columns.tsx (1 hunks)
  • app/routes/admin/data-table.tsx (1 hunks)
  • app/routes/admin/page.tsx (1 hunks)
  • app/routes/auth/account-view.tsx (1 hunks)
  • app/routes/auth/auth-view.tsx (1 hunks)
  • app/routes/auth/ott.tsx (1 hunks)
  • app/routes/backups/page.tsx (1 hunks)
  • app/routes/g/columns.tsx (1 hunks)
  • app/routes/g/data-table.tsx (1 hunks)
  • app/routes/g/index.tsx (1 hunks)
  • app/routes/g/play.tsx (1 hunks)
  • app/routes/home.tsx (1 hunks)
  • app/routes/privacy/page.tsx (1 hunks)
  • app/routes/tools/base64-converter.tsx (1 hunks)
  • app/routes/tools/calculator.tsx (1 hunks)
  • app/routes/tools/color-picker.tsx (1 hunks)
  • app/routes/tools/hash-generator.tsx (1 hunks)
  • app/routes/tools/json-formatter.tsx (1 hunks)
  • app/routes/tools/markdown-preview.tsx (1 hunks)
  • app/routes/tools/number-base.tsx (1 hunks)
  • app/routes/tools/password-generator.tsx (1 hunks)
  • app/routes/tools/qr-code-generator.tsx (1 hunks)
  • app/routes/tools/random-number.tsx (1 hunks)
  • app/routes/tools/regex-tester.tsx (1 hunks)
  • app/routes/tools/roman-numeral.tsx (1 hunks)
  • app/routes/tools/stopwatch-timer.tsx (1 hunks)
  • app/routes/tools/text-case.tsx (1 hunks)
  • app/routes/tools/unit-converter.tsx (1 hunks)
  • app/routes/tools/url-encoder.tsx (1 hunks)
  • app/routes/tools/uuid-generator.tsx (1 hunks)
  • app/routes/tools/word-counter.tsx (1 hunks)
  • components.json (1 hunks)
  • components/app-sidebar.tsx (1 hunks)
  • components/command-palette.tsx (1 hunks)
  • components/header.tsx (1 hunks)
  • components/hotkeys.tsx (1 hunks)
  • components/loading-overlay.tsx (1 hunks)
  • components/search.tsx (1 hunks)
  • components/settings.tsx (1 hunks)
  • components/theme-mode-selector.tsx (1 hunks)
  • components/theme-selector.tsx (1 hunks)
  • components/ui/alert-dialog.tsx (1 hunks)
  • components/ui/breadcrumb.tsx (1 hunks)
  • components/ui/button-group.tsx (1 hunks)
  • components/ui/button.tsx (1 hunks)
  • components/ui/card.tsx (1 hunks)
  • components/ui/checkbox.tsx (1 hunks)
  • components/ui/collapsible.tsx (1 hunks)
  • components/ui/command.tsx (1 hunks)
  • components/ui/dialog.tsx (1 hunks)
  • components/ui/drawer.tsx (1 hunks)
  • components/ui/dropdown-menu.tsx (1 hunks)
  • components/ui/empty.tsx (1 hunks)
  • components/ui/input.tsx (1 hunks)
  • components/ui/kbd.tsx (1 hunks)
  • components/ui/popover.tsx (1 hunks)
  • components/ui/separator.tsx (1 hunks)
  • components/ui/sheet.tsx (1 hunks)
  • components/ui/sidebar.tsx (1 hunks)
  • components/ui/skeleton.tsx (1 hunks)
  • components/ui/sonner.tsx (1 hunks)
  • components/ui/spinner.tsx (1 hunks)
  • components/ui/switch.tsx (1 hunks)
  • components/ui/table.tsx (1 hunks)
  • components/ui/tabs.tsx (1 hunks)
  • components/ui/tooltip.tsx (1 hunks)
  • convex/README.md (1 hunks)
  • convex/auth.config.ts (1 hunks)
  • convex/auth.ts (1 hunks)
  • convex/backups.ts (1 hunks)
  • convex/betterAuth/adapter.ts (1 hunks)
  • convex/betterAuth/auth.ts (1 hunks)
  • convex/betterAuth/convex.config.ts (1 hunks)
  • convex/betterAuth/schema.ts (1 hunks)
  • convex/convex.config.ts (1 hunks)
⛔ Files not processed due to max files limit (30)
  • convex/html.ts
  • convex/http.ts
  • convex/schema.ts
  • convex/trustedmirrors.ts
  • convex/tsconfig.json
  • hooks/use-cloak.ts
  • hooks/use-mobile.ts
  • lib/auth-client.ts
  • lib/auth/ott/client.ts
  • lib/auth/ott/index.ts
  • lib/auth/ott/utils.ts
  • lib/backups/create-backup.ts
  • lib/backups/restore-backup.ts
  • lib/constants.ts
  • lib/experimental-check.ts
  • lib/gmaes.ts
  • lib/idgen.ts
  • lib/menu.ts
  • lib/state.ts
  • lib/themes/better-catppuccin.css
  • lib/themes/catppuccin.css
  • lib/themes/default.css
  • lib/themes/ingo-au.css
  • lib/themes/mono.css
  • lib/themes/noeco.css
  • lib/themes/terminal.css
  • lib/themes/themes.ts
  • lib/tools.ts
  • lib/utils.ts
  • package.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Inglan Inglan merged commit 827e81f into prod Dec 3, 2025
14 of 16 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on January 20

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

lastIndex = regex.lastIndex;

if (!flags.global) break;
}
Copy link

Choose a reason for hiding this comment

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

Bug: Regex tester can freeze browser with zero-length matches

The highlightMatches function can cause an infinite loop and freeze the browser. This happens when a global regex matches a zero-length string, as regex.exec() doesn't advance regex.lastIndex in such cases.

Fix in Cursor Fix in Web

onClick={() => {
setIndentation(2);
if (output && !error) formatJson();
}}
Copy link

Choose a reason for hiding this comment

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

Bug: JSON formatter uses stale indentation value after state change

When clicking the indentation buttons (2 Spaces / 4 Spaces), setIndentation() is called immediately followed by formatJson(). However, React state updates are asynchronous, so formatJson() captures the old indentation value from the closure rather than the newly set value. The output won't reflect the selected indentation until a second format action is triggered.

Additional Locations (1)

Fix in Cursor Fix in Web

COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["npm", "run", "start"] No newline at end of file
Copy link

Choose a reason for hiding this comment

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

Bug: Dockerfile uses npm but project migrated to bun

The Dockerfile uses npm ci with package-lock.json, but the project has migrated to bun (as seen in README, GitHub workflows, and setup scripts). The package-lock.json file won't exist when using bun (which generates bun.lockb), causing the Docker build to fail when copying or installing dependencies.

Fix in Cursor Fix in Web

.catch((error) => {
if (error == "AbortError: Share canceled") return;
toast.error("Failed to share");
});
Copy link

Choose a reason for hiding this comment

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

Bug: Share cancellation incorrectly triggers error toast

The error handling in the share function compares an Error object to a string using error == "AbortError: Share canceled". When users cancel the Web Share dialog, the browser throws a DOMException object with name === "AbortError", not a string. This comparison will always be false, causing "Failed to share" toast to appear whenever users intentionally cancel sharing. The check needs to compare error.name === "AbortError" instead.

Fix in Cursor Fix in Web

if (ctx) {
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, size, size);
ctx.drawImage(img, 0, 0);
Copy link

Choose a reason for hiding this comment

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

Bug: QR code download renders wrong size when exceeding preview cap

The QR code preview is capped at 280px (size > 280 ? 280 : size) but the download function creates a canvas at the user-selected size. Since ctx.drawImage(img, 0, 0) is called without explicit dimensions, the 280px SVG is drawn at its native size on a potentially 512px canvas. When a user selects 512px, they get a 512x512 PNG with the QR code only occupying a 280x280 area in the top-left corner. The comment claims "real size for download" but the SVG dimensions are what get drawn.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

2 participants